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