]> granicus.if.org Git - imagemagick/blob - MagickWand/drawing-wand.c
7233f90ffa600cd1d037590acb110c4596ad6ed0
[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-2011 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 *,size_t,size_t,
259     size_t,size_t);
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 PixelPacket *);
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 PixelPacket *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=RGBColorspace;
404       pixel.matte=packet->alpha != OpaqueAlpha ? MagickTrue : MagickFalse;
405       pixel.red=(MagickRealType) packet->red;
406       pixel.green=(MagickRealType) packet->green;
407       pixel.blue=(MagickRealType) packet->blue;
408       pixel.alpha=(MagickRealType) packet->alpha;
409       GetColorTuple(&pixel,MagickTrue,tuple);
410       (void) MvgPrintf(wand,"%s",tuple);
411     }
412 }
413
414 static void MvgAppendPointsCommand(DrawingWand *wand,const char *command,
415   const size_t number_coordinates,const PointInfo *coordinates)
416 {
417   const PointInfo
418     *coordinate;
419
420   size_t
421     i;
422
423   (void) MvgPrintf(wand,"%s",command);
424   for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
425   {
426     (void) MvgAutoWrapPrintf(wand," %g %g",coordinate->x,coordinate->y);
427     coordinate++;
428   }
429   (void) MvgPrintf(wand, "\n");
430 }
431
432 static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine)
433 {
434   assert(wand != (DrawingWand *) NULL);
435   assert(wand->signature == WandSignature);
436   if (wand->debug != MagickFalse)
437     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
438   if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
439       (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
440     {
441       AffineMatrix
442         current;
443
444       current=CurrentContext->affine;
445       CurrentContext->affine.sx=affine->sx*current.sx+affine->ry*current.rx;
446       CurrentContext->affine.rx=affine->rx*current.sx+affine->sy*current.rx;
447       CurrentContext->affine.ry=affine->sx*current.ry+affine->ry*current.sy;
448       CurrentContext->affine.sy=affine->rx*current.ry+affine->sy*current.sy;
449       CurrentContext->affine.tx=affine->sx*current.tx+affine->ry*current.ty+
450         affine->tx;
451       CurrentContext->affine.ty=affine->rx*current.tx+affine->sy*current.ty+
452         affine->ty;
453     }
454 }
455 \f
456 /*
457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458 %                                                                             %
459 %                                                                             %
460 %                                                                             %
461 %   C l e a r D r a w i n g W a n d                                           %
462 %                                                                             %
463 %                                                                             %
464 %                                                                             %
465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
466 %
467 %  ClearDrawingWand() clears resources associated with the drawing wand.
468 %
469 %  The format of the ClearDrawingWand method is:
470 %
471 %      void ClearDrawingWand(DrawingWand *wand)
472 %
473 %  A description of each parameter follows:
474 %
475 %    o wand: the drawing wand to clear.
476 %
477 */
478 WandExport void ClearDrawingWand(DrawingWand *wand)
479 {
480   assert(wand != (DrawingWand *) NULL);
481   assert(wand->signature == WandSignature);
482   if (wand->debug != MagickFalse)
483     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
484   for ( ; wand->index > 0; wand->index--)
485     CurrentContext=DestroyDrawInfo(CurrentContext);
486   CurrentContext=DestroyDrawInfo(CurrentContext);
487   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
488     wand->graphic_context);
489   if (wand->pattern_id != (char *) NULL)
490     wand->pattern_id=DestroyString(wand->pattern_id);
491   wand->mvg=DestroyString(wand->mvg);
492   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
493     wand->image=DestroyImage(wand->image);
494   else
495     wand->image=(Image *) NULL;
496   wand->mvg=(char *) NULL;
497   wand->mvg_alloc=0;
498   wand->mvg_length=0;
499   wand->mvg_width=0;
500   wand->pattern_id=(char *) NULL;
501   wand->pattern_offset=0;
502   wand->pattern_bounds.x=0;
503   wand->pattern_bounds.y=0;
504   wand->pattern_bounds.width=0;
505   wand->pattern_bounds.height=0;
506   wand->index=0;
507   wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
508     sizeof(*wand->graphic_context));
509   if (wand->graphic_context == (DrawInfo **) NULL)
510     {
511       ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
512         wand->name);
513       return;
514     }
515   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
516   wand->filter_off=MagickTrue;
517   wand->indent_depth=0;
518   wand->path_operation=PathDefaultOperation;
519   wand->path_mode=DefaultPathMode;
520   wand->image=AcquireImage((const ImageInfo *) NULL);
521   ClearMagickException(wand->exception);
522   wand->destroy=MagickTrue;
523   wand->debug=IsEventLogging();
524 }
525 \f
526 /*
527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
528 %                                                                             %
529 %                                                                             %
530 %                                                                             %
531 %   C l o n e D r a w i n g W a n d                                           %
532 %                                                                             %
533 %                                                                             %
534 %                                                                             %
535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536 %
537 %  CloneDrawingWand() makes an exact copy of the specified wand.
538 %
539 %  The format of the CloneDrawingWand method is:
540 %
541 %      DrawingWand *CloneDrawingWand(const DrawingWand *wand)
542 %
543 %  A description of each parameter follows:
544 %
545 %    o wand: the magick wand.
546 %
547 */
548 WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
549 {
550   DrawingWand
551     *clone_wand;
552
553   register ssize_t
554     i;
555
556   assert(wand != (DrawingWand *) NULL);
557   assert(wand->signature == WandSignature);
558   if (wand->debug != MagickFalse)
559     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
560   clone_wand=(DrawingWand *) AcquireMagickMemory(sizeof(*clone_wand));
561   if (clone_wand == (DrawingWand *) NULL)
562     ThrowWandFatalException(ResourceLimitFatalError,
563       "MemoryAllocationFailed",GetExceptionMessage(errno));
564   (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
565   clone_wand->id=AcquireWandId();
566   (void) FormatLocaleString(clone_wand->name,MaxTextExtent,"DrawingWand-%.20g",
567     (double) clone_wand->id);
568   clone_wand->exception=AcquireExceptionInfo();
569   InheritException(clone_wand->exception,wand->exception);
570   clone_wand->mvg=AcquireString(wand->mvg);
571   clone_wand->mvg_length=strlen(clone_wand->mvg);
572   clone_wand->mvg_alloc=wand->mvg_length+1;
573   clone_wand->mvg_width=wand->mvg_width;
574   clone_wand->pattern_id=AcquireString(wand->pattern_id);
575   clone_wand->pattern_offset=wand->pattern_offset;
576   clone_wand->pattern_bounds=wand->pattern_bounds;
577   clone_wand->index=wand->index;
578   clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((size_t)
579     wand->index+1UL,sizeof(*wand->graphic_context));
580   if (clone_wand->graphic_context == (DrawInfo **) NULL)
581     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
582       GetExceptionMessage(errno));
583   for (i=0; i <= (ssize_t) wand->index; i++)
584     clone_wand->graphic_context[i]=
585       CloneDrawInfo((ImageInfo *) NULL,wand->graphic_context[i]);
586   clone_wand->filter_off=wand->filter_off;
587   clone_wand->indent_depth=wand->indent_depth;
588   clone_wand->path_operation=wand->path_operation;
589   clone_wand->path_mode=wand->path_mode;
590   clone_wand->image=wand->image;
591   if (wand->image != (Image *) NULL)
592     clone_wand->image=CloneImage(wand->image,0,0,MagickTrue,
593       clone_wand->exception);
594   clone_wand->destroy=MagickTrue;
595   clone_wand->debug=IsEventLogging();
596   if (clone_wand->debug != MagickFalse)
597     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
598   clone_wand->signature=WandSignature;
599   return(clone_wand);
600 }
601 \f
602 /*
603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 %                                                                             %
605 %                                                                             %
606 %                                                                             %
607 %   D e s t r o y D r a w i n g W a n d                                       %
608 %                                                                             %
609 %                                                                             %
610 %                                                                             %
611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
612 %
613 %  DestroyDrawingWand() frees all resources associated with the drawing wand.
614 %  Once the drawing wand has been freed, it should not be used and further
615 %  unless it re-allocated.
616 %
617 %  The format of the DestroyDrawingWand method is:
618 %
619 %      DrawingWand *DestroyDrawingWand(DrawingWand *wand)
620 %
621 %  A description of each parameter follows:
622 %
623 %    o wand: the drawing wand to destroy.
624 %
625 */
626 WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
627 {
628   assert(wand != (DrawingWand *) NULL);
629   assert(wand->signature == WandSignature);
630   if (wand->debug != MagickFalse)
631     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
632   for ( ; wand->index > 0; wand->index--)
633     CurrentContext=DestroyDrawInfo(CurrentContext);
634   CurrentContext=DestroyDrawInfo(CurrentContext);
635   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
636     wand->graphic_context);
637   if (wand->pattern_id != (char *) NULL)
638     wand->pattern_id=DestroyString(wand->pattern_id);
639   wand->mvg=DestroyString(wand->mvg);
640   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
641     wand->image=DestroyImage(wand->image);
642   wand->image=(Image *) NULL;
643   wand->exception=DestroyExceptionInfo(wand->exception);
644   wand->signature=(~WandSignature);
645   RelinquishWandId(wand->id);
646   wand=(DrawingWand *) RelinquishMagickMemory(wand);
647   return(wand);
648 }
649 \f
650 /*
651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652 %                                                                             %
653 %                                                                             %
654 %                                                                             %
655 %   D r a w A f f i n e                                                       %
656 %                                                                             %
657 %                                                                             %
658 %                                                                             %
659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660 %
661 %  DrawAffine() adjusts the current affine transformation matrix with
662 %  the specified affine transformation matrix. Note that the current affine
663 %  transform is adjusted rather than replaced.
664 %
665 %  The format of the DrawAffine method is:
666 %
667 %      void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
668 %
669 %  A description of each parameter follows:
670 %
671 %    o wand: Drawing wand
672 %
673 %    o affine: Affine matrix parameters
674 %
675 */
676 WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
677 {
678   assert(wand != (DrawingWand *) NULL);
679   assert(wand->signature == WandSignature);
680   if (wand->debug != MagickFalse)
681     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
682   assert(affine != (const AffineMatrix *) NULL);
683   AdjustAffine(wand,affine);
684   (void) MvgPrintf(wand,"affine %g %g %g %g %g %g\n",
685     affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
686 }
687 \f
688 /*
689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
690 %                                                                             %
691 %                                                                             %
692 %                                                                             %
693 +   D r a w A l l o c a t e W a n d                                           %
694 %                                                                             %
695 %                                                                             %
696 %                                                                             %
697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
698 %
699 %  DrawAllocateWand() allocates an initial drawing wand which is an opaque
700 %  handle required by the remaining drawing methods.
701 %
702 %  The format of the DrawAllocateWand method is:
703 %
704 %      DrawingWand DrawAllocateWand(const DrawInfo *draw_info,Image *image)
705 %
706 %  A description of each parameter follows:
707 %
708 %    o draw_info: Initial drawing defaults. Set to NULL to use defaults.
709 %
710 %    o image: the image to draw on.
711 %
712 */
713 WandExport DrawingWand *DrawAllocateWand(const DrawInfo *draw_info,Image *image)
714 {
715   DrawingWand
716     *wand;
717
718   wand=NewDrawingWand();
719   if (draw_info != (const DrawInfo *) NULL)
720     {
721       CurrentContext=DestroyDrawInfo(CurrentContext);
722       CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
723     }
724   if (image != (Image *) NULL)
725     {
726       wand->image=DestroyImage(wand->image);
727       wand->destroy=MagickFalse;
728     }
729   wand->image=image;
730   return(wand);
731 }
732 \f
733 /*
734 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735 %                                                                             %
736 %                                                                             %
737 %                                                                             %
738 %   D r a w A n n o t a t i o n                                               %
739 %                                                                             %
740 %                                                                             %
741 %                                                                             %
742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743 %
744 %  DrawAnnotation() draws text on the image.
745 %
746 %  The format of the DrawAnnotation method is:
747 %
748 %      void DrawAnnotation(DrawingWand *wand,const double x,
749 %        const double y,const unsigned char *text)
750 %
751 %  A description of each parameter follows:
752 %
753 %    o wand: the drawing wand.
754 %
755 %    o x: x ordinate to left of text
756 %
757 %    o y: y ordinate to text baseline
758 %
759 %    o text: text to draw
760 %
761 */
762 WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y,
763   const unsigned char *text)
764 {
765   char
766     *escaped_text;
767
768   assert(wand != (DrawingWand *) NULL);
769   assert(wand->signature == WandSignature);
770   if (wand->debug != MagickFalse)
771     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
772   assert(text != (const unsigned char *) NULL);
773   escaped_text=EscapeString((const char *) text,'\'');
774   if (escaped_text != (char *) NULL)
775     {
776       (void) MvgPrintf(wand,"text %g %g '%s'\n",x,y,escaped_text);
777       escaped_text=DestroyString(escaped_text);
778     }
779 }
780 \f
781 /*
782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783 %                                                                             %
784 %                                                                             %
785 %                                                                             %
786 %   D r a w A r c                                                             %
787 %                                                                             %
788 %                                                                             %
789 %                                                                             %
790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791 %
792 %  DrawArc() draws an arc falling within a specified bounding rectangle on the
793 %  image.
794 %
795 %  The format of the DrawArc method is:
796 %
797 %      void DrawArc(DrawingWand *wand,const double sx,const double sy,
798 %        const double ex,const double ey,const double sd,const double ed)
799 %
800 %  A description of each parameter follows:
801 %
802 %    o wand: the drawing wand.
803 %
804 %    o sx: starting x ordinate of bounding rectangle
805 %
806 %    o sy: starting y ordinate of bounding rectangle
807 %
808 %    o ex: ending x ordinate of bounding rectangle
809 %
810 %    o ey: ending y ordinate of bounding rectangle
811 %
812 %    o sd: starting degrees of rotation
813 %
814 %    o ed: ending degrees of rotation
815 %
816 */
817 WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy,
818   const double ex,const double ey,const double sd,const double ed)
819 {
820   assert(wand != (DrawingWand *) NULL);
821   assert(wand->signature == WandSignature);
822   if (wand->debug != MagickFalse)
823     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
824   (void) MvgPrintf(wand,"arc %g %g %g %g %g %g\n",sx,sy,ex,
825     ey,sd,ed);
826 }
827 \f
828 /*
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 %                                                                             %
831 %                                                                             %
832 %                                                                             %
833 %   D r a w B e z i e r                                                       %
834 %                                                                             %
835 %                                                                             %
836 %                                                                             %
837 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838 %
839 %  DrawBezier() draws a bezier curve through a set of points on the image.
840 %
841 %  The format of the DrawBezier method is:
842 %
843 %      void DrawBezier(DrawingWand *wand,
844 %        const size_t number_coordinates,const PointInfo *coordinates)
845 %
846 %  A description of each parameter follows:
847 %
848 %    o wand: the drawing wand.
849 %
850 %    o number_coordinates: number of coordinates
851 %
852 %    o coordinates: coordinates
853 %
854 */
855 WandExport void DrawBezier(DrawingWand *wand,
856   const size_t number_coordinates,const PointInfo *coordinates)
857 {
858   assert(wand != (DrawingWand *) NULL);
859   assert(wand->signature == WandSignature);
860   if (wand->debug != MagickFalse)
861     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
862   assert(coordinates != (const PointInfo *) NULL);
863   MvgAppendPointsCommand(wand,"bezier",number_coordinates,coordinates);
864 }
865 \f
866 /*
867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868 %                                                                             %
869 %                                                                             %
870 %                                                                             %
871 %   D r a w C i r c l e                                                       %
872 %                                                                             %
873 %                                                                             %
874 %                                                                             %
875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876 %
877 %  DrawCircle() draws a circle on the image.
878 %
879 %  The format of the DrawCircle method is:
880 %
881 %      void DrawCircle(DrawingWand *wand,const double ox,
882 %        const double oy,const double px, const double py)
883 %
884 %  A description of each parameter follows:
885 %
886 %    o wand: the drawing wand.
887 %
888 %    o ox: origin x ordinate
889 %
890 %    o oy: origin y ordinate
891 %
892 %    o px: perimeter x ordinate
893 %
894 %    o py: perimeter y ordinate
895 %
896 */
897 WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
898   const double px,const double py)
899 {
900   assert(wand != (DrawingWand *) NULL);
901   assert(wand->signature == WandSignature);
902   if (wand->debug != MagickFalse)
903     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
904   (void) MvgPrintf(wand,"circle %g %g %g %g\n",ox,oy,px,py);
905 }
906 \f
907 /*
908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
909 %                                                                             %
910 %                                                                             %
911 %                                                                             %
912 %   D r a w C l e a r E x c e p t i o n                                       %
913 %                                                                             %
914 %                                                                             %
915 %                                                                             %
916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
917 %
918 %  DrawClearException() clear any exceptions associated with the wand.
919 %
920 %  The format of the DrawClearException method is:
921 %
922 %      MagickBooleanType DrawClearException(DrawWand *wand)
923 %
924 %  A description of each parameter follows:
925 %
926 %    o wand: the drawing wand.
927 %
928 */
929 WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
930 {
931   assert(wand != (DrawingWand *) NULL);
932   assert(wand->signature == WandSignature);
933   if (wand->debug != MagickFalse)
934     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
935   ClearMagickException(wand->exception);
936   return(MagickTrue);
937 }
938 \f
939 /*
940 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941 %                                                                             %
942 %                                                                             %
943 %                                                                             %
944 %   D r a w C o m p o s i t e                                                 %
945 %                                                                             %
946 %                                                                             %
947 %                                                                             %
948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949 %
950 %  DrawComposite() composites an image onto the current image, using the
951 %  specified composition operator, specified position, and at the specified
952 %  size.
953 %
954 %  The format of the DrawComposite method is:
955 %
956 %      MagickBooleanType DrawComposite(DrawingWand *wand,
957 %        const CompositeOperator compose,const double x,
958 %        const double y,const double width,const double height,
959 %        MagickWand *magick_wand)
960 %
961 %  A description of each parameter follows:
962 %
963 %    o wand: the drawing wand.
964 %
965 %    o compose: composition operator
966 %
967 %    o x: x ordinate of top left corner
968 %
969 %    o y: y ordinate of top left corner
970 %
971 %    o width: Width to resize image to prior to compositing.  Specify zero to
972 %      use existing width.
973 %
974 %    o height: Height to resize image to prior to compositing.  Specify zero
975 %      to use existing height.
976 %
977 %    o magick_wand: Image to composite is obtained from this wand.
978 %
979 */
980 WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
981   const CompositeOperator compose,const double x,const double y,
982   const double width,const double height,MagickWand *magick_wand)
983
984 {
985   char
986     *base64,
987     *media_type;
988
989   const char
990     *mode;
991
992   ImageInfo
993     *image_info;
994
995   Image
996     *clone_image,
997     *image;
998
999   register char
1000     *p;
1001
1002   register ssize_t
1003     i;
1004
1005   size_t
1006     blob_length,
1007     encoded_length;
1008
1009   unsigned char
1010     *blob;
1011
1012   assert(wand != (DrawingWand *) NULL);
1013   assert(wand->signature == WandSignature);
1014   if (wand->debug != MagickFalse)
1015     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1016   assert(magick_wand != (MagickWand *) NULL);
1017   image=GetImageFromMagickWand(magick_wand);
1018   if (image == (Image *) NULL)
1019     return(MagickFalse);
1020   clone_image=CloneImage(image,0,0,MagickTrue,wand->exception);
1021   if (clone_image == (Image *) NULL)
1022     return(MagickFalse);
1023   image_info=AcquireImageInfo();
1024   (void) CopyMagickString(image_info->magick,"MIFF",MaxTextExtent);
1025   blob_length=2048;
1026   blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
1027     wand->exception);
1028   image_info=DestroyImageInfo(image_info);
1029   clone_image=DestroyImageList(clone_image);
1030   if (blob == (void *) NULL)
1031     return(MagickFalse);
1032   encoded_length=0;
1033   base64=Base64Encode(blob,blob_length,&encoded_length);
1034   blob=(unsigned char *) RelinquishMagickMemory(blob);
1035   if (base64 == (char *) NULL)
1036     {
1037       char
1038         buffer[MaxTextExtent];
1039
1040       (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g bytes",(double)
1041         (4L*blob_length/3L+4L));
1042       ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
1043         wand->name);
1044       return(MagickFalse);
1045     }
1046   mode=CommandOptionToMnemonic(MagickComposeOptions,(ssize_t) compose);
1047   media_type=MagickToMime(image->magick);
1048   (void) MvgPrintf(wand,"image %s %g %g %g %g 'data:%s;base64,\n",
1049     mode,x,y,width,height,media_type);
1050   p=base64;
1051   for (i=(ssize_t) encoded_length; i > 0; i-=76)
1052   {
1053     (void) MvgPrintf(wand,"%.76s",p);
1054     p+=76;
1055     if (i > 76)
1056       (void) MvgPrintf(wand,"\n");
1057   }
1058   (void) MvgPrintf(wand,"'\n");
1059   media_type=DestroyString(media_type);
1060   base64=DestroyString(base64);
1061   return(MagickTrue);
1062 }
1063 \f
1064 /*
1065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1066 %                                                                             %
1067 %                                                                             %
1068 %                                                                             %
1069 %   D r a w C o l o r                                                         %
1070 %                                                                             %
1071 %                                                                             %
1072 %                                                                             %
1073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1074 %
1075 %  DrawColor() draws color on image using the current fill color, starting at
1076 %  specified position, and using specified paint method. The available paint
1077 %  methods are:
1078 %
1079 %    PointMethod: Recolors the target pixel
1080 %    ReplaceMethod: Recolor any pixel that matches the target pixel.
1081 %    FloodfillMethod: Recolors target pixels and matching neighbors.
1082 %    ResetMethod: Recolor all pixels.
1083 %
1084 %  The format of the DrawColor method is:
1085 %
1086 %      void DrawColor(DrawingWand *wand,const double x,const double y,
1087 %        const PaintMethod paint_method)
1088 %
1089 %  A description of each parameter follows:
1090 %
1091 %    o wand: the drawing wand.
1092 %
1093 %    o x: x ordinate.
1094 %
1095 %    o y: y ordinate.
1096 %
1097 %    o paint_method: paint method.
1098 %
1099 */
1100 WandExport void DrawColor(DrawingWand *wand,const double x,const double y,
1101   const PaintMethod paint_method)
1102 {
1103   assert(wand != (DrawingWand *) NULL);
1104   assert(wand->signature == WandSignature);
1105   if (wand->debug != MagickFalse)
1106     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1107   (void) MvgPrintf(wand,"color %g %g '%s'\n",x,y,CommandOptionToMnemonic(
1108     MagickMethodOptions,(ssize_t) paint_method));
1109 }
1110 \f
1111 /*
1112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1113 %                                                                             %
1114 %                                                                             %
1115 %                                                                             %
1116 %   D r a w C o m m e n t                                                     %
1117 %                                                                             %
1118 %                                                                             %
1119 %                                                                             %
1120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121 %
1122 %  DrawComment() adds a comment to a vector output stream.
1123 %
1124 %  The format of the DrawComment method is:
1125 %
1126 %      void DrawComment(DrawingWand *wand,const char *comment)
1127 %
1128 %  A description of each parameter follows:
1129 %
1130 %    o wand: the drawing wand.
1131 %
1132 %    o comment: comment text
1133 %
1134 */
1135 WandExport void DrawComment(DrawingWand *wand,const char *comment)
1136 {
1137   (void) MvgPrintf(wand,"#%s\n",comment);
1138 }
1139 \f
1140 /*
1141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1142 %                                                                             %
1143 %                                                                             %
1144 %                                                                             %
1145 %   D r a w E l l i p s e                                                     %
1146 %                                                                             %
1147 %                                                                             %
1148 %                                                                             %
1149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1150 %
1151 %  DrawEllipse() draws an ellipse on the image.
1152 %
1153 %  The format of the DrawEllipse method is:
1154 %
1155 %       void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1156 %         const double rx,const double ry,const double start,const double end)
1157 %
1158 %  A description of each parameter follows:
1159 %
1160 %    o wand: the drawing wand.
1161 %
1162 %    o ox: origin x ordinate
1163 %
1164 %    o oy: origin y ordinate
1165 %
1166 %    o rx: radius in x
1167 %
1168 %    o ry: radius in y
1169 %
1170 %    o start: starting rotation in degrees
1171 %
1172 %    o end: ending rotation in degrees
1173 %
1174 */
1175 WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1176   const double rx,const double ry,const double start,const double end)
1177 {
1178   assert(wand != (DrawingWand *) NULL);
1179   assert(wand->signature == WandSignature);
1180   if (wand->debug != MagickFalse)
1181     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1182   (void) MvgPrintf(wand,"ellipse %g %g %g %g %g %g\n",ox,oy,
1183     rx,ry,start,end);
1184 }
1185 \f
1186 /*
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1188 %                                                                             %
1189 %                                                                             %
1190 %                                                                             %
1191 %   D r a w G e t B o r d e r C o l o r                                       %
1192 %                                                                             %
1193 %                                                                             %
1194 %                                                                             %
1195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1196 %
1197 %  DrawGetBorderColor() returns the border color used for drawing bordered
1198 %  objects.
1199 %
1200 %  The format of the DrawGetBorderColor method is:
1201 %
1202 %      void DrawGetBorderColor(const DrawingWand *wand,
1203 %        PixelWand *border_color)
1204 %
1205 %  A description of each parameter follows:
1206 %
1207 %    o wand: the drawing wand.
1208 %
1209 %    o border_color: Return the border color.
1210 %
1211 */
1212 WandExport void DrawGetBorderColor(const DrawingWand *wand,
1213   PixelWand *border_color)
1214 {
1215   assert(wand != (const DrawingWand *) NULL);
1216   assert(wand->signature == WandSignature);
1217   assert(border_color != (PixelWand *) NULL);
1218   if (wand->debug != MagickFalse)
1219     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1220   PixelSetQuantumPacket(border_color,&CurrentContext->border_color);
1221 }
1222 \f
1223 /*
1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1225 %                                                                             %
1226 %                                                                             %
1227 %                                                                             %
1228 %   D r a w G e t C l i p P a t h                                             %
1229 %                                                                             %
1230 %                                                                             %
1231 %                                                                             %
1232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1233 %
1234 %  DrawGetClipPath() obtains the current clipping path ID. The value returned
1235 %  must be deallocated by the user when it is no longer needed.
1236 %
1237 %  The format of the DrawGetClipPath method is:
1238 %
1239 %      char *DrawGetClipPath(const DrawingWand *wand)
1240 %
1241 %  A description of each parameter follows:
1242 %
1243 %    o wand: the drawing wand.
1244 %
1245 */
1246 WandExport char *DrawGetClipPath(const DrawingWand *wand)
1247 {
1248   assert(wand != (const DrawingWand *) NULL);
1249   assert(wand->signature == WandSignature);
1250   if (wand->debug != MagickFalse)
1251     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1252   if (CurrentContext->clip_mask != (char *) NULL)
1253     return((char *) AcquireString(CurrentContext->clip_mask));
1254   return((char *) NULL);
1255 }
1256 \f
1257 /*
1258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259 %                                                                             %
1260 %                                                                             %
1261 %                                                                             %
1262 %   D r a w G e t C l i p R u l e                                             %
1263 %                                                                             %
1264 %                                                                             %
1265 %                                                                             %
1266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267 %
1268 %  DrawGetClipRule() returns the current polygon fill rule to be used by the
1269 %  clipping path.
1270 %
1271 %  The format of the DrawGetClipRule method is:
1272 %
1273 %     FillRule DrawGetClipRule(const DrawingWand *wand)
1274 %
1275 %  A description of each parameter follows:
1276 %
1277 %    o wand: the drawing wand.
1278 %
1279 */
1280 WandExport FillRule DrawGetClipRule(const DrawingWand *wand)
1281 {
1282   assert(wand != (const DrawingWand *) NULL);
1283   assert(wand->signature == WandSignature);
1284   if (wand->debug != MagickFalse)
1285     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1286   return(CurrentContext->fill_rule);
1287 }
1288 \f
1289 /*
1290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1291 %                                                                             %
1292 %                                                                             %
1293 %                                                                             %
1294 %   D r a w G e t C l i p U n i t s                                           %
1295 %                                                                             %
1296 %                                                                             %
1297 %                                                                             %
1298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1299 %
1300 %  DrawGetClipUnits() returns the interpretation of clip path units.
1301 %
1302 %  The format of the DrawGetClipUnits method is:
1303 %
1304 %      ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1305 %
1306 %  A description of each parameter follows:
1307 %
1308 %    o wand: the drawing wand.
1309 %
1310 */
1311 WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1312 {
1313   assert(wand != (const DrawingWand *) NULL);
1314   assert(wand->signature == WandSignature);
1315   if (wand->debug != MagickFalse)
1316     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1317   return(CurrentContext->clip_units);
1318 }
1319 \f
1320 /*
1321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1322 %                                                                             %
1323 %                                                                             %
1324 %                                                                             %
1325 %   D r a w G e t E x c e p t i o n                                           %
1326 %                                                                             %
1327 %                                                                             %
1328 %                                                                             %
1329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1330 %
1331 %  DrawGetException() returns the severity, reason, and description of any
1332 %  error that occurs when using other methods in this API.
1333 %
1334 %  The format of the DrawGetException method is:
1335 %
1336 %      char *DrawGetException(const DrawWand *wand,
1337 %        ExceptionType *severity)
1338 %
1339 %  A description of each parameter follows:
1340 %
1341 %    o wand: the drawing wand.
1342 %
1343 %    o severity: the severity of the error is returned here.
1344 %
1345 */
1346 WandExport char *DrawGetException(const DrawingWand *wand,
1347   ExceptionType *severity)
1348 {
1349   char
1350     *description;
1351
1352   assert(wand != (const DrawingWand *) NULL);
1353   assert(wand->signature == WandSignature);
1354   if (wand->debug != MagickFalse)
1355     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1356   assert(severity != (ExceptionType *) NULL);
1357   *severity=wand->exception->severity;
1358   description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
1359     sizeof(*description));
1360   if (description == (char *) NULL)
1361     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1362       wand->name);
1363   *description='\0';
1364   if (wand->exception->reason != (char *) NULL)
1365     (void) CopyMagickString(description,GetLocaleExceptionMessage(
1366       wand->exception->severity,wand->exception->reason),
1367       MaxTextExtent);
1368   if (wand->exception->description != (char *) NULL)
1369     {
1370       (void) ConcatenateMagickString(description," (",MaxTextExtent);
1371       (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
1372         wand->exception->severity,wand->exception->description),
1373         MaxTextExtent);
1374       (void) ConcatenateMagickString(description,")",MaxTextExtent);
1375     }
1376   return(description);
1377 }
1378 \f
1379 /*
1380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1381 %                                                                             %
1382 %                                                                             %
1383 %                                                                             %
1384 %   P i x e l G e t E x c e p t i o n T y p e                                 %
1385 %                                                                             %
1386 %                                                                             %
1387 %                                                                             %
1388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1389 %
1390 %  DrawGetExceptionType() the exception type associated with the wand.  If
1391 %  no exception has occurred, UndefinedExceptionType is returned.
1392 %
1393 %  The format of the DrawGetExceptionType method is:
1394 %
1395 %      ExceptionType DrawGetExceptionType(const DrawWand *wand)
1396 %
1397 %  A description of each parameter follows:
1398 %
1399 %    o wand: the magick wand.
1400 %
1401 */
1402 WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand)
1403 {
1404   assert(wand != (const DrawingWand *) NULL);
1405   assert(wand->signature == WandSignature);
1406   if (wand->debug != MagickFalse)
1407     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1408   return(wand->exception->severity);
1409 }
1410 \f
1411 /*
1412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1413 %                                                                             %
1414 %                                                                             %
1415 %                                                                             %
1416 %   D r a w G e t F i l l C o l o r                                           %
1417 %                                                                             %
1418 %                                                                             %
1419 %                                                                             %
1420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1421 %
1422 %  DrawGetFillColor() returns the fill color used for drawing filled objects.
1423 %
1424 %  The format of the DrawGetFillColor method is:
1425 %
1426 %      void DrawGetFillColor(const DrawingWand *wand,
1427 %        PixelWand *fill_color)
1428 %
1429 %  A description of each parameter follows:
1430 %
1431 %    o wand: the drawing wand.
1432 %
1433 %    o fill_color: Return the fill color.
1434 %
1435 */
1436 WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color)
1437 {
1438   assert(wand != (const DrawingWand *) NULL);
1439   assert(wand->signature == WandSignature);
1440   assert(fill_color != (PixelWand *) NULL);
1441   if (wand->debug != MagickFalse)
1442     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1443   PixelSetQuantumPacket(fill_color,&CurrentContext->fill);
1444 }
1445 \f
1446 /*
1447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1448 %                                                                             %
1449 %                                                                             %
1450 %                                                                             %
1451 %   D r a w G e t F i l l O p a c i t y                                       %
1452 %                                                                             %
1453 %                                                                             %
1454 %                                                                             %
1455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1456 %
1457 %  DrawGetFillOpacity() returns the opacity used when drawing using the fill
1458 %  color or fill texture.  Fully opaque is 1.0.
1459 %
1460 %  The format of the DrawGetFillOpacity method is:
1461 %
1462 %      double DrawGetFillOpacity(const DrawingWand *wand)
1463 %
1464 %  A description of each parameter follows:
1465 %
1466 %    o wand: the drawing wand.
1467 %
1468 */
1469 WandExport double DrawGetFillOpacity(const DrawingWand *wand)
1470 {
1471   double
1472     alpha;
1473
1474   assert(wand != (const DrawingWand *) NULL);
1475   assert(wand->signature == WandSignature);
1476   if (wand->debug != MagickFalse)
1477     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1478   alpha=(double) QuantumScale*CurrentContext->fill.alpha;
1479   return(alpha);
1480 }
1481 \f
1482 /*
1483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1484 %                                                                             %
1485 %                                                                             %
1486 %                                                                             %
1487 %   D r a w G e t F i l l R u l e                                             %
1488 %                                                                             %
1489 %                                                                             %
1490 %                                                                             %
1491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1492 %
1493 %  DrawGetFillRule() returns the fill rule used while drawing polygons.
1494 %
1495 %  The format of the DrawGetFillRule method is:
1496 %
1497 %      FillRule DrawGetFillRule(const DrawingWand *wand)
1498 %
1499 %  A description of each parameter follows:
1500 %
1501 %    o wand: the drawing wand.
1502 %
1503 */
1504 WandExport FillRule DrawGetFillRule(const DrawingWand *wand)
1505 {
1506   assert(wand != (const DrawingWand *) NULL);
1507   assert(wand->signature == WandSignature);
1508   if (wand->debug != MagickFalse)
1509     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1510   return(CurrentContext->fill_rule);
1511 }
1512 \f
1513 /*
1514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515 %                                                                             %
1516 %                                                                             %
1517 %                                                                             %
1518 %   D r a w G e t F o n t                                                     %
1519 %                                                                             %
1520 %                                                                             %
1521 %                                                                             %
1522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1523 %
1524 %  DrawGetFont() returns a null-terminaged string specifying the font used
1525 %  when annotating with text. The value returned must be freed by the user
1526 %  when no longer needed.
1527 %
1528 %  The format of the DrawGetFont method is:
1529 %
1530 %      char *DrawGetFont(const DrawingWand *wand)
1531 %
1532 %  A description of each parameter follows:
1533 %
1534 %    o wand: the drawing wand.
1535 %
1536 */
1537 WandExport char *DrawGetFont(const DrawingWand *wand)
1538 {
1539   assert(wand != (const DrawingWand *) NULL);
1540   assert(wand->signature == WandSignature);
1541   if (wand->debug != MagickFalse)
1542     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1543   if (CurrentContext->font != (char *) NULL)
1544     return(AcquireString(CurrentContext->font));
1545   return((char *) NULL);
1546 }
1547 \f
1548 /*
1549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1550 %                                                                             %
1551 %                                                                             %
1552 %                                                                             %
1553 %   D r a w G e t F o n t F a m i l y                                         %
1554 %                                                                             %
1555 %                                                                             %
1556 %                                                                             %
1557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1558 %
1559 %  DrawGetFontFamily() returns the font family to use when annotating with text.
1560 %  The value returned must be freed by the user when it is no longer needed.
1561 %
1562 %  The format of the DrawGetFontFamily method is:
1563 %
1564 %      char *DrawGetFontFamily(const DrawingWand *wand)
1565 %
1566 %  A description of each parameter follows:
1567 %
1568 %    o wand: the drawing wand.
1569 %
1570 */
1571 WandExport char *DrawGetFontFamily(const DrawingWand *wand)
1572 {
1573   assert(wand != (const DrawingWand *) NULL);
1574   assert(wand->signature == WandSignature);
1575   if (wand->debug != MagickFalse)
1576     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1577   if (CurrentContext->family != NULL)
1578     return(AcquireString(CurrentContext->family));
1579   return((char *) NULL);
1580 }
1581 \f
1582 /*
1583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1584 %                                                                             %
1585 %                                                                             %
1586 %                                                                             %
1587 %   D r a w G e t F o n t R e s o l u t i o n                                 %
1588 %                                                                             %
1589 %                                                                             %
1590 %                                                                             %
1591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1592 %
1593 %  DrawGetFontResolution() gets the image X and Y resolution.
1594 %
1595 %  The format of the DrawGetFontResolution method is:
1596 %
1597 %      DrawBooleanType DrawGetFontResolution(const DrawingWand *wand,
1598 %        double *x,double *y)
1599 %
1600 %  A description of each parameter follows:
1601 %
1602 %    o wand: the magick wand.
1603 %
1604 %    o x: the x-resolution.
1605 %
1606 %    o y: the y-resolution.
1607 %
1608 */
1609 WandExport MagickBooleanType DrawGetFontResolution(const DrawingWand *wand,
1610   double *x,double *y)
1611 {
1612   assert(wand != (DrawingWand *) NULL);
1613   assert(wand->signature == WandSignature);
1614   if (wand->debug != MagickFalse)
1615     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1616   *x=72.0;
1617   *y=72.0;
1618   if (CurrentContext->density != (char *) NULL)
1619     {
1620       GeometryInfo
1621         geometry_info;
1622
1623       MagickStatusType
1624         flags;
1625
1626       flags=ParseGeometry(CurrentContext->density,&geometry_info);
1627       *x=geometry_info.rho;
1628       *y=geometry_info.sigma;
1629       if ((flags & SigmaValue) == MagickFalse)
1630         *y=(*x);
1631     }
1632   return(MagickTrue);
1633 }
1634 \f
1635 /*
1636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1637 %                                                                             %
1638 %                                                                             %
1639 %                                                                             %
1640 %   D r a w G e t F o n t S i z e                                             %
1641 %                                                                             %
1642 %                                                                             %
1643 %                                                                             %
1644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1645 %
1646 %  DrawGetFontSize() returns the font pointsize used when annotating with text.
1647 %
1648 %  The format of the DrawGetFontSize method is:
1649 %
1650 %      double DrawGetFontSize(const DrawingWand *wand)
1651 %
1652 %  A description of each parameter follows:
1653 %
1654 %    o wand: the drawing wand.
1655 %
1656 */
1657 WandExport double DrawGetFontSize(const DrawingWand *wand)
1658 {
1659   assert(wand != (const DrawingWand *) NULL);
1660   assert(wand->signature == WandSignature);
1661   if (wand->debug != MagickFalse)
1662     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1663   return(CurrentContext->pointsize);
1664 }
1665 \f
1666 /*
1667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1668 %                                                                             %
1669 %                                                                             %
1670 %                                                                             %
1671 %   D r a w G e t F o n t S t r e t c h                                       %
1672 %                                                                             %
1673 %                                                                             %
1674 %                                                                             %
1675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1676 %
1677 %  DrawGetFontStretch() returns the font stretch used when annotating with text.
1678 %
1679 %  The format of the DrawGetFontStretch method is:
1680 %
1681 %      StretchType DrawGetFontStretch(const DrawingWand *wand)
1682 %
1683 %  A description of each parameter follows:
1684 %
1685 %    o wand: the drawing wand.
1686 %
1687 */
1688 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1689 {
1690   assert(wand != (const DrawingWand *) NULL);
1691   assert(wand->signature == WandSignature);
1692   if (wand->debug != MagickFalse)
1693     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1694   return(CurrentContext->stretch);
1695 }
1696 \f
1697 /*
1698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1699 %                                                                             %
1700 %                                                                             %
1701 %                                                                             %
1702 %   D r a w G e t F o n t S t y l e                                           %
1703 %                                                                             %
1704 %                                                                             %
1705 %                                                                             %
1706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1707 %
1708 %  DrawGetFontStyle() returns the font style used when annotating with text.
1709 %
1710 %  The format of the DrawGetFontStyle method is:
1711 %
1712 %      StyleType DrawGetFontStyle(const DrawingWand *wand)
1713 %
1714 %  A description of each parameter follows:
1715 %
1716 %    o wand: the drawing wand.
1717 %
1718 */
1719 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1720 {
1721   assert(wand != (const DrawingWand *) NULL);
1722   assert(wand->signature == WandSignature);
1723   if (wand->debug != MagickFalse)
1724     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1725   return(CurrentContext->style);
1726 }
1727 \f
1728 /*
1729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1730 %                                                                             %
1731 %                                                                             %
1732 %                                                                             %
1733 %   D r a w G e t F o n t W e i g h t                                         %
1734 %                                                                             %
1735 %                                                                             %
1736 %                                                                             %
1737 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1738 %
1739 %  DrawGetFontWeight() returns the font weight used when annotating with text.
1740 %
1741 %  The format of the DrawGetFontWeight method is:
1742 %
1743 %      size_t DrawGetFontWeight(const DrawingWand *wand)
1744 %
1745 %  A description of each parameter follows:
1746 %
1747 %    o wand: the drawing wand.
1748 %
1749 */
1750 WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
1751 {
1752   assert(wand != (const DrawingWand *) NULL);
1753   assert(wand->signature == WandSignature);
1754   if (wand->debug != MagickFalse)
1755     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1756   return(CurrentContext->weight);
1757 }
1758 \f
1759 /*
1760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1761 %                                                                             %
1762 %                                                                             %
1763 %                                                                             %
1764 %   D r a w G e t G r a v i t y                                               %
1765 %                                                                             %
1766 %                                                                             %
1767 %                                                                             %
1768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1769 %
1770 %  DrawGetGravity() returns the text placement gravity used when annotating
1771 %  with text.
1772 %
1773 %  The format of the DrawGetGravity method is:
1774 %
1775 %      GravityType DrawGetGravity(const DrawingWand *wand)
1776 %
1777 %  A description of each parameter follows:
1778 %
1779 %    o wand: the drawing wand.
1780 %
1781 */
1782 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1783 {
1784   assert(wand != (const DrawingWand *) NULL);
1785   assert(wand->signature == WandSignature);
1786   if (wand->debug != MagickFalse)
1787     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1788   return(CurrentContext->gravity);
1789 }
1790 \f
1791 /*
1792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1793 %                                                                             %
1794 %                                                                             %
1795 %                                                                             %
1796 %   D r a w G e t O p a c i t y                                               %
1797 %                                                                             %
1798 %                                                                             %
1799 %                                                                             %
1800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1801 %
1802 %  DrawGetOpacity() returns the opacity used when drawing with the fill
1803 %  or stroke color or texture.  Fully opaque is 1.0.
1804 %
1805 %  The format of the DrawGetOpacity method is:
1806 %
1807 %      double DrawGetOpacity(const DrawingWand *wand)
1808 %
1809 %  A description of each parameter follows:
1810 %
1811 %    o wand: the drawing wand.
1812 %
1813 */
1814 WandExport double DrawGetOpacity(const DrawingWand *wand)
1815 {
1816   double
1817     alpha;
1818
1819   assert(wand != (const DrawingWand *) NULL);
1820   assert(wand->signature == WandSignature);
1821   if (wand->debug != MagickFalse)
1822     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1823   alpha=(double) QuantumScale*CurrentContext->alpha;
1824   return(alpha);
1825 }
1826 \f
1827 /*
1828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1829 %                                                                             %
1830 %                                                                             %
1831 %                                                                             %
1832 %   D r a w G e t S t r o k e A n t i a l i a s                               %
1833 %                                                                             %
1834 %                                                                             %
1835 %                                                                             %
1836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1837 %
1838 %  DrawGetStrokeAntialias() returns the current stroke antialias setting.
1839 %  Stroked outlines are antialiased by default.  When antialiasing is disabled
1840 %  stroked pixels are thresholded to determine if the stroke color or
1841 %  underlying canvas color should be used.
1842 %
1843 %  The format of the DrawGetStrokeAntialias method is:
1844 %
1845 %      MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1846 %
1847 %  A description of each parameter follows:
1848 %
1849 %    o wand: the drawing wand.
1850 %
1851 */
1852 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1853 {
1854   assert(wand != (const DrawingWand *) NULL);
1855   assert(wand->signature == WandSignature);
1856   if (wand->debug != MagickFalse)
1857     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1858   return(CurrentContext->stroke_antialias);
1859 }
1860 \f
1861 /*
1862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1863 %                                                                             %
1864 %                                                                             %
1865 %                                                                             %
1866 %   D r a w G e t S t r o k e C o l o r                                       %
1867 %                                                                             %
1868 %                                                                             %
1869 %                                                                             %
1870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1871 %
1872 %  DrawGetStrokeColor() returns the color used for stroking object outlines.
1873 %
1874 %  The format of the DrawGetStrokeColor method is:
1875 %
1876 %      void DrawGetStrokeColor(const DrawingWand *wand,
1877 $        PixelWand *stroke_color)
1878 %
1879 %  A description of each parameter follows:
1880 %
1881 %    o wand: the drawing wand.
1882 %
1883 %    o stroke_color: Return the stroke color.
1884 %
1885 */
1886 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1887   PixelWand *stroke_color)
1888 {
1889   assert(wand != (const DrawingWand *) NULL);
1890   assert(wand->signature == WandSignature);
1891   assert(stroke_color != (PixelWand *) NULL);
1892   if (wand->debug != MagickFalse)
1893     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1894   PixelSetQuantumPacket(stroke_color,&CurrentContext->stroke);
1895 }
1896 \f
1897 /*
1898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1899 %                                                                             %
1900 %                                                                             %
1901 %                                                                             %
1902 %   D r a w G e t S t r o k e D a s h A r r a y                               %
1903 %                                                                             %
1904 %                                                                             %
1905 %                                                                             %
1906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1907 %
1908 %  DrawGetStrokeDashArray() returns an array representing the pattern of
1909 %  dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
1910 %  array must be freed once it is no longer required by the user.
1911 %
1912 %  The format of the DrawGetStrokeDashArray method is:
1913 %
1914 %      double *DrawGetStrokeDashArray(const DrawingWand *wand,
1915 %        size_t *number_elements)
1916 %
1917 %  A description of each parameter follows:
1918 %
1919 %    o wand: the drawing wand.
1920 %
1921 %    o number_elements: address to place number of elements in dash array
1922 %
1923 */
1924 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
1925   size_t *number_elements)
1926 {
1927   double
1928     *dash_array;
1929
1930   register const double
1931     *p;
1932
1933   register double
1934     *q;
1935
1936   register ssize_t
1937     i;
1938
1939   size_t
1940     n;
1941
1942   assert(wand != (const DrawingWand *) NULL);
1943   assert(wand->signature == WandSignature);
1944   if (wand->debug != MagickFalse)
1945     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1946   assert(number_elements != (size_t *) NULL);
1947   n=0;
1948   p=CurrentContext->dash_pattern;
1949   if (p != (const double *) NULL)
1950     while (fabs(*p++) >= MagickEpsilon)
1951       n++;
1952   *number_elements=n;
1953   dash_array=(double *) NULL;
1954   if (n != 0)
1955     {
1956       dash_array=(double *) AcquireQuantumMemory((size_t) n,
1957         sizeof(*dash_array));
1958       p=CurrentContext->dash_pattern;
1959       q=dash_array;
1960       for (i=0; i < (ssize_t) n; i++)
1961         *q++=(*p++);
1962     }
1963   return(dash_array);
1964 }
1965 \f
1966 /*
1967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1968 %                                                                             %
1969 %                                                                             %
1970 %                                                                             %
1971 %   D r a w G e t S t r o k e D a s h O f f s e t                             %
1972 %                                                                             %
1973 %                                                                             %
1974 %                                                                             %
1975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1976 %
1977 %  DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1978 %  start the dash.
1979 %
1980 %  The format of the DrawGetStrokeDashOffset method is:
1981 %
1982 %      double DrawGetStrokeDashOffset(const DrawingWand *wand)
1983 %
1984 %  A description of each parameter follows:
1985 %
1986 %    o wand: the drawing wand.
1987 %
1988 */
1989 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1990 {
1991   assert(wand != (const DrawingWand *) NULL);
1992   assert(wand->signature == WandSignature);
1993   if (wand->debug != MagickFalse)
1994     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1995   return(CurrentContext->dash_offset);
1996 }
1997 \f
1998 /*
1999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2000 %                                                                             %
2001 %                                                                             %
2002 %                                                                             %
2003 %   D r a w G e t S t r o k e L i n e C a p                                   %
2004 %                                                                             %
2005 %                                                                             %
2006 %                                                                             %
2007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2008 %
2009 %  DrawGetStrokeLineCap() returns the shape to be used at the end of
2010 %  open subpaths when they are stroked. Values of LineCap are
2011 %  UndefinedCap, ButtCap, RoundCap, and SquareCap.
2012 %
2013 %  The format of the DrawGetStrokeLineCap method is:
2014 %
2015 %      LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2016 %
2017 %  A description of each parameter follows:
2018 %
2019 %    o wand: the drawing wand.
2020 %
2021 */
2022 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2023 {
2024   assert(wand != (const DrawingWand *) NULL);
2025   assert(wand->signature == WandSignature);
2026   if (wand->debug != MagickFalse)
2027     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2028   return(CurrentContext->linecap);
2029 }
2030 \f
2031 /*
2032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2033 %                                                                             %
2034 %                                                                             %
2035 %                                                                             %
2036 %   D r a w G e t S t r o k e L i n e J o i n                                 %
2037 %                                                                             %
2038 %                                                                             %
2039 %                                                                             %
2040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2041 %
2042 %  DrawGetStrokeLineJoin() returns the shape to be used at the
2043 %  corners of paths (or other vector shapes) when they are
2044 %  stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
2045 %  and BevelJoin.
2046 %
2047 %  The format of the DrawGetStrokeLineJoin method is:
2048 %
2049 %      LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2050 %
2051 %  A description of each parameter follows:
2052 %
2053 %    o wand: the drawing wand.
2054 %
2055 */
2056 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2057 {
2058   assert(wand != (const DrawingWand *) NULL);
2059   assert(wand->signature == WandSignature);
2060   if (wand->debug != MagickFalse)
2061     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2062   return(CurrentContext->linejoin);
2063 }
2064 \f
2065 /*
2066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2067 %                                                                             %
2068 %                                                                             %
2069 %                                                                             %
2070 %   D r a w G e t S t r o k e M i t e r L i m i t                             %
2071 %                                                                             %
2072 %                                                                             %
2073 %                                                                             %
2074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2075 %
2076 %  DrawGetStrokeMiterLimit() returns the miter limit. When two line
2077 %  segments meet at a sharp angle and miter joins have been specified for
2078 %  'lineJoin', it is possible for the miter to extend far beyond the
2079 %  thickness of the line stroking the path. The miterLimit' imposes a
2080 %  limit on the ratio of the miter length to the 'lineWidth'.
2081 %
2082 %  The format of the DrawGetStrokeMiterLimit method is:
2083 %
2084 %      size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2085 %
2086 %  A description of each parameter follows:
2087 %
2088 %    o wand: the drawing wand.
2089 %
2090 */
2091 WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2092 {
2093   assert(wand != (const DrawingWand *) NULL);
2094   assert(wand->signature == WandSignature);
2095   if (wand->debug != MagickFalse)
2096     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2097   return CurrentContext->miterlimit;
2098 }
2099 \f
2100 /*
2101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2102 %                                                                             %
2103 %                                                                             %
2104 %                                                                             %
2105 %   D r a w G e t S t r o k e O p a c i t y                                   %
2106 %                                                                             %
2107 %                                                                             %
2108 %                                                                             %
2109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2110 %
2111 %  DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
2112 %
2113 %  The format of the DrawGetStrokeOpacity method is:
2114 %
2115 %      double DrawGetStrokeOpacity(const DrawingWand *wand)
2116 %
2117 %  A description of each parameter follows:
2118 %
2119 %    o wand: the drawing wand.
2120 %
2121 */
2122 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2123 {
2124   double
2125     alpha;
2126
2127   assert(wand != (const DrawingWand *) NULL);
2128   assert(wand->signature == WandSignature);
2129   if (wand->debug != MagickFalse)
2130     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2131   alpha=(double) QuantumScale*CurrentContext->stroke.alpha;
2132   return(alpha);
2133 }
2134 \f
2135 /*
2136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2137 %                                                                             %
2138 %                                                                             %
2139 %                                                                             %
2140 %   D r a w G e t S t r o k e W i d t h                                       %
2141 %                                                                             %
2142 %                                                                             %
2143 %                                                                             %
2144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2145 %
2146 %  DrawGetStrokeWidth() returns the width of the stroke used to draw object
2147 %  outlines.
2148 %
2149 %  The format of the DrawGetStrokeWidth method is:
2150 %
2151 %      double DrawGetStrokeWidth(const DrawingWand *wand)
2152 %
2153 %  A description of each parameter follows:
2154 %
2155 %    o wand: the drawing wand.
2156 %
2157 */
2158 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2159 {
2160   assert(wand != (const DrawingWand *) NULL);
2161   assert(wand->signature == WandSignature);
2162   if (wand->debug != MagickFalse)
2163     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2164   return(CurrentContext->stroke_width);
2165 }
2166 \f
2167 /*
2168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2169 %                                                                             %
2170 %                                                                             %
2171 %                                                                             %
2172 %   D r a w G e t T e x t A l i g n m e n t                                   %
2173 %                                                                             %
2174 %                                                                             %
2175 %                                                                             %
2176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2177 %
2178 %  DrawGetTextAlignment() returns the alignment applied when annotating with
2179 %  text.
2180 %
2181 %  The format of the DrawGetTextAlignment method is:
2182 %
2183 %      AlignType DrawGetTextAlignment(DrawingWand *wand)
2184 %
2185 %  A description of each parameter follows:
2186 %
2187 %    o wand: the drawing wand.
2188 %
2189 */
2190 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2191 {
2192   assert(wand != (const DrawingWand *) NULL);
2193   assert(wand->signature == WandSignature);
2194   if (wand->debug != MagickFalse)
2195     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2196   return(CurrentContext->align);
2197 }
2198 \f
2199 /*
2200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2201 %                                                                             %
2202 %                                                                             %
2203 %                                                                             %
2204 %   D r a w G e t T e x t A n t i a l i a s                                   %
2205 %                                                                             %
2206 %                                                                             %
2207 %                                                                             %
2208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2209 %
2210 %  DrawGetTextAntialias() returns the current text antialias setting, which
2211 %  determines whether text is antialiased.  Text is antialiased by default.
2212 %
2213 %  The format of the DrawGetTextAntialias method is:
2214 %
2215 %      MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2216 %
2217 %  A description of each parameter follows:
2218 %
2219 %    o wand: the drawing wand.
2220 %
2221 */
2222 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2223 {
2224   assert(wand != (const DrawingWand *) NULL);
2225   assert(wand->signature == WandSignature);
2226   if (wand->debug != MagickFalse)
2227     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2228   return(CurrentContext->text_antialias);
2229 }
2230 \f
2231 /*
2232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2233 %                                                                             %
2234 %                                                                             %
2235 %                                                                             %
2236 %   D r a w G e t T e x t D e c o r a t i o n                                 %
2237 %                                                                             %
2238 %                                                                             %
2239 %                                                                             %
2240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2241 %
2242 %  DrawGetTextDecoration() returns the decoration applied when annotating with
2243 %  text.
2244 %
2245 %  The format of the DrawGetTextDecoration method is:
2246 %
2247 %      DecorationType DrawGetTextDecoration(DrawingWand *wand)
2248 %
2249 %  A description of each parameter follows:
2250 %
2251 %    o wand: the drawing wand.
2252 %
2253 */
2254 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2255 {
2256   assert(wand != (const DrawingWand *) NULL);
2257   assert(wand->signature == WandSignature);
2258   if (wand->debug != MagickFalse)
2259     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2260   return(CurrentContext->decorate);
2261 }
2262 \f
2263 /*
2264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2265 %                                                                             %
2266 %                                                                             %
2267 %                                                                             %
2268 %   D r a w G e t T e x t E n c o d i n g                                     %
2269 %                                                                             %
2270 %                                                                             %
2271 %                                                                             %
2272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2273 %
2274 %  DrawGetTextEncoding() returns a null-terminated string which specifies the
2275 %  code set used for text annotations. The string must be freed by the user
2276 %  once it is no longer required.
2277 %
2278 %  The format of the DrawGetTextEncoding method is:
2279 %
2280 %      char *DrawGetTextEncoding(const DrawingWand *wand)
2281 %
2282 %  A description of each parameter follows:
2283 %
2284 %    o wand: the drawing wand.
2285 %
2286 */
2287 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2288 {
2289   assert(wand != (const DrawingWand *) NULL);
2290   assert(wand->signature == WandSignature);
2291   if (wand->debug != MagickFalse)
2292     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2293   if (CurrentContext->encoding != (char *) NULL)
2294     return((char *) AcquireString(CurrentContext->encoding));
2295   return((char *) NULL);
2296 }
2297 \f
2298 /*
2299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2300 %                                                                             %
2301 %                                                                             %
2302 %                                                                             %
2303 %   D r a w G e t T e x t K e r n i n g                                       %
2304 %                                                                             %
2305 %                                                                             %
2306 %                                                                             %
2307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2308 %
2309 %  DrawGetTextKerning() gets the spacing between characters in text.
2310 %
2311 %  The format of the DrawSetFontKerning method is:
2312 %
2313 %      double DrawGetTextKerning(DrawingWand *wand)
2314 %
2315 %  A description of each parameter follows:
2316 %
2317 %    o wand: the drawing wand.
2318 %
2319 */
2320 WandExport double DrawGetTextKerning(DrawingWand *wand)
2321 {
2322   assert(wand != (DrawingWand *) NULL);
2323   assert(wand->signature == WandSignature);
2324
2325   if (wand->debug != MagickFalse)
2326     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2327   return(CurrentContext->kerning);
2328 }
2329 \f
2330 /*
2331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2332 %                                                                             %
2333 %                                                                             %
2334 %                                                                             %
2335 %   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                     %
2336 %                                                                             %
2337 %                                                                             %
2338 %                                                                             %
2339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2340 %
2341 %  DrawGetTextInterwordSpacing() gets the spacing between lines in text.
2342 %
2343 %  The format of the DrawSetFontKerning method is:
2344 %
2345 %      double DrawGetTextInterwordSpacing(DrawingWand *wand)
2346 %
2347 %  A description of each parameter follows:
2348 %
2349 %    o wand: the drawing wand.
2350 %
2351 */
2352 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2353 {
2354   assert(wand != (DrawingWand *) NULL);
2355   assert(wand->signature == WandSignature);
2356   if (wand->debug != MagickFalse)
2357     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2358   return(CurrentContext->interline_spacing);
2359 }
2360 \f
2361 /*
2362 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2363 %                                                                             %
2364 %                                                                             %
2365 %                                                                             %
2366 %   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                     %
2367 %                                                                             %
2368 %                                                                             %
2369 %                                                                             %
2370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2371 %
2372 %  DrawGetTextInterwordSpacing() gets the spacing between words in text.
2373 %
2374 %  The format of the DrawSetFontKerning method is:
2375 %
2376 %      double DrawGetTextInterwordSpacing(DrawingWand *wand)
2377 %
2378 %  A description of each parameter follows:
2379 %
2380 %    o wand: the drawing wand.
2381 %
2382 */
2383 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2384 {
2385   assert(wand != (DrawingWand *) NULL);
2386   assert(wand->signature == WandSignature);
2387   if (wand->debug != MagickFalse)
2388     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2389   return(CurrentContext->interword_spacing);
2390 }
2391 \f
2392 /*
2393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2394 %                                                                             %
2395 %                                                                             %
2396 %                                                                             %
2397 %   D r a w G e t V e c t o r G r a p h i c s                                 %
2398 %                                                                             %
2399 %                                                                             %
2400 %                                                                             %
2401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2402 %
2403 %  DrawGetVectorGraphics() returns a null-terminated string which specifies the
2404 %  vector graphics generated by any graphics calls made since the wand was
2405 %  instantiated.  The string must be freed by the user once it is no longer
2406 %  required.
2407 %
2408 %  The format of the DrawGetVectorGraphics method is:
2409 %
2410 %      char *DrawGetVectorGraphics(const DrawingWand *wand)
2411 %
2412 %  A description of each parameter follows:
2413 %
2414 %    o wand: the drawing wand.
2415 %
2416 */
2417 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2418 {
2419   char
2420     value[MaxTextExtent],
2421     *xml;
2422
2423   PixelInfo
2424     pixel;
2425
2426   register ssize_t
2427     i;
2428
2429   XMLTreeInfo
2430     *child,
2431     *xml_info;
2432
2433   assert(wand != (const DrawingWand *) NULL);
2434   assert(wand->signature == WandSignature);
2435   if (wand->debug != MagickFalse)
2436     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2437   xml_info=NewXMLTreeTag("drawing-wand");
2438   if (xml_info == (XMLTreeInfo *) NULL)
2439     return(char *) NULL;
2440   GetPixelInfo(wand->image,&pixel);
2441   child=AddChildToXMLTree(xml_info,"clip-path",0);
2442   if (child != (XMLTreeInfo *) NULL)
2443     (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2444   child=AddChildToXMLTree(xml_info,"clip-units",0);
2445   if (child != (XMLTreeInfo *) NULL)
2446     {
2447       (void) CopyMagickString(value,CommandOptionToMnemonic(
2448         MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),
2449         MaxTextExtent);
2450       (void) SetXMLTreeContent(child,value);
2451     }
2452   child=AddChildToXMLTree(xml_info,"decorate",0);
2453   if (child != (XMLTreeInfo *) NULL)
2454     {
2455       (void) CopyMagickString(value,CommandOptionToMnemonic(
2456         MagickDecorateOptions,(ssize_t) CurrentContext->decorate),
2457         MaxTextExtent);
2458       (void) SetXMLTreeContent(child,value);
2459     }
2460   child=AddChildToXMLTree(xml_info,"encoding",0);
2461   if (child != (XMLTreeInfo *) NULL)
2462     (void) SetXMLTreeContent(child,CurrentContext->encoding);
2463   child=AddChildToXMLTree(xml_info,"fill",0);
2464   if (child != (XMLTreeInfo *) NULL)
2465     {
2466       if (CurrentContext->fill.alpha != OpaqueAlpha)
2467         pixel.matte=CurrentContext->fill.alpha != OpaqueAlpha ?
2468           MagickTrue : MagickFalse;
2469       SetPixelInfoPacket(wand->image,&CurrentContext->fill,&pixel);
2470       GetColorTuple(&pixel,MagickTrue,value);
2471       (void) SetXMLTreeContent(child,value);
2472     }
2473   child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2474   if (child != (XMLTreeInfo *) NULL)
2475     {
2476       (void) FormatLocaleString(value,MaxTextExtent,"%g",
2477         (double) QuantumScale*CurrentContext->fill.alpha);
2478       (void) SetXMLTreeContent(child,value);
2479     }
2480   child=AddChildToXMLTree(xml_info,"fill-rule",0);
2481   if (child != (XMLTreeInfo *) NULL)
2482     {
2483       (void) CopyMagickString(value,CommandOptionToMnemonic(
2484         MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),
2485         MaxTextExtent);
2486       (void) SetXMLTreeContent(child,value);
2487     }
2488   child=AddChildToXMLTree(xml_info,"font",0);
2489   if (child != (XMLTreeInfo *) NULL)
2490     (void) SetXMLTreeContent(child,CurrentContext->font);
2491   child=AddChildToXMLTree(xml_info,"font-family",0);
2492   if (child != (XMLTreeInfo *) NULL)
2493     (void) SetXMLTreeContent(child,CurrentContext->family);
2494   child=AddChildToXMLTree(xml_info,"font-size",0);
2495   if (child != (XMLTreeInfo *) NULL)
2496     {
2497       (void) FormatLocaleString(value,MaxTextExtent,"%g",
2498         CurrentContext->pointsize);
2499       (void) SetXMLTreeContent(child,value);
2500     }
2501   child=AddChildToXMLTree(xml_info,"font-stretch",0);
2502   if (child != (XMLTreeInfo *) NULL)
2503     {
2504       (void) CopyMagickString(value,CommandOptionToMnemonic(
2505         MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
2506       (void) SetXMLTreeContent(child,value);
2507     }
2508   child=AddChildToXMLTree(xml_info,"font-style",0);
2509   if (child != (XMLTreeInfo *) NULL)
2510     {
2511       (void) CopyMagickString(value,CommandOptionToMnemonic(
2512         MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
2513       (void) SetXMLTreeContent(child,value);
2514     }
2515   child=AddChildToXMLTree(xml_info,"font-weight",0);
2516   if (child != (XMLTreeInfo *) NULL)
2517     {
2518       (void) FormatLocaleString(value,MaxTextExtent,"%.20g",(double)
2519         CurrentContext->weight);
2520       (void) SetXMLTreeContent(child,value);
2521     }
2522   child=AddChildToXMLTree(xml_info,"gravity",0);
2523   if (child != (XMLTreeInfo *) NULL)
2524     {
2525       (void) CopyMagickString(value,CommandOptionToMnemonic(
2526         MagickGravityOptions,(ssize_t) CurrentContext->gravity),MaxTextExtent);
2527       (void) SetXMLTreeContent(child,value);
2528     }
2529   child=AddChildToXMLTree(xml_info,"stroke",0);
2530   if (child != (XMLTreeInfo *) NULL)
2531     {
2532       if (CurrentContext->stroke.alpha != OpaqueAlpha)
2533         pixel.matte=CurrentContext->stroke.alpha != OpaqueAlpha ?
2534           MagickTrue : MagickFalse;
2535       SetPixelInfoPacket(wand->image,&CurrentContext->stroke,&pixel);
2536       GetColorTuple(&pixel,MagickTrue,value);
2537       (void) SetXMLTreeContent(child,value);
2538     }
2539   child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2540   if (child != (XMLTreeInfo *) NULL)
2541     {
2542       (void) FormatLocaleString(value,MaxTextExtent,"%d",
2543         CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2544       (void) SetXMLTreeContent(child,value);
2545     }
2546   child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2547   if ((child != (XMLTreeInfo *) NULL) &&
2548       (CurrentContext->dash_pattern != (double *) NULL))
2549     {
2550       char
2551         *dash_pattern;
2552
2553       dash_pattern=AcquireString((char *) NULL);
2554       for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++)
2555       {
2556         if (i != 0)
2557           (void) ConcatenateString(&dash_pattern,",");
2558         (void) FormatLocaleString(value,MaxTextExtent,"%g",
2559           CurrentContext->dash_pattern[i]);
2560         (void) ConcatenateString(&dash_pattern,value);
2561       }
2562       (void) SetXMLTreeContent(child,dash_pattern);
2563       dash_pattern=DestroyString(dash_pattern);
2564     }
2565   child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2566   if (child != (XMLTreeInfo *) NULL)
2567     {
2568       (void) FormatLocaleString(value,MaxTextExtent,"%g",
2569         CurrentContext->dash_offset);
2570       (void) SetXMLTreeContent(child,value);
2571     }
2572   child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2573   if (child != (XMLTreeInfo *) NULL)
2574     {
2575       (void) CopyMagickString(value,CommandOptionToMnemonic(MagickLineCapOptions,
2576         (ssize_t) CurrentContext->linecap),MaxTextExtent);
2577       (void) SetXMLTreeContent(child,value);
2578     }
2579   child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2580   if (child != (XMLTreeInfo *) NULL)
2581     {
2582       (void) CopyMagickString(value,CommandOptionToMnemonic(
2583         MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2584         MaxTextExtent);
2585       (void) SetXMLTreeContent(child,value);
2586     }
2587   child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2588   if (child != (XMLTreeInfo *) NULL)
2589     {
2590       (void) FormatLocaleString(value,MaxTextExtent,"%.20g",(double)
2591         CurrentContext->miterlimit);
2592       (void) SetXMLTreeContent(child,value);
2593     }
2594   child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2595   if (child != (XMLTreeInfo *) NULL)
2596     {
2597       (void) FormatLocaleString(value,MaxTextExtent,"%g",
2598         (double) QuantumScale*CurrentContext->stroke.alpha);
2599       (void) SetXMLTreeContent(child,value);
2600     }
2601   child=AddChildToXMLTree(xml_info,"stroke-width",0);
2602   if (child != (XMLTreeInfo *) NULL)
2603     {
2604       (void) FormatLocaleString(value,MaxTextExtent,"%g",
2605         CurrentContext->stroke_width);
2606       (void) SetXMLTreeContent(child,value);
2607     }
2608   child=AddChildToXMLTree(xml_info,"text-align",0);
2609   if (child != (XMLTreeInfo *) NULL)
2610     {
2611       (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
2612         (ssize_t) CurrentContext->align),MaxTextExtent);
2613       (void) SetXMLTreeContent(child,value);
2614     }
2615   child=AddChildToXMLTree(xml_info,"text-antialias",0);
2616   if (child != (XMLTreeInfo *) NULL)
2617     {
2618       (void) FormatLocaleString(value,MaxTextExtent,"%d",
2619         CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2620       (void) SetXMLTreeContent(child,value);
2621     }
2622   child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2623   if (child != (XMLTreeInfo *) NULL)
2624     {
2625       if (CurrentContext->undercolor.alpha != OpaqueAlpha)
2626         pixel.matte=CurrentContext->undercolor.alpha != OpaqueAlpha ?
2627           MagickTrue : MagickFalse;
2628       SetPixelInfoPacket(wand->image,&CurrentContext->undercolor,&pixel);
2629       GetColorTuple(&pixel,MagickTrue,value);
2630       (void) SetXMLTreeContent(child,value);
2631     }
2632   child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2633   if (child != (XMLTreeInfo *) NULL)
2634     (void) SetXMLTreeContent(child,wand->mvg);
2635   xml=XMLTreeInfoToXML(xml_info);
2636   xml_info=DestroyXMLTree(xml_info);
2637   return(xml);
2638 }
2639 \f
2640 /*
2641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2642 %                                                                             %
2643 %                                                                             %
2644 %                                                                             %
2645 %   D r a w G e t T e x t U n d e r C o l o r                                 %
2646 %                                                                             %
2647 %                                                                             %
2648 %                                                                             %
2649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2650 %
2651 %  DrawGetTextUnderColor() returns the color of a background rectangle
2652 %  to place under text annotations.
2653 %
2654 %  The format of the DrawGetTextUnderColor method is:
2655 %
2656 %      void DrawGetTextUnderColor(const DrawingWand *wand,
2657 %        PixelWand *under_color)
2658 %
2659 %  A description of each parameter follows:
2660 %
2661 %    o wand: the drawing wand.
2662 %
2663 %    o under_color: Return the under color.
2664 %
2665 */
2666 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2667   PixelWand *under_color)
2668 {
2669   assert(wand != (const DrawingWand *) NULL);
2670   assert(wand->signature == WandSignature);
2671   assert(under_color != (PixelWand *) NULL);
2672   if (wand->debug != MagickFalse)
2673     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2674   PixelSetQuantumPacket(under_color,&CurrentContext->undercolor);
2675 }
2676 \f
2677 /*
2678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2679 %                                                                             %
2680 %                                                                             %
2681 %                                                                             %
2682 %   D r a w L i n e                                                           %
2683 %                                                                             %
2684 %                                                                             %
2685 %                                                                             %
2686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2687 %
2688 %  DrawLine() draws a line on the image using the current stroke color,
2689 %  stroke opacity, and stroke width.
2690 %
2691 %  The format of the DrawLine method is:
2692 %
2693 %      void DrawLine(DrawingWand *wand,const double sx,const double sy,
2694 %        const double ex,const double ey)
2695 %
2696 %  A description of each parameter follows:
2697 %
2698 %    o wand: the drawing wand.
2699 %
2700 %    o sx: starting x ordinate
2701 %
2702 %    o sy: starting y ordinate
2703 %
2704 %    o ex: ending x ordinate
2705 %
2706 %    o ey: ending y ordinate
2707 %
2708 */
2709 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2710   const double ex,const double ey)
2711 {
2712   assert(wand != (DrawingWand *) NULL);
2713   assert(wand->signature == WandSignature);
2714   if (wand->debug != MagickFalse)
2715     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2716   (void) MvgPrintf(wand,"line %g %g %g %g\n",sx,sy,ex,ey);
2717 }
2718 \f
2719 /*
2720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2721 %                                                                             %
2722 %                                                                             %
2723 %                                                                             %
2724 %   D r a w M a t t e                                                         %
2725 %                                                                             %
2726 %                                                                             %
2727 %                                                                             %
2728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2729 %
2730 %  DrawMatte() paints on the image's opacity channel in order to set effected
2731 %  pixels to transparent.
2732 %  to influence the opacity of pixels. The available paint
2733 %  methods are:
2734 %
2735 %    PointMethod: Select the target pixel
2736 %    ReplaceMethod: Select any pixel that matches the target pixel.
2737 %    FloodfillMethod: Select the target pixel and matching neighbors.
2738 %    FillToBorderMethod: Select the target pixel and neighbors not matching
2739 %      border color.
2740 %    ResetMethod: Select all pixels.
2741 %
2742 %  The format of the DrawMatte method is:
2743 %
2744 %      void DrawMatte(DrawingWand *wand,const double x,const double y,
2745 %        const PaintMethod paint_method)
2746 %
2747 %  A description of each parameter follows:
2748 %
2749 %    o wand: the drawing wand.
2750 %
2751 %    o x: x ordinate
2752 %
2753 %    o y: y ordinate
2754 %
2755 %    o paint_method: paint method.
2756 %
2757 */
2758 WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2759   const PaintMethod paint_method)
2760 {
2761   assert(wand != (DrawingWand *) NULL);
2762   assert(wand->signature == WandSignature);
2763   if (wand->debug != MagickFalse)
2764     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2765   (void) MvgPrintf(wand,"matte %g %g '%s'\n",x,y,CommandOptionToMnemonic(
2766     MagickMethodOptions,(ssize_t) paint_method));
2767 }
2768 \f
2769 /*
2770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2771 %                                                                             %
2772 %                                                                             %
2773 %                                                                             %
2774 %   D r a w P a t h C l o s e                                                 %
2775 %                                                                             %
2776 %                                                                             %
2777 %                                                                             %
2778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2779 %
2780 %  DrawPathClose() adds a path element to the current path which closes the
2781 %  current subpath by drawing a straight line from the current point to the
2782 %  current subpath's most recent starting point (usually, the most recent
2783 %  moveto point).
2784 %
2785 %  The format of the DrawPathClose method is:
2786 %
2787 %      void DrawPathClose(DrawingWand *wand)
2788 %
2789 %  A description of each parameter follows:
2790 %
2791 %    o wand: the drawing wand.
2792 %
2793 */
2794 WandExport void DrawPathClose(DrawingWand *wand)
2795 {
2796   assert(wand != (DrawingWand *) NULL);
2797   assert(wand->signature == WandSignature);
2798   if (wand->debug != MagickFalse)
2799     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2800   (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2801     "Z" : "z");
2802 }
2803 \f
2804 /*
2805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2806 %                                                                             %
2807 %                                                                             %
2808 %                                                                             %
2809 %   D r a w P a t h C u r v e T o A b s o l u t e                             %
2810 %                                                                             %
2811 %                                                                             %
2812 %                                                                             %
2813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2814 %
2815 %  DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2816 %  point to (x,y) using (x1,y1) as the control point at the beginning of
2817 %  the curve and (x2,y2) as the control point at the end of the curve using
2818 %  absolute coordinates. At the end of the command, the new current point
2819 %  becomes the final (x,y) coordinate pair used in the polybezier.
2820 %
2821 %  The format of the DrawPathCurveToAbsolute method is:
2822 %
2823 %      void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2824 %        const double y1,const double x2,const double y2,const double x,
2825 %        const double y)
2826 %
2827 %  A description of each parameter follows:
2828 %
2829 %    o wand: the drawing wand.
2830 %
2831 %    o x1: x ordinate of control point for curve beginning
2832 %
2833 %    o y1: y ordinate of control point for curve beginning
2834 %
2835 %    o x2: x ordinate of control point for curve ending
2836 %
2837 %    o y2: y ordinate of control point for curve ending
2838 %
2839 %    o x: x ordinate of the end of the curve
2840 %
2841 %    o y: y ordinate of the end of the curve
2842 %
2843 */
2844
2845 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2846   const double x1,const double y1,const double x2,const double y2,
2847   const double x,const double y)
2848 {
2849   assert(wand != (DrawingWand *) NULL);
2850   assert(wand->signature == WandSignature);
2851   if (wand->debug != MagickFalse)
2852     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2853   if ((wand->path_operation != PathCurveToOperation) ||
2854       (wand->path_mode != mode))
2855     {
2856       wand->path_operation=PathCurveToOperation;
2857       wand->path_mode=mode;
2858       (void) MvgAutoWrapPrintf(wand, "%c%g %g %g %g %g %g",
2859         mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2860     }
2861   else
2862     (void) MvgAutoWrapPrintf(wand," %g %g %g %g %g %g",x1,y1,
2863       x2,y2,x,y);
2864 }
2865
2866 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2867   const double y1,const double x2,const double y2,const double x,const double y)
2868 {
2869   assert(wand != (DrawingWand *) NULL);
2870   assert(wand->signature == WandSignature);
2871   if (wand->debug != MagickFalse)
2872     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2873   DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2874 }
2875 \f
2876 /*
2877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2878 %                                                                             %
2879 %                                                                             %
2880 %                                                                             %
2881 %   D r a w P a t h C u r v e T o R e l a t i v e                             %
2882 %                                                                             %
2883 %                                                                             %
2884 %                                                                             %
2885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2886 %
2887 %  DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2888 %  point to (x,y) using (x1,y1) as the control point at the beginning of
2889 %  the curve and (x2,y2) as the control point at the end of the curve using
2890 %  relative coordinates. At the end of the command, the new current point
2891 %  becomes the final (x,y) coordinate pair used in the polybezier.
2892 %
2893 %  The format of the DrawPathCurveToRelative method is:
2894 %
2895 %      void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2896 %        const double y1,const double x2,const double y2,const double x,
2897 %        const double y)
2898 %
2899 %  A description of each parameter follows:
2900 %
2901 %    o wand: the drawing wand.
2902 %
2903 %    o x1: x ordinate of control point for curve beginning
2904 %
2905 %    o y1: y ordinate of control point for curve beginning
2906 %
2907 %    o x2: x ordinate of control point for curve ending
2908 %
2909 %    o y2: y ordinate of control point for curve ending
2910 %
2911 %    o x: x ordinate of the end of the curve
2912 %
2913 %    o y: y ordinate of the end of the curve
2914 %
2915 */
2916 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2917   const double y1,const double x2,const double y2,const double x,const double y)
2918 {
2919   assert(wand != (DrawingWand *) NULL);
2920   assert(wand->signature == WandSignature);
2921   if (wand->debug != MagickFalse)
2922     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2923   DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2924 }
2925 \f
2926 /*
2927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2928 %                                                                             %
2929 %                                                                             %
2930 %                                                                             %
2931 %   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 %
2932 %                                                                             %
2933 %                                                                             %
2934 %                                                                             %
2935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2936 %
2937 %  DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2938 %  from the current point to (x,y) using (x1,y1) as the control point using
2939 %  absolute coordinates. At the end of the command, the new current point
2940 %  becomes the final (x,y) coordinate pair used in the polybezier.
2941 %
2942 %  The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2943 %
2944 %      void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2945 %        const double x1,const double y1,onst double x,const double y)
2946 %
2947 %  A description of each parameter follows:
2948 %
2949 %    o wand: the drawing wand.
2950 %
2951 %    o x1: x ordinate of the control point
2952 %
2953 %    o y1: y ordinate of the control point
2954 %
2955 %    o x: x ordinate of final point
2956 %
2957 %    o y: y ordinate of final point
2958 %
2959 */
2960
2961 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2962   const PathMode mode,const double x1,double y1,const double x,const double y)
2963 {
2964   assert(wand != (DrawingWand *) NULL);
2965   assert(wand->signature == WandSignature);
2966   if (wand->debug != MagickFalse)
2967     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2968   if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2969       (wand->path_mode != mode))
2970     {
2971       wand->path_operation=PathCurveToQuadraticBezierOperation;
2972       wand->path_mode=mode;
2973       (void) MvgAutoWrapPrintf(wand, "%c%g %g %g %g",
2974          mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
2975     }
2976   else
2977     (void) MvgAutoWrapPrintf(wand," %g %g %g %g",x1,y1,x,y);
2978 }
2979
2980 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2981   const double x1,const double y1,const double x,const double y)
2982 {
2983   assert(wand != (DrawingWand *) NULL);
2984   assert(wand->signature == WandSignature);
2985   if (wand->debug != MagickFalse)
2986     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2987   DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
2988 }
2989 \f
2990 /*
2991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2992 %                                                                             %
2993 %                                                                             %
2994 %                                                                             %
2995 %   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
2996 %                                                                             %
2997 %                                                                             %
2998 %                                                                             %
2999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3000 %
3001 %  DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
3002 %  from the current point to (x,y) using (x1,y1) as the control point using
3003 %  relative coordinates. At the end of the command, the new current point
3004 %  becomes the final (x,y) coordinate pair used in the polybezier.
3005 %
3006 %  The format of the DrawPathCurveToQuadraticBezierRelative method is:
3007 %
3008 %      void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3009 %        const double x1,const double y1,const double x,const double y)
3010 %
3011 %  A description of each parameter follows:
3012 %
3013 %    o wand: the drawing wand.
3014 %
3015 %    o x1: x ordinate of the control point
3016 %
3017 %    o y1: y ordinate of the control point
3018 %
3019 %    o x: x ordinate of final point
3020 %
3021 %    o y: y ordinate of final point
3022 %
3023 */
3024 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3025   const double x1,const double y1,const double x,const double y)
3026 {
3027   assert(wand != (DrawingWand *) NULL);
3028   assert(wand->signature == WandSignature);
3029   if (wand->debug != MagickFalse)
3030     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3031   DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
3032 }
3033 \f
3034 /*
3035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3036 %                                                                             %
3037 %                                                                             %
3038 %                                                                             %
3039 %   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   %
3040 %                                                                             %
3041 %                                                                             %
3042 %                                                                             %
3043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3044 %
3045 %  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3046 %  Bezier curve (using absolute coordinates) from the current point to
3047 %  (x,y). The control point is assumed to be the reflection of the
3048 %  control point on the previous command relative to the current
3049 %  point. (If there is no previous command or if the previous command was
3050 %  not a DrawPathCurveToQuadraticBezierAbsolute,
3051 %  DrawPathCurveToQuadraticBezierRelative,
3052 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
3053 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3054 %  is coincident with the current point.). At the end of the command, the
3055 %  new current point becomes the final (x,y) coordinate pair used in the
3056 %  polybezier.
3057 %
3058 %  The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3059 %
3060 %      void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3061 %        DrawingWand *wand,const double x,const double y)
3062 %
3063 %  A description of each parameter follows:
3064 %
3065 %    o wand: the drawing wand.
3066 %
3067 %    o x: x ordinate of final point
3068 %
3069 %    o y: y ordinate of final point
3070 %
3071 */
3072
3073 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3074   const PathMode mode,const double x,const double y)
3075 {
3076   assert(wand != (DrawingWand *) NULL);
3077   assert(wand->signature == WandSignature);
3078   if (wand->debug != MagickFalse)
3079     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3080   if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3081       (wand->path_mode != mode))
3082     {
3083       wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3084       wand->path_mode=mode;
3085       (void) MvgAutoWrapPrintf(wand,"%c%g %g",mode == AbsolutePathMode ?
3086         'T' : 't',x,y);
3087     }
3088   else
3089     (void) MvgAutoWrapPrintf(wand," %g %g",x,y);
3090 }
3091
3092 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3093   const double x,const double y)
3094 {
3095   assert(wand != (DrawingWand *) NULL);
3096   assert(wand->signature == WandSignature);
3097   if (wand->debug != MagickFalse)
3098     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3099   DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3100 }
3101 \f
3102 /*
3103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3104 %                                                                             %
3105 %                                                                             %
3106 %                                                                             %
3107 %   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   %
3108 %                                                                             %
3109 %                                                                             %
3110 %                                                                             %
3111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3112 %
3113 %  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3114 %  curve (using relative coordinates) from the current point to (x,y). The
3115 %  control point is assumed to be the reflection of the control point on the
3116 %  previous command relative to the current point. (If there is no previous
3117 %  command or if the previous command was not a
3118 %  DrawPathCurveToQuadraticBezierAbsolute,
3119 %  DrawPathCurveToQuadraticBezierRelative,
3120 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
3121 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3122 %  coincident with the current point.). At the end of the command, the new
3123 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
3124 %
3125 %  The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3126 %
3127 %      void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3128 %        const double x,const double y)
3129 %
3130 %  A description of each parameter follows:
3131 %
3132 %    o wand: the drawing wand.
3133 %
3134 %    o x: x ordinate of final point
3135 %
3136 %    o y: y ordinate of final point
3137 %
3138 */
3139 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3140   const double x,const double y)
3141 {
3142   DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3143 }
3144 \f
3145 /*
3146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3147 %                                                                             %
3148 %                                                                             %
3149 %                                                                             %
3150 %   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                 %
3151 %                                                                             %
3152 %                                                                             %
3153 %                                                                             %
3154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3155 %
3156 %  DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3157 %  current point to (x,y) using absolute coordinates. The first control
3158 %  point is assumed to be the reflection of the second control point on
3159 %  the previous command relative to the current point. (If there is no
3160 %  previous command or if the previous command was not an
3161 %  DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3162 %  DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3163 %  the first control point is coincident with the current point.) (x2,y2)
3164 %  is the second control point (i.e., the control point at the end of the
3165 %  curve). At the end of the command, the new current point becomes the
3166 %  final (x,y) coordinate pair used in the polybezier.
3167 %
3168 %  The format of the DrawPathCurveToSmoothAbsolute method is:
3169 %
3170 %      void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3171 %        const double x2const double y2,const double x,const double y)
3172 %
3173 %  A description of each parameter follows:
3174 %
3175 %    o wand: the drawing wand.
3176 %
3177 %    o x2: x ordinate of second control point
3178 %
3179 %    o y2: y ordinate of second control point
3180 %
3181 %    o x: x ordinate of termination point
3182 %
3183 %    o y: y ordinate of termination point
3184 %
3185 */
3186
3187 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3188   const double x2,const double y2,const double x,const double y)
3189 {
3190   assert(wand != (DrawingWand *) NULL);
3191   assert(wand->signature == WandSignature);
3192   if (wand->debug != MagickFalse)
3193     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3194   if ((wand->path_operation != PathCurveToSmoothOperation) ||
3195       (wand->path_mode != mode))
3196     {
3197       wand->path_operation=PathCurveToSmoothOperation;
3198       wand->path_mode=mode;
3199       (void) MvgAutoWrapPrintf(wand,"%c%g %g %g %g",
3200         mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
3201     }
3202   else
3203     (void) MvgAutoWrapPrintf(wand," %g %g %g %g",x2,y2,x,y);
3204 }
3205
3206 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3207   const double y2,const double x,const double y)
3208 {
3209   assert(wand != (DrawingWand *) NULL);
3210   assert(wand->signature == WandSignature);
3211   if (wand->debug != MagickFalse)
3212     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3213   DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3214 }
3215 \f
3216 /*
3217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3218 %                                                                             %
3219 %                                                                             %
3220 %                                                                             %
3221 %   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                 %
3222 %                                                                             %
3223 %                                                                             %
3224 %                                                                             %
3225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3226 %
3227 %  DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3228 %  point to (x,y) using relative coordinates. The first control point is
3229 %  assumed to be the reflection of the second control point on the previous
3230 %  command relative to the current point. (If there is no previous command or
3231 %  if the previous command was not an DrawPathCurveToAbsolute,
3232 %  DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3233 %  DrawPathCurveToSmoothRelative, assume the first control point is coincident
3234 %  with the current point.) (x2,y2) is the second control point (i.e., the
3235 %  control point at the end of the curve). At the end of the command, the new
3236 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
3237 %
3238 %  The format of the DrawPathCurveToSmoothRelative method is:
3239 %
3240 %      void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3241 %        const double x2,const double y2,const double x,const double y)
3242 %
3243 %  A description of each parameter follows:
3244 %
3245 %    o wand: the drawing wand.
3246 %
3247 %    o x2: x ordinate of second control point
3248 %
3249 %    o y2: y ordinate of second control point
3250 %
3251 %    o x: x ordinate of termination point
3252 %
3253 %    o y: y ordinate of termination point
3254 %
3255 */
3256 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3257   const double y2,const double x,const double y)
3258 {
3259   assert(wand != (DrawingWand *) NULL);
3260   assert(wand->signature == WandSignature);
3261   if (wand->debug != MagickFalse)
3262     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3263   DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3264 }
3265 \f
3266 /*
3267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3268 %                                                                             %
3269 %                                                                             %
3270 %                                                                             %
3271 %   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                     %
3272 %                                                                             %
3273 %                                                                             %
3274 %                                                                             %
3275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3276 %
3277 %  DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3278 %  to (x, y) using absolute coordinates. The size and orientation of the
3279 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3280 %  indicates how the ellipse as a whole is rotated relative to the current
3281 %  coordinate system. The center (cx, cy) of the ellipse is calculated
3282 %  automagically to satisfy the constraints imposed by the other parameters.
3283 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
3284 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
3285 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
3286 %  clock-wise rotation.
3287 %
3288 %  The format of the DrawPathEllipticArcAbsolute method is:
3289 %
3290 %      void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3291 %        const double rx,const double ry,const double x_axis_rotation,
3292 %        const MagickBooleanType large_arc_flag,
3293 %        const MagickBooleanType sweep_flag,const double x,const double y)
3294 %
3295 %  A description of each parameter follows:
3296 %
3297 %    o wand: the drawing wand.
3298 %
3299 %    o rx: x radius
3300 %
3301 %    o ry: y radius
3302 %
3303 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
3304 %        relative to the current coordinate system
3305 %
3306 %    o large_arc_flag: If non-zero (true) then draw the larger of the
3307 %        available arcs
3308 %
3309 %    o sweep_flag: If non-zero (true) then draw the arc matching a
3310 %        clock-wise rotation
3311 %
3312 %
3313 */
3314
3315 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3316   const double rx,const double ry,const double x_axis_rotation,
3317   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3318   const double x,const double y)
3319 {
3320   assert(wand != (DrawingWand *) NULL);
3321   assert(wand->signature == WandSignature);
3322   if (wand->debug != MagickFalse)
3323     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3324   if ((wand->path_operation != PathEllipticArcOperation) ||
3325       (wand->path_mode != mode))
3326     {
3327       wand->path_operation=PathEllipticArcOperation;
3328       wand->path_mode=mode;
3329       (void) MvgAutoWrapPrintf(wand, "%c%g %g %g %u %u %g %g",
3330         mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3331         large_arc_flag,sweep_flag,x,y);
3332     }
3333   else
3334     (void) MvgAutoWrapPrintf(wand," %g %g %g %u %u %g %g",rx,ry,
3335       x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3336 }
3337
3338 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3339   const double ry,const double x_axis_rotation,
3340   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3341   const double x,const double y)
3342 {
3343   assert(wand != (DrawingWand *) NULL);
3344   assert(wand->signature == WandSignature);
3345   if (wand->debug != MagickFalse)
3346     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3347   DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3348     large_arc_flag,sweep_flag,x,y);
3349 }
3350 \f
3351 /*
3352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3353 %                                                                             %
3354 %                                                                             %
3355 %                                                                             %
3356 %   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                     %
3357 %                                                                             %
3358 %                                                                             %
3359 %                                                                             %
3360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3361 %
3362 %  DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3363 %  to (x, y) using relative coordinates. The size and orientation of the
3364 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3365 %  indicates how the ellipse as a whole is rotated relative to the current
3366 %  coordinate system. The center (cx, cy) of the ellipse is calculated
3367 %  automagically to satisfy the constraints imposed by the other parameters.
3368 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
3369 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
3370 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
3371 %  clock-wise rotation.
3372 %
3373 %  The format of the DrawPathEllipticArcRelative method is:
3374 %
3375 %      void DrawPathEllipticArcRelative(DrawingWand *wand,
3376 %        const double rx,const double ry,const double x_axis_rotation,
3377 %        const MagickBooleanType large_arc_flag,
3378 %        const MagickBooleanType sweep_flag,const double x,const double y)
3379 %
3380 %  A description of each parameter follows:
3381 %
3382 %    o wand: the drawing wand.
3383 %
3384 %    o rx: x radius
3385 %
3386 %    o ry: y radius
3387 %
3388 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
3389 %                       relative to the current coordinate system
3390 %
3391 %    o large_arc_flag: If non-zero (true) then draw the larger of the
3392 %                      available arcs
3393 %
3394 %    o sweep_flag: If non-zero (true) then draw the arc matching a
3395 %                  clock-wise rotation
3396 %
3397 */
3398 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3399   const double ry,const double x_axis_rotation,
3400   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3401   const double x,const double y)
3402 {
3403   DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3404     large_arc_flag,sweep_flag,x,y);
3405 }
3406 \f
3407 /*
3408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3409 %                                                                             %
3410 %                                                                             %
3411 %                                                                             %
3412 %   D r a w P a t h F i n i s h                                               %
3413 %                                                                             %
3414 %                                                                             %
3415 %                                                                             %
3416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3417 %
3418 %  DrawPathFinish() terminates the current path.
3419 %
3420 %  The format of the DrawPathFinish method is:
3421 %
3422 %      void DrawPathFinish(DrawingWand *wand)
3423 %
3424 %  A description of each parameter follows:
3425 %
3426 %    o wand: the drawing wand.
3427 %
3428 */
3429 WandExport void DrawPathFinish(DrawingWand *wand)
3430 {
3431   assert(wand != (DrawingWand *) NULL);
3432   assert(wand->signature == WandSignature);
3433   if (wand->debug != MagickFalse)
3434     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3435   (void) MvgPrintf(wand,"'\n");
3436   wand->path_operation=PathDefaultOperation;
3437   wand->path_mode=DefaultPathMode;
3438 }
3439 \f
3440 /*
3441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3442 %                                                                             %
3443 %                                                                             %
3444 %                                                                             %
3445 %   D r a w P a t h L i n e T o A b s o l u t e                               %
3446 %                                                                             %
3447 %                                                                             %
3448 %                                                                             %
3449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3450 %
3451 %  DrawPathLineToAbsolute() draws a line path from the current point to the
3452 %  given coordinate using absolute coordinates. The coordinate then becomes
3453 %  the new current point.
3454 %
3455 %  The format of the DrawPathLineToAbsolute method is:
3456 %
3457 %      void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3458 %        const double y)
3459 %
3460 %  A description of each parameter follows:
3461 %
3462 %    o wand: the drawing wand.
3463 %
3464 %    o x: target x ordinate
3465 %
3466 %    o y: target y ordinate
3467 %
3468 */
3469 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3470   const double x,const double y)
3471 {
3472   assert(wand != (DrawingWand *) NULL);
3473   assert(wand->signature == WandSignature);
3474   if (wand->debug != MagickFalse)
3475     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3476   if ((wand->path_operation != PathLineToOperation) ||
3477       (wand->path_mode != mode))
3478     {
3479       wand->path_operation=PathLineToOperation;
3480       wand->path_mode=mode;
3481       (void) MvgAutoWrapPrintf(wand,"%c%g %g",mode == AbsolutePathMode ?
3482         'L' : 'l',x,y);
3483     }
3484   else
3485     (void) MvgAutoWrapPrintf(wand," %g %g",x,y);
3486 }
3487
3488 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3489   const double y)
3490 {
3491   assert(wand != (DrawingWand *) NULL);
3492   assert(wand->signature == WandSignature);
3493   if (wand->debug != MagickFalse)
3494     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3495   DrawPathLineTo(wand,AbsolutePathMode,x,y);
3496 }
3497 \f
3498 /*
3499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3500 %                                                                             %
3501 %                                                                             %
3502 %                                                                             %
3503 %   D r a w P a t h L i n e T o R e l a t i v e                               %
3504 %                                                                             %
3505 %                                                                             %
3506 %                                                                             %
3507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3508 %
3509 %  DrawPathLineToRelative() draws a line path from the current point to the
3510 %  given coordinate using relative coordinates. The coordinate then becomes
3511 %  the new current point.
3512 %
3513 %  The format of the DrawPathLineToRelative method is:
3514 %
3515 %      void DrawPathLineToRelative(DrawingWand *wand,const double x,
3516 %        const double y)
3517 %
3518 %  A description of each parameter follows:
3519 %
3520 %    o wand: the drawing wand.
3521 %
3522 %    o x: target x ordinate
3523 %
3524 %    o y: target y ordinate
3525 %
3526 */
3527 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3528   const double y)
3529 {
3530   assert(wand != (DrawingWand *) NULL);
3531   assert(wand->signature == WandSignature);
3532   if (wand->debug != MagickFalse)
3533     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3534   DrawPathLineTo(wand,RelativePathMode,x,y);
3535 }
3536 \f
3537 /*
3538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3539 %                                                                             %
3540 %                                                                             %
3541 %                                                                             %
3542 %   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           %
3543 %                                                                             %
3544 %                                                                             %
3545 %                                                                             %
3546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3547 %
3548 %  DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3549 %  current point to the target point using absolute coordinates.  The target
3550 %  point then becomes the new current point.
3551 %
3552 %  The format of the DrawPathLineToHorizontalAbsolute method is:
3553 %
3554 %      void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3555 %        const PathMode mode,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   PixelPacket
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       (IsPixelPacketEquivalent(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   PixelPacket
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       (IsPixelPacketEquivalent(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 %  DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4716 %  color or fill texture.  Fully opaque is 1.0.
4717 %
4718 %  The format of the DrawSetFillOpacity method is:
4719 %
4720 %      void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4721 %
4722 %  A description of each parameter follows:
4723 %
4724 %    o wand: the drawing wand.
4725 %
4726 %    o fill_opacity: fill opacity
4727 %
4728 */
4729 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4730 {
4731   Quantum
4732     opacity;
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   opacity=ClampToQuantum((double) QuantumRange*(1.0-fill_opacity));
4739   if ((wand->filter_off != MagickFalse) ||
4740       (CurrentContext->fill.alpha != opacity))
4741     {
4742       CurrentContext->fill.alpha=opacity;
4743       (void) MvgPrintf(wand,"fill-opacity %g\n",fill_opacity);
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 %      DrawBooleanType DrawSetFontResolution(DrawingWand *wand,
4763 %        const double x_resolution,const doubtl 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 %  DrawSetOpacity() sets the opacity to use when drawing using the fill or
4802 %  stroke color or texture.  Fully opaque is 1.0.
4803 %
4804 %  The format of the DrawSetOpacity method is:
4805 %
4806 %      void DrawSetOpacity(DrawingWand *wand,const double opacity)
4807 %
4808 %  A description of each parameter follows:
4809 %
4810 %    o wand: the drawing wand.
4811 %
4812 %    o opacity: fill opacity
4813 %
4814 */
4815 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4816 {
4817   Quantum
4818     quantum_opacity;
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_opacity=ClampToQuantum((double) QuantumRange*(1.0-opacity));
4825   if ((wand->filter_off != MagickFalse) ||
4826       (CurrentContext->alpha != quantum_opacity))
4827     {
4828       CurrentContext->alpha=(Quantum) opacity;
4829       (void) MvgPrintf(wand,"opacity %g\n",opacity);
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=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   PixelPacket
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       (IsPixelPacketEquivalent(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=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 %  DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5682 %
5683 %  The format of the DrawSetStrokeOpacity method is:
5684 %
5685 %      void DrawSetStrokeOpacity(DrawingWand *wand,
5686 %        const double stroke_opacity)
5687 %
5688 %  A description of each parameter follows:
5689 %
5690 %    o wand: the drawing wand.
5691 %
5692 %    o stroke_opacity: stroke opacity.  The value 1.0 is opaque.
5693 %
5694 */
5695 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5696   const double stroke_opacity)
5697 {
5698   Quantum
5699     opacity;
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   opacity=ClampToQuantum((double) QuantumRange*(1.0-stroke_opacity));
5706   if ((wand->filter_off != MagickFalse) ||
5707       (CurrentContext->stroke.alpha != opacity))
5708     {
5709       CurrentContext->stroke.alpha=opacity;
5710       (void) MvgPrintf(wand,"stroke-opacity %g\n",stroke_opacity);
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 %  DrawSetTextInterwordSpacing() sets the spacing between line in text.
5977 %
5978 %  The format of the DrawSetInterwordSpacing method is:
5979 %
5980 %      void DrawSetTextInterwordSpacing(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   PixelPacket
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       (IsPixelPacketEquivalent(&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) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6185     }
6186   child=GetXMLTreeChild(xml_info,"fill-opacity");
6187   if (child != (XMLTreeInfo *) NULL)
6188     {
6189       value=GetXMLTreeContent(child);
6190       if (value != (const char *) NULL)
6191         CurrentContext->fill.alpha=ClampToQuantum((MagickRealType)
6192           QuantumRange*(1.0-InterpretLocaleValue(value,(char **) NULL)));
6193     }
6194   child=GetXMLTreeChild(xml_info,"fill-rule");
6195   if (child != (XMLTreeInfo *) NULL)
6196     {
6197       value=GetXMLTreeContent(child);
6198       if (value != (const char *) NULL)
6199         CurrentContext->fill_rule=(FillRule) ParseCommandOption(
6200           MagickFillRuleOptions,MagickFalse,value);
6201     }
6202   child=GetXMLTreeChild(xml_info,"font");
6203   if (child != (XMLTreeInfo *) NULL)
6204     (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6205   child=GetXMLTreeChild(xml_info,"font-family");
6206   if (child != (XMLTreeInfo *) NULL)
6207     (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6208   child=GetXMLTreeChild(xml_info,"font-size");
6209   if (child != (XMLTreeInfo *) NULL)
6210     {
6211       value=GetXMLTreeContent(child);
6212       if (value != (const char *) NULL)
6213         CurrentContext->pointsize=InterpretLocaleValue(value,(char **) NULL);
6214     }
6215   child=GetXMLTreeChild(xml_info,"font-stretch");
6216   if (child != (XMLTreeInfo *) NULL)
6217     {
6218       value=GetXMLTreeContent(child);
6219       if (value != (const char *) NULL)
6220         CurrentContext->stretch=(StretchType) ParseCommandOption(
6221           MagickStretchOptions,MagickFalse,value);
6222     }
6223   child=GetXMLTreeChild(xml_info,"font-style");
6224   if (child != (XMLTreeInfo *) NULL)
6225     {
6226       value=GetXMLTreeContent(child);
6227       if (value != (const char *) NULL)
6228         CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
6229           MagickFalse,value);
6230     }
6231   child=GetXMLTreeChild(xml_info,"font-weight");
6232   if (child != (XMLTreeInfo *) NULL)
6233     {
6234       value=GetXMLTreeContent(child);
6235       if (value != (const char *) NULL)
6236         CurrentContext->weight=StringToUnsignedLong(value);
6237     }
6238   child=GetXMLTreeChild(xml_info,"gravity");
6239   if (child != (XMLTreeInfo *) NULL)
6240     {
6241       value=GetXMLTreeContent(child);
6242       if (value != (const char *) NULL)
6243         CurrentContext->gravity=(GravityType) ParseCommandOption(
6244           MagickGravityOptions,MagickFalse,value);
6245     }
6246   child=GetXMLTreeChild(xml_info,"stroke");
6247   if (child != (XMLTreeInfo *) NULL)
6248     {
6249       value=GetXMLTreeContent(child);
6250       if (value != (const char *) NULL)
6251         (void) QueryColorDatabase(value,&CurrentContext->stroke,
6252           wand->exception);
6253     }
6254   child=GetXMLTreeChild(xml_info,"stroke-antialias");
6255   if (child != (XMLTreeInfo *) NULL)
6256     {
6257       value=GetXMLTreeContent(child);
6258       if (value != (const char *) NULL)
6259         CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6260           MagickFalse;
6261     }
6262   child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6263   if (child != (XMLTreeInfo *) NULL)
6264     {
6265       char
6266         token[MaxTextExtent];
6267
6268       const char
6269         *q;
6270
6271       register ssize_t
6272         x;
6273
6274       ssize_t
6275         j;
6276
6277       value=GetXMLTreeContent(child);
6278       if (value != (const char *) NULL)
6279         {
6280           if (CurrentContext->dash_pattern != (double *) NULL)
6281             CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6282               CurrentContext->dash_pattern);
6283           q=(char *) value;
6284           if (IsPoint(q) != MagickFalse)
6285             {
6286               const char
6287                 *p;
6288
6289               p=q;
6290               GetMagickToken(p,&p,token);
6291               if (*token == ',')
6292                 GetMagickToken(p,&p,token);
6293               for (x=0; IsPoint(token) != MagickFalse; x++)
6294               {
6295                 GetMagickToken(p,&p,token);
6296                 if (*token == ',')
6297                   GetMagickToken(p,&p,token);
6298               }
6299               CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6300                 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6301               if (CurrentContext->dash_pattern == (double *) NULL)
6302                 ThrowWandFatalException(ResourceLimitFatalError,
6303                   "MemoryAllocationFailed",wand->name);
6304               for (j=0; j < x; j++)
6305               {
6306                 GetMagickToken(q,&q,token);
6307                 if (*token == ',')
6308                   GetMagickToken(q,&q,token);
6309                 CurrentContext->dash_pattern[j]=InterpretLocaleValue(token,
6310                   (char **) NULL);
6311               }
6312               if ((x & 0x01) != 0)
6313                 for ( ; j < (2*x); j++)
6314                   CurrentContext->dash_pattern[j]=
6315                     CurrentContext->dash_pattern[j-x];
6316               CurrentContext->dash_pattern[j]=0.0;
6317             }
6318         }
6319     }
6320   child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6321   if (child != (XMLTreeInfo *) NULL)
6322     {
6323       value=GetXMLTreeContent(child);
6324       if (value != (const char *) NULL)
6325         CurrentContext->dash_offset=InterpretLocaleValue(value,(char **) NULL);
6326     }
6327   child=GetXMLTreeChild(xml_info,"stroke-linecap");
6328   if (child != (XMLTreeInfo *) NULL)
6329     {
6330       value=GetXMLTreeContent(child);
6331       if (value != (const char *) NULL)
6332         CurrentContext->linecap=(LineCap) ParseCommandOption(
6333           MagickLineCapOptions,MagickFalse,value);
6334     }
6335   child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6336   if (child != (XMLTreeInfo *) NULL)
6337     {
6338       value=GetXMLTreeContent(child);
6339       if (value != (const char *) NULL)
6340         CurrentContext->linejoin=(LineJoin) ParseCommandOption(
6341           MagickLineJoinOptions,MagickFalse,value);
6342     }
6343   child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6344   if (child != (XMLTreeInfo *) NULL)
6345     {
6346       value=GetXMLTreeContent(child);
6347       if (value != (const char *) NULL)
6348         CurrentContext->miterlimit=StringToUnsignedLong(value);
6349     }
6350   child=GetXMLTreeChild(xml_info,"stroke-opacity");
6351   if (child != (XMLTreeInfo *) NULL)
6352     {
6353       value=GetXMLTreeContent(child);
6354       if (value != (const char *) NULL)
6355         CurrentContext->stroke.alpha=ClampToQuantum((MagickRealType)
6356           QuantumRange*(1.0-InterpretLocaleValue(value,(char **) NULL)));
6357     }
6358   child=GetXMLTreeChild(xml_info,"stroke-width");
6359   if (child != (XMLTreeInfo *) NULL)
6360     {
6361       value=GetXMLTreeContent(child);
6362       if (value != (const char *) NULL)
6363         CurrentContext->stroke_width=InterpretLocaleValue(value,(char **) NULL);
6364     }
6365   child=GetXMLTreeChild(xml_info,"text-align");
6366   if (child != (XMLTreeInfo *) NULL)
6367     {
6368       value=GetXMLTreeContent(child);
6369       if (value != (const char *) NULL)
6370         CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
6371           MagickFalse,value);
6372     }
6373   child=GetXMLTreeChild(xml_info,"text-antialias");
6374   if (child != (XMLTreeInfo *) NULL)
6375     {
6376       value=GetXMLTreeContent(child);
6377       if (value != (const char *) NULL)
6378         CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6379           MagickFalse;
6380     }
6381   child=GetXMLTreeChild(xml_info,"text-undercolor");
6382   if (child != (XMLTreeInfo *) NULL)
6383     {
6384       value=GetXMLTreeContent(child);
6385       if (value != (const char *) NULL)
6386         (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6387           wand->exception);
6388     }
6389   child=GetXMLTreeChild(xml_info,"vector-graphics");
6390   if (child != (XMLTreeInfo *) NULL)
6391     {
6392       (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6393       wand->mvg_length=strlen(wand->mvg);
6394       wand->mvg_alloc=wand->mvg_length+1;
6395     }
6396   xml_info=DestroyXMLTree(xml_info);
6397   return(MagickTrue);
6398 }
6399 \f
6400 /*
6401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6402 %                                                                             %
6403 %                                                                             %
6404 %                                                                             %
6405 %   D r a w S k e w X                                                         %
6406 %                                                                             %
6407 %                                                                             %
6408 %                                                                             %
6409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6410 %
6411 %  DrawSkewX() skews the current coordinate system in the horizontal
6412 %  direction.
6413 %
6414 %  The format of the DrawSkewX method is:
6415 %
6416 %      void DrawSkewX(DrawingWand *wand,const double degrees)
6417 %
6418 %  A description of each parameter follows:
6419 %
6420 %    o wand: the drawing wand.
6421 %
6422 %    o degrees: number of degrees to skew the coordinates
6423 %
6424 */
6425 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6426 {
6427   assert(wand != (DrawingWand *) NULL);
6428   assert(wand->signature == WandSignature);
6429   if (wand->debug != MagickFalse)
6430     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6431   (void) MvgPrintf(wand,"skewX %g\n",degrees);
6432 }
6433 \f
6434 /*
6435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6436 %                                                                             %
6437 %                                                                             %
6438 %                                                                             %
6439 %   D r a w S k e w Y                                                         %
6440 %                                                                             %
6441 %                                                                             %
6442 %                                                                             %
6443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6444 %
6445 %  DrawSkewY() skews the current coordinate system in the vertical
6446 %  direction.
6447 %
6448 %  The format of the DrawSkewY method is:
6449 %
6450 %      void DrawSkewY(DrawingWand *wand,const double degrees)
6451 %
6452 %  A description of each parameter follows:
6453 %
6454 %    o wand: the drawing wand.
6455 %
6456 %    o degrees: number of degrees to skew the coordinates
6457 %
6458 */
6459 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6460 {
6461   assert(wand != (DrawingWand *) NULL);
6462   assert(wand->signature == WandSignature);
6463   if (wand->debug != MagickFalse)
6464     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6465   (void) MvgPrintf(wand,"skewY %g\n",degrees);
6466 }
6467 \f
6468 /*
6469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6470 %                                                                             %
6471 %                                                                             %
6472 %                                                                             %
6473 %   D r a w T r a n s l a t e                                                 %
6474 %                                                                             %
6475 %                                                                             %
6476 %                                                                             %
6477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6478 %
6479 %  DrawTranslate() applies a translation to the current coordinate
6480 %  system which moves the coordinate system origin to the specified
6481 %  coordinate.
6482 %
6483 %  The format of the DrawTranslate method is:
6484 %
6485 %      void DrawTranslate(DrawingWand *wand,const double x,
6486 %        const double y)
6487 %
6488 %  A description of each parameter follows:
6489 %
6490 %    o wand: the drawing wand.
6491 %
6492 %    o x: new x ordinate for coordinate system origin
6493 %
6494 %    o y: new y ordinate for coordinate system origin
6495 %
6496 */
6497 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6498 {
6499   assert(wand != (DrawingWand *) NULL);
6500   assert(wand->signature == WandSignature);
6501   if (wand->debug != MagickFalse)
6502     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6503   (void) MvgPrintf(wand,"translate %g %g\n",x,y);
6504 }
6505 \f
6506 /*
6507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6508 %                                                                             %
6509 %                                                                             %
6510 %                                                                             %
6511 %   D r a w S e t V i e w b o x                                               %
6512 %                                                                             %
6513 %                                                                             %
6514 %                                                                             %
6515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6516 %
6517 %  DrawSetViewbox() sets the overall canvas size to be recorded with the
6518 %  drawing vector data.  Usually this will be specified using the same
6519 %  size as the canvas image.  When the vector data is saved to SVG or MVG
6520 %  formats, the viewbox is use to specify the size of the canvas image that
6521 %  a viewer will render the vector data on.
6522 %
6523 %  The format of the DrawSetViewbox method is:
6524 %
6525 %      void DrawSetViewbox(DrawingWand *wand,size_t x1,
6526 %        size_t y1,size_t x2,size_t y2)
6527 %
6528 %  A description of each parameter follows:
6529 %
6530 %    o wand: the drawing wand.
6531 %
6532 %    o x1: left x ordinate
6533 %
6534 %    o y1: top y ordinate
6535 %
6536 %    o x2: right x ordinate
6537 %
6538 %    o y2: bottom y ordinate
6539 %
6540 */
6541 WandExport void DrawSetViewbox(DrawingWand *wand,ssize_t x1,ssize_t y1,
6542   ssize_t x2,ssize_t y2)
6543 {
6544   assert(wand != (DrawingWand *) NULL);
6545   assert(wand->signature == WandSignature);
6546   if (wand->debug != MagickFalse)
6547     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6548   (void) MvgPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",(double) x1,
6549     (double) y1,(double) x2,(double) 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->image=AcquireImage((const ImageInfo *) NULL);
6649   wand->exception=AcquireExceptionInfo();
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) SetImageClipMask(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 }