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