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