blob: 6be98739a159ba120e0e651afa0e74a61f885606 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% DDDD RRRR AAA W W IIIII N N GGGG %
7% D D R R A A W W I NN N G %
8% D D RRRR AAAAA W W I N N N G GG %
9% D D R R A A W W W I N NN G G %
10% DDDD R R A A W W IIIII N N GGG %
11% %
12% W W AAA N N DDDD %
13% W W A A NN N D D %
14% W W W AAAAA N N N D D %
15% WW WW A A N NN D D %
16% W W A A N N DDDD %
17% %
18% %
19% MagickWand Image Vector Drawing Methods %
20% %
21% Software Design %
22% Bob Friesenhahn %
23% March 2002 %
24% %
25% %
cristy16af1cb2009-12-11 21:38:29 +000026% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000027% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42%
43%
44*/
45
46/*
47 Include declarations.
48*/
49#include "wand/studio.h"
50#include "wand/MagickWand.h"
51#include "wand/magick-wand-private.h"
52#include "wand/wand.h"
cristyf2f27272009-12-17 14:48:46 +000053#include "magick/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000054
55/*
56 Define declarations.
57*/
58#define DRAW_BINARY_IMPLEMENTATION 0
59
60#define CurrentContext (wand->graphic_context[wand->index])
61#define DrawingWandId "DrawingWand"
62#define ThrowDrawException(severity,tag,reason) (void) ThrowMagickException( \
63 wand->exception,GetMagickModule(),severity,tag,"`%s'",reason);
64
65/*
66 Typedef declarations.
67*/
68typedef enum
69{
70 PathDefaultOperation,
71 PathCloseOperation, /* Z|z (none) */
72 PathCurveToOperation, /* C|c (x1 y1 x2 y2 x y)+ */
73 PathCurveToQuadraticBezierOperation, /* Q|q (x1 y1 x y)+ */
74 PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
75 PathCurveToSmoothOperation, /* S|s (x2 y2 x y)+ */
76 PathEllipticArcOperation, /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
77 PathLineToHorizontalOperation, /* H|h x+ */
78 PathLineToOperation, /* L|l (x y)+ */
79 PathLineToVerticalOperation, /* V|v y+ */
80 PathMoveToOperation /* M|m (x y)+ */
81} PathOperation;
82
83typedef enum
84{
85 DefaultPathMode,
86 AbsolutePathMode,
87 RelativePathMode
88} PathMode;
89
90struct _DrawingWand
91{
cristybb503372010-05-27 20:51:26 +000092 size_t
cristy3ed852e2009-09-05 21:47:34 +000093 id;
94
95 char
96 name[MaxTextExtent];
97
98 /* Support structures */
99 Image
100 *image;
101
102 ExceptionInfo
103 *exception;
104
105 /* MVG output string and housekeeping */
106 char
107 *mvg; /* MVG data */
108
109 size_t
110 mvg_alloc, /* total allocated memory */
111 mvg_length; /* total MVG length */
112
cristybb503372010-05-27 20:51:26 +0000113 size_t
cristy3ed852e2009-09-05 21:47:34 +0000114 mvg_width; /* current line width */
115
116 /* Pattern support */
117 char
118 *pattern_id;
119
120 RectangleInfo
121 pattern_bounds;
122
123 size_t
124 pattern_offset;
125
126 /* Graphic wand */
cristybb503372010-05-27 20:51:26 +0000127 size_t
cristy3ed852e2009-09-05 21:47:34 +0000128 index; /* array index */
129
130 DrawInfo
131 **graphic_context;
132
133 MagickBooleanType
134 filter_off; /* true if not filtering attributes */
135
136 /* Pretty-printing depth */
cristybb503372010-05-27 20:51:26 +0000137 size_t
cristy3ed852e2009-09-05 21:47:34 +0000138 indent_depth; /* number of left-hand pad characters */
139
140 /* Path operation support */
141 PathOperation
142 path_operation;
143
144 PathMode
145 path_mode;
146
147 MagickBooleanType
148 destroy,
149 debug;
150
cristybb503372010-05-27 20:51:26 +0000151 size_t
cristy3ed852e2009-09-05 21:47:34 +0000152 signature;
153};
154
155/* Vector table for invoking subordinate renderers */
156struct _DrawVTable
157{
158 DrawingWand *(*DestroyDrawingWand) (DrawingWand *);
159 void (*DrawAnnotation)(DrawingWand *,const double,const double,
160 const unsigned char *);
161 void (*DrawArc)(DrawingWand *,const double,const double,const double,
162 const double,const double,const double);
cristybb503372010-05-27 20:51:26 +0000163 void (*DrawBezier)(DrawingWand *,const size_t,const PointInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000164 void (*DrawCircle)(DrawingWand *,const double,const double,const double,
165 const double);
166 void (*DrawColor)(DrawingWand *,const double,const double,const PaintMethod);
167 void (*DrawComment)(DrawingWand *,const char *);
168 void (*DrawEllipse)(DrawingWand *,const double,const double,const double,
169 const double,const double,const double);
170 MagickBooleanType (*DrawComposite)(DrawingWand *,const CompositeOperator,
171 const double,const double,const double,const double,const Image *);
172 void (*DrawLine)(DrawingWand *,const double,const double,const double,
173 const double);
174 void (*DrawMatte)(DrawingWand *,const double,const double,const PaintMethod);
175 void (*DrawPathClose)(DrawingWand *);
176 void (*DrawPathCurveToAbsolute)(DrawingWand *,const double,const double,
177 const double,const double,const double,const double);
178 void (*DrawPathCurveToRelative)(DrawingWand *,const double,const double,
179 const double,const double,const double,const double);
180 void (*DrawPathCurveToQuadraticBezierAbsolute)(DrawingWand *,const double,
181 const double,const double,const double);
182 void (*DrawPathCurveToQuadraticBezierRelative)(DrawingWand *,const double,
183 const double,const double,const double);
184 void (*DrawPathCurveToQuadraticBezierSmoothAbsolute)(DrawingWand *,
185 const double,const double);
186 void (*DrawPathCurveToQuadraticBezierSmoothRelative)(DrawingWand *,
187 const double,const double);
188 void (*DrawPathCurveToSmoothAbsolute)(DrawingWand *,const double,
189 const double,const double,const double);
190 void (*DrawPathCurveToSmoothRelative)(DrawingWand *,const double,
191 const double,const double,const double);
192 void (*DrawPathEllipticArcAbsolute)(DrawingWand *,const double,const double,
193 const double,const MagickBooleanType,const MagickBooleanType,const double,
194 const double);
195 void (*DrawPathEllipticArcRelative)(DrawingWand *,const double,const double,
196 const double,const MagickBooleanType,const MagickBooleanType,const double,
197 const double);
198 void (*DrawPathFinish)(DrawingWand *);
199 void (*DrawPathLineToAbsolute)(DrawingWand *,const double,const double);
200 void (*DrawPathLineToRelative)(DrawingWand *,const double,const double);
201 void (*DrawPathLineToHorizontalAbsolute)(DrawingWand *,const double);
202 void (*DrawPathLineToHorizontalRelative)(DrawingWand *,const double);
203 void (*DrawPathLineToVerticalAbsolute)(DrawingWand *,const double);
204 void (*DrawPathLineToVerticalRelative)(DrawingWand *,const double);
205 void (*DrawPathMoveToAbsolute)(DrawingWand *,const double,const double);
206 void (*DrawPathMoveToRelative)(DrawingWand *,const double,const double);
207 void (*DrawPathStart)(DrawingWand *);
208 void (*DrawPoint)(DrawingWand *,const double,const double);
cristybb503372010-05-27 20:51:26 +0000209 void (*DrawPolygon)(DrawingWand *,const size_t,const PointInfo *);
210 void (*DrawPolyline)(DrawingWand *,const size_t,const PointInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000211 void (*DrawPopClipPath)(DrawingWand *);
212 void (*DrawPopDefs)(DrawingWand *);
213 MagickBooleanType (*DrawPopPattern)(DrawingWand *);
214 void (*DrawPushClipPath)(DrawingWand *,const char *);
215 void (*DrawPushDefs)(DrawingWand *);
216 MagickBooleanType (*DrawPushPattern)(DrawingWand *,const char *,const double,
217 const double,const double,const double);
218 void (*DrawRectangle)(DrawingWand *,const double,const double,const double,
219 const double);
220 void (*DrawRoundRectangle)(DrawingWand *,double,double,double,double,
221 double,double);
222 void (*DrawAffine)(DrawingWand *,const AffineMatrix *);
223 MagickBooleanType (*DrawSetClipPath)(DrawingWand *,const char *);
224 void (*DrawSetBorderColor)(DrawingWand *,const PixelWand *);
225 void (*DrawSetClipRule)(DrawingWand *,const FillRule);
226 void (*DrawSetClipUnits)(DrawingWand *,const ClipPathUnits);
227 void (*DrawSetFillColor)(DrawingWand *,const PixelWand *);
228 void (*DrawSetFillRule)(DrawingWand *,const FillRule);
229 MagickBooleanType (*DrawSetFillPatternURL)(DrawingWand *,const char *);
230 MagickBooleanType (*DrawSetFont)(DrawingWand *,const char *);
231 MagickBooleanType (*DrawSetFontFamily)(DrawingWand *,const char *);
232 void (*DrawSetTextKerning)(DrawingWand *,const double);
233 void (*DrawSetTextInterwordSpacing)(DrawingWand *,const double);
234 double (*DrawGetTextKerning)(DrawingWand *);
235 double (*DrawGetTextInterwordSpacing)(DrawingWand *);
236 void (*DrawSetFontSize)(DrawingWand *,const double);
237 void (*DrawSetFontStretch)(DrawingWand *,const StretchType);
238 void (*DrawSetFontStyle)(DrawingWand *,const StyleType);
cristybb503372010-05-27 20:51:26 +0000239 void (*DrawSetFontWeight)(DrawingWand *,const size_t);
cristy3ed852e2009-09-05 21:47:34 +0000240 void (*DrawSetGravity)(DrawingWand *,const GravityType);
241 void (*DrawRotate)(DrawingWand *,const double);
242 void (*DrawScale)(DrawingWand *,const double,const double);
243 void (*DrawSkewX)(DrawingWand *,const double);
244 void (*DrawSkewY)(DrawingWand *,const double);
245 void (*DrawSetStrokeAntialias)(DrawingWand *,const MagickBooleanType);
246 void (*DrawSetStrokeColor)(DrawingWand *,const PixelWand *);
247 MagickBooleanType (*DrawSetStrokeDashArray)(DrawingWand *,const double *);
248 void (*DrawSetStrokeDashOffset)(DrawingWand *,const double);
249 void (*DrawSetStrokeLineCap)(DrawingWand *,const LineCap);
250 void (*DrawSetStrokeLineJoin)(DrawingWand *,const LineJoin);
cristybb503372010-05-27 20:51:26 +0000251 void (*DrawSetStrokeMiterLimit)(DrawingWand *,const size_t);
cristy3ed852e2009-09-05 21:47:34 +0000252 MagickBooleanType (*DrawSetStrokePatternURL)(DrawingWand *,const char *);
253 void (*DrawSetStrokeWidth)(DrawingWand *,const double);
254 void (*DrawSetTextAntialias)(DrawingWand *,const MagickBooleanType);
255 void (*DrawSetTextDecoration)(DrawingWand *,const DecorationType);
256 void (*DrawSetTextUnderColor)(DrawingWand *,const PixelWand *);
257 void (*DrawTranslate)(DrawingWand *,const double,const double);
cristybb503372010-05-27 20:51:26 +0000258 void (*DrawSetViewbox)(DrawingWand *,size_t,size_t,
259 size_t,size_t);
cristy3ed852e2009-09-05 21:47:34 +0000260 void (*PeekDrawingWand)(DrawingWand *);
261 MagickBooleanType (*PopDrawingWand)(DrawingWand *);
262 MagickBooleanType (*PushDrawingWand)(DrawingWand *);
263};
264
265/*
266 Forward declarations.
267*/
268static int
269 MvgPrintf(DrawingWand *,const char *,...) wand_attribute((format
270 (printf,2,3))),
271 MvgAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format
272 (printf,2,3)));
273
274static void
275 MvgAppendColor(DrawingWand *,const PixelPacket *);
276
277/*
278 "Printf" for MVG commands
279*/
280static int MvgPrintf(DrawingWand *wand,const char *format,...)
281{
282 size_t
283 alloc_size;
284
285 if (wand->debug != MagickFalse)
286 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format);
287 assert(wand != (DrawingWand *) NULL);
288 assert(wand->signature == WandSignature);
289 alloc_size=20UL*MaxTextExtent;
290 if (wand->mvg == (char *) NULL)
291 {
292 wand->mvg=(char *) AcquireQuantumMemory(alloc_size,sizeof(*wand->mvg));
293 if (wand->mvg == (char *) NULL)
294 {
295 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
296 wand->name);
297 return(-1);
298 }
299 wand->mvg_alloc=alloc_size;
300 wand->mvg_length=0;
301 }
302 if (wand->mvg_alloc < (wand->mvg_length+10*MaxTextExtent))
303 {
304 size_t
305 realloc_size;
306
307 realloc_size=wand->mvg_alloc+alloc_size;
308 wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,realloc_size,
309 sizeof(*wand->mvg));
310 if (wand->mvg == (char *) NULL)
311 {
312 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
313 wand->name);
314 return -1;
315 }
316 wand->mvg_alloc=realloc_size;
317 }
318 {
319 int
320 formatted_length;
321
322 va_list
323 argp;
324
325 while (wand->mvg_width < wand->indent_depth)
326 {
327 wand->mvg[wand->mvg_length]=' ';
328 wand->mvg_length++;
329 wand->mvg_width++;
330 }
331 wand->mvg[wand->mvg_length]='\0';
332 va_start(argp, format);
333#if defined(MAGICKCORE_HAVE_VSNPRINTF)
334 formatted_length=vsnprintf(wand->mvg+wand->mvg_length,
335 wand->mvg_alloc-wand->mvg_length-1,format,argp);
336#else
337 formatted_length=vsprintf(wand->mvg+wand->mvg_length,
338 format,argp);
339#endif
340 va_end(argp);
341 if (formatted_length < 0)
342 ThrowDrawException(DrawError,"UnableToPrint",format)
343 else
344 {
345 wand->mvg_length+=formatted_length;
346 wand->mvg_width+=formatted_length;
347 }
348 wand->mvg[wand->mvg_length]='\0';
349 if ((wand->mvg_length > 1) &&
350 (wand->mvg[wand->mvg_length-1] == '\n'))
351 wand->mvg_width=0;
352 assert((wand->mvg_length+1) < wand->mvg_alloc);
353 return formatted_length;
354 }
355}
356
357static int MvgAutoWrapPrintf(DrawingWand *wand,const char *format,...)
358{
359 char
360 buffer[MaxTextExtent];
361
362 int
363 formatted_length;
364
365 va_list
366 argp;
367
368 va_start(argp,format);
369#if defined(MAGICKCORE_HAVE_VSNPRINTF)
370 formatted_length=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
371#else
372 formatted_length=vsprintf(buffer,format,argp);
373#endif
374 va_end(argp);
375 *(buffer+sizeof(buffer)-1)='\0';
376 if (formatted_length < 0)
377 ThrowDrawException(DrawError,"UnableToPrint",format)
378 else
379 {
380 if (((wand->mvg_width + formatted_length) > 78) &&
381 (buffer[formatted_length-1] != '\n'))
382 (void) MvgPrintf(wand, "\n");
383 (void) MvgPrintf(wand,"%s",buffer);
384 }
385 return(formatted_length);
386}
387
388static void MvgAppendColor(DrawingWand *wand,const PixelPacket *color)
389{
390 if ((color->red == 0) && (color->green == 0) && (color->blue == 0) &&
391 (color->opacity == (Quantum) TransparentOpacity))
392 (void) MvgPrintf(wand,"none");
393 else
394 {
395 char
396 tuple[MaxTextExtent];
397
398 MagickPixelPacket
399 pixel;
400
401 GetMagickPixelPacket(wand->image,&pixel);
402 pixel.colorspace=RGBColorspace;
403 pixel.matte=color->opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
404 pixel.red=(MagickRealType) color->red;
405 pixel.green=(MagickRealType) color->green;
406 pixel.blue=(MagickRealType) color->blue;
407 pixel.opacity=(MagickRealType) color->opacity;
408 GetColorTuple(&pixel,MagickTrue,tuple);
409 (void) MvgPrintf(wand,"%s",tuple);
410 }
411}
412
413static void MvgAppendPointsCommand(DrawingWand *wand,const char *command,
cristybb503372010-05-27 20:51:26 +0000414 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +0000415{
416 const PointInfo
417 *coordinate;
418
cristybb503372010-05-27 20:51:26 +0000419 size_t
cristy3ed852e2009-09-05 21:47:34 +0000420 i;
421
422 (void) MvgPrintf(wand,"%s",command);
423 for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
424 {
cristye7f51092010-01-17 00:39:37 +0000425 (void) MvgAutoWrapPrintf(wand," %g,%g",coordinate->x,coordinate->y);
cristy3ed852e2009-09-05 21:47:34 +0000426 coordinate++;
427 }
428 (void) MvgPrintf(wand, "\n");
429}
430
431static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine)
432{
433 assert(wand != (DrawingWand *) NULL);
434 assert(wand->signature == WandSignature);
435 if (wand->debug != MagickFalse)
436 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
437 if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
438 (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
439 {
440 AffineMatrix
441 current;
442
443 current=CurrentContext->affine;
444 CurrentContext->affine.sx=current.sx*affine->sx+current.ry*affine->rx;
445 CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
446 CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
447 CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
448 CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+
449 current.tx;
450 CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+
451 current.ty;
452 }
453}
454
455/*
456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457% %
458% %
459% %
460% C l e a r D r a w i n g W a n d %
461% %
462% %
463% %
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465%
466% ClearDrawingWand() clear resources associated with the drawing wand.
467%
468% The format of the ClearDrawingWand method is:
469%
470% DrawingWand *ClearDrawingWand(DrawingWand *wand)
471%
472% A description of each parameter follows:
473%
474% o wand: the drawing wand. to destroy
475%
476*/
477WandExport void ClearDrawingWand(DrawingWand *wand)
478{
479 assert(wand != (DrawingWand *) NULL);
480 assert(wand->signature == WandSignature);
481 if (wand->debug != MagickFalse)
482 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
483 for ( ; wand->index > 0; wand->index--)
484 CurrentContext=DestroyDrawInfo(CurrentContext);
485 CurrentContext=DestroyDrawInfo(CurrentContext);
486 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
487 wand->graphic_context);
488 if (wand->pattern_id != (char *) NULL)
489 wand->pattern_id=DestroyString(wand->pattern_id);
490 wand->mvg=DestroyString(wand->mvg);
491 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
492 wand->image=DestroyImage(wand->image);
493 else
494 wand->image=(Image *) NULL;
495 wand->mvg=(char *) NULL;
496 wand->mvg_alloc=0;
497 wand->mvg_length=0;
498 wand->mvg_width=0;
499 wand->pattern_id=(char *) NULL;
500 wand->pattern_offset=0;
501 wand->pattern_bounds.x=0;
502 wand->pattern_bounds.y=0;
503 wand->pattern_bounds.width=0;
504 wand->pattern_bounds.height=0;
505 wand->index=0;
506 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
507 sizeof(*wand->graphic_context));
508 if (wand->graphic_context == (DrawInfo **) NULL)
509 {
510 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
511 wand->name);
512 return;
513 }
514 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
515 wand->filter_off=MagickTrue;
516 wand->indent_depth=0;
517 wand->path_operation=PathDefaultOperation;
518 wand->path_mode=DefaultPathMode;
519 wand->image=AcquireImage((const ImageInfo *) NULL);
520 ClearMagickException(wand->exception);
521 wand->destroy=MagickTrue;
522 wand->debug=IsEventLogging();
523}
524
525/*
526%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
527% %
528% %
529% %
530% C l o n e D r a w i n g W a n d %
531% %
532% %
533% %
534%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
535%
536% CloneDrawingWand() makes an exact copy of the specified wand.
537%
538% The format of the CloneDrawingWand method is:
539%
540% DrawingWand *CloneDrawingWand(const DrawingWand *wand)
541%
542% A description of each parameter follows:
543%
544% o wand: the magick wand.
545%
546*/
547WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
548{
549 DrawingWand
550 *clone_wand;
551
cristybb503372010-05-27 20:51:26 +0000552 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000553 i;
554
555 assert(wand != (DrawingWand *) NULL);
556 assert(wand->signature == WandSignature);
557 if (wand->debug != MagickFalse)
558 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy90823212009-12-12 20:48:33 +0000559 clone_wand=(DrawingWand *) AcquireAlignedMemory(1,sizeof(*clone_wand));
cristy3ed852e2009-09-05 21:47:34 +0000560 if (clone_wand == (DrawingWand *) NULL)
561 ThrowWandFatalException(ResourceLimitFatalError,
562 "MemoryAllocationFailed",GetExceptionMessage(errno));
563 (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
564 clone_wand->id=AcquireWandId();
565 (void) FormatMagickString(clone_wand->name,MaxTextExtent,"DrawingWand-%lu",
cristyf2faecf2010-05-28 19:19:36 +0000566 (unsigned long) clone_wand->id);
cristy3ed852e2009-09-05 21:47:34 +0000567 clone_wand->exception=AcquireExceptionInfo();
568 InheritException(clone_wand->exception,wand->exception);
569 clone_wand->mvg=AcquireString(wand->mvg);
570 clone_wand->mvg_length=strlen(clone_wand->mvg);
571 clone_wand->mvg_alloc=wand->mvg_length+1;
572 clone_wand->mvg_width=wand->mvg_width;
573 clone_wand->pattern_id=AcquireString(wand->pattern_id);
574 clone_wand->pattern_offset=wand->pattern_offset;
575 clone_wand->pattern_bounds=wand->pattern_bounds;
576 clone_wand->index=wand->index;
577 clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((size_t)
578 wand->index+1UL,sizeof(*wand->graphic_context));
579 if (clone_wand->graphic_context == (DrawInfo **) NULL)
580 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
581 GetExceptionMessage(errno));
cristybb503372010-05-27 20:51:26 +0000582 for (i=0; i <= (ssize_t) wand->index; i++)
cristy3ed852e2009-09-05 21:47:34 +0000583 clone_wand->graphic_context[i]=
584 CloneDrawInfo((ImageInfo *) NULL,wand->graphic_context[i]);
585 clone_wand->filter_off=wand->filter_off;
586 clone_wand->indent_depth=wand->indent_depth;
587 clone_wand->path_operation=wand->path_operation;
588 clone_wand->path_mode=wand->path_mode;
589 clone_wand->image=wand->image;
590 if (wand->image != (Image *) NULL)
591 clone_wand->image=CloneImage(wand->image,0,0,MagickTrue,
592 clone_wand->exception);
593 clone_wand->destroy=MagickTrue;
594 clone_wand->debug=IsEventLogging();
595 if (clone_wand->debug != MagickFalse)
596 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
597 clone_wand->signature=WandSignature;
598 return(clone_wand);
599}
600
601/*
602%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603% %
604% %
605% %
606% D e s t r o y D r a w i n g W a n d %
607% %
608% %
609% %
610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611%
612% DestroyDrawingWand() frees all resources associated with the drawing wand.
613% Once the drawing wand has been freed, it should not be used and further
614% unless it re-allocated.
615%
616% The format of the DestroyDrawingWand method is:
617%
618% DrawingWand *DestroyDrawingWand(DrawingWand *wand)
619%
620% A description of each parameter follows:
621%
622% o wand: the drawing wand. to destroy
623%
624*/
625WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
626{
627 assert(wand != (DrawingWand *) NULL);
628 assert(wand->signature == WandSignature);
629 if (wand->debug != MagickFalse)
630 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
631 for ( ; wand->index > 0; wand->index--)
632 CurrentContext=DestroyDrawInfo(CurrentContext);
633 CurrentContext=DestroyDrawInfo(CurrentContext);
634 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
635 wand->graphic_context);
636 if (wand->pattern_id != (char *) NULL)
637 wand->pattern_id=DestroyString(wand->pattern_id);
638 wand->mvg=DestroyString(wand->mvg);
639 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
640 wand->image=DestroyImage(wand->image);
641 wand->image=(Image *) NULL;
642 wand->exception=DestroyExceptionInfo(wand->exception);
643 wand->signature=(~WandSignature);
644 RelinquishWandId(wand->id);
645 wand=(DrawingWand *) RelinquishMagickMemory(wand);
646 return(wand);
647}
648
649/*
650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651% %
652% %
653% %
654% D r a w A f f i n e %
655% %
656% %
657% %
658%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659%
660% DrawAffine() adjusts the current affine transformation matrix with
661% the specified affine transformation matrix. Note that the current affine
662% transform is adjusted rather than replaced.
663%
664% The format of the DrawAffine method is:
665%
666% void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
667%
668% A description of each parameter follows:
669%
670% o wand: Drawing wand
671%
672% o affine: Affine matrix parameters
673%
674*/
675WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
676{
677 assert(wand != (DrawingWand *) NULL);
678 assert(wand->signature == WandSignature);
679 if (wand->debug != MagickFalse)
680 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
681 assert(affine != (const AffineMatrix *) NULL);
682 AdjustAffine(wand,affine);
cristye7f51092010-01-17 00:39:37 +0000683 (void) MvgPrintf(wand,"affine %g,%g,%g,%g,%g,%g\n",
cristy8cd5b312010-01-07 01:10:24 +0000684 affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
cristy3ed852e2009-09-05 21:47:34 +0000685}
686
687/*
688%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
689% %
690% %
691% %
692+ D r a w A l l o c a t e W a n d %
693% %
694% %
695% %
696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697%
698% DrawAllocateWand() allocates an initial drawing wand which is an opaque
699% handle required by the remaining drawing methods.
700%
701% The format of the DrawAllocateWand method is:
702%
703% DrawingWand DrawAllocateWand(const DrawInfo *draw_info,Image *image)
704%
705% A description of each parameter follows:
706%
707% o draw_info: Initial drawing defaults. Set to NULL to use defaults.
708%
709% o image: the image to draw on.
710%
711*/
712WandExport DrawingWand *DrawAllocateWand(const DrawInfo *draw_info,Image *image)
713{
714 DrawingWand
715 *wand;
716
717 wand=NewDrawingWand();
718 if (draw_info != (const DrawInfo *) NULL)
719 {
720 CurrentContext=DestroyDrawInfo(CurrentContext);
721 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
722 }
723 if (image != (Image *) NULL)
724 {
725 wand->image=DestroyImage(wand->image);
726 wand->destroy=MagickFalse;
727 }
728 wand->image=image;
729 return(wand);
730}
731
732/*
733%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
734% %
735% %
736% %
737% D r a w A n n o t a t i o n %
738% %
739% %
740% %
741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742%
743% DrawAnnotation() draws text on the image.
744%
745% The format of the DrawAnnotation method is:
746%
747% void DrawAnnotation(DrawingWand *wand,const double x,
748% const double y,const unsigned char *text)
749%
750% A description of each parameter follows:
751%
752% o wand: the drawing wand.
753%
754% o x: x ordinate to left of text
755%
756% o y: y ordinate to text baseline
757%
758% o text: text to draw
759%
760*/
761WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y,
762 const unsigned char *text)
763{
764 char
765 *escaped_text;
766
767 assert(wand != (DrawingWand *) NULL);
768 assert(wand->signature == WandSignature);
769 if (wand->debug != MagickFalse)
770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
771 assert(text != (const unsigned char *) NULL);
772 escaped_text=EscapeString((const char *) text,'\'');
cristye7f51092010-01-17 00:39:37 +0000773 (void) MvgPrintf(wand,"text %g,%g '%s'\n",x,y,escaped_text);
cristy3ed852e2009-09-05 21:47:34 +0000774 escaped_text=DestroyString(escaped_text);
775}
776
777/*
778%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779% %
780% %
781% %
782% D r a w A r c %
783% %
784% %
785% %
786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787%
788% DrawArc() draws an arc falling within a specified bounding rectangle on the
789% image.
790%
791% The format of the DrawArc method is:
792%
793% void DrawArc(DrawingWand *wand,const double sx,const double sy,
794% const double ex,const double ey,const double sd,const double ed)
795%
796% A description of each parameter follows:
797%
798% o wand: the drawing wand.
799%
800% o sx: starting x ordinate of bounding rectangle
801%
802% o sy: starting y ordinate of bounding rectangle
803%
804% o ex: ending x ordinate of bounding rectangle
805%
806% o ey: ending y ordinate of bounding rectangle
807%
808% o sd: starting degrees of rotation
809%
810% o ed: ending degrees of rotation
811%
812*/
813WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy,
814 const double ex,const double ey,const double sd,const double ed)
815{
816 assert(wand != (DrawingWand *) NULL);
817 assert(wand->signature == WandSignature);
818 if (wand->debug != MagickFalse)
819 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +0000820 (void) MvgPrintf(wand,"arc %g,%g %g,%g %g,%g\n",sx,sy,ex,
cristy8cd5b312010-01-07 01:10:24 +0000821 ey,sd,ed);
cristy3ed852e2009-09-05 21:47:34 +0000822}
823
824/*
825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
826% %
827% %
828% %
829% D r a w B e z i e r %
830% %
831% %
832% %
833%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834%
835% DrawBezier() draws a bezier curve through a set of points on the image.
836%
837% The format of the DrawBezier method is:
838%
839% void DrawBezier(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +0000840% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +0000841%
842% A description of each parameter follows:
843%
844% o wand: the drawing wand.
845%
846% o number_coordinates: number of coordinates
847%
848% o coordinates: coordinates
849%
850*/
851WandExport void DrawBezier(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +0000852 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +0000853{
854 assert(wand != (DrawingWand *) NULL);
855 assert(wand->signature == WandSignature);
856 if (wand->debug != MagickFalse)
857 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
858 assert(coordinates != (const PointInfo *) NULL);
859 MvgAppendPointsCommand(wand,"bezier",number_coordinates,coordinates);
860}
861
862/*
863%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
864% %
865% %
866% %
867% D r a w C i r c l e %
868% %
869% %
870% %
871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872%
873% DrawCircle() draws a circle on the image.
874%
875% The format of the DrawCircle method is:
876%
877% void DrawCircle(DrawingWand *wand,const double ox,
878% const double oy,const double px, const double py)
879%
880% A description of each parameter follows:
881%
882% o wand: the drawing wand.
883%
884% o ox: origin x ordinate
885%
886% o oy: origin y ordinate
887%
888% o px: perimeter x ordinate
889%
890% o py: perimeter y ordinate
891%
892*/
893WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
894 const double px,const double py)
895{
896 assert(wand != (DrawingWand *) NULL);
897 assert(wand->signature == WandSignature);
898 if (wand->debug != MagickFalse)
899 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +0000900 (void) MvgPrintf(wand,"circle %g,%g %g,%g\n",ox,oy,px,py);
cristy3ed852e2009-09-05 21:47:34 +0000901}
902
903/*
904%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
905% %
906% %
907% %
908% D r a w C l e a r E x c e p t i o n %
909% %
910% %
911% %
912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913%
914% DrawClearException() clear any exceptions associated with the wand.
915%
916% The format of the DrawClearException method is:
917%
918% MagickBooleanType DrawClearException(DrawWand *wand)
919%
920% A description of each parameter follows:
921%
922% o wand: the drawing wand.
923%
924*/
925WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
926{
927 assert(wand != (DrawingWand *) NULL);
928 assert(wand->signature == WandSignature);
929 if (wand->debug != MagickFalse)
930 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
931 ClearMagickException(wand->exception);
932 return(MagickTrue);
933}
934
935/*
936%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
937% %
938% %
939% %
940% D r a w C o m p o s i t e %
941% %
942% %
943% %
944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945%
946% DrawComposite() composites an image onto the current image, using the
947% specified composition operator, specified position, and at the specified
948% size.
949%
950% The format of the DrawComposite method is:
951%
952% MagickBooleanType DrawComposite(DrawingWand *wand,
953% const CompositeOperator compose,const double x,
954% const double y,const double width,const double height,
955% MagickWand *magick_wand)
956%
957% A description of each parameter follows:
958%
959% o wand: the drawing wand.
960%
961% o compose: composition operator
962%
963% o x: x ordinate of top left corner
964%
965% o y: y ordinate of top left corner
966%
967% o width: Width to resize image to prior to compositing. Specify zero to
968% use existing width.
969%
970% o height: Height to resize image to prior to compositing. Specify zero
971% to use existing height.
972%
973% o magick_wand: Image to composite is obtained from this wand.
974%
975*/
976WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
977 const CompositeOperator compose,const double x,const double y,
978 const double width,const double height,MagickWand *magick_wand)
979
980{
981 char
982 *base64,
983 *media_type;
984
985 const char
986 *mode;
987
988 ImageInfo
989 *image_info;
990
991 Image
992 *clone_image,
993 *image;
994
995 register char
996 *p;
997
cristybb503372010-05-27 20:51:26 +0000998 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000999 i;
1000
1001 size_t
1002 blob_length,
1003 encoded_length;
1004
1005 unsigned char
1006 *blob;
1007
1008 assert(wand != (DrawingWand *) NULL);
1009 assert(wand->signature == WandSignature);
1010 if (wand->debug != MagickFalse)
1011 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1012 assert(magick_wand != (MagickWand *) NULL);
1013 image=GetImageFromMagickWand(magick_wand);
1014 if (image == (Image *) NULL)
1015 return(MagickFalse);
1016 clone_image=CloneImage(image,0,0,MagickTrue,wand->exception);
1017 if (clone_image == (Image *) NULL)
1018 return(MagickFalse);
1019 image_info=AcquireImageInfo();
1020 (void) CopyMagickString(image_info->magick,"MIFF",MaxTextExtent);
1021 blob_length=2048;
1022 blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
1023 wand->exception);
1024 image_info=DestroyImageInfo(image_info);
1025 clone_image=DestroyImageList(clone_image);
1026 if (blob == (void *) NULL)
1027 return(MagickFalse);
1028 encoded_length=0;
1029 base64=Base64Encode(blob,blob_length,&encoded_length);
1030 blob=(unsigned char *) RelinquishMagickMemory(blob);
1031 if (base64 == (char *) NULL)
1032 {
1033 char
1034 buffer[MaxTextExtent];
1035
1036 (void) FormatMagickString(buffer,MaxTextExtent,"%ld bytes",
1037 (4L*blob_length/3L+4L));
1038 ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
1039 wand->name);
1040 return(MagickFalse);
1041 }
cristybb503372010-05-27 20:51:26 +00001042 mode=MagickOptionToMnemonic(MagickComposeOptions,(ssize_t) compose);
cristy3ed852e2009-09-05 21:47:34 +00001043 media_type=MagickToMime(image->magick);
cristye7f51092010-01-17 00:39:37 +00001044 (void) MvgPrintf(wand,"image %s %g,%g %g,%g 'data:%s;base64,\n",
cristy8cd5b312010-01-07 01:10:24 +00001045 mode,x,y,width,height,media_type);
cristy3ed852e2009-09-05 21:47:34 +00001046 p=base64;
cristybb503372010-05-27 20:51:26 +00001047 for (i=(ssize_t) encoded_length; i > 0; i-=76)
cristy3ed852e2009-09-05 21:47:34 +00001048 {
1049 (void) MvgPrintf(wand,"%.76s",p);
1050 p+=76;
1051 if (i > 76)
1052 (void) MvgPrintf(wand,"\n");
1053 }
1054 (void) MvgPrintf(wand,"'\n");
1055 media_type=DestroyString(media_type);
1056 base64=DestroyString(base64);
1057 return(MagickTrue);
1058}
1059
1060/*
1061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062% %
1063% %
1064% %
1065% D r a w C o l o r %
1066% %
1067% %
1068% %
1069%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070%
1071% DrawColor() draws color on image using the current fill color, starting at
1072% specified position, and using specified paint method. The available paint
1073% methods are:
1074%
1075% PointMethod: Recolors the target pixel
1076% ReplaceMethod: Recolor any pixel that matches the target pixel.
1077% FloodfillMethod: Recolors target pixels and matching neighbors.
1078% ResetMethod: Recolor all pixels.
1079%
1080% The format of the DrawColor method is:
1081%
1082% void DrawColor(DrawingWand *wand,const double x,const double y,
1083% const PaintMethod paint_method)
1084%
1085% A description of each parameter follows:
1086%
1087% o wand: the drawing wand.
1088%
1089% o x: x ordinate.
1090%
1091% o y: y ordinate.
1092%
1093% o paint_method: paint method.
1094%
1095*/
1096WandExport void DrawColor(DrawingWand *wand,const double x,const double y,
1097 const PaintMethod paint_method)
1098{
1099 assert(wand != (DrawingWand *) NULL);
1100 assert(wand->signature == WandSignature);
1101 if (wand->debug != MagickFalse)
1102 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00001103 (void) MvgPrintf(wand,"color %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00001104 MagickMethodOptions,(ssize_t) paint_method));
cristy3ed852e2009-09-05 21:47:34 +00001105}
1106
1107/*
1108%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109% %
1110% %
1111% %
1112% D r a w C o m m e n t %
1113% %
1114% %
1115% %
1116%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1117%
1118% DrawComment() adds a comment to a vector output stream.
1119%
1120% The format of the DrawComment method is:
1121%
1122% void DrawComment(DrawingWand *wand,const char *comment)
1123%
1124% A description of each parameter follows:
1125%
1126% o wand: the drawing wand.
1127%
1128% o comment: comment text
1129%
1130*/
1131WandExport void DrawComment(DrawingWand *wand,const char *comment)
1132{
1133 (void) MvgPrintf(wand,"#%s\n",comment);
1134}
1135
1136/*
1137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1138% %
1139% %
1140% %
1141% D r a w E l l i p s e %
1142% %
1143% %
1144% %
1145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1146%
1147% DrawEllipse() draws an ellipse on the image.
1148%
1149% The format of the DrawEllipse method is:
1150%
1151% void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1152% const double rx,const double ry,const double start,const double end)
1153%
1154% A description of each parameter follows:
1155%
1156% o wand: the drawing wand.
1157%
1158% o ox: origin x ordinate
1159%
1160% o oy: origin y ordinate
1161%
1162% o rx: radius in x
1163%
1164% o ry: radius in y
1165%
1166% o start: starting rotation in degrees
1167%
1168% o end: ending rotation in degrees
1169%
1170*/
1171WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1172 const double rx,const double ry,const double start,const double end)
1173{
1174 assert(wand != (DrawingWand *) NULL);
1175 assert(wand->signature == WandSignature);
1176 if (wand->debug != MagickFalse)
1177 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00001178 (void) MvgPrintf(wand,"ellipse %g,%g %g,%g %g,%g\n",ox,oy,
cristy8cd5b312010-01-07 01:10:24 +00001179 rx,ry,start,end);
cristy3ed852e2009-09-05 21:47:34 +00001180}
1181
1182/*
1183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1184% %
1185% %
1186% %
1187% D r a w G e t B o r d e r C o l o r %
1188% %
1189% %
1190% %
1191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1192%
1193% DrawGetBorderColor() returns the border color used for drawing bordered
1194% objects.
1195%
1196% The format of the DrawGetBorderColor method is:
1197%
1198% void DrawGetBorderColor(const DrawingWand *wand,
1199% PixelWand *border_color)
1200%
1201% A description of each parameter follows:
1202%
1203% o wand: the drawing wand.
1204%
1205% o border_color: Return the border color.
1206%
1207*/
1208WandExport void DrawGetBorderColor(const DrawingWand *wand,
1209 PixelWand *border_color)
1210{
1211 assert(wand != (const DrawingWand *) NULL);
1212 assert(wand->signature == WandSignature);
1213 assert(border_color != (PixelWand *) NULL);
1214 if (wand->debug != MagickFalse)
1215 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1216 PixelSetQuantumColor(border_color,&CurrentContext->border_color);
1217}
1218
1219/*
1220%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1221% %
1222% %
1223% %
1224% D r a w G e t C l i p P a t h %
1225% %
1226% %
1227% %
1228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1229%
1230% DrawGetClipPath() obtains the current clipping path ID. The value returned
cristybb503372010-05-27 20:51:26 +00001231% must be deallocated by the user when it is no ssize_ter needed.
cristy3ed852e2009-09-05 21:47:34 +00001232%
1233% The format of the DrawGetClipPath method is:
1234%
1235% char *DrawGetClipPath(const DrawingWand *wand)
1236%
1237% A description of each parameter follows:
1238%
1239% o wand: the drawing wand.
1240%
1241*/
1242WandExport char *DrawGetClipPath(const DrawingWand *wand)
1243{
1244 assert(wand != (const DrawingWand *) NULL);
1245 assert(wand->signature == WandSignature);
1246 if (wand->debug != MagickFalse)
1247 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1248 if (CurrentContext->clip_mask != (char *) NULL)
1249 return((char *) AcquireString(CurrentContext->clip_mask));
1250 return((char *) NULL);
1251}
1252
1253/*
1254%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1255% %
1256% %
1257% %
1258% D r a w G e t C l i p R u l e %
1259% %
1260% %
1261% %
1262%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1263%
1264% DrawGetClipRule() returns the current polygon fill rule to be used by the
1265% clipping path.
1266%
1267% The format of the DrawGetClipRule method is:
1268%
1269% FillRule DrawGetClipRule(const DrawingWand *wand)
1270%
1271% A description of each parameter follows:
1272%
1273% o wand: the drawing wand.
1274%
1275*/
1276WandExport FillRule DrawGetClipRule(const DrawingWand *wand)
1277{
1278 assert(wand != (const DrawingWand *) NULL);
1279 assert(wand->signature == WandSignature);
1280 if (wand->debug != MagickFalse)
1281 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1282 return(CurrentContext->fill_rule);
1283}
1284
1285/*
1286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287% %
1288% %
1289% %
1290% D r a w G e t C l i p U n i t s %
1291% %
1292% %
1293% %
1294%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295%
1296% DrawGetClipUnits() returns the interpretation of clip path units.
1297%
1298% The format of the DrawGetClipUnits method is:
1299%
1300% ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1301%
1302% A description of each parameter follows:
1303%
1304% o wand: the drawing wand.
1305%
1306*/
1307WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1308{
1309 assert(wand != (const DrawingWand *) NULL);
1310 assert(wand->signature == WandSignature);
1311 if (wand->debug != MagickFalse)
1312 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1313 return(CurrentContext->clip_units);
1314}
1315
1316/*
1317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318% %
1319% %
1320% %
1321% D r a w G e t E x c e p t i o n %
1322% %
1323% %
1324% %
1325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326%
1327% DrawGetException() returns the severity, reason, and description of any
1328% error that occurs when using other methods in this API.
1329%
1330% The format of the DrawGetException method is:
1331%
1332% char *DrawGetException(const DrawWand *wand,
1333% ExceptionType *severity)
1334%
1335% A description of each parameter follows:
1336%
1337% o wand: the drawing wand.
1338%
1339% o severity: the severity of the error is returned here.
1340%
1341*/
1342WandExport char *DrawGetException(const DrawingWand *wand,
1343 ExceptionType *severity)
1344{
1345 char
1346 *description;
1347
1348 assert(wand != (const DrawingWand *) NULL);
1349 assert(wand->signature == WandSignature);
1350 if (wand->debug != MagickFalse)
1351 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1352 assert(severity != (ExceptionType *) NULL);
1353 *severity=wand->exception->severity;
1354 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
1355 sizeof(*description));
1356 if (description == (char *) NULL)
1357 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1358 wand->name);
1359 *description='\0';
1360 if (wand->exception->reason != (char *) NULL)
1361 (void) CopyMagickString(description,GetLocaleExceptionMessage(
1362 wand->exception->severity,wand->exception->reason),
1363 MaxTextExtent);
1364 if (wand->exception->description != (char *) NULL)
1365 {
1366 (void) ConcatenateMagickString(description," (",MaxTextExtent);
1367 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
1368 wand->exception->severity,wand->exception->description),
1369 MaxTextExtent);
1370 (void) ConcatenateMagickString(description,")",MaxTextExtent);
1371 }
1372 return(description);
1373}
1374
1375/*
1376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1377% %
1378% %
1379% %
1380% P i x e l G e t E x c e p t i o n T y p e %
1381% %
1382% %
1383% %
1384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1385%
1386% DrawGetExceptionType() the exception type associated with the wand. If
1387% no exception has occurred, UndefinedExceptionType is returned.
1388%
1389% The format of the DrawGetExceptionType method is:
1390%
1391% ExceptionType DrawGetExceptionType(const DrawWand *wand)
1392%
1393% A description of each parameter follows:
1394%
1395% o wand: the magick wand.
1396%
1397*/
1398WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand)
1399{
1400 assert(wand != (const DrawingWand *) NULL);
1401 assert(wand->signature == WandSignature);
1402 if (wand->debug != MagickFalse)
1403 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1404 return(wand->exception->severity);
1405}
1406
1407/*
1408%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409% %
1410% %
1411% %
1412% D r a w G e t F i l l C o l o r %
1413% %
1414% %
1415% %
1416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417%
1418% DrawGetFillColor() returns the fill color used for drawing filled objects.
1419%
1420% The format of the DrawGetFillColor method is:
1421%
1422% void DrawGetFillColor(const DrawingWand *wand,
1423% PixelWand *fill_color)
1424%
1425% A description of each parameter follows:
1426%
1427% o wand: the drawing wand.
1428%
1429% o fill_color: Return the fill color.
1430%
1431*/
1432WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color)
1433{
1434 assert(wand != (const DrawingWand *) NULL);
1435 assert(wand->signature == WandSignature);
1436 assert(fill_color != (PixelWand *) NULL);
1437 if (wand->debug != MagickFalse)
1438 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1439 PixelSetQuantumColor(fill_color,&CurrentContext->fill);
1440}
1441
1442/*
1443%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444% %
1445% %
1446% %
1447% D r a w G e t F i l l O p a c i t y %
1448% %
1449% %
1450% %
1451%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1452%
1453% DrawGetFillOpacity() returns the opacity used when drawing using the fill
1454% color or fill texture. Fully opaque is 1.0.
1455%
1456% The format of the DrawGetFillOpacity method is:
1457%
1458% double DrawGetFillOpacity(const DrawingWand *wand)
1459%
1460% A description of each parameter follows:
1461%
1462% o wand: the drawing wand.
1463%
1464*/
1465WandExport double DrawGetFillOpacity(const DrawingWand *wand)
1466{
1467 double
1468 alpha;
1469
1470 assert(wand != (const DrawingWand *) NULL);
1471 assert(wand->signature == WandSignature);
1472 if (wand->debug != MagickFalse)
1473 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1474 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity);
1475 return(alpha);
1476}
1477
1478/*
1479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1480% %
1481% %
1482% %
1483% D r a w G e t F i l l R u l e %
1484% %
1485% %
1486% %
1487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1488%
1489% DrawGetFillRule() returns the fill rule used while drawing polygons.
1490%
1491% The format of the DrawGetFillRule method is:
1492%
1493% FillRule DrawGetFillRule(const DrawingWand *wand)
1494%
1495% A description of each parameter follows:
1496%
1497% o wand: the drawing wand.
1498%
1499*/
1500WandExport FillRule DrawGetFillRule(const DrawingWand *wand)
1501{
1502 assert(wand != (const DrawingWand *) NULL);
1503 assert(wand->signature == WandSignature);
1504 if (wand->debug != MagickFalse)
1505 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1506 return(CurrentContext->fill_rule);
1507}
1508
1509/*
1510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1511% %
1512% %
1513% %
1514% D r a w G e t F o n t %
1515% %
1516% %
1517% %
1518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1519%
1520% DrawGetFont() returns a null-terminaged string specifying the font used
1521% when annotating with text. The value returned must be freed by the user
cristybb503372010-05-27 20:51:26 +00001522% when no ssize_ter needed.
cristy3ed852e2009-09-05 21:47:34 +00001523%
1524% The format of the DrawGetFont method is:
1525%
1526% char *DrawGetFont(const DrawingWand *wand)
1527%
1528% A description of each parameter follows:
1529%
1530% o wand: the drawing wand.
1531%
1532*/
1533WandExport char *DrawGetFont(const DrawingWand *wand)
1534{
1535 assert(wand != (const DrawingWand *) NULL);
1536 assert(wand->signature == WandSignature);
1537 if (wand->debug != MagickFalse)
1538 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1539 if (CurrentContext->font != (char *) NULL)
1540 return(AcquireString(CurrentContext->font));
1541 return((char *) NULL);
1542}
1543
1544/*
1545%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1546% %
1547% %
1548% %
1549% D r a w G e t F o n t F a m i l y %
1550% %
1551% %
1552% %
1553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1554%
1555% DrawGetFontFamily() returns the font family to use when annotating with text.
cristybb503372010-05-27 20:51:26 +00001556% The value returned must be freed by the user when it is no ssize_ter needed.
cristy3ed852e2009-09-05 21:47:34 +00001557%
1558% The format of the DrawGetFontFamily method is:
1559%
1560% char *DrawGetFontFamily(const DrawingWand *wand)
1561%
1562% A description of each parameter follows:
1563%
1564% o wand: the drawing wand.
1565%
1566*/
1567WandExport char *DrawGetFontFamily(const DrawingWand *wand)
1568{
1569 assert(wand != (const DrawingWand *) NULL);
1570 assert(wand->signature == WandSignature);
1571 if (wand->debug != MagickFalse)
1572 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1573 if (CurrentContext->family != NULL)
1574 return(AcquireString(CurrentContext->family));
1575 return((char *) NULL);
1576}
1577
1578/*
1579%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1580% %
1581% %
1582% %
1583% D r a w G e t F o n t S i z e %
1584% %
1585% %
1586% %
1587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1588%
1589% DrawGetFontSize() returns the font pointsize used when annotating with text.
1590%
1591% The format of the DrawGetFontSize method is:
1592%
1593% double DrawGetFontSize(const DrawingWand *wand)
1594%
1595% A description of each parameter follows:
1596%
1597% o wand: the drawing wand.
1598%
1599*/
1600WandExport double DrawGetFontSize(const DrawingWand *wand)
1601{
1602 assert(wand != (const DrawingWand *) NULL);
1603 assert(wand->signature == WandSignature);
1604 if (wand->debug != MagickFalse)
1605 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1606 return(CurrentContext->pointsize);
1607}
1608
1609/*
1610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1611% %
1612% %
1613% %
1614% D r a w G e t F o n t S t r e t c h %
1615% %
1616% %
1617% %
1618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1619%
1620% DrawGetFontStretch() returns the font stretch used when annotating with text.
1621%
1622% The format of the DrawGetFontStretch method is:
1623%
1624% StretchType DrawGetFontStretch(const DrawingWand *wand)
1625%
1626% A description of each parameter follows:
1627%
1628% o wand: the drawing wand.
1629%
1630*/
1631WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1632{
1633 assert(wand != (const DrawingWand *) NULL);
1634 assert(wand->signature == WandSignature);
1635 if (wand->debug != MagickFalse)
1636 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1637 return(CurrentContext->stretch);
1638}
1639
1640/*
1641%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1642% %
1643% %
1644% %
1645% D r a w G e t F o n t S t y l e %
1646% %
1647% %
1648% %
1649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1650%
1651% DrawGetFontStyle() returns the font style used when annotating with text.
1652%
1653% The format of the DrawGetFontStyle method is:
1654%
1655% StyleType DrawGetFontStyle(const DrawingWand *wand)
1656%
1657% A description of each parameter follows:
1658%
1659% o wand: the drawing wand.
1660%
1661*/
1662WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1663{
1664 assert(wand != (const DrawingWand *) NULL);
1665 assert(wand->signature == WandSignature);
1666 if (wand->debug != MagickFalse)
1667 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1668 return(CurrentContext->style);
1669}
1670
1671/*
1672%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673% %
1674% %
1675% %
1676% D r a w G e t F o n t W e i g h t %
1677% %
1678% %
1679% %
1680%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1681%
1682% DrawGetFontWeight() returns the font weight used when annotating with text.
1683%
1684% The format of the DrawGetFontWeight method is:
1685%
cristybb503372010-05-27 20:51:26 +00001686% size_t DrawGetFontWeight(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001687%
1688% A description of each parameter follows:
1689%
1690% o wand: the drawing wand.
1691%
1692*/
cristybb503372010-05-27 20:51:26 +00001693WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001694{
1695 assert(wand != (const DrawingWand *) NULL);
1696 assert(wand->signature == WandSignature);
1697 if (wand->debug != MagickFalse)
1698 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1699 return(CurrentContext->weight);
1700}
1701
1702/*
1703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1704% %
1705% %
1706% %
1707% D r a w G e t G r a v i t y %
1708% %
1709% %
1710% %
1711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1712%
1713% DrawGetGravity() returns the text placement gravity used when annotating
1714% with text.
1715%
1716% The format of the DrawGetGravity method is:
1717%
1718% GravityType DrawGetGravity(const DrawingWand *wand)
1719%
1720% A description of each parameter follows:
1721%
1722% o wand: the drawing wand.
1723%
1724*/
1725WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1726{
1727 assert(wand != (const DrawingWand *) NULL);
1728 assert(wand->signature == WandSignature);
1729 if (wand->debug != MagickFalse)
1730 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1731 return(CurrentContext->gravity);
1732}
1733
1734/*
1735%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1736% %
1737% %
1738% %
1739% D r a w G e t O p a c i t y %
1740% %
1741% %
1742% %
1743%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1744%
1745% DrawGetOpacity() returns the opacity used when drawing with the fill
1746% or stroke color or texture. Fully opaque is 1.0.
1747%
1748% The format of the DrawGetOpacity method is:
1749%
1750% double DrawGetOpacity(const DrawingWand *wand)
1751%
1752% A description of each parameter follows:
1753%
1754% o wand: the drawing wand.
1755%
1756*/
1757WandExport double DrawGetOpacity(const DrawingWand *wand)
1758{
1759 double
1760 alpha;
1761
1762 assert(wand != (const DrawingWand *) NULL);
1763 assert(wand->signature == WandSignature);
1764 if (wand->debug != MagickFalse)
1765 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1766 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->opacity);
1767 return(alpha);
1768}
1769
1770/*
1771%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1772% %
1773% %
1774% %
1775% D r a w G e t S t r o k e A n t i a l i a s %
1776% %
1777% %
1778% %
1779%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1780%
1781% DrawGetStrokeAntialias() returns the current stroke antialias setting.
1782% Stroked outlines are antialiased by default. When antialiasing is disabled
1783% stroked pixels are thresholded to determine if the stroke color or
1784% underlying canvas color should be used.
1785%
1786% The format of the DrawGetStrokeAntialias method is:
1787%
1788% MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1789%
1790% A description of each parameter follows:
1791%
1792% o wand: the drawing wand.
1793%
1794*/
1795WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1796{
1797 assert(wand != (const DrawingWand *) NULL);
1798 assert(wand->signature == WandSignature);
1799 if (wand->debug != MagickFalse)
1800 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1801 return(CurrentContext->stroke_antialias);
1802}
1803
1804/*
1805%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1806% %
1807% %
1808% %
1809% D r a w G e t S t r o k e C o l o r %
1810% %
1811% %
1812% %
1813%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1814%
1815% DrawGetStrokeColor() returns the color used for stroking object outlines.
1816%
1817% The format of the DrawGetStrokeColor method is:
1818%
1819% void DrawGetStrokeColor(const DrawingWand *wand,
1820$ PixelWand *stroke_color)
1821%
1822% A description of each parameter follows:
1823%
1824% o wand: the drawing wand.
1825%
1826% o stroke_color: Return the stroke color.
1827%
1828*/
1829WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1830 PixelWand *stroke_color)
1831{
1832 assert(wand != (const DrawingWand *) NULL);
1833 assert(wand->signature == WandSignature);
1834 assert(stroke_color != (PixelWand *) NULL);
1835 if (wand->debug != MagickFalse)
1836 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1837 PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
1838}
1839
1840/*
1841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1842% %
1843% %
1844% %
1845% D r a w G e t S t r o k e D a s h A r r a y %
1846% %
1847% %
1848% %
1849%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1850%
1851% DrawGetStrokeDashArray() returns an array representing the pattern of
1852% dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
cristybb503372010-05-27 20:51:26 +00001853% array must be freed once it is no ssize_ter required by the user.
cristy3ed852e2009-09-05 21:47:34 +00001854%
1855% The format of the DrawGetStrokeDashArray method is:
1856%
1857% double *DrawGetStrokeDashArray(const DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00001858% size_t *number_elements)
cristy3ed852e2009-09-05 21:47:34 +00001859%
1860% A description of each parameter follows:
1861%
1862% o wand: the drawing wand.
1863%
1864% o number_elements: address to place number of elements in dash array
1865%
1866*/
1867WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00001868 size_t *number_elements)
cristy3ed852e2009-09-05 21:47:34 +00001869{
1870 double
1871 *dash_array;
1872
1873 register const double
1874 *p;
1875
1876 register double
1877 *q;
1878
cristybb503372010-05-27 20:51:26 +00001879 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001880 i;
1881
cristybb503372010-05-27 20:51:26 +00001882 size_t
cristy3ed852e2009-09-05 21:47:34 +00001883 n;
1884
1885 assert(wand != (const DrawingWand *) NULL);
1886 assert(wand->signature == WandSignature);
1887 if (wand->debug != MagickFalse)
1888 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristybb503372010-05-27 20:51:26 +00001889 assert(number_elements != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001890 n=0;
1891 p=CurrentContext->dash_pattern;
1892 if (p != (const double *) NULL)
1893 while (*p++ != 0.0)
1894 n++;
1895 *number_elements=n;
1896 dash_array=(double *) NULL;
1897 if (n != 0)
1898 {
1899 dash_array=(double *) AcquireQuantumMemory((size_t) n,
1900 sizeof(*dash_array));
1901 p=CurrentContext->dash_pattern;
1902 q=dash_array;
cristybb503372010-05-27 20:51:26 +00001903 for (i=0; i < (ssize_t) n; i++)
cristy3ed852e2009-09-05 21:47:34 +00001904 *q++=(*p++);
1905 }
1906 return(dash_array);
1907}
1908
1909/*
1910%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1911% %
1912% %
1913% %
1914% D r a w G e t S t r o k e D a s h O f f s e t %
1915% %
1916% %
1917% %
1918%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1919%
1920% DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1921% start the dash.
1922%
1923% The format of the DrawGetStrokeDashOffset method is:
1924%
1925% double DrawGetStrokeDashOffset(const DrawingWand *wand)
1926%
1927% A description of each parameter follows:
1928%
1929% o wand: the drawing wand.
1930%
1931*/
1932WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1933{
1934 assert(wand != (const DrawingWand *) NULL);
1935 assert(wand->signature == WandSignature);
1936 if (wand->debug != MagickFalse)
1937 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1938 return(CurrentContext->dash_offset);
1939}
1940
1941/*
1942%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1943% %
1944% %
1945% %
1946% D r a w G e t S t r o k e L i n e C a p %
1947% %
1948% %
1949% %
1950%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1951%
1952% DrawGetStrokeLineCap() returns the shape to be used at the end of
1953% open subpaths when they are stroked. Values of LineCap are
1954% UndefinedCap, ButtCap, RoundCap, and SquareCap.
1955%
1956% The format of the DrawGetStrokeLineCap method is:
1957%
1958% LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1959%
1960% A description of each parameter follows:
1961%
1962% o wand: the drawing wand.
1963%
1964*/
1965WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1966{
1967 assert(wand != (const DrawingWand *) NULL);
1968 assert(wand->signature == WandSignature);
1969 if (wand->debug != MagickFalse)
1970 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1971 return(CurrentContext->linecap);
1972}
1973
1974/*
1975%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1976% %
1977% %
1978% %
1979% D r a w G e t S t r o k e L i n e J o i n %
1980% %
1981% %
1982% %
1983%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1984%
1985% DrawGetStrokeLineJoin() returns the shape to be used at the
1986% corners of paths (or other vector shapes) when they are
1987% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
1988% and BevelJoin.
1989%
1990% The format of the DrawGetStrokeLineJoin method is:
1991%
1992% LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
1993%
1994% A description of each parameter follows:
1995%
1996% o wand: the drawing wand.
1997%
1998*/
1999WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2000{
2001 assert(wand != (const DrawingWand *) NULL);
2002 assert(wand->signature == WandSignature);
2003 if (wand->debug != MagickFalse)
2004 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2005 return(CurrentContext->linejoin);
2006}
2007
2008/*
2009%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2010% %
2011% %
2012% %
2013% D r a w G e t S t r o k e M i t e r L i m i t %
2014% %
2015% %
2016% %
2017%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2018%
2019% DrawGetStrokeMiterLimit() returns the miter limit. When two line
2020% segments meet at a sharp angle and miter joins have been specified for
2021% 'lineJoin', it is possible for the miter to extend far beyond the
2022% thickness of the line stroking the path. The miterLimit' imposes a
2023% limit on the ratio of the miter length to the 'lineWidth'.
2024%
2025% The format of the DrawGetStrokeMiterLimit method is:
2026%
cristybb503372010-05-27 20:51:26 +00002027% size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002028%
2029% A description of each parameter follows:
2030%
2031% o wand: the drawing wand.
2032%
2033*/
cristybb503372010-05-27 20:51:26 +00002034WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002035{
2036 assert(wand != (const DrawingWand *) NULL);
2037 assert(wand->signature == WandSignature);
2038 if (wand->debug != MagickFalse)
2039 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2040 return CurrentContext->miterlimit;
2041}
2042
2043/*
2044%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2045% %
2046% %
2047% %
2048% D r a w G e t S t r o k e O p a c i t y %
2049% %
2050% %
2051% %
2052%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2053%
2054% DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
2055%
2056% The format of the DrawGetStrokeOpacity method is:
2057%
2058% double DrawGetStrokeOpacity(const DrawingWand *wand)
2059%
2060% A description of each parameter follows:
2061%
2062% o wand: the drawing wand.
2063%
2064*/
2065WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2066{
2067 double
2068 alpha;
2069
2070 assert(wand != (const DrawingWand *) NULL);
2071 assert(wand->signature == WandSignature);
2072 if (wand->debug != MagickFalse)
2073 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2074 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity);
2075 return(alpha);
2076}
2077
2078/*
2079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2080% %
2081% %
2082% %
2083% D r a w G e t S t r o k e W i d t h %
2084% %
2085% %
2086% %
2087%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2088%
2089% DrawGetStrokeWidth() returns the width of the stroke used to draw object
2090% outlines.
2091%
2092% The format of the DrawGetStrokeWidth method is:
2093%
2094% double DrawGetStrokeWidth(const DrawingWand *wand)
2095%
2096% A description of each parameter follows:
2097%
2098% o wand: the drawing wand.
2099%
2100*/
2101WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2102{
2103 assert(wand != (const DrawingWand *) NULL);
2104 assert(wand->signature == WandSignature);
2105 if (wand->debug != MagickFalse)
2106 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2107 return(CurrentContext->stroke_width);
2108}
2109
2110/*
2111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2112% %
2113% %
2114% %
2115% D r a w G e t T e x t A l i g n m e n t %
2116% %
2117% %
2118% %
2119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2120%
2121% DrawGetTextAlignment() returns the alignment applied when annotating with
2122% text.
2123%
2124% The format of the DrawGetTextAlignment method is:
2125%
2126% AlignType DrawGetTextAlignment(DrawingWand *wand)
2127%
2128% A description of each parameter follows:
2129%
2130% o wand: the drawing wand.
2131%
2132*/
2133WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2134{
2135 assert(wand != (const DrawingWand *) NULL);
2136 assert(wand->signature == WandSignature);
2137 if (wand->debug != MagickFalse)
2138 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2139 return(CurrentContext->align);
2140}
2141
2142/*
2143%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2144% %
2145% %
2146% %
2147% D r a w G e t T e x t A n t i a l i a s %
2148% %
2149% %
2150% %
2151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2152%
2153% DrawGetTextAntialias() returns the current text antialias setting, which
2154% determines whether text is antialiased. Text is antialiased by default.
2155%
2156% The format of the DrawGetTextAntialias method is:
2157%
2158% MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2159%
2160% A description of each parameter follows:
2161%
2162% o wand: the drawing wand.
2163%
2164*/
2165WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2166{
2167 assert(wand != (const DrawingWand *) NULL);
2168 assert(wand->signature == WandSignature);
2169 if (wand->debug != MagickFalse)
2170 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2171 return(CurrentContext->text_antialias);
2172}
2173
2174/*
2175%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2176% %
2177% %
2178% %
2179% D r a w G e t T e x t D e c o r a t i o n %
2180% %
2181% %
2182% %
2183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2184%
2185% DrawGetTextDecoration() returns the decoration applied when annotating with
2186% text.
2187%
2188% The format of the DrawGetTextDecoration method is:
2189%
2190% DecorationType DrawGetTextDecoration(DrawingWand *wand)
2191%
2192% A description of each parameter follows:
2193%
2194% o wand: the drawing wand.
2195%
2196*/
2197WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2198{
2199 assert(wand != (const DrawingWand *) NULL);
2200 assert(wand->signature == WandSignature);
2201 if (wand->debug != MagickFalse)
2202 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2203 return(CurrentContext->decorate);
2204}
2205
2206/*
2207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2208% %
2209% %
2210% %
2211% D r a w G e t T e x t E n c o d i n g %
2212% %
2213% %
2214% %
2215%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2216%
2217% DrawGetTextEncoding() returns a null-terminated string which specifies the
2218% code set used for text annotations. The string must be freed by the user
cristybb503372010-05-27 20:51:26 +00002219% once it is no ssize_ter required.
cristy3ed852e2009-09-05 21:47:34 +00002220%
2221% The format of the DrawGetTextEncoding method is:
2222%
2223% char *DrawGetTextEncoding(const DrawingWand *wand)
2224%
2225% A description of each parameter follows:
2226%
2227% o wand: the drawing wand.
2228%
2229*/
2230WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2231{
2232 assert(wand != (const DrawingWand *) NULL);
2233 assert(wand->signature == WandSignature);
2234 if (wand->debug != MagickFalse)
2235 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2236 if (CurrentContext->encoding != (char *) NULL)
2237 return((char *) AcquireString(CurrentContext->encoding));
2238 return((char *) NULL);
2239}
2240
2241/*
2242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2243% %
2244% %
2245% %
2246% D r a w G e t T e x t K e r n i n g %
2247% %
2248% %
2249% %
2250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2251%
2252% DrawGetTextKerning() gets the spacing between characters in text.
2253%
2254% The format of the DrawSetFontKerning method is:
2255%
2256% double DrawGetTextKerning(DrawingWand *wand)
2257%
2258% A description of each parameter follows:
2259%
2260% o wand: the drawing wand.
2261%
2262*/
2263WandExport double DrawGetTextKerning(DrawingWand *wand)
2264{
2265 assert(wand != (DrawingWand *) NULL);
2266 assert(wand->signature == WandSignature);
2267
2268 if (wand->debug != MagickFalse)
2269 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2270 return(CurrentContext->kerning);
2271}
2272
2273/*
2274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2275% %
2276% %
2277% %
cristyb32b90a2009-09-07 21:45:48 +00002278% D r a w G e t T e x t I n t e r L i n e S p a c i n g %
2279% %
2280% %
2281% %
2282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2283%
2284% DrawGetTextInterwordSpacing() gets the spacing between lines in text.
2285%
2286% The format of the DrawSetFontKerning method is:
2287%
2288% double DrawGetTextInterwordSpacing(DrawingWand *wand)
2289%
2290% A description of each parameter follows:
2291%
2292% o wand: the drawing wand.
2293%
2294*/
2295WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2296{
2297 assert(wand != (DrawingWand *) NULL);
2298 assert(wand->signature == WandSignature);
2299 if (wand->debug != MagickFalse)
2300 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2301 return(CurrentContext->interline_spacing);
2302}
2303
2304/*
2305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2306% %
2307% %
2308% %
cristy3ed852e2009-09-05 21:47:34 +00002309% D r a w G e t T e x t I n t e r w o r d S p a c i n g %
2310% %
2311% %
2312% %
2313%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2314%
2315% DrawGetTextInterwordSpacing() gets the spacing between words in text.
2316%
2317% The format of the DrawSetFontKerning method is:
2318%
2319% double DrawGetTextInterwordSpacing(DrawingWand *wand)
2320%
2321% A description of each parameter follows:
2322%
2323% o wand: the drawing wand.
2324%
2325*/
2326WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2327{
2328 assert(wand != (DrawingWand *) NULL);
2329 assert(wand->signature == WandSignature);
2330 if (wand->debug != MagickFalse)
2331 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2332 return(CurrentContext->interword_spacing);
2333}
2334
2335/*
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337% %
2338% %
2339% %
2340% D r a w G e t V e c t o r G r a p h i c s %
2341% %
2342% %
2343% %
2344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2345%
2346% DrawGetVectorGraphics() returns a null-terminated string which specifies the
2347% vector graphics generated by any graphics calls made since the wand was
cristybb503372010-05-27 20:51:26 +00002348% instantiated. The string must be freed by the user once it is no ssize_ter
cristy3ed852e2009-09-05 21:47:34 +00002349% required.
2350%
2351% The format of the DrawGetVectorGraphics method is:
2352%
2353% char *DrawGetVectorGraphics(const DrawingWand *wand)
2354%
2355% A description of each parameter follows:
2356%
2357% o wand: the drawing wand.
2358%
2359*/
2360
2361static inline void SetMagickPixelPacket(const Image *image,
2362 const PixelPacket *color,const IndexPacket *index,MagickPixelPacket *pixel)
2363{
2364 pixel->red=(MagickRealType) color->red;
2365 pixel->green=(MagickRealType) color->green;
2366 pixel->blue=(MagickRealType) color->blue;
2367 if (image->matte != MagickFalse)
2368 pixel->opacity=(MagickRealType) color->opacity;
2369 if (((image->colorspace == CMYKColorspace) ||
2370 (image->storage_class == PseudoClass)) &&
2371 (index != (const IndexPacket *) NULL))
2372 pixel->index=(MagickRealType) *index;
2373}
2374
2375WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2376{
2377 char
2378 value[MaxTextExtent],
2379 *xml;
2380
2381 MagickPixelPacket
2382 pixel;
2383
cristybb503372010-05-27 20:51:26 +00002384 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002385 i;
2386
2387 XMLTreeInfo
2388 *child,
2389 *xml_info;
2390
2391 assert(wand != (const DrawingWand *) NULL);
2392 assert(wand->signature == WandSignature);
2393 if (wand->debug != MagickFalse)
2394 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2395 xml_info=NewXMLTreeTag("drawing-wand");
2396 if (xml_info == (XMLTreeInfo *) NULL)
2397 return(char *) NULL;
2398 GetMagickPixelPacket(wand->image,&pixel);
2399 child=AddChildToXMLTree(xml_info,"clip-path",0);
2400 if (child != (XMLTreeInfo *) NULL)
2401 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2402 child=AddChildToXMLTree(xml_info,"clip-units",0);
2403 if (child != (XMLTreeInfo *) NULL)
2404 {
2405 (void) CopyMagickString(value,MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002406 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002407 (void) SetXMLTreeContent(child,value);
2408 }
2409 child=AddChildToXMLTree(xml_info,"decorate",0);
2410 if (child != (XMLTreeInfo *) NULL)
2411 {
2412 (void) CopyMagickString(value,MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002413 MagickDecorateOptions,(ssize_t) CurrentContext->decorate),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002414 (void) SetXMLTreeContent(child,value);
2415 }
2416 child=AddChildToXMLTree(xml_info,"encoding",0);
2417 if (child != (XMLTreeInfo *) NULL)
2418 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2419 child=AddChildToXMLTree(xml_info,"fill",0);
2420 if (child != (XMLTreeInfo *) NULL)
2421 {
2422 if (CurrentContext->fill.opacity != OpaqueOpacity)
2423 pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2424 MagickTrue : MagickFalse;
2425 SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2426 (const IndexPacket *) NULL,&pixel);
2427 GetColorTuple(&pixel,MagickTrue,value);
2428 (void) SetXMLTreeContent(child,value);
2429 }
2430 child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2431 if (child != (XMLTreeInfo *) NULL)
2432 {
cristye7f51092010-01-17 00:39:37 +00002433 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002434 (double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity));
2435 (void) SetXMLTreeContent(child,value);
2436 }
2437 child=AddChildToXMLTree(xml_info,"fill-rule",0);
2438 if (child != (XMLTreeInfo *) NULL)
2439 {
2440 (void) CopyMagickString(value,MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002441 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002442 (void) SetXMLTreeContent(child,value);
2443 }
2444 child=AddChildToXMLTree(xml_info,"font",0);
2445 if (child != (XMLTreeInfo *) NULL)
2446 (void) SetXMLTreeContent(child,CurrentContext->font);
2447 child=AddChildToXMLTree(xml_info,"font-family",0);
2448 if (child != (XMLTreeInfo *) NULL)
2449 (void) SetXMLTreeContent(child,CurrentContext->family);
2450 child=AddChildToXMLTree(xml_info,"font-size",0);
2451 if (child != (XMLTreeInfo *) NULL)
2452 {
cristye7f51092010-01-17 00:39:37 +00002453 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002454 CurrentContext->pointsize);
2455 (void) SetXMLTreeContent(child,value);
2456 }
2457 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2458 if (child != (XMLTreeInfo *) NULL)
2459 {
2460 (void) CopyMagickString(value,MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002461 MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002462 (void) SetXMLTreeContent(child,value);
2463 }
2464 child=AddChildToXMLTree(xml_info,"font-style",0);
2465 if (child != (XMLTreeInfo *) NULL)
2466 {
2467 (void) CopyMagickString(value,MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002468 MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002469 (void) SetXMLTreeContent(child,value);
2470 }
2471 child=AddChildToXMLTree(xml_info,"font-weight",0);
2472 if (child != (XMLTreeInfo *) NULL)
2473 {
cristyf2faecf2010-05-28 19:19:36 +00002474 (void) FormatMagickString(value,MaxTextExtent,"%lu",(unsigned long)
cristy3ed852e2009-09-05 21:47:34 +00002475 CurrentContext->weight);
2476 (void) SetXMLTreeContent(child,value);
2477 }
2478 child=AddChildToXMLTree(xml_info,"gravity",0);
2479 if (child != (XMLTreeInfo *) NULL)
2480 {
2481 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickGravityOptions,
cristybb503372010-05-27 20:51:26 +00002482 (ssize_t) CurrentContext->gravity),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002483 (void) SetXMLTreeContent(child,value);
2484 }
2485 child=AddChildToXMLTree(xml_info,"stroke",0);
2486 if (child != (XMLTreeInfo *) NULL)
2487 {
2488 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2489 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2490 MagickTrue : MagickFalse;
2491 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2492 (const IndexPacket *) NULL,&pixel);
2493 GetColorTuple(&pixel,MagickTrue,value);
2494 (void) SetXMLTreeContent(child,value);
2495 }
2496 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2497 if (child != (XMLTreeInfo *) NULL)
2498 {
2499 (void) FormatMagickString(value,MaxTextExtent,"%d",
2500 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2501 (void) SetXMLTreeContent(child,value);
2502 }
2503 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2504 if ((child != (XMLTreeInfo *) NULL) &&
2505 (CurrentContext->dash_pattern != (double *) NULL))
2506 {
2507 char
2508 *dash_pattern;
2509
2510 dash_pattern=AcquireString((char *) NULL);
2511 for (i=0; CurrentContext->dash_pattern[i] != 0.0; i++)
2512 {
2513 if (i != 0)
2514 (void) ConcatenateString(&dash_pattern,",");
cristye7f51092010-01-17 00:39:37 +00002515 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002516 CurrentContext->dash_pattern[i]);
2517 (void) ConcatenateString(&dash_pattern,value);
2518 }
2519 (void) SetXMLTreeContent(child,dash_pattern);
2520 dash_pattern=DestroyString(dash_pattern);
2521 }
2522 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2523 if (child != (XMLTreeInfo *) NULL)
2524 {
cristye7f51092010-01-17 00:39:37 +00002525 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002526 CurrentContext->dash_offset);
2527 (void) SetXMLTreeContent(child,value);
2528 }
2529 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2530 if (child != (XMLTreeInfo *) NULL)
2531 {
2532 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickLineCapOptions,
cristybb503372010-05-27 20:51:26 +00002533 (ssize_t) CurrentContext->linecap),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002534 (void) SetXMLTreeContent(child,value);
2535 }
2536 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2537 if (child != (XMLTreeInfo *) NULL)
2538 {
2539 (void) CopyMagickString(value,MagickOptionToMnemonic(
cristyf2faecf2010-05-28 19:19:36 +00002540 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2541 MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002542 (void) SetXMLTreeContent(child,value);
2543 }
2544 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2545 if (child != (XMLTreeInfo *) NULL)
2546 {
cristyf2faecf2010-05-28 19:19:36 +00002547 (void) FormatMagickString(value,MaxTextExtent,"%lu",(unsigned long)
cristy3ed852e2009-09-05 21:47:34 +00002548 CurrentContext->miterlimit);
2549 (void) SetXMLTreeContent(child,value);
2550 }
2551 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2552 if (child != (XMLTreeInfo *) NULL)
2553 {
cristye7f51092010-01-17 00:39:37 +00002554 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002555 (double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity));
2556 (void) SetXMLTreeContent(child,value);
2557 }
2558 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2559 if (child != (XMLTreeInfo *) NULL)
2560 {
cristye7f51092010-01-17 00:39:37 +00002561 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002562 CurrentContext->stroke_width);
2563 (void) SetXMLTreeContent(child,value);
2564 }
2565 child=AddChildToXMLTree(xml_info,"text-align",0);
2566 if (child != (XMLTreeInfo *) NULL)
2567 {
2568 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickAlignOptions,
cristybb503372010-05-27 20:51:26 +00002569 (ssize_t) CurrentContext->align),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002570 (void) SetXMLTreeContent(child,value);
2571 }
2572 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2573 if (child != (XMLTreeInfo *) NULL)
2574 {
2575 (void) FormatMagickString(value,MaxTextExtent,"%d",
2576 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2577 (void) SetXMLTreeContent(child,value);
2578 }
2579 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2580 if (child != (XMLTreeInfo *) NULL)
2581 {
2582 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2583 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2584 MagickTrue : MagickFalse;
2585 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2586 (const IndexPacket *) NULL,&pixel);
2587 GetColorTuple(&pixel,MagickTrue,value);
2588 (void) SetXMLTreeContent(child,value);
2589 }
2590 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2591 if (child != (XMLTreeInfo *) NULL)
2592 (void) SetXMLTreeContent(child,wand->mvg);
2593 xml=XMLTreeInfoToXML(xml_info);
2594 xml_info=DestroyXMLTree(xml_info);
2595 return(xml);
2596}
2597
2598/*
2599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2600% %
2601% %
2602% %
2603% D r a w G e t T e x t U n d e r C o l o r %
2604% %
2605% %
2606% %
2607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2608%
2609% DrawGetTextUnderColor() returns the color of a background rectangle
2610% to place under text annotations.
2611%
2612% The format of the DrawGetTextUnderColor method is:
2613%
2614% void DrawGetTextUnderColor(const DrawingWand *wand,
2615% PixelWand *under_color)
2616%
2617% A description of each parameter follows:
2618%
2619% o wand: the drawing wand.
2620%
2621% o under_color: Return the under color.
2622%
2623*/
2624WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2625 PixelWand *under_color)
2626{
2627 assert(wand != (const DrawingWand *) NULL);
2628 assert(wand->signature == WandSignature);
2629 assert(under_color != (PixelWand *) NULL);
2630 if (wand->debug != MagickFalse)
2631 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2632 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2633}
2634
2635/*
2636%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2637% %
2638% %
2639% %
2640% D r a w L i n e %
2641% %
2642% %
2643% %
2644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2645%
2646% DrawLine() draws a line on the image using the current stroke color,
2647% stroke opacity, and stroke width.
2648%
2649% The format of the DrawLine method is:
2650%
2651% void DrawLine(DrawingWand *wand,const double sx,const double sy,
2652% const double ex,const double ey)
2653%
2654% A description of each parameter follows:
2655%
2656% o wand: the drawing wand.
2657%
2658% o sx: starting x ordinate
2659%
2660% o sy: starting y ordinate
2661%
2662% o ex: ending x ordinate
2663%
2664% o ey: ending y ordinate
2665%
2666*/
2667WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2668 const double ex,const double ey)
2669{
2670 assert(wand != (DrawingWand *) NULL);
2671 assert(wand->signature == WandSignature);
2672 if (wand->debug != MagickFalse)
2673 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00002674 (void) MvgPrintf(wand,"line %g,%g %g,%g\n",sx,sy,ex,ey);
cristy3ed852e2009-09-05 21:47:34 +00002675}
2676
2677/*
2678%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2679% %
2680% %
2681% %
2682% D r a w M a t t e %
2683% %
2684% %
2685% %
2686%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2687%
2688% DrawMatte() paints on the image's opacity channel in order to set effected
2689% pixels to transparent.
2690% to influence the opacity of pixels. The available paint
2691% methods are:
2692%
2693% PointMethod: Select the target pixel
2694% ReplaceMethod: Select any pixel that matches the target pixel.
2695% FloodfillMethod: Select the target pixel and matching neighbors.
2696% FillToBorderMethod: Select the target pixel and neighbors not matching
2697% border color.
2698% ResetMethod: Select all pixels.
2699%
2700% The format of the DrawMatte method is:
2701%
2702% void DrawMatte(DrawingWand *wand,const double x,const double y,
2703% const PaintMethod paint_method)
2704%
2705% A description of each parameter follows:
2706%
2707% o wand: the drawing wand.
2708%
2709% o x: x ordinate
2710%
2711% o y: y ordinate
2712%
2713% o paint_method: paint method.
2714%
2715*/
2716WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2717 const PaintMethod paint_method)
2718{
2719 assert(wand != (DrawingWand *) NULL);
2720 assert(wand->signature == WandSignature);
2721 if (wand->debug != MagickFalse)
2722 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00002723 (void) MvgPrintf(wand,"matte %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002724 MagickMethodOptions,(ssize_t) paint_method));
cristy3ed852e2009-09-05 21:47:34 +00002725}
2726
2727/*
2728%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2729% %
2730% %
2731% %
2732% D r a w P a t h C l o s e %
2733% %
2734% %
2735% %
2736%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2737%
2738% DrawPathClose() adds a path element to the current path which closes the
2739% current subpath by drawing a straight line from the current point to the
2740% current subpath's most recent starting point (usually, the most recent
2741% moveto point).
2742%
2743% The format of the DrawPathClose method is:
2744%
2745% void DrawPathClose(DrawingWand *wand)
2746%
2747% A description of each parameter follows:
2748%
2749% o wand: the drawing wand.
2750%
2751*/
2752WandExport void DrawPathClose(DrawingWand *wand)
2753{
2754 assert(wand != (DrawingWand *) NULL);
2755 assert(wand->signature == WandSignature);
2756 if (wand->debug != MagickFalse)
2757 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2758 (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2759 "Z" : "z");
2760}
2761
2762/*
2763%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2764% %
2765% %
2766% %
2767% D r a w P a t h C u r v e T o A b s o l u t e %
2768% %
2769% %
2770% %
2771%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2772%
2773% DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2774% point to (x,y) using (x1,y1) as the control point at the beginning of
2775% the curve and (x2,y2) as the control point at the end of the curve using
2776% absolute coordinates. At the end of the command, the new current point
2777% becomes the final (x,y) coordinate pair used in the polybezier.
2778%
2779% The format of the DrawPathCurveToAbsolute method is:
2780%
2781% void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2782% const double y1,const double x2,const double y2,const double x,
2783% const double y)
2784%
2785% A description of each parameter follows:
2786%
2787% o wand: the drawing wand.
2788%
2789% o x1: x ordinate of control point for curve beginning
2790%
2791% o y1: y ordinate of control point for curve beginning
2792%
2793% o x2: x ordinate of control point for curve ending
2794%
2795% o y2: y ordinate of control point for curve ending
2796%
2797% o x: x ordinate of the end of the curve
2798%
2799% o y: y ordinate of the end of the curve
2800%
2801*/
2802
2803static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2804 const double x1,const double y1,const double x2,const double y2,
2805 const double x,const double y)
2806{
2807 assert(wand != (DrawingWand *) NULL);
2808 assert(wand->signature == WandSignature);
2809 if (wand->debug != MagickFalse)
2810 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2811 if ((wand->path_operation != PathCurveToOperation) ||
2812 (wand->path_mode != mode))
2813 {
2814 wand->path_operation=PathCurveToOperation;
2815 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00002816 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g %g,%g",
cristy3ed852e2009-09-05 21:47:34 +00002817 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2818 }
2819 else
cristye7f51092010-01-17 00:39:37 +00002820 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g %g,%g",x1,y1,
cristy8cd5b312010-01-07 01:10:24 +00002821 x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002822}
2823
2824WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2825 const double y1,const double x2,const double y2,const double x,const double y)
2826{
2827 assert(wand != (DrawingWand *) NULL);
2828 assert(wand->signature == WandSignature);
2829 if (wand->debug != MagickFalse)
2830 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2831 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2832}
2833
2834/*
2835%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2836% %
2837% %
2838% %
2839% D r a w P a t h C u r v e T o R e l a t i v e %
2840% %
2841% %
2842% %
2843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2844%
2845% DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2846% point to (x,y) using (x1,y1) as the control point at the beginning of
2847% the curve and (x2,y2) as the control point at the end of the curve using
2848% relative coordinates. At the end of the command, the new current point
2849% becomes the final (x,y) coordinate pair used in the polybezier.
2850%
2851% The format of the DrawPathCurveToRelative method is:
2852%
2853% void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2854% const double y1,const double x2,const double y2,const double x,
2855% const double y)
2856%
2857% A description of each parameter follows:
2858%
2859% o wand: the drawing wand.
2860%
2861% o x1: x ordinate of control point for curve beginning
2862%
2863% o y1: y ordinate of control point for curve beginning
2864%
2865% o x2: x ordinate of control point for curve ending
2866%
2867% o y2: y ordinate of control point for curve ending
2868%
2869% o x: x ordinate of the end of the curve
2870%
2871% o y: y ordinate of the end of the curve
2872%
2873*/
2874WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2875 const double y1,const double x2,const double y2,const double x,const double y)
2876{
2877 assert(wand != (DrawingWand *) NULL);
2878 assert(wand->signature == WandSignature);
2879 if (wand->debug != MagickFalse)
2880 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2881 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2882}
2883
2884/*
2885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2886% %
2887% %
2888% %
2889% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r A b s o l u t e %
2890% %
2891% %
2892% %
2893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2894%
2895% DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2896% from the current point to (x,y) using (x1,y1) as the control point using
2897% absolute coordinates. At the end of the command, the new current point
2898% becomes the final (x,y) coordinate pair used in the polybezier.
2899%
2900% The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2901%
2902% void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2903% const double x1,const double y1,onst double x,const double y)
2904%
2905% A description of each parameter follows:
2906%
2907% o wand: the drawing wand.
2908%
2909% o x1: x ordinate of the control point
2910%
2911% o y1: y ordinate of the control point
2912%
2913% o x: x ordinate of final point
2914%
2915% o y: y ordinate of final point
2916%
2917*/
2918
2919static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2920 const PathMode mode,const double x1,double y1,const double x,const double y)
2921{
2922 assert(wand != (DrawingWand *) NULL);
2923 assert(wand->signature == WandSignature);
2924 if (wand->debug != MagickFalse)
2925 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2926 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2927 (wand->path_mode != mode))
2928 {
2929 wand->path_operation=PathCurveToQuadraticBezierOperation;
2930 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00002931 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g",
cristy8cd5b312010-01-07 01:10:24 +00002932 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002933 }
2934 else
cristye7f51092010-01-17 00:39:37 +00002935 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x1,y1,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002936}
2937
2938WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2939 const double x1,const double y1,const double x,const double y)
2940{
2941 assert(wand != (DrawingWand *) NULL);
2942 assert(wand->signature == WandSignature);
2943 if (wand->debug != MagickFalse)
2944 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2945 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
2946}
2947
2948/*
2949%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2950% %
2951% %
2952% %
2953% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r R e l a t i v e
2954% %
2955% %
2956% %
2957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2958%
2959% DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
2960% from the current point to (x,y) using (x1,y1) as the control point using
2961% relative coordinates. At the end of the command, the new current point
2962% becomes the final (x,y) coordinate pair used in the polybezier.
2963%
2964% The format of the DrawPathCurveToQuadraticBezierRelative method is:
2965%
2966% void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2967% const double x1,const double y1,const double x,const double y)
2968%
2969% A description of each parameter follows:
2970%
2971% o wand: the drawing wand.
2972%
2973% o x1: x ordinate of the control point
2974%
2975% o y1: y ordinate of the control point
2976%
2977% o x: x ordinate of final point
2978%
2979% o y: y ordinate of final point
2980%
2981*/
2982WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2983 const double x1,const double y1,const double x,const double y)
2984{
2985 assert(wand != (DrawingWand *) NULL);
2986 assert(wand->signature == WandSignature);
2987 if (wand->debug != MagickFalse)
2988 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2989 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
2990}
2991
2992/*
2993%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2994% %
2995% %
2996% %
2997% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h %
2998% %
2999% %
3000% %
3001%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3002%
3003% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3004% Bezier curve (using absolute coordinates) from the current point to
3005% (x,y). The control point is assumed to be the reflection of the
3006% control point on the previous command relative to the current
3007% point. (If there is no previous command or if the previous command was
3008% not a DrawPathCurveToQuadraticBezierAbsolute,
3009% DrawPathCurveToQuadraticBezierRelative,
3010% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3011% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3012% is coincident with the current point.). At the end of the command, the
3013% new current point becomes the final (x,y) coordinate pair used in the
3014% polybezier.
3015%
3016% The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3017%
3018% void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3019% DrawingWand *wand,const double x,const double y)
3020%
3021% A description of each parameter follows:
3022%
3023% o wand: the drawing wand.
3024%
3025% o x: x ordinate of final point
3026%
3027% o y: y ordinate of final point
3028%
3029*/
3030
3031static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3032 const PathMode mode,const double x,const double y)
3033{
3034 assert(wand != (DrawingWand *) NULL);
3035 assert(wand->signature == WandSignature);
3036 if (wand->debug != MagickFalse)
3037 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3038 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3039 (wand->path_mode != mode))
3040 {
3041 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3042 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003043 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003044 'T' : 't',x,y);
3045 }
3046 else
cristye7f51092010-01-17 00:39:37 +00003047 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003048}
3049
3050WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3051 const double x,const double y)
3052{
3053 assert(wand != (DrawingWand *) NULL);
3054 assert(wand->signature == WandSignature);
3055 if (wand->debug != MagickFalse)
3056 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3057 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3058}
3059
3060/*
3061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3062% %
3063% %
3064% %
3065% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h %
3066% %
3067% %
3068% %
3069%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3070%
3071% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3072% curve (using relative coordinates) from the current point to (x,y). The
3073% control point is assumed to be the reflection of the control point on the
3074% previous command relative to the current point. (If there is no previous
3075% command or if the previous command was not a
3076% DrawPathCurveToQuadraticBezierAbsolute,
3077% DrawPathCurveToQuadraticBezierRelative,
3078% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3079% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3080% coincident with the current point.). At the end of the command, the new
3081% current point becomes the final (x,y) coordinate pair used in the polybezier.
3082%
3083% The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3084%
3085% void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3086% const double x,const double y)
3087%
3088% A description of each parameter follows:
3089%
3090% o wand: the drawing wand.
3091%
3092% o x: x ordinate of final point
3093%
3094% o y: y ordinate of final point
3095%
3096*/
3097WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3098 const double x,const double y)
3099{
3100 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3101}
3102
3103/*
3104%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3105% %
3106% %
3107% %
3108% D r a w P a t h C u r v e T o S m o o t h A b s o l u t e %
3109% %
3110% %
3111% %
3112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3113%
3114% DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3115% current point to (x,y) using absolute coordinates. The first control
3116% point is assumed to be the reflection of the second control point on
3117% the previous command relative to the current point. (If there is no
3118% previous command or if the previous command was not an
3119% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3120% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3121% the first control point is coincident with the current point.) (x2,y2)
3122% is the second control point (i.e., the control point at the end of the
3123% curve). At the end of the command, the new current point becomes the
3124% final (x,y) coordinate pair used in the polybezier.
3125%
3126% The format of the DrawPathCurveToSmoothAbsolute method is:
3127%
3128% void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3129% const double x2const double y2,const double x,const double y)
3130%
3131% A description of each parameter follows:
3132%
3133% o wand: the drawing wand.
3134%
3135% o x2: x ordinate of second control point
3136%
3137% o y2: y ordinate of second control point
3138%
3139% o x: x ordinate of termination point
3140%
3141% o y: y ordinate of termination point
3142%
3143*/
3144
3145static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3146 const double x2,const double y2,const double x,const double y)
3147{
3148 assert(wand != (DrawingWand *) NULL);
3149 assert(wand->signature == WandSignature);
3150 if (wand->debug != MagickFalse)
3151 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3152 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3153 (wand->path_mode != mode))
3154 {
3155 wand->path_operation=PathCurveToSmoothOperation;
3156 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003157 (void) MvgAutoWrapPrintf(wand,"%c%g,%g %g,%g",
cristy8cd5b312010-01-07 01:10:24 +00003158 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003159 }
3160 else
cristye7f51092010-01-17 00:39:37 +00003161 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003162}
3163
3164WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3165 const double y2,const double x,const double y)
3166{
3167 assert(wand != (DrawingWand *) NULL);
3168 assert(wand->signature == WandSignature);
3169 if (wand->debug != MagickFalse)
3170 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3171 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3172}
3173
3174/*
3175%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3176% %
3177% %
3178% %
3179% D r a w P a t h C u r v e T o S m o o t h R e l a t i v e %
3180% %
3181% %
3182% %
3183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3184%
3185% DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3186% point to (x,y) using relative coordinates. The first control point is
3187% assumed to be the reflection of the second control point on the previous
3188% command relative to the current point. (If there is no previous command or
3189% if the previous command was not an DrawPathCurveToAbsolute,
3190% DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3191% DrawPathCurveToSmoothRelative, assume the first control point is coincident
3192% with the current point.) (x2,y2) is the second control point (i.e., the
3193% control point at the end of the curve). At the end of the command, the new
3194% current point becomes the final (x,y) coordinate pair used in the polybezier.
3195%
3196% The format of the DrawPathCurveToSmoothRelative method is:
3197%
3198% void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3199% const double x2,const double y2,const double x,const double y)
3200%
3201% A description of each parameter follows:
3202%
3203% o wand: the drawing wand.
3204%
3205% o x2: x ordinate of second control point
3206%
3207% o y2: y ordinate of second control point
3208%
3209% o x: x ordinate of termination point
3210%
3211% o y: y ordinate of termination point
3212%
3213*/
3214WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3215 const double y2,const double x,const double y)
3216{
3217 assert(wand != (DrawingWand *) NULL);
3218 assert(wand->signature == WandSignature);
3219 if (wand->debug != MagickFalse)
3220 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3221 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3222}
3223
3224/*
3225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3226% %
3227% %
3228% %
3229% D r a w P a t h E l l i p t i c A r c A b s o l u t e %
3230% %
3231% %
3232% %
3233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3234%
3235% DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3236% to (x, y) using absolute coordinates. The size and orientation of the
3237% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3238% indicates how the ellipse as a whole is rotated relative to the current
3239% coordinate system. The center (cx, cy) of the ellipse is calculated
3240% automagically to satisfy the constraints imposed by the other parameters.
3241% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3242% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3243% of the available arcs. If sweepFlag is true, then draw the arc matching a
3244% clock-wise rotation.
3245%
3246% The format of the DrawPathEllipticArcAbsolute method is:
3247%
3248% void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3249% const double rx,const double ry,const double x_axis_rotation,
3250% const MagickBooleanType large_arc_flag,
3251% const MagickBooleanType sweep_flag,const double x,const double y)
3252%
3253% A description of each parameter follows:
3254%
3255% o wand: the drawing wand.
3256%
3257% o rx: x radius
3258%
3259% o ry: y radius
3260%
3261% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3262% relative to the current coordinate system
3263%
3264% o large_arc_flag: If non-zero (true) then draw the larger of the
3265% available arcs
3266%
3267% o sweep_flag: If non-zero (true) then draw the arc matching a
3268% clock-wise rotation
3269%
3270%
3271*/
3272
3273static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3274 const double rx,const double ry,const double x_axis_rotation,
3275 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3276 const double x,const double y)
3277{
3278 assert(wand != (DrawingWand *) NULL);
3279 assert(wand->signature == WandSignature);
3280 if (wand->debug != MagickFalse)
3281 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3282 if ((wand->path_operation != PathEllipticArcOperation) ||
3283 (wand->path_mode != mode))
3284 {
3285 wand->path_operation=PathEllipticArcOperation;
3286 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003287 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g %u %u %g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003288 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3289 large_arc_flag,sweep_flag,x,y);
3290 }
3291 else
cristye7f51092010-01-17 00:39:37 +00003292 (void) MvgAutoWrapPrintf(wand," %g,%g %g %u %u %g,%g",rx,ry,
cristy8cd5b312010-01-07 01:10:24 +00003293 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003294}
3295
3296WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3297 const double ry,const double x_axis_rotation,
3298 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3299 const double x,const double y)
3300{
3301 assert(wand != (DrawingWand *) NULL);
3302 assert(wand->signature == WandSignature);
3303 if (wand->debug != MagickFalse)
3304 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3305 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3306 large_arc_flag,sweep_flag,x,y);
3307}
3308
3309/*
3310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3311% %
3312% %
3313% %
3314% D r a w P a t h E l l i p t i c A r c R e l a t i v e %
3315% %
3316% %
3317% %
3318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3319%
3320% DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3321% to (x, y) using relative coordinates. The size and orientation of the
3322% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3323% indicates how the ellipse as a whole is rotated relative to the current
3324% coordinate system. The center (cx, cy) of the ellipse is calculated
3325% automagically to satisfy the constraints imposed by the other parameters.
3326% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3327% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3328% of the available arcs. If sweepFlag is true, then draw the arc matching a
3329% clock-wise rotation.
3330%
3331% The format of the DrawPathEllipticArcRelative method is:
3332%
3333% void DrawPathEllipticArcRelative(DrawingWand *wand,
3334% const double rx,const double ry,const double x_axis_rotation,
3335% const MagickBooleanType large_arc_flag,
3336% const MagickBooleanType sweep_flag,const double x,const double y)
3337%
3338% A description of each parameter follows:
3339%
3340% o wand: the drawing wand.
3341%
3342% o rx: x radius
3343%
3344% o ry: y radius
3345%
3346% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3347% relative to the current coordinate system
3348%
3349% o large_arc_flag: If non-zero (true) then draw the larger of the
3350% available arcs
3351%
3352% o sweep_flag: If non-zero (true) then draw the arc matching a
3353% clock-wise rotation
3354%
3355*/
3356WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3357 const double ry,const double x_axis_rotation,
3358 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3359 const double x,const double y)
3360{
3361 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3362 large_arc_flag,sweep_flag,x,y);
3363}
3364
3365/*
3366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3367% %
3368% %
3369% %
3370% D r a w P a t h F i n i s h %
3371% %
3372% %
3373% %
3374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3375%
3376% DrawPathFinish() terminates the current path.
3377%
3378% The format of the DrawPathFinish method is:
3379%
3380% void DrawPathFinish(DrawingWand *wand)
3381%
3382% A description of each parameter follows:
3383%
3384% o wand: the drawing wand.
3385%
3386*/
3387WandExport void DrawPathFinish(DrawingWand *wand)
3388{
3389 assert(wand != (DrawingWand *) NULL);
3390 assert(wand->signature == WandSignature);
3391 if (wand->debug != MagickFalse)
3392 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3393 (void) MvgPrintf(wand,"'\n");
3394 wand->path_operation=PathDefaultOperation;
3395 wand->path_mode=DefaultPathMode;
3396}
3397
3398/*
3399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3400% %
3401% %
3402% %
3403% D r a w P a t h L i n e T o A b s o l u t e %
3404% %
3405% %
3406% %
3407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3408%
3409% DrawPathLineToAbsolute() draws a line path from the current point to the
3410% given coordinate using absolute coordinates. The coordinate then becomes
3411% the new current point.
3412%
3413% The format of the DrawPathLineToAbsolute method is:
3414%
3415% void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3416% const double y)
3417%
3418% A description of each parameter follows:
3419%
3420% o wand: the drawing wand.
3421%
3422% o x: target x ordinate
3423%
3424% o y: target y ordinate
3425%
3426*/
3427static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3428 const double x,const double y)
3429{
3430 assert(wand != (DrawingWand *) NULL);
3431 assert(wand->signature == WandSignature);
3432 if (wand->debug != MagickFalse)
3433 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3434 if ((wand->path_operation != PathLineToOperation) ||
3435 (wand->path_mode != mode))
3436 {
3437 wand->path_operation=PathLineToOperation;
3438 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003439 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003440 'L' : 'l',x,y);
3441 }
3442 else
cristye7f51092010-01-17 00:39:37 +00003443 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003444}
3445
3446WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3447 const double y)
3448{
3449 assert(wand != (DrawingWand *) NULL);
3450 assert(wand->signature == WandSignature);
3451 if (wand->debug != MagickFalse)
3452 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3453 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3454}
3455
3456/*
3457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3458% %
3459% %
3460% %
3461% D r a w P a t h L i n e T o R e l a t i v e %
3462% %
3463% %
3464% %
3465%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3466%
3467% DrawPathLineToRelative() draws a line path from the current point to the
3468% given coordinate using relative coordinates. The coordinate then becomes
3469% the new current point.
3470%
3471% The format of the DrawPathLineToRelative method is:
3472%
3473% void DrawPathLineToRelative(DrawingWand *wand,const double x,
3474% const double y)
3475%
3476% A description of each parameter follows:
3477%
3478% o wand: the drawing wand.
3479%
3480% o x: target x ordinate
3481%
3482% o y: target y ordinate
3483%
3484*/
3485WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3486 const double y)
3487{
3488 assert(wand != (DrawingWand *) NULL);
3489 assert(wand->signature == WandSignature);
3490 if (wand->debug != MagickFalse)
3491 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3492 DrawPathLineTo(wand,RelativePathMode,x,y);
3493}
3494
3495/*
3496%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3497% %
3498% %
3499% %
3500% D r a w P a t h L i n e T o H o r i z o n t a l A b s o l u t e %
3501% %
3502% %
3503% %
3504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3505%
3506% DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3507% current point to the target point using absolute coordinates. The target
3508% point then becomes the new current point.
3509%
3510% The format of the DrawPathLineToHorizontalAbsolute method is:
3511%
3512% void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3513% const PathMode mode,const double x)
3514%
3515% A description of each parameter follows:
3516%
3517% o wand: the drawing wand.
3518%
3519% o x: target x ordinate
3520%
3521*/
3522
3523static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3524 const double x)
3525{
3526 assert(wand != (DrawingWand *) NULL);
3527 assert(wand->signature == WandSignature);
3528 if (wand->debug != MagickFalse)
3529 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3530 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3531 (wand->path_mode != mode))
3532 {
3533 wand->path_operation=PathLineToHorizontalOperation;
3534 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003535 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003536 'H' : 'h',x);
3537 }
3538 else
cristye7f51092010-01-17 00:39:37 +00003539 (void) MvgAutoWrapPrintf(wand," %g",x);
cristy3ed852e2009-09-05 21:47:34 +00003540}
3541
3542WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3543 const double x)
3544{
3545 assert(wand != (DrawingWand *) NULL);
3546 assert(wand->signature == WandSignature);
3547 if (wand->debug != MagickFalse)
3548 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3549 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3550}
3551
3552/*
3553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3554% %
3555% %
3556% %
3557% D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e %
3558% %
3559% %
3560% %
3561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3562%
3563% DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3564% current point to the target point using relative coordinates. The target
3565% point then becomes the new current point.
3566%
3567% The format of the DrawPathLineToHorizontalRelative method is:
3568%
3569% void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3570% const double x)
3571%
3572% A description of each parameter follows:
3573%
3574% o wand: the drawing wand.
3575%
3576% o x: target x ordinate
3577%
3578*/
3579WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3580 const double x)
3581{
3582 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3583}
3584
3585/*
3586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3587% %
3588% %
3589% %
3590% D r a w P a t h L i n e T o V e r t i c a l A b s o l u t e %
3591% %
3592% %
3593% %
3594%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3595%
3596% DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3597% current point to the target point using absolute coordinates. The target
3598% point then becomes the new current point.
3599%
3600% The format of the DrawPathLineToVerticalAbsolute method is:
3601%
3602% void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3603% const double y)
3604%
3605% A description of each parameter follows:
3606%
3607% o wand: the drawing wand.
3608%
3609% o y: target y ordinate
3610%
3611*/
3612
3613static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3614 const double y)
3615{
3616 assert(wand != (DrawingWand *) NULL);
3617 assert(wand->signature == WandSignature);
3618 if (wand->debug != MagickFalse)
3619 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3620 if ((wand->path_operation != PathLineToVerticalOperation) ||
3621 (wand->path_mode != mode))
3622 {
3623 wand->path_operation=PathLineToVerticalOperation;
3624 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003625 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003626 'V' : 'v',y);
3627 }
3628 else
cristye7f51092010-01-17 00:39:37 +00003629 (void) MvgAutoWrapPrintf(wand," %g",y);
cristy3ed852e2009-09-05 21:47:34 +00003630}
3631
3632WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3633{
3634 assert(wand != (DrawingWand *) NULL);
3635 assert(wand->signature == WandSignature);
3636 if (wand->debug != MagickFalse)
3637 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3638 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3639}
3640
3641/*
3642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3643% %
3644% %
3645% %
3646% D r a w P a t h L i n e T o V e r t i c a l R e l a t i v e %
3647% %
3648% %
3649% %
3650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3651%
3652% DrawPathLineToVerticalRelative() draws a vertical line path from the
3653% current point to the target point using relative coordinates. The target
3654% point then becomes the new current point.
3655%
3656% The format of the DrawPathLineToVerticalRelative method is:
3657%
3658% void DrawPathLineToVerticalRelative(DrawingWand *wand,
3659% const double y)
3660%
3661% A description of each parameter follows:
3662%
3663% o wand: the drawing wand.
3664%
3665% o y: target y ordinate
3666%
3667*/
3668WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3669{
3670 assert(wand != (DrawingWand *) NULL);
3671 assert(wand->signature == WandSignature);
3672 if (wand->debug != MagickFalse)
3673 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3674 DrawPathLineToVertical(wand,RelativePathMode,y);
3675}
3676/*
3677%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3678% %
3679% %
3680% %
3681% D r a w P a t h M o v e T o A b s o l u t e %
3682% %
3683% %
3684% %
3685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3686%
3687% DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3688% using absolute coordinates. The current point then becomes the
3689% specified coordinate.
3690%
3691% The format of the DrawPathMoveToAbsolute method is:
3692%
3693% void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3694% const double y)
3695%
3696% A description of each parameter follows:
3697%
3698% o wand: the drawing wand.
3699%
3700% o x: target x ordinate
3701%
3702% o y: target y ordinate
3703%
3704*/
3705
3706static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3707 const double y)
3708{
3709 assert(wand != (DrawingWand *) NULL);
3710 assert(wand->signature == WandSignature);
3711 if (wand->debug != MagickFalse)
3712 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3713 if ((wand->path_operation != PathMoveToOperation) ||
3714 (wand->path_mode != mode))
3715 {
3716 wand->path_operation=PathMoveToOperation;
3717 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003718 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003719 'M' : 'm',x,y);
3720 }
3721 else
cristye7f51092010-01-17 00:39:37 +00003722 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003723}
3724
3725WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3726 const double y)
3727{
3728 assert(wand != (DrawingWand *) NULL);
3729 assert(wand->signature == WandSignature);
3730 if (wand->debug != MagickFalse)
3731 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3732 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3733}
3734
3735/*
3736%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3737% %
3738% %
3739% %
3740% D r a w P a t h M o v e T o R e l a t i v e %
3741% %
3742% %
3743% %
3744%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3745%
3746% DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3747% relative coordinates. The current point then becomes the specified
3748% coordinate.
3749%
3750% The format of the DrawPathMoveToRelative method is:
3751%
3752% void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3753% const double y)
3754%
3755% A description of each parameter follows:
3756%
3757% o wand: the drawing wand.
3758%
3759% o x: target x ordinate
3760%
3761% o y: target y ordinate
3762%
3763*/
3764WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3765 const double y)
3766{
3767 assert(wand != (DrawingWand *) NULL);
3768 assert(wand->signature == WandSignature);
3769 if (wand->debug != MagickFalse)
3770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3771 DrawPathMoveTo(wand,RelativePathMode,x,y);
3772}
3773
3774/*
3775%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3776% %
3777% %
3778% %
3779% D r a w P a t h S t a r t %
3780% %
3781% %
3782% %
3783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3784%
3785% DrawPathStart() declares the start of a path drawing list which is terminated
3786% by a matching DrawPathFinish() command. All other DrawPath commands must
3787% be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3788% is because path drawing commands are subordinate commands and they do not
3789% function by themselves.
3790%
3791% The format of the DrawPathStart method is:
3792%
3793% void DrawPathStart(DrawingWand *wand)
3794%
3795% A description of each parameter follows:
3796%
3797% o wand: the drawing wand.
3798%
3799*/
3800WandExport void DrawPathStart(DrawingWand *wand)
3801{
3802 assert(wand != (DrawingWand *) NULL);
3803 assert(wand->signature == WandSignature);
3804 if (wand->debug != MagickFalse)
3805 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3806 (void) MvgPrintf(wand,"path '");
3807 wand->path_operation=PathDefaultOperation;
3808 wand->path_mode=DefaultPathMode;
3809}
3810
3811/*
3812%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3813% %
3814% %
3815% %
3816% D r a w P o i n t %
3817% %
3818% %
3819% %
3820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3821%
3822% DrawPoint() draws a point using the current fill color.
3823%
3824% The format of the DrawPoint method is:
3825%
3826% void DrawPoint(DrawingWand *wand,const double x,const double y)
3827%
3828% A description of each parameter follows:
3829%
3830% o wand: the drawing wand.
3831%
3832% o x: target x coordinate
3833%
3834% o y: target y coordinate
3835%
3836*/
3837WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3838{
3839 assert(wand != (DrawingWand *) NULL);
3840 assert(wand->signature == WandSignature);
3841 if (wand->debug != MagickFalse)
3842 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00003843 (void) MvgPrintf(wand,"point %g,%g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003844}
3845
3846/*
3847%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3848% %
3849% %
3850% %
3851% D r a w P o l y g o n %
3852% %
3853% %
3854% %
3855%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3856%
3857% DrawPolygon() draws a polygon using the current stroke, stroke width, and
3858% fill color or texture, using the specified array of coordinates.
3859%
3860% The format of the DrawPolygon method is:
3861%
3862% void DrawPolygon(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003863% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003864%
3865% A description of each parameter follows:
3866%
3867% o wand: the drawing wand.
3868%
3869% o number_coordinates: number of coordinates
3870%
3871% o coordinates: coordinate array
3872%
3873*/
3874WandExport void DrawPolygon(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003875 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003876{
3877 assert(wand != (DrawingWand *) NULL);
3878 assert(wand->signature == WandSignature);
3879 if (wand->debug != MagickFalse)
3880 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3881 MvgAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3882}
3883
3884/*
3885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3886% %
3887% %
3888% %
3889% D r a w P o l y l i n e %
3890% %
3891% %
3892% %
3893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3894%
3895% DrawPolyline() draws a polyline using the current stroke, stroke width, and
3896% fill color or texture, using the specified array of coordinates.
3897%
3898% The format of the DrawPolyline method is:
3899%
3900% void DrawPolyline(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003901% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003902%
3903% A description of each parameter follows:
3904%
3905% o wand: the drawing wand.
3906%
3907% o number_coordinates: number of coordinates
3908%
3909% o coordinates: coordinate array
3910%
3911*/
3912WandExport void DrawPolyline(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003913 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003914{
3915 assert(wand != (DrawingWand *) NULL);
3916 assert(wand->signature == WandSignature);
3917 if (wand->debug != MagickFalse)
3918 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3919 MvgAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
3920}
3921
3922/*
3923%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3924% %
3925% %
3926% %
3927% D r a w P o p C l i p P a t h %
3928% %
3929% %
3930% %
3931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932%
3933% DrawPopClipPath() terminates a clip path definition.
3934%
3935% The format of the DrawPopClipPath method is:
3936%
3937% void DrawPopClipPath(DrawingWand *wand)
3938%
3939% A description of each parameter follows:
3940%
3941% o wand: the drawing wand.
3942%
3943*/
3944WandExport void DrawPopClipPath(DrawingWand *wand)
3945{
3946 assert(wand != (DrawingWand *) NULL);
3947 assert(wand->signature == WandSignature);
3948 if (wand->debug != MagickFalse)
3949 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3950 if (wand->indent_depth > 0)
3951 wand->indent_depth--;
3952 (void) MvgPrintf(wand,"pop clip-path\n");
3953}
3954
3955/*
3956%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3957% %
3958% %
3959% %
3960% D r a w P o p D e f s %
3961% %
3962% %
3963% %
3964%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3965%
3966% DrawPopDefs() terminates a definition list.
3967%
3968% The format of the DrawPopDefs method is:
3969%
3970% void DrawPopDefs(DrawingWand *wand)
3971%
3972% A description of each parameter follows:
3973%
3974% o wand: the drawing wand.
3975%
3976*/
3977WandExport void DrawPopDefs(DrawingWand *wand)
3978{
3979 assert(wand != (DrawingWand *) NULL);
3980 assert(wand->signature == WandSignature);
3981 if (wand->debug != MagickFalse)
3982 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3983 if (wand->indent_depth > 0)
3984 wand->indent_depth--;
3985 (void) MvgPrintf(wand,"pop defs\n");
3986}
3987
3988/*
3989%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3990% %
3991% %
3992% %
3993% D r a w P o p P a t t e r n %
3994% %
3995% %
3996% %
3997%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3998%
3999% DrawPopPattern() terminates a pattern definition.
4000%
4001% The format of the DrawPopPattern method is:
4002%
4003% MagickBooleanType DrawPopPattern(DrawingWand *wand)
4004%
4005% A description of each parameter follows:
4006%
4007% o wand: the drawing wand.
4008%
4009*/
4010WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4011{
4012 char
4013 geometry[MaxTextExtent],
4014 key[MaxTextExtent];
4015
4016 assert(wand != (DrawingWand *) NULL);
4017 assert(wand->signature == WandSignature);
4018 if (wand->debug != MagickFalse)
4019 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4020 if (wand->image == (Image *) NULL)
4021 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4022 if (wand->pattern_id == (const char *) NULL)
4023 {
4024 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4025 wand->name);
4026 return(MagickFalse);
4027 }
4028 (void) FormatMagickString(key,MaxTextExtent,"%s",wand->pattern_id);
4029 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4030 (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
cristyf2faecf2010-05-28 19:19:36 +00004031 (unsigned long) wand->pattern_bounds.width,(unsigned long)
4032 wand->pattern_bounds.height,(long) wand->pattern_bounds.x,
4033 (long) wand->pattern_bounds.y);
cristy3ed852e2009-09-05 21:47:34 +00004034 (void) SetImageArtifact(wand->image,key,geometry);
4035 wand->pattern_id=DestroyString(wand->pattern_id);
4036 wand->pattern_offset=0;
4037 wand->pattern_bounds.x=0;
4038 wand->pattern_bounds.y=0;
4039 wand->pattern_bounds.width=0;
4040 wand->pattern_bounds.height=0;
4041 wand->filter_off=MagickTrue;
4042 if (wand->indent_depth > 0)
4043 wand->indent_depth--;
4044 (void) MvgPrintf(wand,"pop pattern\n");
4045 return(MagickTrue);
4046}
4047
4048/*
4049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4050% %
4051% %
4052% %
4053% D r a w P u s h C l i p P a t h %
4054% %
4055% %
4056% %
4057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4058%
4059% DrawPushClipPath() starts a clip path definition which is comprized of any
4060% number of drawing commands and terminated by a DrawPopClipPath() command.
4061%
4062% The format of the DrawPushClipPath method is:
4063%
4064% void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4065%
4066% A description of each parameter follows:
4067%
4068% o wand: the drawing wand.
4069%
4070% o clip_mask_id: string identifier to associate with the clip path for
4071% later use.
4072%
4073*/
4074WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4075{
4076 assert(wand != (DrawingWand *) NULL);
4077 assert(wand->signature == WandSignature);
4078 if (wand->debug != MagickFalse)
4079 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4080 assert(clip_mask_id != (const char *) NULL);
4081 (void) MvgPrintf(wand,"push clip-path %s\n",clip_mask_id);
4082 wand->indent_depth++;
4083}
4084
4085/*
4086%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4087% %
4088% %
4089% %
4090% D r a w P u s h D e f s %
4091% %
4092% %
4093% %
4094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4095%
4096% DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4097% command create named elements (e.g. clip-paths, textures, etc.) which
4098% may safely be processed earlier for the sake of efficiency.
4099%
4100% The format of the DrawPushDefs method is:
4101%
4102% void DrawPushDefs(DrawingWand *wand)
4103%
4104% A description of each parameter follows:
4105%
4106% o wand: the drawing wand.
4107%
4108*/
4109WandExport void DrawPushDefs(DrawingWand *wand)
4110{
4111 assert(wand != (DrawingWand *) NULL);
4112 assert(wand->signature == WandSignature);
4113 if (wand->debug != MagickFalse)
4114 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4115 (void) MvgPrintf(wand,"push defs\n");
4116 wand->indent_depth++;
4117}
4118
4119/*
4120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121% %
4122% %
4123% %
4124% D r a w P u s h P a t t e r n %
4125% %
4126% %
4127% %
4128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4129%
4130% DrawPushPattern() indicates that subsequent commands up to a
4131% DrawPopPattern() command comprise the definition of a named pattern.
4132% The pattern space is assigned top left corner coordinates, a width
4133% and height, and becomes its own drawing space. Anything which can
4134% be drawn may be used in a pattern definition.
4135% Named patterns may be used as stroke or brush definitions.
4136%
4137% The format of the DrawPushPattern method is:
4138%
4139% MagickBooleanType DrawPushPattern(DrawingWand *wand,
4140% const char *pattern_id,const double x,const double y,
4141% const double width,const double height)
4142%
4143% A description of each parameter follows:
4144%
4145% o wand: the drawing wand.
4146%
4147% o pattern_id: pattern identification for later reference
4148%
4149% o x: x ordinate of top left corner
4150%
4151% o y: y ordinate of top left corner
4152%
4153% o width: width of pattern space
4154%
4155% o height: height of pattern space
4156%
4157*/
4158WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4159 const char *pattern_id,const double x,const double y,const double width,
4160 const double height)
4161{
4162 assert(wand != (DrawingWand *) NULL);
4163 assert(wand->signature == WandSignature);
4164 if (wand->debug != MagickFalse)
4165 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4166 assert(pattern_id != (const char *) NULL);
4167 if (wand->pattern_id != NULL)
4168 {
4169 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4170 wand->pattern_id);
4171 return(MagickFalse);
4172 }
4173 wand->filter_off=MagickTrue;
cristye7f51092010-01-17 00:39:37 +00004174 (void) MvgPrintf(wand,"push pattern %s %g,%g %g,%g\n",pattern_id,
cristy8cd5b312010-01-07 01:10:24 +00004175 x,y,width,height);
cristy3ed852e2009-09-05 21:47:34 +00004176 wand->indent_depth++;
4177 wand->pattern_id=AcquireString(pattern_id);
cristybb503372010-05-27 20:51:26 +00004178 wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
4179 wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
4180 wand->pattern_bounds.width=(size_t) floor(width+0.5);
4181 wand->pattern_bounds.height=(size_t) floor(height+0.5);
cristy3ed852e2009-09-05 21:47:34 +00004182 wand->pattern_offset=wand->mvg_length;
4183 return(MagickTrue);
4184}
4185
4186/*
4187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4188% %
4189% %
4190% %
4191% D r a w R e c t a n g l e %
4192% %
4193% %
4194% %
4195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4196%
4197% DrawRectangle() draws a rectangle given two coordinates and using the
4198% current stroke, stroke width, and fill settings.
4199%
4200% The format of the DrawRectangle method is:
4201%
4202% void DrawRectangle(DrawingWand *wand,const double x1,
4203% const double y1,const double x2,const double y2)
4204%
4205% A description of each parameter follows:
4206%
4207% o x1: x ordinate of first coordinate
4208%
4209% o y1: y ordinate of first coordinate
4210%
4211% o x2: x ordinate of second coordinate
4212%
4213% o y2: y ordinate of second coordinate
4214%
4215*/
4216WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4217 const double x2,const double y2)
4218{
4219 assert(wand != (DrawingWand *) NULL);
4220 assert(wand->signature == WandSignature);
4221 if (wand->debug != MagickFalse)
4222 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00004223 (void) MvgPrintf(wand,"rectangle %g,%g %g,%g\n",x1,y1,x2,y2);
cristy3ed852e2009-09-05 21:47:34 +00004224}
4225
4226/*
4227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4228% %
4229% %
4230% %
4231+ D r a w R e n d e r %
4232% %
4233% %
4234% %
4235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4236%
4237% DrawRender() renders all preceding drawing commands onto the image.
4238%
4239% The format of the DrawRender method is:
4240%
4241% MagickBooleanType DrawRender(DrawingWand *wand)
4242%
4243% A description of each parameter follows:
4244%
4245% o wand: the drawing wand.
4246%
4247*/
4248WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4249{
4250 MagickBooleanType
4251 status;
4252
4253 assert(wand != (const DrawingWand *) NULL);
4254 assert(wand->signature == WandSignature);
4255 if (wand->debug != MagickFalse)
4256 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4257 CurrentContext->primitive=wand->mvg;
4258 if (wand->debug != MagickFalse)
4259 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4260 if (wand->image == (Image *) NULL)
4261 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4262 status=DrawImage(wand->image,CurrentContext);
4263 InheritException(wand->exception,&wand->image->exception);
4264 CurrentContext->primitive=(char *) NULL;
4265 return(status);
4266}
4267
4268/*
4269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4270% %
4271% %
4272% %
4273% D r a w R e s e t V e c t o r G r a p h i c s %
4274% %
4275% %
4276% %
4277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4278%
4279% DrawResetVectorGraphics() resets the vector graphics associated with the
4280% specified wand.
4281%
4282% The format of the DrawResetVectorGraphics method is:
4283%
4284% void DrawResetVectorGraphics(DrawingWand *wand)
4285%
4286% A description of each parameter follows:
4287%
4288% o wand: the drawing wand.
4289%
4290*/
4291WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4292{
4293 assert(wand != (DrawingWand *) NULL);
4294 assert(wand->signature == WandSignature);
4295 if (wand->debug != MagickFalse)
4296 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4297 if (wand->mvg != (char *) NULL)
4298 wand->mvg=DestroyString(wand->mvg);
4299 wand->mvg_alloc=0;
4300 wand->mvg_length=0;
4301 wand->mvg_width=0;
4302}
4303
4304/*
4305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4306% %
4307% %
4308% %
4309% D r a w R o t a t e %
4310% %
4311% %
4312% %
4313%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4314%
4315% DrawRotate() applies the specified rotation to the current coordinate space.
4316%
4317% The format of the DrawRotate method is:
4318%
4319% void DrawRotate(DrawingWand *wand,const double degrees)
4320%
4321% A description of each parameter follows:
4322%
4323% o wand: the drawing wand.
4324%
4325% o degrees: degrees of rotation
4326%
4327*/
4328WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4329{
4330 AffineMatrix
4331 affine;
4332
4333 assert(wand != (DrawingWand *) NULL);
4334 assert(wand->signature == WandSignature);
4335 if (wand->debug != MagickFalse)
4336 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4337 GetAffineMatrix(&affine);
4338 affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
4339 affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
4340 affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
4341 affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
4342 AdjustAffine(wand,&affine);
cristye7f51092010-01-17 00:39:37 +00004343 (void) MvgPrintf(wand,"rotate %g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00004344}
4345
4346/*
4347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4348% %
4349% %
4350% %
4351% D r a w R o u n d R e c t a n g l e %
4352% %
4353% %
4354% %
4355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4356%
4357% DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4358% x & y corner radiuses and using the current stroke, stroke width,
4359% and fill settings.
4360%
4361% The format of the DrawRoundRectangle method is:
4362%
4363% void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4364% double x2,double y2,double rx,double ry)
4365%
4366% A description of each parameter follows:
4367%
4368% o wand: the drawing wand.
4369%
4370% o x1: x ordinate of first coordinate
4371%
4372% o y1: y ordinate of first coordinate
4373%
4374% o x2: x ordinate of second coordinate
4375%
4376% o y2: y ordinate of second coordinate
4377%
4378% o rx: radius of corner in horizontal direction
4379%
4380% o ry: radius of corner in vertical direction
4381%
4382*/
4383WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4384 double x2,double y2,double rx,double ry)
4385{
4386 assert(wand != (DrawingWand *) NULL);
4387 assert(wand->signature == WandSignature);
4388 if (wand->debug != MagickFalse)
4389 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00004390 (void) MvgPrintf(wand,"roundrectangle %g,%g %g,%g %g,%g\n",
cristy8cd5b312010-01-07 01:10:24 +00004391 x1,y1,x2,y2,rx,ry);
cristy3ed852e2009-09-05 21:47:34 +00004392}
4393
4394/*
4395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4396% %
4397% %
4398% %
4399% D r a w S c a l e %
4400% %
4401% %
4402% %
4403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4404%
4405% DrawScale() adjusts the scaling factor to apply in the horizontal and
4406% vertical directions to the current coordinate space.
4407%
4408% The format of the DrawScale method is:
4409%
4410% void DrawScale(DrawingWand *wand,const double x,const double y)
4411%
4412% A description of each parameter follows:
4413%
4414% o wand: the drawing wand.
4415%
4416% o x: horizontal scale factor
4417%
4418% o y: vertical scale factor
4419%
4420*/
4421WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4422{
4423 AffineMatrix
4424 affine;
4425
4426 assert(wand != (DrawingWand *) NULL);
4427 assert(wand->signature == WandSignature);
4428 if (wand->debug != MagickFalse)
4429 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4430 GetAffineMatrix(&affine);
4431 affine.sx=x;
4432 affine.sy=y;
4433 AdjustAffine(wand,&affine);
cristye7f51092010-01-17 00:39:37 +00004434 (void) MvgPrintf(wand,"scale %g,%g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00004435}
4436
4437/*
4438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4439% %
4440% %
4441% %
4442% D r a w S e t B o r d e r C o l o r %
4443% %
4444% %
4445% %
4446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4447%
4448% DrawSetBorderColor() sets the border color to be used for drawing bordered
4449% objects.
4450%
4451% The format of the DrawSetBorderColor method is:
4452%
4453% void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4454%
4455% A description of each parameter follows:
4456%
4457% o wand: the drawing wand.
4458%
4459% o border_wand: border wand.
4460%
4461*/
4462
4463static inline MagickBooleanType IsColorEqual(const PixelPacket *p,
4464 const PixelPacket *q)
4465{
4466 if (p->red != q->red)
4467 return(MagickFalse);
4468 if (p->green != q->green)
4469 return(MagickFalse);
4470 if (p->blue != q->blue)
4471 return(MagickFalse);
4472 if (p->opacity != q->opacity)
4473 return(MagickFalse);
4474 return(MagickTrue);
4475}
4476
4477WandExport void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4478{
4479 PixelPacket
4480 *current_border,
4481 border_color,
4482 new_border;
4483
4484 assert(wand != (DrawingWand *) NULL);
4485 assert(wand->signature == WandSignature);
4486 if (wand->debug != MagickFalse)
4487 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4488 assert(border_wand != (const PixelWand *) NULL);
4489 PixelGetQuantumColor(border_wand,&border_color);
4490 new_border=border_color;
4491 current_border=(&CurrentContext->border_color);
4492 if ((wand->filter_off != MagickFalse) ||
4493 (IsColorEqual(current_border,&new_border) == MagickFalse))
4494 {
4495 CurrentContext->border_color=new_border;
4496 (void) MvgPrintf(wand,"border-color '");
4497 MvgAppendColor(wand,&border_color);
4498 (void) MvgPrintf(wand,"'\n");
4499 }
4500}
4501
4502/*
4503%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4504% %
4505% %
4506% %
4507% D r a w S e t C l i p P a t h %
4508% %
4509% %
4510% %
4511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4512%
4513% DrawSetClipPath() associates a named clipping path with the image. Only
cristybb503372010-05-27 20:51:26 +00004514% the areas drawn on by the clipping path will be modified as ssize_t as it
cristy3ed852e2009-09-05 21:47:34 +00004515% remains in effect.
4516%
4517% The format of the DrawSetClipPath method is:
4518%
4519% MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4520% const char *clip_mask)
4521%
4522% A description of each parameter follows:
4523%
4524% o wand: the drawing wand.
4525%
4526% o clip_mask: name of clipping path to associate with image
4527%
4528*/
4529WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4530 const char *clip_mask)
4531{
4532 if (wand->debug != MagickFalse)
4533 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4534 assert(wand != (DrawingWand *) NULL);
4535 assert(wand->signature == WandSignature);
4536 assert(clip_mask != (const char *) NULL);
4537 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4538 (wand->filter_off != MagickFalse) ||
4539 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4540 {
4541 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4542#if DRAW_BINARY_IMPLEMENTATION
4543 if (wand->image == (Image *) NULL)
4544 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4545 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4546#endif
4547 (void) MvgPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4548 }
4549 return(MagickTrue);
4550}
4551
4552/*
4553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4554% %
4555% %
4556% %
4557% D r a w S e t C l i p R u l e %
4558% %
4559% %
4560% %
4561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4562%
4563% DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4564%
4565% The format of the DrawSetClipRule method is:
4566%
4567% void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4568%
4569% A description of each parameter follows:
4570%
4571% o wand: the drawing wand.
4572%
4573% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4574%
4575*/
4576WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4577{
4578 assert(wand != (DrawingWand *) NULL);
4579 assert(wand->signature == WandSignature);
4580 if (wand->debug != MagickFalse)
4581 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4582 if ((wand->filter_off != MagickFalse) ||
4583 (CurrentContext->fill_rule != fill_rule))
4584 {
4585 CurrentContext->fill_rule=fill_rule;
4586 (void) MvgPrintf(wand, "clip-rule '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004587 MagickFillRuleOptions,(ssize_t) fill_rule));
cristy3ed852e2009-09-05 21:47:34 +00004588 }
4589}
4590
4591/*
4592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4593% %
4594% %
4595% %
4596% D r a w S e t C l i p U n i t s %
4597% %
4598% %
4599% %
4600%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4601%
4602% DrawSetClipUnits() sets the interpretation of clip path units.
4603%
4604% The format of the DrawSetClipUnits method is:
4605%
4606% void DrawSetClipUnits(DrawingWand *wand,
4607% const ClipPathUnits clip_units)
4608%
4609% A description of each parameter follows:
4610%
4611% o wand: the drawing wand.
4612%
4613% o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4614% ObjectBoundingBox)
4615%
4616*/
4617WandExport void DrawSetClipUnits(DrawingWand *wand,
4618 const ClipPathUnits clip_units)
4619{
4620 assert(wand != (DrawingWand *) NULL);
4621 assert(wand->signature == WandSignature);
4622 if (wand->debug != MagickFalse)
4623 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4624 if ((wand->filter_off != MagickFalse) ||
4625 (CurrentContext->clip_units != clip_units))
4626 {
4627 CurrentContext->clip_units=clip_units;
4628 if (clip_units == ObjectBoundingBox)
4629 {
4630 AffineMatrix
4631 affine;
4632
4633 GetAffineMatrix(&affine);
4634 affine.sx=CurrentContext->bounds.x2;
4635 affine.sy=CurrentContext->bounds.y2;
4636 affine.tx=CurrentContext->bounds.x1;
4637 affine.ty=CurrentContext->bounds.y1;
4638 AdjustAffine(wand,&affine);
4639 }
4640 (void) MvgPrintf(wand, "clip-units '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004641 MagickClipPathOptions,(ssize_t) clip_units));
cristy3ed852e2009-09-05 21:47:34 +00004642 }
4643}
4644
4645/*
4646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4647% %
4648% %
4649% %
4650% D r a w S e t F i l l C o l o r %
4651% %
4652% %
4653% %
4654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4655%
4656% DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4657%
4658% The format of the DrawSetFillColor method is:
4659%
4660% void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4661%
4662% A description of each parameter follows:
4663%
4664% o wand: the drawing wand.
4665%
4666% o fill_wand: fill wand.
4667%
4668*/
4669WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4670{
4671 PixelPacket
4672 *current_fill,
4673 fill_color,
4674 new_fill;
4675
4676 assert(wand != (DrawingWand *) NULL);
4677 assert(wand->signature == WandSignature);
4678 if (wand->debug != MagickFalse)
4679 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4680 assert(fill_wand != (const PixelWand *) NULL);
4681 PixelGetQuantumColor(fill_wand,&fill_color);
4682 new_fill=fill_color;
4683 current_fill=(&CurrentContext->fill);
4684 if ((wand->filter_off != MagickFalse) ||
4685 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4686 {
4687 CurrentContext->fill=new_fill;
4688 (void) MvgPrintf(wand,"fill '");
4689 MvgAppendColor(wand,&fill_color);
4690 (void) MvgPrintf(wand,"'\n");
4691 }
4692}
4693
4694/*
4695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4696% %
4697% %
4698% %
4699% D r a w S e t F i l l O p a c i t y %
4700% %
4701% %
4702% %
4703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4704%
4705% DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4706% color or fill texture. Fully opaque is 1.0.
4707%
4708% The format of the DrawSetFillOpacity method is:
4709%
4710% void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4711%
4712% A description of each parameter follows:
4713%
4714% o wand: the drawing wand.
4715%
4716% o fill_opacity: fill opacity
4717%
4718*/
4719WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4720{
4721 Quantum
4722 opacity;
4723
4724 assert(wand != (DrawingWand *) NULL);
4725 assert(wand->signature == WandSignature);
4726 if (wand->debug != MagickFalse)
4727 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyce70c172010-01-07 17:15:30 +00004728 opacity=ClampToQuantum((double) QuantumRange*(1.0-fill_opacity));
cristy3ed852e2009-09-05 21:47:34 +00004729 if ((wand->filter_off != MagickFalse) ||
4730 (CurrentContext->fill.opacity != opacity))
4731 {
4732 CurrentContext->fill.opacity=opacity;
cristye7f51092010-01-17 00:39:37 +00004733 (void) MvgPrintf(wand,"fill-opacity %g\n",fill_opacity);
cristy3ed852e2009-09-05 21:47:34 +00004734 }
4735}
4736
4737/*
4738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4739% %
4740% %
4741% %
4742% D r a w S e t O p a c i t y %
4743% %
4744% %
4745% %
4746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4747%
4748% DrawSetOpacity() sets the opacity to use when drawing using the fill or
4749% stroke color or texture. Fully opaque is 1.0.
4750%
4751% The format of the DrawSetOpacity method is:
4752%
4753% void DrawSetOpacity(DrawingWand *wand,const double opacity)
4754%
4755% A description of each parameter follows:
4756%
4757% o wand: the drawing wand.
4758%
4759% o opacity: fill opacity
4760%
4761*/
4762WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4763{
4764 Quantum
4765 quantum_opacity;
4766
4767 assert(wand != (DrawingWand *) NULL);
4768 assert(wand->signature == WandSignature);
4769 if (wand->debug != MagickFalse)
4770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyce70c172010-01-07 17:15:30 +00004771 quantum_opacity=ClampToQuantum((double) QuantumRange*(1.0-opacity));
cristy3ed852e2009-09-05 21:47:34 +00004772 if ((wand->filter_off != MagickFalse) ||
4773 (CurrentContext->opacity != quantum_opacity))
4774 {
cristycee97112010-05-28 00:44:52 +00004775 CurrentContext->opacity=(Quantum) opacity;
cristye7f51092010-01-17 00:39:37 +00004776 (void) MvgPrintf(wand,"opacity %g\n",opacity);
cristy3ed852e2009-09-05 21:47:34 +00004777 }
4778}
4779
4780/*
4781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4782% %
4783% %
4784% %
4785% D r a w S e t F i l l P a t t e r n U R L %
4786% %
4787% %
4788% %
4789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4790%
4791% DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4792% objects. Only local URLs ("#identifier") are supported at this time. These
4793% local URLs are normally created by defining a named fill pattern with
4794% DrawPushPattern/DrawPopPattern.
4795%
4796% The format of the DrawSetFillPatternURL method is:
4797%
4798% MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4799% const char *fill_url)
4800%
4801% A description of each parameter follows:
4802%
4803% o wand: the drawing wand.
4804%
4805% o fill_url: URL to use to obtain fill pattern.
4806%
4807*/
4808WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4809 const char *fill_url)
4810{
4811 char
4812 pattern[MaxTextExtent],
4813 pattern_spec[MaxTextExtent];
4814
4815 assert(wand != (DrawingWand *) NULL);
4816 assert(wand->signature == WandSignature);
4817 if (wand->debug != MagickFalse)
4818 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4819 if (wand->image == (Image *) NULL)
4820 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4821 assert(fill_url != (const char *) NULL);
4822 if (*fill_url != '#')
4823 {
4824 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4825 return(MagickFalse);
4826 }
4827 (void) FormatMagickString(pattern,MaxTextExtent,"%s",fill_url+1);
4828 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4829 {
4830 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4831 return(MagickFalse);
4832 }
4833 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",fill_url);
4834#if DRAW_BINARY_IMPLEMENTATION
4835 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4836 &CurrentContext->fill_pattern);
4837#endif
4838 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4839 CurrentContext->fill.opacity=CurrentContext->opacity;
4840 (void) MvgPrintf(wand,"fill %s\n",pattern_spec);
4841 return(MagickTrue);
4842}
4843
4844/*
4845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4846% %
4847% %
4848% %
4849% D r a w S e t F i l l R u l e %
4850% %
4851% %
4852% %
4853%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4854%
4855% DrawSetFillRule() sets the fill rule to use while drawing polygons.
4856%
4857% The format of the DrawSetFillRule method is:
4858%
4859% void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4860%
4861% A description of each parameter follows:
4862%
4863% o wand: the drawing wand.
4864%
4865% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4866%
4867*/
4868WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4869{
4870 assert(wand != (DrawingWand *) NULL);
4871 assert(wand->signature == WandSignature);
4872 if (wand->debug != MagickFalse)
4873 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4874 if ((wand->filter_off != MagickFalse) ||
4875 (CurrentContext->fill_rule != fill_rule))
4876 {
4877 CurrentContext->fill_rule=fill_rule;
4878 (void) MvgPrintf(wand, "fill-rule '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004879 MagickFillRuleOptions,(ssize_t) fill_rule));
cristy3ed852e2009-09-05 21:47:34 +00004880 }
4881}
4882
4883/*
4884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4885% %
4886% %
4887% %
4888% D r a w S e t F o n t %
4889% %
4890% %
4891% %
4892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4893%
4894% DrawSetFont() sets the fully-sepecified font to use when annotating with
4895% text.
4896%
4897% The format of the DrawSetFont method is:
4898%
4899% MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4900%
4901% A description of each parameter follows:
4902%
4903% o wand: the drawing wand.
4904%
4905% o font_name: font name
4906%
4907*/
4908WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4909 const char *font_name)
4910{
4911 assert(wand != (DrawingWand *) NULL);
4912 assert(wand->signature == WandSignature);
4913 if (wand->debug != MagickFalse)
4914 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4915 assert(font_name != (const char *) NULL);
4916 if ((wand->filter_off != MagickFalse) ||
4917 (CurrentContext->font == (char *) NULL) ||
4918 (LocaleCompare(CurrentContext->font,font_name) != 0))
4919 {
4920 (void) CloneString(&CurrentContext->font,font_name);
4921 (void) MvgPrintf(wand,"font '%s'\n",font_name);
4922 }
4923 return(MagickTrue);
4924}
4925
4926/*
4927%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4928% %
4929% %
4930% %
4931% D r a w S e t F o n t F a m i l y %
4932% %
4933% %
4934% %
4935%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4936%
4937% DrawSetFontFamily() sets the font family to use when annotating with text.
4938%
4939% The format of the DrawSetFontFamily method is:
4940%
4941% MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4942% const char *font_family)
4943%
4944% A description of each parameter follows:
4945%
4946% o wand: the drawing wand.
4947%
4948% o font_family: font family
4949%
4950*/
4951WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4952 const char *font_family)
4953{
4954 assert(wand != (DrawingWand *) NULL);
4955 assert(wand->signature == WandSignature);
4956 if (wand->debug != MagickFalse)
4957 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4958 assert(font_family != (const char *) NULL);
4959 if ((wand->filter_off != MagickFalse) ||
4960 (CurrentContext->family == (const char *) NULL) ||
4961 (LocaleCompare(CurrentContext->family,font_family) != 0))
4962 {
4963 (void) CloneString(&CurrentContext->family,font_family);
4964 (void) MvgPrintf(wand,"font-family '%s'\n",font_family);
4965 }
4966 return(MagickTrue);
4967}
4968
4969/*
4970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4971% %
4972% %
4973% %
4974% D r a w S e t F o n t S i z e %
4975% %
4976% %
4977% %
4978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4979%
4980% DrawSetFontSize() sets the font pointsize to use when annotating with text.
4981%
4982% The format of the DrawSetFontSize method is:
4983%
4984% void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4985%
4986% A description of each parameter follows:
4987%
4988% o wand: the drawing wand.
4989%
4990% o pointsize: text pointsize
4991%
4992*/
4993WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4994{
4995 assert(wand != (DrawingWand *) NULL);
4996 assert(wand->signature == WandSignature);
4997 if (wand->debug != MagickFalse)
4998 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4999 if ((wand->filter_off != MagickFalse) ||
5000 (fabs(CurrentContext->pointsize-pointsize) > MagickEpsilon))
5001 {
5002 CurrentContext->pointsize=pointsize;
cristye7f51092010-01-17 00:39:37 +00005003 (void) MvgPrintf(wand,"font-size %g\n",pointsize);
cristy3ed852e2009-09-05 21:47:34 +00005004 }
5005}
5006
5007/*
5008%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5009% %
5010% %
5011% %
5012% D r a w S e t F o n t S t r e t c h %
5013% %
5014% %
5015% %
5016%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5017%
5018% DrawSetFontStretch() sets the font stretch to use when annotating with text.
5019% The AnyStretch enumeration acts as a wild-card "don't care" option.
5020%
5021% The format of the DrawSetFontStretch method is:
5022%
5023% void DrawSetFontStretch(DrawingWand *wand,
5024% const StretchType font_stretch)
5025%
5026% A description of each parameter follows:
5027%
5028% o wand: the drawing wand.
5029%
5030% o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5031% CondensedStretch, SemiCondensedStretch,
5032% SemiExpandedStretch, ExpandedStretch,
5033% ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5034%
5035*/
5036WandExport void DrawSetFontStretch(DrawingWand *wand,
5037 const StretchType font_stretch)
5038{
5039 assert(wand != (DrawingWand *) NULL);
5040 assert(wand->signature == WandSignature);
5041 if (wand->debug != MagickFalse)
5042 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5043 if ((wand->filter_off != MagickFalse) ||
5044 (CurrentContext->stretch != font_stretch))
5045 {
5046 CurrentContext->stretch=font_stretch;
5047 (void) MvgPrintf(wand, "font-stretch '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005048 MagickStretchOptions,(ssize_t) font_stretch));
cristy3ed852e2009-09-05 21:47:34 +00005049 }
5050}
5051
5052/*
5053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5054% %
5055% %
5056% %
5057% D r a w S e t F o n t S t y l e %
5058% %
5059% %
5060% %
5061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5062%
5063% DrawSetFontStyle() sets the font style to use when annotating with text.
5064% The AnyStyle enumeration acts as a wild-card "don't care" option.
5065%
5066% The format of the DrawSetFontStyle method is:
5067%
5068% void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5069%
5070% A description of each parameter follows:
5071%
5072% o wand: the drawing wand.
5073%
5074% o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5075%
5076*/
5077WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5078{
5079 assert(wand != (DrawingWand *) NULL);
5080 assert(wand->signature == WandSignature);
5081 if (wand->debug != MagickFalse)
5082 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5083 if ((wand->filter_off != MagickFalse) ||
5084 (CurrentContext->style != style))
5085 {
5086 CurrentContext->style=style;
5087 (void) MvgPrintf(wand, "font-style '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005088 MagickStyleOptions,(ssize_t) style));
cristy3ed852e2009-09-05 21:47:34 +00005089 }
5090}
5091
5092/*
5093%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5094% %
5095% %
5096% %
5097% D r a w S e t F o n t W e i g h t %
5098% %
5099% %
5100% %
5101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5102%
5103% DrawSetFontWeight() sets the font weight to use when annotating with text.
5104%
5105% The format of the DrawSetFontWeight method is:
5106%
5107% void DrawSetFontWeight(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005108% const size_t font_weight)
cristy3ed852e2009-09-05 21:47:34 +00005109%
5110% A description of each parameter follows:
5111%
5112% o wand: the drawing wand.
5113%
5114% o font_weight: font weight (valid range 100-900)
5115%
5116*/
5117WandExport void DrawSetFontWeight(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005118 const size_t font_weight)
cristy3ed852e2009-09-05 21:47:34 +00005119{
5120 assert(wand != (DrawingWand *) NULL);
5121 assert(wand->signature == WandSignature);
5122 if (wand->debug != MagickFalse)
5123 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5124 if ((wand->filter_off != MagickFalse) ||
5125 (CurrentContext->weight != font_weight))
5126 {
5127 CurrentContext->weight=font_weight;
cristyf2faecf2010-05-28 19:19:36 +00005128 (void) MvgPrintf(wand,"font-weight %lu\n",(unsigned long) font_weight);
cristy3ed852e2009-09-05 21:47:34 +00005129 }
5130}
5131
5132/*
5133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5134% %
5135% %
5136% %
5137% D r a w S e t G r a v i t y %
5138% %
5139% %
5140% %
5141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5142%
5143% DrawSetGravity() sets the text placement gravity to use when annotating
5144% with text.
5145%
5146% The format of the DrawSetGravity method is:
5147%
5148% void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5149%
5150% A description of each parameter follows:
5151%
5152% o wand: the drawing wand.
5153%
5154% o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5155% NorthEastGravity, WestGravity, CenterGravity,
5156% EastGravity, SouthWestGravity, SouthGravity,
5157% SouthEastGravity)
5158%
5159*/
5160WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5161{
5162 assert(wand != (DrawingWand *) NULL);
5163 assert(wand->signature == WandSignature);
5164 if (wand->debug != MagickFalse)
5165 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5166 if ((wand->filter_off != MagickFalse) ||
5167 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5168 {
5169 CurrentContext->gravity=gravity;
5170 (void) MvgPrintf(wand,"gravity '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005171 MagickGravityOptions,(ssize_t) gravity));
cristy3ed852e2009-09-05 21:47:34 +00005172 }
5173}
5174
5175/*
5176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5177% %
5178% %
5179% %
5180% D r a w S e t S t r o k e C o l o r %
5181% %
5182% %
5183% %
5184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5185%
5186% DrawSetStrokeColor() sets the color used for stroking object outlines.
5187%
5188% The format of the DrawSetStrokeColor method is:
5189%
5190% void DrawSetStrokeColor(DrawingWand *wand,
5191% const PixelWand *stroke_wand)
5192%
5193% A description of each parameter follows:
5194%
5195% o wand: the drawing wand.
5196%
5197% o stroke_wand: stroke wand.
5198%
5199*/
5200WandExport void DrawSetStrokeColor(DrawingWand *wand,
5201 const PixelWand *stroke_wand)
5202{
5203 PixelPacket
5204 *current_stroke,
5205 new_stroke,
5206 stroke_color;
5207
5208 assert(wand != (DrawingWand *) NULL);
5209 assert(wand->signature == WandSignature);
5210 if (wand->debug != MagickFalse)
5211 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5212 assert(stroke_wand != (const PixelWand *) NULL);
5213 PixelGetQuantumColor(stroke_wand,&stroke_color);
5214 new_stroke=stroke_color;
5215 current_stroke=(&CurrentContext->stroke);
5216 if ((wand->filter_off != MagickFalse) ||
5217 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5218 {
5219 CurrentContext->stroke=new_stroke;
5220 (void) MvgPrintf(wand,"stroke '");
5221 MvgAppendColor(wand,&stroke_color);
5222 (void) MvgPrintf(wand,"'\n");
5223 }
5224}
5225
5226/*
5227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5228% %
5229% %
5230% %
5231% D r a w S e t S t r o k e P a t t e r n U R L %
5232% %
5233% %
5234% %
5235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5236%
5237% DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5238%
5239% The format of the DrawSetStrokePatternURL method is:
5240%
5241% MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5242% const char *stroke_url)
5243%
5244% A description of each parameter follows:
5245%
5246% o wand: the drawing wand.
5247%
5248% o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5249%
5250*/
5251WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5252 const char *stroke_url)
5253{
5254 char
5255 pattern[MaxTextExtent],
5256 pattern_spec[MaxTextExtent];
5257
5258 assert(wand != (DrawingWand *) NULL);
5259 assert(wand->signature == WandSignature);
5260 if (wand->debug != MagickFalse)
5261 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5262 if (wand->image == (Image *) NULL)
5263 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5264 assert(stroke_url != NULL);
5265 if (stroke_url[0] != '#')
5266 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5267 (void) FormatMagickString(pattern,MaxTextExtent,"%s",stroke_url+1);
5268 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5269 {
5270 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5271 return(MagickFalse);
5272 }
5273 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",stroke_url);
5274#if DRAW_BINARY_IMPLEMENTATION
5275 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5276 &CurrentContext->stroke_pattern);
5277#endif
5278 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5279 CurrentContext->stroke.opacity=CurrentContext->opacity;
5280 (void) MvgPrintf(wand,"stroke %s\n",pattern_spec);
5281 return(MagickTrue);
5282}
5283
5284/*
5285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5286% %
5287% %
5288% %
5289% D r a w S e t S t r o k e A n t i a l i a s %
5290% %
5291% %
5292% %
5293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5294%
5295% DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5296% Stroked outlines are antialiased by default. When antialiasing is disabled
5297% stroked pixels are thresholded to determine if the stroke color or
5298% underlying canvas color should be used.
5299%
5300% The format of the DrawSetStrokeAntialias method is:
5301%
5302% void DrawSetStrokeAntialias(DrawingWand *wand,
5303% const MagickBooleanType stroke_antialias)
5304%
5305% A description of each parameter follows:
5306%
5307% o wand: the drawing wand.
5308%
5309% o stroke_antialias: set to false (zero) to disable antialiasing
5310%
5311*/
5312WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5313 const MagickBooleanType stroke_antialias)
5314{
5315 assert(wand != (DrawingWand *) NULL);
5316 assert(wand->signature == WandSignature);
5317 if (wand->debug != MagickFalse)
5318 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5319 if ((wand->filter_off != MagickFalse) ||
5320 (CurrentContext->stroke_antialias != stroke_antialias))
5321 {
5322 CurrentContext->stroke_antialias=stroke_antialias;
5323 (void) MvgPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5324 1 : 0);
5325 }
5326}
5327
5328/*
5329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5330% %
5331% %
5332% %
5333% D r a w S e t S t r o k e D a s h A r r a y %
5334% %
5335% %
5336% %
5337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5338%
5339% DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5340% stroke paths. The stroke dash array represents an array of numbers that
5341% specify the lengths of alternating dashes and gaps in pixels. If an odd
5342% number of values is provided, then the list of values is repeated to yield
5343% an even number of values. To remove an existing dash array, pass a zero
5344% number_elements argument and null dash_array. A typical stroke dash array
5345% might contain the members 5 3 2.
5346%
5347% The format of the DrawSetStrokeDashArray method is:
5348%
5349% MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005350% const size_t number_elements,const double *dash_array)
cristy3ed852e2009-09-05 21:47:34 +00005351%
5352% A description of each parameter follows:
5353%
5354% o wand: the drawing wand.
5355%
5356% o number_elements: number of elements in dash array
5357%
5358% o dash_array: dash array values
5359%
5360*/
5361WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005362 const size_t number_elements,const double *dash_array)
cristy3ed852e2009-09-05 21:47:34 +00005363{
5364 MagickBooleanType
5365 update;
5366
5367 register const double
5368 *p;
5369
5370 register double
5371 *q;
5372
cristybb503372010-05-27 20:51:26 +00005373 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005374 i;
5375
cristybb503372010-05-27 20:51:26 +00005376 size_t
cristy3ed852e2009-09-05 21:47:34 +00005377 n_new,
5378 n_old;
5379
5380 assert(wand != (DrawingWand *) NULL);
5381 assert(wand->signature == WandSignature);
5382 if (wand->debug != MagickFalse)
5383 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5384 n_new=number_elements;
5385 n_old=0;
5386 update=MagickFalse;
5387 q=CurrentContext->dash_pattern;
5388 if (q != (const double *) NULL)
5389 while (*q++ != 0.0)
5390 n_old++;
5391 if ((n_old == 0) && (n_new == 0))
5392 update=MagickFalse;
5393 else
5394 if (n_old != n_new)
5395 update=MagickTrue;
5396 else
5397 if ((CurrentContext->dash_pattern != (double *) NULL) &&
5398 (dash_array != (double *) NULL))
5399 {
5400 p=dash_array;
5401 q=CurrentContext->dash_pattern;
cristybb503372010-05-27 20:51:26 +00005402 for (i=0; i < (ssize_t) n_new; i++)
cristy3ed852e2009-09-05 21:47:34 +00005403 {
5404 if (fabs((*p)-(*q)) > MagickEpsilon)
5405 {
5406 update=MagickTrue;
5407 break;
5408 }
5409 p++;
5410 q++;
5411 }
5412 }
5413 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5414 {
5415 if (CurrentContext->dash_pattern != (double *) NULL)
5416 CurrentContext->dash_pattern=(double *)
5417 RelinquishMagickMemory(CurrentContext->dash_pattern);
5418 if (n_new != 0)
5419 {
5420 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5421 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5422 if (!CurrentContext->dash_pattern)
5423 {
5424 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5425 wand->name);
5426 return(MagickFalse);
5427 }
5428 q=CurrentContext->dash_pattern;
5429 p=dash_array;
cristybb503372010-05-27 20:51:26 +00005430 for (i=0; i < (ssize_t) n_new; i++)
cristy3ed852e2009-09-05 21:47:34 +00005431 *q++=(*p++);
5432 *q=0;
5433 }
5434 (void) MvgPrintf(wand,"stroke-dasharray ");
5435 if (n_new == 0)
5436 (void) MvgPrintf(wand,"none\n");
5437 else
5438 {
5439 p=dash_array;
cristye7f51092010-01-17 00:39:37 +00005440 (void) MvgPrintf(wand,"%g",*p++);
cristybb503372010-05-27 20:51:26 +00005441 for (i=1; i < (ssize_t) n_new; i++)
cristye7f51092010-01-17 00:39:37 +00005442 (void) MvgPrintf(wand,",%g",*p++);
cristy3ed852e2009-09-05 21:47:34 +00005443 (void) MvgPrintf(wand,"\n");
5444 }
5445 }
5446 return(MagickTrue);
5447}
5448
5449/*
5450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5451% %
5452% %
5453% %
5454% D r a w S e t S t r o k e D a s h O f f s e t %
5455% %
5456% %
5457% %
5458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5459%
5460% DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5461% start the dash.
5462%
5463% The format of the DrawSetStrokeDashOffset method is:
5464%
5465% void DrawSetStrokeDashOffset(DrawingWand *wand,
5466% const double dash_offset)
5467%
5468% A description of each parameter follows:
5469%
5470% o wand: the drawing wand.
5471%
5472% o dash_offset: dash offset
5473%
5474*/
5475WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5476 const double dash_offset)
5477{
5478 assert(wand != (DrawingWand *) NULL);
5479 assert(wand->signature == WandSignature);
5480 if (wand->debug != MagickFalse)
5481 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5482 if ((wand->filter_off != MagickFalse) ||
5483 (fabs(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
5484 {
5485 CurrentContext->dash_offset=dash_offset;
cristye7f51092010-01-17 00:39:37 +00005486 (void) MvgPrintf(wand,"stroke-dashoffset %g\n",dash_offset);
cristy3ed852e2009-09-05 21:47:34 +00005487 }
5488}
5489
5490/*
5491%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5492% %
5493% %
5494% %
5495% D r a w S e t S t r o k e L i n e C a p %
5496% %
5497% %
5498% %
5499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5500%
5501% DrawSetStrokeLineCap() specifies the shape to be used at the end of
5502% open subpaths when they are stroked. Values of LineCap are
5503% UndefinedCap, ButtCap, RoundCap, and SquareCap.
5504%
5505% The format of the DrawSetStrokeLineCap method is:
5506%
5507% void DrawSetStrokeLineCap(DrawingWand *wand,
5508% const LineCap linecap)
5509%
5510% A description of each parameter follows:
5511%
5512% o wand: the drawing wand.
5513%
5514% o linecap: linecap style
5515%
5516*/
5517WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5518{
5519 assert(wand != (DrawingWand *) NULL);
5520 assert(wand->signature == WandSignature);
5521 if (wand->debug != MagickFalse)
5522 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5523 if ((wand->filter_off != MagickFalse) ||
5524 (CurrentContext->linecap != linecap))
5525 {
5526 CurrentContext->linecap=linecap;
5527 (void) MvgPrintf(wand,"stroke-linecap '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005528 MagickLineCapOptions,(ssize_t) linecap));
cristy3ed852e2009-09-05 21:47:34 +00005529 }
5530}
5531
5532/*
5533%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5534% %
5535% %
5536% %
5537% D r a w S e t S t r o k e L i n e J o i n %
5538% %
5539% %
5540% %
5541%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5542%
5543% DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5544% paths (or other vector shapes) when they are stroked. Values of LineJoin are
5545% UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5546%
5547% The format of the DrawSetStrokeLineJoin method is:
5548%
5549% void DrawSetStrokeLineJoin(DrawingWand *wand,
5550% const LineJoin linejoin)
5551%
5552% A description of each parameter follows:
5553%
5554% o wand: the drawing wand.
5555%
5556% o linejoin: line join style
5557%
5558*/
5559WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5560{
5561 assert(wand != (DrawingWand *) NULL);
5562 assert(wand->signature == WandSignature);
5563 if (wand->debug != MagickFalse)
5564 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5565 if ((wand->filter_off != MagickFalse) ||
5566 (CurrentContext->linejoin != linejoin))
5567 {
5568 CurrentContext->linejoin=linejoin;
5569 (void) MvgPrintf(wand, "stroke-linejoin '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005570 MagickLineJoinOptions,(ssize_t) linejoin));
cristy3ed852e2009-09-05 21:47:34 +00005571 }
5572}
5573
5574/*
5575%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5576% %
5577% %
5578% %
5579% D r a w S e t S t r o k e M i t e r L i m i t %
5580% %
5581% %
5582% %
5583%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5584%
5585% DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5586% segments meet at a sharp angle and miter joins have been specified for
5587% 'lineJoin', it is possible for the miter to extend far beyond the
5588% thickness of the line stroking the path. The miterLimit' imposes a
5589% limit on the ratio of the miter length to the 'lineWidth'.
5590%
5591% The format of the DrawSetStrokeMiterLimit method is:
5592%
5593% void DrawSetStrokeMiterLimit(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005594% const size_t miterlimit)
cristy3ed852e2009-09-05 21:47:34 +00005595%
5596% A description of each parameter follows:
5597%
5598% o wand: the drawing wand.
5599%
5600% o miterlimit: miter limit
5601%
5602*/
5603WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005604 const size_t miterlimit)
cristy3ed852e2009-09-05 21:47:34 +00005605{
5606 assert(wand != (DrawingWand *) NULL);
5607 assert(wand->signature == WandSignature);
5608 if (wand->debug != MagickFalse)
5609 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5610 if (CurrentContext->miterlimit != miterlimit)
5611 {
5612 CurrentContext->miterlimit=miterlimit;
cristyf2faecf2010-05-28 19:19:36 +00005613 (void) MvgPrintf(wand,"stroke-miterlimit %lu\n",(unsigned long)
5614 miterlimit);
cristy3ed852e2009-09-05 21:47:34 +00005615 }
5616}
5617
5618/*
5619%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5620% %
5621% %
5622% %
5623% D r a w S e t S t r o k e O p a c i t y %
5624% %
5625% %
5626% %
5627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5628%
5629% DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5630%
5631% The format of the DrawSetStrokeOpacity method is:
5632%
5633% void DrawSetStrokeOpacity(DrawingWand *wand,
5634% const double stroke_opacity)
5635%
5636% A description of each parameter follows:
5637%
5638% o wand: the drawing wand.
5639%
5640% o stroke_opacity: stroke opacity. The value 1.0 is opaque.
5641%
5642*/
5643WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5644 const double stroke_opacity)
5645{
5646 Quantum
5647 opacity;
5648
5649 assert(wand != (DrawingWand *) NULL);
5650 assert(wand->signature == WandSignature);
5651 if (wand->debug != MagickFalse)
5652 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyce70c172010-01-07 17:15:30 +00005653 opacity=ClampToQuantum((double) QuantumRange*(1.0-stroke_opacity));
cristy3ed852e2009-09-05 21:47:34 +00005654 if ((wand->filter_off != MagickFalse) ||
5655 (CurrentContext->stroke.opacity != opacity))
5656 {
5657 CurrentContext->stroke.opacity=opacity;
cristye7f51092010-01-17 00:39:37 +00005658 (void) MvgPrintf(wand,"stroke-opacity %g\n",stroke_opacity);
cristy3ed852e2009-09-05 21:47:34 +00005659 }
5660}
5661
5662/*
5663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5664% %
5665% %
5666% %
5667% D r a w S e t S t r o k e W i d t h %
5668% %
5669% %
5670% %
5671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5672%
5673% DrawSetStrokeWidth() sets the width of the stroke used to draw object
5674% outlines.
5675%
5676% The format of the DrawSetStrokeWidth method is:
5677%
5678% void DrawSetStrokeWidth(DrawingWand *wand,
5679% const double stroke_width)
5680%
5681% A description of each parameter follows:
5682%
5683% o wand: the drawing wand.
5684%
5685% o stroke_width: stroke width
5686%
5687*/
5688WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5689{
5690 assert(wand != (DrawingWand *) NULL);
5691 assert(wand->signature == WandSignature);
5692 if (wand->debug != MagickFalse)
5693 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5694 if ((wand->filter_off != MagickFalse) ||
5695 (fabs(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
5696 {
5697 CurrentContext->stroke_width=stroke_width;
cristye7f51092010-01-17 00:39:37 +00005698 (void) MvgPrintf(wand,"stroke-width %g\n",stroke_width);
cristy3ed852e2009-09-05 21:47:34 +00005699 }
5700}
5701
5702/*
5703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5704% %
5705% %
5706% %
5707% D r a w S e t T e x t A l i g n m e n t %
5708% %
5709% %
5710% %
5711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5712%
5713% DrawSetTextAlignment() specifies a text alignment to be applied when
5714% annotating with text.
5715%
5716% The format of the DrawSetTextAlignment method is:
5717%
5718% void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5719%
5720% A description of each parameter follows:
5721%
5722% o wand: the drawing wand.
5723%
5724% o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5725% CenterAlign, or RightAlign.
5726%
5727*/
5728WandExport void DrawSetTextAlignment(DrawingWand *wand,
5729 const AlignType alignment)
5730{
5731 assert(wand != (DrawingWand *) NULL);
5732 assert(wand->signature == WandSignature);
5733 if (wand->debug != MagickFalse)
5734 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5735 if ((wand->filter_off != MagickFalse) ||
5736 (CurrentContext->align != alignment))
5737 {
5738 CurrentContext->align=alignment;
5739 (void) MvgPrintf(wand,"text-align '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005740 MagickAlignOptions,(ssize_t) alignment));
cristy3ed852e2009-09-05 21:47:34 +00005741 }
5742}
5743
5744/*
5745%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5746% %
5747% %
5748% %
5749% D r a w S e t T e x t A n t i a l i a s %
5750% %
5751% %
5752% %
5753%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5754%
5755% DrawSetTextAntialias() controls whether text is antialiased. Text is
5756% antialiased by default.
5757%
5758% The format of the DrawSetTextAntialias method is:
5759%
5760% void DrawSetTextAntialias(DrawingWand *wand,
5761% const MagickBooleanType text_antialias)
5762%
5763% A description of each parameter follows:
5764%
5765% o wand: the drawing wand.
5766%
5767% o text_antialias: antialias boolean. Set to false (0) to disable
5768% antialiasing.
5769%
5770*/
5771WandExport void DrawSetTextAntialias(DrawingWand *wand,
5772 const MagickBooleanType text_antialias)
5773{
5774 assert(wand != (DrawingWand *) NULL);
5775 assert(wand->signature == WandSignature);
5776 if (wand->debug != MagickFalse)
5777 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5778 if ((wand->filter_off != MagickFalse) ||
5779 (CurrentContext->text_antialias != text_antialias))
5780 {
5781 CurrentContext->text_antialias=text_antialias;
5782 (void) MvgPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5783 }
5784}
5785
5786/*
5787%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5788% %
5789% %
5790% %
5791% D r a w S e t T e x t D e c o r a t i o n %
5792% %
5793% %
5794% %
5795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5796%
5797% DrawSetTextDecoration() specifies a decoration to be applied when
5798% annotating with text.
5799%
5800% The format of the DrawSetTextDecoration method is:
5801%
5802% void DrawSetTextDecoration(DrawingWand *wand,
5803% const DecorationType decoration)
5804%
5805% A description of each parameter follows:
5806%
5807% o wand: the drawing wand.
5808%
5809% o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5810% OverlineDecoration, or LineThroughDecoration
5811%
5812*/
5813WandExport void DrawSetTextDecoration(DrawingWand *wand,
5814 const DecorationType decoration)
5815{
5816 assert(wand != (DrawingWand *) NULL);
5817 assert(wand->signature == WandSignature);
5818 if (wand->debug != MagickFalse)
5819 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5820 if ((wand->filter_off != MagickFalse) ||
5821 (CurrentContext->decorate != decoration))
5822 {
5823 CurrentContext->decorate=decoration;
5824 (void) MvgPrintf(wand,"decorate '%s'\n",MagickOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005825 MagickDecorateOptions,(ssize_t) decoration));
cristy3ed852e2009-09-05 21:47:34 +00005826 }
5827}
5828
5829/*
5830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5831% %
5832% %
5833% %
5834% D r a w S e t T e x t E n c o d i n g %
5835% %
5836% %
5837% %
5838%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5839%
5840% DrawSetTextEncoding() specifies the code set to use for text
5841% annotations. The only character encoding which may be specified
5842% at this time is "UTF-8" for representing Unicode as a sequence of
5843% bytes. Specify an empty string to set text encoding to the system's
5844% default. Successful text annotation using Unicode may require fonts
5845% designed to support Unicode.
5846%
5847% The format of the DrawSetTextEncoding method is:
5848%
5849% void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5850%
5851% A description of each parameter follows:
5852%
5853% o wand: the drawing wand.
5854%
5855% o encoding: character string specifying text encoding
5856%
5857*/
5858WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5859{
5860 assert(wand != (DrawingWand *) NULL);
5861 assert(wand->signature == WandSignature);
5862 if (wand->debug != MagickFalse)
5863 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5864 assert(encoding != (char *) NULL);
5865 if ((wand->filter_off != MagickFalse) ||
5866 (CurrentContext->encoding == (char *) NULL) ||
5867 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
5868 {
5869 (void) CloneString(&CurrentContext->encoding,encoding);
5870 (void) MvgPrintf(wand,"encoding '%s'\n",encoding);
5871 }
5872}
5873
5874/*
5875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5876% %
5877% %
5878% %
5879% D r a w S e t T e x t K e r n i n g %
5880% %
5881% %
5882% %
5883%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5884%
5885% DrawSetTextKerning() sets the spacing between characters in text.
5886%
5887% The format of the DrawSetTextKerning method is:
5888%
5889% void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5890%
5891% A description of each parameter follows:
5892%
5893% o wand: the drawing wand.
5894%
5895% o kerning: text kerning
5896%
5897*/
5898WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5899{
5900 assert(wand != (DrawingWand *) NULL);
5901 assert(wand->signature == WandSignature);
5902
5903 if (wand->debug != MagickFalse)
5904 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00005905 if ((wand->filter_off != MagickFalse) &&
cristy3ed852e2009-09-05 21:47:34 +00005906 (CurrentContext->kerning != kerning))
5907 {
5908 CurrentContext->kerning=kerning;
5909 (void) MvgPrintf(wand,"kerning %lf\n",kerning);
5910 }
5911}
5912
5913/*
5914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5915% %
5916% %
5917% %
cristyb32b90a2009-09-07 21:45:48 +00005918% D r a w S e t T e x t I n t e r L i n e S p a c i n g %
5919% %
5920% %
5921% %
5922%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5923%
5924% DrawSetTextInterwordSpacing() sets the spacing between line in text.
5925%
5926% The format of the DrawSetInterwordSpacing method is:
5927%
5928% void DrawSetTextInterwordSpacing(DrawingWand *wand,
5929% const double interline_spacing)
5930%
5931% A description of each parameter follows:
5932%
5933% o wand: the drawing wand.
5934%
5935% o interline_spacing: text line spacing
5936%
5937*/
5938WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
5939 const double interline_spacing)
5940{
5941 assert(wand != (DrawingWand *) NULL);
5942 assert(wand->signature == WandSignature);
5943
5944 if (wand->debug != MagickFalse)
5945 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00005946 if ((wand->filter_off != MagickFalse) &&
cristyb32b90a2009-09-07 21:45:48 +00005947 (CurrentContext->interline_spacing != interline_spacing))
5948 {
5949 CurrentContext->interline_spacing=interline_spacing;
cristy738d3d32009-12-03 23:47:08 +00005950 (void) MvgPrintf(wand,"interline-spacing %lf\n",interline_spacing);
cristyb32b90a2009-09-07 21:45:48 +00005951 }
5952}
5953
5954/*
5955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5956% %
5957% %
5958% %
cristy3ed852e2009-09-05 21:47:34 +00005959% D r a w S e t T e x t I n t e r w o r d S p a c i n g %
5960% %
5961% %
5962% %
5963%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5964%
5965% DrawSetTextInterwordSpacing() sets the spacing between words in text.
5966%
5967% The format of the DrawSetInterwordSpacing method is:
5968%
5969% void DrawSetTextInterwordSpacing(DrawingWand *wand,
5970% const double interword_spacing)
5971%
5972% A description of each parameter follows:
5973%
5974% o wand: the drawing wand.
5975%
5976% o interword_spacing: text word spacing
5977%
5978*/
5979WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
5980 const double interword_spacing)
5981{
5982 assert(wand != (DrawingWand *) NULL);
5983 assert(wand->signature == WandSignature);
5984
5985 if (wand->debug != MagickFalse)
5986 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00005987 if ((wand->filter_off != MagickFalse) &&
cristy3ed852e2009-09-05 21:47:34 +00005988 (CurrentContext->interword_spacing != interword_spacing))
5989 {
5990 CurrentContext->interword_spacing=interword_spacing;
cristy738d3d32009-12-03 23:47:08 +00005991 (void) MvgPrintf(wand,"interword-spacing %lf\n",interword_spacing);
cristy3ed852e2009-09-05 21:47:34 +00005992 }
5993}
5994
5995/*
5996%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5997% %
5998% %
5999% %
6000% D r a w S e t T e x t U n d e r C o l o r %
6001% %
6002% %
6003% %
6004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6005%
6006% DrawSetTextUnderColor() specifies the color of a background rectangle
6007% to place under text annotations.
6008%
6009% The format of the DrawSetTextUnderColor method is:
6010%
6011% void DrawSetTextUnderColor(DrawingWand *wand,
6012% const PixelWand *under_wand)
6013%
6014% A description of each parameter follows:
6015%
6016% o wand: the drawing wand.
6017%
6018% o under_wand: text under wand.
6019%
6020*/
6021WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6022 const PixelWand *under_wand)
6023{
6024 PixelPacket
6025 under_color;
6026
6027 assert(wand != (DrawingWand *) NULL);
6028 assert(wand->signature == WandSignature);
6029 if (wand->debug != MagickFalse)
6030 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6031 assert(under_wand != (const PixelWand *) NULL);
6032 PixelGetQuantumColor(under_wand,&under_color);
6033 if ((wand->filter_off != MagickFalse) ||
6034 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6035 {
6036 CurrentContext->undercolor=under_color;
6037 (void) MvgPrintf(wand,"text-undercolor '");
6038 MvgAppendColor(wand,&under_color);
6039 (void) MvgPrintf(wand,"'\n");
6040 }
6041}
6042
6043/*
6044%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6045% %
6046% %
6047% %
6048% D r a w S e t V e c t o r G r a p h i c s %
6049% %
6050% %
6051% %
6052%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6053%
6054% DrawSetVectorGraphics() sets the vector graphics associated with the
6055% specified wand. Use this method with DrawGetVectorGraphics() as a method
6056% to persist the vector graphics state.
6057%
6058% The format of the DrawSetVectorGraphics method is:
6059%
6060% MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6061% const char *xml)
6062%
6063% A description of each parameter follows:
6064%
6065% o wand: the drawing wand.
6066%
6067% o xml: the drawing wand XML.
6068%
6069*/
6070
6071static inline MagickBooleanType IsPoint(const char *point)
6072{
6073 char
6074 *p;
6075
cristycee97112010-05-28 00:44:52 +00006076 long
cristy3ed852e2009-09-05 21:47:34 +00006077 value;
6078
6079 value=strtol(point,&p,10);
6080 return(p != point ? MagickTrue : MagickFalse);
6081}
6082
6083WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6084 const char *xml)
6085{
6086 const char
6087 *value;
6088
6089 XMLTreeInfo
6090 *child,
6091 *xml_info;
6092
6093 assert(wand != (DrawingWand *) NULL);
6094 assert(wand->signature == WandSignature);
6095 if (wand->debug != MagickFalse)
6096 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6097 CurrentContext=DestroyDrawInfo(CurrentContext);
6098 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6099 if (xml == (const char *) NULL)
6100 return(MagickFalse);
6101 xml_info=NewXMLTree(xml,wand->exception);
6102 if (xml_info == (XMLTreeInfo *) NULL)
6103 return(MagickFalse);
6104 child=GetXMLTreeChild(xml_info,"clip-path");
6105 if (child != (XMLTreeInfo *) NULL)
6106 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6107 child=GetXMLTreeChild(xml_info,"clip-units");
6108 if (child != (XMLTreeInfo *) NULL)
6109 {
6110 value=GetXMLTreeContent(child);
6111 if (value != (const char *) NULL)
6112 CurrentContext->clip_units=(ClipPathUnits) ParseMagickOption(
6113 MagickClipPathOptions,MagickFalse,value);
6114 }
6115 child=GetXMLTreeChild(xml_info,"decorate");
6116 if (child != (XMLTreeInfo *) NULL)
6117 {
6118 value=GetXMLTreeContent(child);
6119 if (value != (const char *) NULL)
6120 CurrentContext->decorate=(DecorationType) ParseMagickOption(
6121 MagickDecorateOptions,MagickFalse,value);
6122 }
6123 child=GetXMLTreeChild(xml_info,"encoding");
6124 if (child != (XMLTreeInfo *) NULL)
6125 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6126 child=GetXMLTreeChild(xml_info,"fill");
6127 if (child != (XMLTreeInfo *) NULL)
6128 {
6129 value=GetXMLTreeContent(child);
6130 if (value != (const char *) NULL)
6131 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6132 }
6133 child=GetXMLTreeChild(xml_info,"fill-opacity");
6134 if (child != (XMLTreeInfo *) NULL)
6135 {
6136 value=GetXMLTreeContent(child);
6137 if (value != (const char *) NULL)
cristyce70c172010-01-07 17:15:30 +00006138 CurrentContext->fill.opacity=ClampToQuantum((MagickRealType)
cristyf2f27272009-12-17 14:48:46 +00006139 QuantumRange*(1.0-StringToDouble(value)));
cristy3ed852e2009-09-05 21:47:34 +00006140 }
6141 child=GetXMLTreeChild(xml_info,"fill-rule");
6142 if (child != (XMLTreeInfo *) NULL)
6143 {
6144 value=GetXMLTreeContent(child);
6145 if (value != (const char *) NULL)
6146 CurrentContext->fill_rule=(FillRule) ParseMagickOption(
6147 MagickFillRuleOptions,MagickFalse,value);
6148 }
6149 child=GetXMLTreeChild(xml_info,"font");
6150 if (child != (XMLTreeInfo *) NULL)
6151 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6152 child=GetXMLTreeChild(xml_info,"font-family");
6153 if (child != (XMLTreeInfo *) NULL)
6154 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6155 child=GetXMLTreeChild(xml_info,"font-size");
6156 if (child != (XMLTreeInfo *) NULL)
6157 {
6158 value=GetXMLTreeContent(child);
6159 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006160 CurrentContext->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006161 }
6162 child=GetXMLTreeChild(xml_info,"font-stretch");
6163 if (child != (XMLTreeInfo *) NULL)
6164 {
6165 value=GetXMLTreeContent(child);
6166 if (value != (const char *) NULL)
6167 CurrentContext->stretch=(StretchType) ParseMagickOption(
6168 MagickStretchOptions,MagickFalse,value);
6169 }
6170 child=GetXMLTreeChild(xml_info,"font-style");
6171 if (child != (XMLTreeInfo *) NULL)
6172 {
6173 value=GetXMLTreeContent(child);
6174 if (value != (const char *) NULL)
6175 CurrentContext->style=(StyleType) ParseMagickOption(MagickStyleOptions,
6176 MagickFalse,value);
6177 }
6178 child=GetXMLTreeChild(xml_info,"font-weight");
6179 if (child != (XMLTreeInfo *) NULL)
6180 {
6181 value=GetXMLTreeContent(child);
6182 if (value != (const char *) NULL)
cristye27293e2009-12-18 02:53:20 +00006183 CurrentContext->weight=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006184 }
6185 child=GetXMLTreeChild(xml_info,"gravity");
6186 if (child != (XMLTreeInfo *) NULL)
6187 {
6188 value=GetXMLTreeContent(child);
6189 if (value != (const char *) NULL)
6190 CurrentContext->gravity=(GravityType) ParseMagickOption(
6191 MagickGravityOptions,MagickFalse,value);
6192 }
6193 child=GetXMLTreeChild(xml_info,"stroke");
6194 if (child != (XMLTreeInfo *) NULL)
6195 {
6196 value=GetXMLTreeContent(child);
6197 if (value != (const char *) NULL)
6198 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6199 wand->exception);
6200 }
6201 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6202 if (child != (XMLTreeInfo *) NULL)
6203 {
6204 value=GetXMLTreeContent(child);
6205 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006206 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
cristy3ed852e2009-09-05 21:47:34 +00006207 MagickFalse;
6208 }
6209 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6210 if (child != (XMLTreeInfo *) NULL)
6211 {
6212 char
6213 token[MaxTextExtent];
6214
6215 const char
6216 *q;
6217
cristybb503372010-05-27 20:51:26 +00006218 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006219 j;
6220
cristybb503372010-05-27 20:51:26 +00006221 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006222 x;
6223
6224 value=GetXMLTreeContent(child);
6225 if (value != (const char *) NULL)
6226 {
6227 if (CurrentContext->dash_pattern != (double *) NULL)
6228 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6229 CurrentContext->dash_pattern);
6230 q=(char *) value;
6231 if (IsPoint(q) != MagickFalse)
6232 {
6233 const char
6234 *p;
6235
6236 p=q;
6237 GetMagickToken(p,&p,token);
6238 if (*token == ',')
6239 GetMagickToken(p,&p,token);
6240 for (x=0; IsPoint(token) != MagickFalse; x++)
6241 {
6242 GetMagickToken(p,&p,token);
6243 if (*token == ',')
6244 GetMagickToken(p,&p,token);
6245 }
6246 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6247 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6248 if (CurrentContext->dash_pattern == (double *) NULL)
6249 ThrowWandFatalException(ResourceLimitFatalError,
6250 "MemoryAllocationFailed",wand->name);
6251 for (j=0; j < x; j++)
6252 {
6253 GetMagickToken(q,&q,token);
6254 if (*token == ',')
6255 GetMagickToken(q,&q,token);
cristyf2f27272009-12-17 14:48:46 +00006256 CurrentContext->dash_pattern[j]=StringToDouble(token);
cristy3ed852e2009-09-05 21:47:34 +00006257 }
6258 if ((x & 0x01) != 0)
6259 for ( ; j < (2*x); j++)
6260 CurrentContext->dash_pattern[j]=
6261 CurrentContext->dash_pattern[j-x];
6262 CurrentContext->dash_pattern[j]=0.0;
6263 }
6264 }
6265 }
6266 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6267 if (child != (XMLTreeInfo *) NULL)
6268 {
6269 value=GetXMLTreeContent(child);
6270 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006271 CurrentContext->dash_offset=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006272 }
6273 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6274 if (child != (XMLTreeInfo *) NULL)
6275 {
6276 value=GetXMLTreeContent(child);
6277 if (value != (const char *) NULL)
6278 CurrentContext->linecap=(LineCap) ParseMagickOption(
6279 MagickLineCapOptions,MagickFalse,value);
6280 }
6281 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6282 if (child != (XMLTreeInfo *) NULL)
6283 {
6284 value=GetXMLTreeContent(child);
6285 if (value != (const char *) NULL)
6286 CurrentContext->linejoin=(LineJoin) ParseMagickOption(
6287 MagickLineJoinOptions,MagickFalse,value);
6288 }
6289 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6290 if (child != (XMLTreeInfo *) NULL)
6291 {
6292 value=GetXMLTreeContent(child);
6293 if (value != (const char *) NULL)
cristye27293e2009-12-18 02:53:20 +00006294 CurrentContext->miterlimit=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006295 }
6296 child=GetXMLTreeChild(xml_info,"stroke-opacity");
6297 if (child != (XMLTreeInfo *) NULL)
6298 {
6299 value=GetXMLTreeContent(child);
6300 if (value != (const char *) NULL)
cristyce70c172010-01-07 17:15:30 +00006301 CurrentContext->stroke.opacity=ClampToQuantum((MagickRealType)
cristyf2f27272009-12-17 14:48:46 +00006302 QuantumRange*(1.0-StringToDouble(value)));
cristy3ed852e2009-09-05 21:47:34 +00006303 }
6304 child=GetXMLTreeChild(xml_info,"stroke-width");
6305 if (child != (XMLTreeInfo *) NULL)
6306 {
6307 value=GetXMLTreeContent(child);
6308 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006309 CurrentContext->stroke_width=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006310 }
6311 child=GetXMLTreeChild(xml_info,"text-align");
6312 if (child != (XMLTreeInfo *) NULL)
6313 {
6314 value=GetXMLTreeContent(child);
6315 if (value != (const char *) NULL)
6316 CurrentContext->align=(AlignType) ParseMagickOption(MagickAlignOptions,
6317 MagickFalse,value);
6318 }
6319 child=GetXMLTreeChild(xml_info,"text-antialias");
6320 if (child != (XMLTreeInfo *) NULL)
6321 {
6322 value=GetXMLTreeContent(child);
6323 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006324 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
cristy3ed852e2009-09-05 21:47:34 +00006325 MagickFalse;
6326 }
6327 child=GetXMLTreeChild(xml_info,"text-undercolor");
6328 if (child != (XMLTreeInfo *) NULL)
6329 {
6330 value=GetXMLTreeContent(child);
6331 if (value != (const char *) NULL)
6332 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6333 wand->exception);
6334 }
6335 child=GetXMLTreeChild(xml_info,"vector-graphics");
6336 if (child != (XMLTreeInfo *) NULL)
6337 {
6338 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6339 wand->mvg_length=strlen(wand->mvg);
6340 wand->mvg_alloc=wand->mvg_length+1;
6341 }
6342 xml_info=DestroyXMLTree(xml_info);
6343 return(MagickTrue);
6344}
6345
6346/*
6347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6348% %
6349% %
6350% %
6351% D r a w S k e w X %
6352% %
6353% %
6354% %
6355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6356%
6357% DrawSkewX() skews the current coordinate system in the horizontal
6358% direction.
6359%
6360% The format of the DrawSkewX method is:
6361%
6362% void DrawSkewX(DrawingWand *wand,const double degrees)
6363%
6364% A description of each parameter follows:
6365%
6366% o wand: the drawing wand.
6367%
6368% o degrees: number of degrees to skew the coordinates
6369%
6370*/
6371WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6372{
6373 AffineMatrix
6374 affine;
6375
6376 assert(wand != (DrawingWand *) NULL);
6377 assert(wand->signature == WandSignature);
6378 if (wand->debug != MagickFalse)
6379 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6380 GetAffineMatrix(&affine);
6381 affine.ry=tan(DegreesToRadians(fmod(degrees,360.0)));
6382 AdjustAffine(wand,&affine);
cristye7f51092010-01-17 00:39:37 +00006383 (void) MvgPrintf(wand,"skewX %g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00006384}
6385
6386/*
6387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6388% %
6389% %
6390% %
6391% D r a w S k e w Y %
6392% %
6393% %
6394% %
6395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6396%
6397% DrawSkewY() skews the current coordinate system in the vertical
6398% direction.
6399%
6400% The format of the DrawSkewY method is:
6401%
6402% void DrawSkewY(DrawingWand *wand,const double degrees)
6403%
6404% A description of each parameter follows:
6405%
6406% o wand: the drawing wand.
6407%
6408% o degrees: number of degrees to skew the coordinates
6409%
6410*/
6411WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6412{
6413 AffineMatrix
6414 affine;
6415
6416 assert(wand != (DrawingWand *) NULL);
6417 assert(wand->signature == WandSignature);
6418 if (wand->debug != MagickFalse)
6419 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6420 GetAffineMatrix(&affine);
6421 affine.rx=tan(DegreesToRadians(fmod(degrees,360.0)));
6422 DrawAffine(wand,&affine);
cristye7f51092010-01-17 00:39:37 +00006423 (void) MvgPrintf(wand,"skewY %g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00006424}
6425
6426/*
6427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6428% %
6429% %
6430% %
6431% D r a w T r a n s l a t e %
6432% %
6433% %
6434% %
6435%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6436%
6437% DrawTranslate() applies a translation to the current coordinate
6438% system which moves the coordinate system origin to the specified
6439% coordinate.
6440%
6441% The format of the DrawTranslate method is:
6442%
6443% void DrawTranslate(DrawingWand *wand,const double x,
6444% const double y)
6445%
6446% A description of each parameter follows:
6447%
6448% o wand: the drawing wand.
6449%
6450% o x: new x ordinate for coordinate system origin
6451%
6452% o y: new y ordinate for coordinate system origin
6453%
6454*/
6455WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6456{
6457 AffineMatrix
6458 affine;
6459
6460 assert(wand != (DrawingWand *) NULL);
6461 assert(wand->signature == WandSignature);
6462 if (wand->debug != MagickFalse)
6463 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6464 GetAffineMatrix(&affine);
6465 affine.tx=x;
6466 affine.ty=y;
6467 AdjustAffine(wand,&affine);
cristye7f51092010-01-17 00:39:37 +00006468 (void) MvgPrintf(wand,"translate %g,%g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00006469}
6470
6471/*
6472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6473% %
6474% %
6475% %
6476% D r a w S e t V i e w b o x %
6477% %
6478% %
6479% %
6480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6481%
6482% DrawSetViewbox() sets the overall canvas size to be recorded with the
6483% drawing vector data. Usually this will be specified using the same
6484% size as the canvas image. When the vector data is saved to SVG or MVG
6485% formats, the viewbox is use to specify the size of the canvas image that
6486% a viewer will render the vector data on.
6487%
6488% The format of the DrawSetViewbox method is:
6489%
cristybb503372010-05-27 20:51:26 +00006490% void DrawSetViewbox(DrawingWand *wand,size_t x1,
6491% size_t y1,size_t x2,size_t y2)
cristy3ed852e2009-09-05 21:47:34 +00006492%
6493% A description of each parameter follows:
6494%
6495% o wand: the drawing wand.
6496%
6497% o x1: left x ordinate
6498%
6499% o y1: top y ordinate
6500%
6501% o x2: right x ordinate
6502%
6503% o y2: bottom y ordinate
6504%
6505*/
cristy5ed838e2010-05-31 00:05:35 +00006506WandExport void DrawSetViewbox(DrawingWand *wand,ssize_t x1,ssize_t y1,
6507 ssize_t x2,ssize_t y2)
cristy3ed852e2009-09-05 21:47:34 +00006508{
6509 assert(wand != (DrawingWand *) NULL);
6510 assert(wand->signature == WandSignature);
6511 if (wand->debug != MagickFalse)
6512 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy5ed838e2010-05-31 00:05:35 +00006513 (void) MvgPrintf(wand,"viewbox %ld %ld %ld %ld\n",(long) x1,(long) y1,
6514 (long) x2,(long) y2);
cristy3ed852e2009-09-05 21:47:34 +00006515}
6516
6517/*
6518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6519% %
6520% %
6521% %
6522% I s D r a w i n g W a n d %
6523% %
6524% %
6525% %
6526%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6527%
6528% IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6529%
6530% The format of the IsDrawingWand method is:
6531%
6532% MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6533%
6534% A description of each parameter follows:
6535%
6536% o wand: the drawing wand.
6537%
6538*/
6539WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6540{
6541 if (wand == (const DrawingWand *) NULL)
6542 return(MagickFalse);
6543 if (wand->signature != WandSignature)
6544 return(MagickFalse);
6545 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6546 return(MagickFalse);
6547 return(MagickTrue);
6548}
6549
6550/*
6551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6552% %
6553% %
6554% %
6555% N e w D r a w i n g W a n d %
6556% %
6557% %
6558% %
6559%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6560%
6561% NewDrawingWand() returns a drawing wand required for all other methods in
6562% the API.
6563%
6564% The format of the NewDrawingWand method is:
6565%
6566% DrawingWand NewDrawingWand(void)
6567%
6568*/
6569WandExport DrawingWand *NewDrawingWand(void)
6570{
6571 const char
6572 *quantum;
6573
6574 DrawingWand
6575 *wand;
6576
cristybb503372010-05-27 20:51:26 +00006577 size_t
cristy3ed852e2009-09-05 21:47:34 +00006578 depth;
6579
6580 quantum=GetMagickQuantumDepth(&depth);
6581 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6582 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
cristy90823212009-12-12 20:48:33 +00006583 wand=(DrawingWand *) AcquireAlignedMemory(1,sizeof(*wand));
cristy3ed852e2009-09-05 21:47:34 +00006584 if (wand == (DrawingWand *) NULL)
6585 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6586 GetExceptionMessage(errno));
6587 (void) ResetMagickMemory(wand,0,sizeof(*wand));
6588 wand->id=AcquireWandId();
6589 (void) FormatMagickString(wand->name,MaxTextExtent,"%s-%lu",DrawingWandId,
cristyf2faecf2010-05-28 19:19:36 +00006590 (unsigned long) wand->id);
cristy3ed852e2009-09-05 21:47:34 +00006591 if (wand->debug != MagickFalse)
6592 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6593 wand->mvg=(char *) NULL;
6594 wand->mvg_alloc=0;
6595 wand->mvg_length=0;
6596 wand->mvg_width=0;
6597 wand->pattern_id=(char *) NULL;
6598 wand->pattern_offset=0;
6599 wand->pattern_bounds.x=0;
6600 wand->pattern_bounds.y=0;
6601 wand->pattern_bounds.width=0;
6602 wand->pattern_bounds.height=0;
6603 wand->index=0;
cristy90823212009-12-12 20:48:33 +00006604 wand->graphic_context=(DrawInfo **) AcquireAlignedMemory(1,sizeof(
cristy3ed852e2009-09-05 21:47:34 +00006605 *wand->graphic_context));
6606 if (wand->graphic_context == (DrawInfo **) NULL)
6607 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6608 GetExceptionMessage(errno));
6609 wand->filter_off=MagickTrue;
6610 wand->indent_depth=0;
6611 wand->path_operation=PathDefaultOperation;
6612 wand->path_mode=DefaultPathMode;
6613 wand->image=AcquireImage((const ImageInfo *) NULL);
6614 wand->exception=AcquireExceptionInfo();
6615 wand->destroy=MagickTrue;
6616 wand->debug=IsEventLogging();
6617 wand->signature=WandSignature;
6618 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6619 return(wand);
6620}
6621
6622/*
6623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6624% %
6625% %
6626% %
6627% P e e k D r a w i n g W a n d %
6628% %
6629% %
6630% %
6631%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6632%
6633% PeekDrawingWand() returns the current drawing wand.
6634%
6635% The format of the PeekDrawingWand method is:
6636%
6637% DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6638%
6639% A description of each parameter follows:
6640%
6641% o wand: the drawing wand.
6642%
6643*/
6644WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6645{
6646 DrawInfo
6647 *draw_info;
6648
6649 assert(wand != (const DrawingWand *) NULL);
6650 assert(wand->signature == WandSignature);
6651 if (wand->debug != MagickFalse)
6652 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6653 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6654 GetAffineMatrix(&draw_info->affine);
6655 (void) CloneString(&draw_info->primitive,wand->mvg);
6656 return(draw_info);
6657}
6658
6659/*
6660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6661% %
6662% %
6663% %
6664% P o p D r a w i n g W a n d %
6665% %
6666% %
6667% %
6668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6669%
6670% PopDrawingWand() destroys the current drawing wand and returns to the
6671% previously pushed drawing wand. Multiple drawing wands may exist. It is an
6672% error to attempt to pop more drawing wands than have been pushed, and it is
6673% proper form to pop all drawing wands which have been pushed.
6674%
6675% The format of the PopDrawingWand method is:
6676%
6677% MagickBooleanType PopDrawingWand(DrawingWand *wand)
6678%
6679% A description of each parameter follows:
6680%
6681% o wand: the drawing wand.
6682%
6683*/
6684WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6685{
6686 assert(wand != (DrawingWand *) NULL);
6687 assert(wand->signature == WandSignature);
6688 if (wand->debug != MagickFalse)
6689 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6690 if (wand->index == 0)
6691 {
6692 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6693 return(MagickFalse);
6694 }
6695 /*
6696 Destroy clip path if not same in preceding wand.
6697 */
6698#if DRAW_BINARY_IMPLEMENTATION
6699 if (wand->image == (Image *) NULL)
6700 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6701 if (CurrentContext->clip_mask != (char *) NULL)
6702 if (LocaleCompare(CurrentContext->clip_mask,
6703 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6704 (void) SetImageClipMask(wand->image,(Image *) NULL);
6705#endif
6706 CurrentContext=DestroyDrawInfo(CurrentContext);
6707 wand->index--;
6708 if (wand->indent_depth > 0)
6709 wand->indent_depth--;
6710 (void) MvgPrintf(wand,"pop graphic-context\n");
6711 return(MagickTrue);
6712}
6713
6714/*
6715%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6716% %
6717% %
6718% %
6719% P u s h D r a w i n g W a n d %
6720% %
6721% %
6722% %
6723%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6724%
6725% PushDrawingWand() clones the current drawing wand to create a new drawing
6726% wand. The original drawing wand(s) may be returned to by invoking
6727% PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6728% For every Pop there must have already been an equivalent Push.
6729%
6730% The format of the PushDrawingWand method is:
6731%
6732% MagickBooleanType PushDrawingWand(DrawingWand *wand)
6733%
6734% A description of each parameter follows:
6735%
6736% o wand: the drawing wand.
6737%
6738*/
6739WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6740{
6741 assert(wand != (DrawingWand *) NULL);
6742 assert(wand->signature == WandSignature);
6743 if (wand->debug != MagickFalse)
6744 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6745 wand->index++;
6746 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6747 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6748 if (wand->graphic_context == (DrawInfo **) NULL)
6749 {
6750 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6751 wand->name);
6752 return(MagickFalse);
6753 }
6754 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6755 wand->graphic_context[wand->index-1]);
6756 (void) MvgPrintf(wand,"push graphic-context\n");
6757 wand->indent_depth++;
6758 return(MagickTrue);
6759}