]> 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=current.sx*affine->sx+current.ry*affine->rx;
445       CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
446       CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
447       CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
448       CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+
449         current.tx;
450       CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+
451         current.ty;
452     }
453 }
454 \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 *) AcquireAlignedMemory(1,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-%lu",
566     (unsigned long) 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,"%ld bytes",
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 ssize_ter 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 ssize_ter 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 ssize_ter 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 S i z e                                             %
1584 %                                                                             %
1585 %                                                                             %
1586 %                                                                             %
1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1588 %
1589 %  DrawGetFontSize() returns the font pointsize used when annotating with text.
1590 %
1591 %  The format of the DrawGetFontSize method is:
1592 %
1593 %      double DrawGetFontSize(const DrawingWand *wand)
1594 %
1595 %  A description of each parameter follows:
1596 %
1597 %    o wand: the drawing wand.
1598 %
1599 */
1600 WandExport double DrawGetFontSize(const DrawingWand *wand)
1601 {
1602   assert(wand != (const DrawingWand *) NULL);
1603   assert(wand->signature == WandSignature);
1604   if (wand->debug != MagickFalse)
1605     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1606   return(CurrentContext->pointsize);
1607 }
1608 \f
1609 /*
1610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1611 %                                                                             %
1612 %                                                                             %
1613 %                                                                             %
1614 %   D r a w G e t F o n t S t r e t c h                                       %
1615 %                                                                             %
1616 %                                                                             %
1617 %                                                                             %
1618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1619 %
1620 %  DrawGetFontStretch() returns the font stretch used when annotating with text.
1621 %
1622 %  The format of the DrawGetFontStretch method is:
1623 %
1624 %      StretchType DrawGetFontStretch(const DrawingWand *wand)
1625 %
1626 %  A description of each parameter follows:
1627 %
1628 %    o wand: the drawing wand.
1629 %
1630 */
1631 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1632 {
1633   assert(wand != (const DrawingWand *) NULL);
1634   assert(wand->signature == WandSignature);
1635   if (wand->debug != MagickFalse)
1636     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1637   return(CurrentContext->stretch);
1638 }
1639 \f
1640 /*
1641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1642 %                                                                             %
1643 %                                                                             %
1644 %                                                                             %
1645 %   D r a w G e t F o n t S t y l e                                           %
1646 %                                                                             %
1647 %                                                                             %
1648 %                                                                             %
1649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1650 %
1651 %  DrawGetFontStyle() returns the font style used when annotating with text.
1652 %
1653 %  The format of the DrawGetFontStyle method is:
1654 %
1655 %      StyleType DrawGetFontStyle(const DrawingWand *wand)
1656 %
1657 %  A description of each parameter follows:
1658 %
1659 %    o wand: the drawing wand.
1660 %
1661 */
1662 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1663 {
1664   assert(wand != (const DrawingWand *) NULL);
1665   assert(wand->signature == WandSignature);
1666   if (wand->debug != MagickFalse)
1667     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1668   return(CurrentContext->style);
1669 }
1670 \f
1671 /*
1672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673 %                                                                             %
1674 %                                                                             %
1675 %                                                                             %
1676 %   D r a w G e t F o n t W e i g h t                                         %
1677 %                                                                             %
1678 %                                                                             %
1679 %                                                                             %
1680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1681 %
1682 %  DrawGetFontWeight() returns the font weight used when annotating with text.
1683 %
1684 %  The format of the DrawGetFontWeight method is:
1685 %
1686 %      size_t DrawGetFontWeight(const DrawingWand *wand)
1687 %
1688 %  A description of each parameter follows:
1689 %
1690 %    o wand: the drawing wand.
1691 %
1692 */
1693 WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
1694 {
1695   assert(wand != (const DrawingWand *) NULL);
1696   assert(wand->signature == WandSignature);
1697   if (wand->debug != MagickFalse)
1698     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1699   return(CurrentContext->weight);
1700 }
1701 \f
1702 /*
1703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1704 %                                                                             %
1705 %                                                                             %
1706 %                                                                             %
1707 %   D r a w G e t G r a v i t y                                               %
1708 %                                                                             %
1709 %                                                                             %
1710 %                                                                             %
1711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1712 %
1713 %  DrawGetGravity() returns the text placement gravity used when annotating
1714 %  with text.
1715 %
1716 %  The format of the DrawGetGravity method is:
1717 %
1718 %      GravityType DrawGetGravity(const DrawingWand *wand)
1719 %
1720 %  A description of each parameter follows:
1721 %
1722 %    o wand: the drawing wand.
1723 %
1724 */
1725 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1726 {
1727   assert(wand != (const DrawingWand *) NULL);
1728   assert(wand->signature == WandSignature);
1729   if (wand->debug != MagickFalse)
1730     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1731   return(CurrentContext->gravity);
1732 }
1733 \f
1734 /*
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1736 %                                                                             %
1737 %                                                                             %
1738 %                                                                             %
1739 %   D r a w G e t O p a c i t y                                               %
1740 %                                                                             %
1741 %                                                                             %
1742 %                                                                             %
1743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1744 %
1745 %  DrawGetOpacity() returns the opacity used when drawing with the fill
1746 %  or stroke color or texture.  Fully opaque is 1.0.
1747 %
1748 %  The format of the DrawGetOpacity method is:
1749 %
1750 %      double DrawGetOpacity(const DrawingWand *wand)
1751 %
1752 %  A description of each parameter follows:
1753 %
1754 %    o wand: the drawing wand.
1755 %
1756 */
1757 WandExport double DrawGetOpacity(const DrawingWand *wand)
1758 {
1759   double
1760     alpha;
1761
1762   assert(wand != (const DrawingWand *) NULL);
1763   assert(wand->signature == WandSignature);
1764   if (wand->debug != MagickFalse)
1765     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1766   alpha=(double) QuantumScale*(QuantumRange-CurrentContext->opacity);
1767   return(alpha);
1768 }
1769 \f
1770 /*
1771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1772 %                                                                             %
1773 %                                                                             %
1774 %                                                                             %
1775 %   D r a w G e t S t r o k e A n t i a l i a s                               %
1776 %                                                                             %
1777 %                                                                             %
1778 %                                                                             %
1779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1780 %
1781 %  DrawGetStrokeAntialias() returns the current stroke antialias setting.
1782 %  Stroked outlines are antialiased by default.  When antialiasing is disabled
1783 %  stroked pixels are thresholded to determine if the stroke color or
1784 %  underlying canvas color should be used.
1785 %
1786 %  The format of the DrawGetStrokeAntialias method is:
1787 %
1788 %      MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1789 %
1790 %  A description of each parameter follows:
1791 %
1792 %    o wand: the drawing wand.
1793 %
1794 */
1795 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1796 {
1797   assert(wand != (const DrawingWand *) NULL);
1798   assert(wand->signature == WandSignature);
1799   if (wand->debug != MagickFalse)
1800     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1801   return(CurrentContext->stroke_antialias);
1802 }
1803 \f
1804 /*
1805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1806 %                                                                             %
1807 %                                                                             %
1808 %                                                                             %
1809 %   D r a w G e t S t r o k e C o l o r                                       %
1810 %                                                                             %
1811 %                                                                             %
1812 %                                                                             %
1813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1814 %
1815 %  DrawGetStrokeColor() returns the color used for stroking object outlines.
1816 %
1817 %  The format of the DrawGetStrokeColor method is:
1818 %
1819 %      void DrawGetStrokeColor(const DrawingWand *wand,
1820 $        PixelWand *stroke_color)
1821 %
1822 %  A description of each parameter follows:
1823 %
1824 %    o wand: the drawing wand.
1825 %
1826 %    o stroke_color: Return the stroke color.
1827 %
1828 */
1829 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1830   PixelWand *stroke_color)
1831 {
1832   assert(wand != (const DrawingWand *) NULL);
1833   assert(wand->signature == WandSignature);
1834   assert(stroke_color != (PixelWand *) NULL);
1835   if (wand->debug != MagickFalse)
1836     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1837   PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
1838 }
1839 \f
1840 /*
1841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1842 %                                                                             %
1843 %                                                                             %
1844 %                                                                             %
1845 %   D r a w G e t S t r o k e D a s h A r r a y                               %
1846 %                                                                             %
1847 %                                                                             %
1848 %                                                                             %
1849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1850 %
1851 %  DrawGetStrokeDashArray() returns an array representing the pattern of
1852 %  dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
1853 %  array must be freed once it is no ssize_ter required by the user.
1854 %
1855 %  The format of the DrawGetStrokeDashArray method is:
1856 %
1857 %      double *DrawGetStrokeDashArray(const DrawingWand *wand,
1858 %        size_t *number_elements)
1859 %
1860 %  A description of each parameter follows:
1861 %
1862 %    o wand: the drawing wand.
1863 %
1864 %    o number_elements: address to place number of elements in dash array
1865 %
1866 */
1867 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
1868   size_t *number_elements)
1869 {
1870   double
1871     *dash_array;
1872
1873   register const double
1874     *p;
1875
1876   register double
1877     *q;
1878
1879   register ssize_t
1880     i;
1881
1882   size_t
1883     n;
1884
1885   assert(wand != (const DrawingWand *) NULL);
1886   assert(wand->signature == WandSignature);
1887   if (wand->debug != MagickFalse)
1888     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1889   assert(number_elements != (size_t *) NULL);
1890   n=0;
1891   p=CurrentContext->dash_pattern;
1892   if (p != (const double *) NULL)
1893     while (*p++ != 0.0)
1894       n++;
1895   *number_elements=n;
1896   dash_array=(double *) NULL;
1897   if (n != 0)
1898     {
1899       dash_array=(double *) AcquireQuantumMemory((size_t) n,
1900         sizeof(*dash_array));
1901       p=CurrentContext->dash_pattern;
1902       q=dash_array;
1903       for (i=0; i < (ssize_t) n; i++)
1904         *q++=(*p++);
1905     }
1906   return(dash_array);
1907 }
1908 \f
1909 /*
1910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1911 %                                                                             %
1912 %                                                                             %
1913 %                                                                             %
1914 %   D r a w G e t S t r o k e D a s h O f f s e t                             %
1915 %                                                                             %
1916 %                                                                             %
1917 %                                                                             %
1918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1919 %
1920 %  DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1921 %  start the dash.
1922 %
1923 %  The format of the DrawGetStrokeDashOffset method is:
1924 %
1925 %      double DrawGetStrokeDashOffset(const DrawingWand *wand)
1926 %
1927 %  A description of each parameter follows:
1928 %
1929 %    o wand: the drawing wand.
1930 %
1931 */
1932 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1933 {
1934   assert(wand != (const DrawingWand *) NULL);
1935   assert(wand->signature == WandSignature);
1936   if (wand->debug != MagickFalse)
1937     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1938   return(CurrentContext->dash_offset);
1939 }
1940 \f
1941 /*
1942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1943 %                                                                             %
1944 %                                                                             %
1945 %                                                                             %
1946 %   D r a w G e t S t r o k e L i n e C a p                                   %
1947 %                                                                             %
1948 %                                                                             %
1949 %                                                                             %
1950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1951 %
1952 %  DrawGetStrokeLineCap() returns the shape to be used at the end of
1953 %  open subpaths when they are stroked. Values of LineCap are
1954 %  UndefinedCap, ButtCap, RoundCap, and SquareCap.
1955 %
1956 %  The format of the DrawGetStrokeLineCap method is:
1957 %
1958 %      LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1959 %
1960 %  A description of each parameter follows:
1961 %
1962 %    o wand: the drawing wand.
1963 %
1964 */
1965 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1966 {
1967   assert(wand != (const DrawingWand *) NULL);
1968   assert(wand->signature == WandSignature);
1969   if (wand->debug != MagickFalse)
1970     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1971   return(CurrentContext->linecap);
1972 }
1973 \f
1974 /*
1975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1976 %                                                                             %
1977 %                                                                             %
1978 %                                                                             %
1979 %   D r a w G e t S t r o k e L i n e J o i n                                 %
1980 %                                                                             %
1981 %                                                                             %
1982 %                                                                             %
1983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1984 %
1985 %  DrawGetStrokeLineJoin() returns the shape to be used at the
1986 %  corners of paths (or other vector shapes) when they are
1987 %  stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
1988 %  and BevelJoin.
1989 %
1990 %  The format of the DrawGetStrokeLineJoin method is:
1991 %
1992 %      LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
1993 %
1994 %  A description of each parameter follows:
1995 %
1996 %    o wand: the drawing wand.
1997 %
1998 */
1999 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2000 {
2001   assert(wand != (const DrawingWand *) NULL);
2002   assert(wand->signature == WandSignature);
2003   if (wand->debug != MagickFalse)
2004     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2005   return(CurrentContext->linejoin);
2006 }
2007 \f
2008 /*
2009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2010 %                                                                             %
2011 %                                                                             %
2012 %                                                                             %
2013 %   D r a w G e t S t r o k e M i t e r L i m i t                             %
2014 %                                                                             %
2015 %                                                                             %
2016 %                                                                             %
2017 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2018 %
2019 %  DrawGetStrokeMiterLimit() returns the miter limit. When two line
2020 %  segments meet at a sharp angle and miter joins have been specified for
2021 %  'lineJoin', it is possible for the miter to extend far beyond the
2022 %  thickness of the line stroking the path. The miterLimit' imposes a
2023 %  limit on the ratio of the miter length to the 'lineWidth'.
2024 %
2025 %  The format of the DrawGetStrokeMiterLimit method is:
2026 %
2027 %      size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2028 %
2029 %  A description of each parameter follows:
2030 %
2031 %    o wand: the drawing wand.
2032 %
2033 */
2034 WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2035 {
2036   assert(wand != (const DrawingWand *) NULL);
2037   assert(wand->signature == WandSignature);
2038   if (wand->debug != MagickFalse)
2039     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2040   return CurrentContext->miterlimit;
2041 }
2042 \f
2043 /*
2044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2045 %                                                                             %
2046 %                                                                             %
2047 %                                                                             %
2048 %   D r a w G e t S t r o k e O p a c i t y                                   %
2049 %                                                                             %
2050 %                                                                             %
2051 %                                                                             %
2052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2053 %
2054 %  DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
2055 %
2056 %  The format of the DrawGetStrokeOpacity method is:
2057 %
2058 %      double DrawGetStrokeOpacity(const DrawingWand *wand)
2059 %
2060 %  A description of each parameter follows:
2061 %
2062 %    o wand: the drawing wand.
2063 %
2064 */
2065 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2066 {
2067   double
2068     alpha;
2069
2070   assert(wand != (const DrawingWand *) NULL);
2071   assert(wand->signature == WandSignature);
2072   if (wand->debug != MagickFalse)
2073     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2074   alpha=(double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity);
2075   return(alpha);
2076 }
2077 \f
2078 /*
2079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2080 %                                                                             %
2081 %                                                                             %
2082 %                                                                             %
2083 %   D r a w G e t S t r o k e W i d t h                                       %
2084 %                                                                             %
2085 %                                                                             %
2086 %                                                                             %
2087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2088 %
2089 %  DrawGetStrokeWidth() returns the width of the stroke used to draw object
2090 %  outlines.
2091 %
2092 %  The format of the DrawGetStrokeWidth method is:
2093 %
2094 %      double DrawGetStrokeWidth(const DrawingWand *wand)
2095 %
2096 %  A description of each parameter follows:
2097 %
2098 %    o wand: the drawing wand.
2099 %
2100 */
2101 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2102 {
2103   assert(wand != (const DrawingWand *) NULL);
2104   assert(wand->signature == WandSignature);
2105   if (wand->debug != MagickFalse)
2106     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2107   return(CurrentContext->stroke_width);
2108 }
2109 \f
2110 /*
2111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2112 %                                                                             %
2113 %                                                                             %
2114 %                                                                             %
2115 %   D r a w G e t T e x t A l i g n m e n t                                   %
2116 %                                                                             %
2117 %                                                                             %
2118 %                                                                             %
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2120 %
2121 %  DrawGetTextAlignment() returns the alignment applied when annotating with
2122 %  text.
2123 %
2124 %  The format of the DrawGetTextAlignment method is:
2125 %
2126 %      AlignType DrawGetTextAlignment(DrawingWand *wand)
2127 %
2128 %  A description of each parameter follows:
2129 %
2130 %    o wand: the drawing wand.
2131 %
2132 */
2133 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2134 {
2135   assert(wand != (const DrawingWand *) NULL);
2136   assert(wand->signature == WandSignature);
2137   if (wand->debug != MagickFalse)
2138     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2139   return(CurrentContext->align);
2140 }
2141 \f
2142 /*
2143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2144 %                                                                             %
2145 %                                                                             %
2146 %                                                                             %
2147 %   D r a w G e t T e x t A n t i a l i a s                                   %
2148 %                                                                             %
2149 %                                                                             %
2150 %                                                                             %
2151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2152 %
2153 %  DrawGetTextAntialias() returns the current text antialias setting, which
2154 %  determines whether text is antialiased.  Text is antialiased by default.
2155 %
2156 %  The format of the DrawGetTextAntialias method is:
2157 %
2158 %      MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2159 %
2160 %  A description of each parameter follows:
2161 %
2162 %    o wand: the drawing wand.
2163 %
2164 */
2165 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2166 {
2167   assert(wand != (const DrawingWand *) NULL);
2168   assert(wand->signature == WandSignature);
2169   if (wand->debug != MagickFalse)
2170     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2171   return(CurrentContext->text_antialias);
2172 }
2173 \f
2174 /*
2175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2176 %                                                                             %
2177 %                                                                             %
2178 %                                                                             %
2179 %   D r a w G e t T e x t D e c o r a t i o n                                 %
2180 %                                                                             %
2181 %                                                                             %
2182 %                                                                             %
2183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2184 %
2185 %  DrawGetTextDecoration() returns the decoration applied when annotating with
2186 %  text.
2187 %
2188 %  The format of the DrawGetTextDecoration method is:
2189 %
2190 %      DecorationType DrawGetTextDecoration(DrawingWand *wand)
2191 %
2192 %  A description of each parameter follows:
2193 %
2194 %    o wand: the drawing wand.
2195 %
2196 */
2197 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2198 {
2199   assert(wand != (const DrawingWand *) NULL);
2200   assert(wand->signature == WandSignature);
2201   if (wand->debug != MagickFalse)
2202     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2203   return(CurrentContext->decorate);
2204 }
2205 \f
2206 /*
2207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2208 %                                                                             %
2209 %                                                                             %
2210 %                                                                             %
2211 %   D r a w G e t T e x t E n c o d i n g                                     %
2212 %                                                                             %
2213 %                                                                             %
2214 %                                                                             %
2215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2216 %
2217 %  DrawGetTextEncoding() returns a null-terminated string which specifies the
2218 %  code set used for text annotations. The string must be freed by the user
2219 %  once it is no ssize_ter required.
2220 %
2221 %  The format of the DrawGetTextEncoding method is:
2222 %
2223 %      char *DrawGetTextEncoding(const DrawingWand *wand)
2224 %
2225 %  A description of each parameter follows:
2226 %
2227 %    o wand: the drawing wand.
2228 %
2229 */
2230 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2231 {
2232   assert(wand != (const DrawingWand *) NULL);
2233   assert(wand->signature == WandSignature);
2234   if (wand->debug != MagickFalse)
2235     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2236   if (CurrentContext->encoding != (char *) NULL)
2237     return((char *) AcquireString(CurrentContext->encoding));
2238   return((char *) NULL);
2239 }
2240 \f
2241 /*
2242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2243 %                                                                             %
2244 %                                                                             %
2245 %                                                                             %
2246 %   D r a w G e t T e x t K e r n i n g                                       %
2247 %                                                                             %
2248 %                                                                             %
2249 %                                                                             %
2250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2251 %
2252 %  DrawGetTextKerning() gets the spacing between characters in text.
2253 %
2254 %  The format of the DrawSetFontKerning method is:
2255 %
2256 %      double DrawGetTextKerning(DrawingWand *wand)
2257 %
2258 %  A description of each parameter follows:
2259 %
2260 %    o wand: the drawing wand.
2261 %
2262 */
2263 WandExport double DrawGetTextKerning(DrawingWand *wand)
2264 {
2265   assert(wand != (DrawingWand *) NULL);
2266   assert(wand->signature == WandSignature);
2267
2268   if (wand->debug != MagickFalse)
2269     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2270   return(CurrentContext->kerning);
2271 }
2272 \f
2273 /*
2274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2275 %                                                                             %
2276 %                                                                             %
2277 %                                                                             %
2278 %   D r a w G e t T e x t I n t e r L i n e S p a c i n g                     %
2279 %                                                                             %
2280 %                                                                             %
2281 %                                                                             %
2282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2283 %
2284 %  DrawGetTextInterwordSpacing() gets the spacing between lines in text.
2285 %
2286 %  The format of the DrawSetFontKerning method is:
2287 %
2288 %      double DrawGetTextInterwordSpacing(DrawingWand *wand)
2289 %
2290 %  A description of each parameter follows:
2291 %
2292 %    o wand: the drawing wand.
2293 %
2294 */
2295 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2296 {
2297   assert(wand != (DrawingWand *) NULL);
2298   assert(wand->signature == WandSignature);
2299   if (wand->debug != MagickFalse)
2300     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2301   return(CurrentContext->interline_spacing);
2302 }
2303 \f
2304 /*
2305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2306 %                                                                             %
2307 %                                                                             %
2308 %                                                                             %
2309 %   D r a w G e t T e x t I n t e r w o r d S p a c i n g                     %
2310 %                                                                             %
2311 %                                                                             %
2312 %                                                                             %
2313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2314 %
2315 %  DrawGetTextInterwordSpacing() gets the spacing between words in text.
2316 %
2317 %  The format of the DrawSetFontKerning method is:
2318 %
2319 %      double DrawGetTextInterwordSpacing(DrawingWand *wand)
2320 %
2321 %  A description of each parameter follows:
2322 %
2323 %    o wand: the drawing wand.
2324 %
2325 */
2326 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2327 {
2328   assert(wand != (DrawingWand *) NULL);
2329   assert(wand->signature == WandSignature);
2330   if (wand->debug != MagickFalse)
2331     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2332   return(CurrentContext->interword_spacing);
2333 }
2334 \f
2335 /*
2336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337 %                                                                             %
2338 %                                                                             %
2339 %                                                                             %
2340 %   D r a w G e t V e c t o r G r a p h i c s                                 %
2341 %                                                                             %
2342 %                                                                             %
2343 %                                                                             %
2344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2345 %
2346 %  DrawGetVectorGraphics() returns a null-terminated string which specifies the
2347 %  vector graphics generated by any graphics calls made since the wand was
2348 %  instantiated.  The string must be freed by the user once it is no ssize_ter
2349 %  required.
2350 %
2351 %  The format of the DrawGetVectorGraphics method is:
2352 %
2353 %      char *DrawGetVectorGraphics(const DrawingWand *wand)
2354 %
2355 %  A description of each parameter follows:
2356 %
2357 %    o wand: the drawing wand.
2358 %
2359 */
2360
2361 static inline void SetMagickPixelPacket(const Image *image,
2362   const PixelPacket *color,const IndexPacket *index,MagickPixelPacket *pixel)
2363 {
2364   pixel->red=(MagickRealType) color->red;
2365   pixel->green=(MagickRealType) color->green;
2366   pixel->blue=(MagickRealType) color->blue;
2367   if (image->matte != MagickFalse)
2368     pixel->opacity=(MagickRealType) color->opacity;
2369   if (((image->colorspace == CMYKColorspace) ||
2370        (image->storage_class == PseudoClass)) &&
2371       (index != (const IndexPacket *) NULL))
2372     pixel->index=(MagickRealType) *index;
2373 }
2374
2375 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2376 {
2377   char
2378     value[MaxTextExtent],
2379     *xml;
2380
2381   MagickPixelPacket
2382     pixel;
2383
2384   register ssize_t
2385     i;
2386
2387   XMLTreeInfo
2388     *child,
2389     *xml_info;
2390
2391   assert(wand != (const DrawingWand *) NULL);
2392   assert(wand->signature == WandSignature);
2393   if (wand->debug != MagickFalse)
2394     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2395   xml_info=NewXMLTreeTag("drawing-wand");
2396   if (xml_info == (XMLTreeInfo *) NULL)
2397     return(char *) NULL;
2398   GetMagickPixelPacket(wand->image,&pixel);
2399   child=AddChildToXMLTree(xml_info,"clip-path",0);
2400   if (child != (XMLTreeInfo *) NULL)
2401     (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2402   child=AddChildToXMLTree(xml_info,"clip-units",0);
2403   if (child != (XMLTreeInfo *) NULL)
2404     {
2405       (void) CopyMagickString(value,MagickOptionToMnemonic(
2406         MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),MaxTextExtent);
2407       (void) SetXMLTreeContent(child,value);
2408     }
2409   child=AddChildToXMLTree(xml_info,"decorate",0);
2410   if (child != (XMLTreeInfo *) NULL)
2411     {
2412       (void) CopyMagickString(value,MagickOptionToMnemonic(
2413         MagickDecorateOptions,(ssize_t) CurrentContext->decorate),MaxTextExtent);
2414       (void) SetXMLTreeContent(child,value);
2415     }
2416   child=AddChildToXMLTree(xml_info,"encoding",0);
2417   if (child != (XMLTreeInfo *) NULL)
2418     (void) SetXMLTreeContent(child,CurrentContext->encoding);
2419   child=AddChildToXMLTree(xml_info,"fill",0);
2420   if (child != (XMLTreeInfo *) NULL)
2421     {
2422       if (CurrentContext->fill.opacity != OpaqueOpacity)
2423         pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2424           MagickTrue : MagickFalse;
2425       SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2426         (const IndexPacket *) NULL,&pixel);
2427       GetColorTuple(&pixel,MagickTrue,value);
2428       (void) SetXMLTreeContent(child,value);
2429     }
2430   child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2431   if (child != (XMLTreeInfo *) NULL)
2432     {
2433       (void) FormatMagickString(value,MaxTextExtent,"%g",
2434         (double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity));
2435       (void) SetXMLTreeContent(child,value);
2436     }
2437   child=AddChildToXMLTree(xml_info,"fill-rule",0);
2438   if (child != (XMLTreeInfo *) NULL)
2439     {
2440       (void) CopyMagickString(value,MagickOptionToMnemonic(
2441         MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),MaxTextExtent);
2442       (void) SetXMLTreeContent(child,value);
2443     }
2444   child=AddChildToXMLTree(xml_info,"font",0);
2445   if (child != (XMLTreeInfo *) NULL)
2446     (void) SetXMLTreeContent(child,CurrentContext->font);
2447   child=AddChildToXMLTree(xml_info,"font-family",0);
2448   if (child != (XMLTreeInfo *) NULL)
2449     (void) SetXMLTreeContent(child,CurrentContext->family);
2450   child=AddChildToXMLTree(xml_info,"font-size",0);
2451   if (child != (XMLTreeInfo *) NULL)
2452     {
2453       (void) FormatMagickString(value,MaxTextExtent,"%g",
2454         CurrentContext->pointsize);
2455       (void) SetXMLTreeContent(child,value);
2456     }
2457   child=AddChildToXMLTree(xml_info,"font-stretch",0);
2458   if (child != (XMLTreeInfo *) NULL)
2459     {
2460       (void) CopyMagickString(value,MagickOptionToMnemonic(
2461         MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
2462       (void) SetXMLTreeContent(child,value);
2463     }
2464   child=AddChildToXMLTree(xml_info,"font-style",0);
2465   if (child != (XMLTreeInfo *) NULL)
2466     {
2467       (void) CopyMagickString(value,MagickOptionToMnemonic(
2468         MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
2469       (void) SetXMLTreeContent(child,value);
2470     }
2471   child=AddChildToXMLTree(xml_info,"font-weight",0);
2472   if (child != (XMLTreeInfo *) NULL)
2473     {
2474       (void) FormatMagickString(value,MaxTextExtent,"%lu",(unsigned long)
2475         CurrentContext->weight);
2476       (void) SetXMLTreeContent(child,value);
2477     }
2478   child=AddChildToXMLTree(xml_info,"gravity",0);
2479   if (child != (XMLTreeInfo *) NULL)
2480     {
2481       (void) CopyMagickString(value,MagickOptionToMnemonic(MagickGravityOptions,
2482         (ssize_t) CurrentContext->gravity),MaxTextExtent);
2483       (void) SetXMLTreeContent(child,value);
2484     }
2485   child=AddChildToXMLTree(xml_info,"stroke",0);
2486   if (child != (XMLTreeInfo *) NULL)
2487     {
2488       if (CurrentContext->stroke.opacity != OpaqueOpacity)
2489         pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2490           MagickTrue : MagickFalse;
2491       SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2492         (const IndexPacket *) NULL,&pixel);
2493       GetColorTuple(&pixel,MagickTrue,value);
2494       (void) SetXMLTreeContent(child,value);
2495     }
2496   child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2497   if (child != (XMLTreeInfo *) NULL)
2498     {
2499       (void) FormatMagickString(value,MaxTextExtent,"%d",
2500         CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2501       (void) SetXMLTreeContent(child,value);
2502     }
2503   child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2504   if ((child != (XMLTreeInfo *) NULL) &&
2505       (CurrentContext->dash_pattern != (double *) NULL))
2506     {
2507       char
2508         *dash_pattern;
2509
2510       dash_pattern=AcquireString((char *) NULL);
2511       for (i=0; CurrentContext->dash_pattern[i] != 0.0; i++)
2512       {
2513         if (i != 0)
2514           (void) ConcatenateString(&dash_pattern,",");
2515         (void) FormatMagickString(value,MaxTextExtent,"%g",
2516           CurrentContext->dash_pattern[i]);
2517         (void) ConcatenateString(&dash_pattern,value);
2518       }
2519       (void) SetXMLTreeContent(child,dash_pattern);
2520       dash_pattern=DestroyString(dash_pattern);
2521     }
2522   child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2523   if (child != (XMLTreeInfo *) NULL)
2524     {
2525       (void) FormatMagickString(value,MaxTextExtent,"%g",
2526         CurrentContext->dash_offset);
2527       (void) SetXMLTreeContent(child,value);
2528     }
2529   child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2530   if (child != (XMLTreeInfo *) NULL)
2531     {
2532       (void) CopyMagickString(value,MagickOptionToMnemonic(MagickLineCapOptions,
2533         (ssize_t) CurrentContext->linecap),MaxTextExtent);
2534       (void) SetXMLTreeContent(child,value);
2535     }
2536   child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2537   if (child != (XMLTreeInfo *) NULL)
2538     {
2539       (void) CopyMagickString(value,MagickOptionToMnemonic(
2540         MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2541         MaxTextExtent);
2542       (void) SetXMLTreeContent(child,value);
2543     }
2544   child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2545   if (child != (XMLTreeInfo *) NULL)
2546     {
2547       (void) FormatMagickString(value,MaxTextExtent,"%lu",(unsigned long)
2548         CurrentContext->miterlimit);
2549       (void) SetXMLTreeContent(child,value);
2550     }
2551   child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2552   if (child != (XMLTreeInfo *) NULL)
2553     {
2554       (void) FormatMagickString(value,MaxTextExtent,"%g",
2555         (double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity));
2556       (void) SetXMLTreeContent(child,value);
2557     }
2558   child=AddChildToXMLTree(xml_info,"stroke-width",0);
2559   if (child != (XMLTreeInfo *) NULL)
2560     {
2561       (void) FormatMagickString(value,MaxTextExtent,"%g",
2562         CurrentContext->stroke_width);
2563       (void) SetXMLTreeContent(child,value);
2564     }
2565   child=AddChildToXMLTree(xml_info,"text-align",0);
2566   if (child != (XMLTreeInfo *) NULL)
2567     {
2568       (void) CopyMagickString(value,MagickOptionToMnemonic(MagickAlignOptions,
2569         (ssize_t) CurrentContext->align),MaxTextExtent);
2570       (void) SetXMLTreeContent(child,value);
2571     }
2572   child=AddChildToXMLTree(xml_info,"text-antialias",0);
2573   if (child != (XMLTreeInfo *) NULL)
2574     {
2575       (void) FormatMagickString(value,MaxTextExtent,"%d",
2576         CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2577       (void) SetXMLTreeContent(child,value);
2578     }
2579   child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2580   if (child != (XMLTreeInfo *) NULL)
2581     {
2582       if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2583         pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2584           MagickTrue : MagickFalse;
2585       SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2586         (const IndexPacket *) NULL,&pixel);
2587       GetColorTuple(&pixel,MagickTrue,value);
2588       (void) SetXMLTreeContent(child,value);
2589     }
2590   child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2591   if (child != (XMLTreeInfo *) NULL)
2592     (void) SetXMLTreeContent(child,wand->mvg);
2593   xml=XMLTreeInfoToXML(xml_info);
2594   xml_info=DestroyXMLTree(xml_info);
2595   return(xml);
2596 }
2597 \f
2598 /*
2599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2600 %                                                                             %
2601 %                                                                             %
2602 %                                                                             %
2603 %   D r a w G e t T e x t U n d e r C o l o r                                 %
2604 %                                                                             %
2605 %                                                                             %
2606 %                                                                             %
2607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2608 %
2609 %  DrawGetTextUnderColor() returns the color of a background rectangle
2610 %  to place under text annotations.
2611 %
2612 %  The format of the DrawGetTextUnderColor method is:
2613 %
2614 %      void DrawGetTextUnderColor(const DrawingWand *wand,
2615 %        PixelWand *under_color)
2616 %
2617 %  A description of each parameter follows:
2618 %
2619 %    o wand: the drawing wand.
2620 %
2621 %    o under_color: Return the under color.
2622 %
2623 */
2624 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2625   PixelWand *under_color)
2626 {
2627   assert(wand != (const DrawingWand *) NULL);
2628   assert(wand->signature == WandSignature);
2629   assert(under_color != (PixelWand *) NULL);
2630   if (wand->debug != MagickFalse)
2631     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2632   PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2633 }
2634 \f
2635 /*
2636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2637 %                                                                             %
2638 %                                                                             %
2639 %                                                                             %
2640 %   D r a w L i n e                                                           %
2641 %                                                                             %
2642 %                                                                             %
2643 %                                                                             %
2644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2645 %
2646 %  DrawLine() draws a line on the image using the current stroke color,
2647 %  stroke opacity, and stroke width.
2648 %
2649 %  The format of the DrawLine method is:
2650 %
2651 %      void DrawLine(DrawingWand *wand,const double sx,const double sy,
2652 %        const double ex,const double ey)
2653 %
2654 %  A description of each parameter follows:
2655 %
2656 %    o wand: the drawing wand.
2657 %
2658 %    o sx: starting x ordinate
2659 %
2660 %    o sy: starting y ordinate
2661 %
2662 %    o ex: ending x ordinate
2663 %
2664 %    o ey: ending y ordinate
2665 %
2666 */
2667 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2668   const double ex,const double ey)
2669 {
2670   assert(wand != (DrawingWand *) NULL);
2671   assert(wand->signature == WandSignature);
2672   if (wand->debug != MagickFalse)
2673     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2674   (void) MvgPrintf(wand,"line %g,%g %g,%g\n",sx,sy,ex,ey);
2675 }
2676 \f
2677 /*
2678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2679 %                                                                             %
2680 %                                                                             %
2681 %                                                                             %
2682 %   D r a w M a t t e                                                         %
2683 %                                                                             %
2684 %                                                                             %
2685 %                                                                             %
2686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2687 %
2688 %  DrawMatte() paints on the image's opacity channel in order to set effected
2689 %  pixels to transparent.
2690 %  to influence the opacity of pixels. The available paint
2691 %  methods are:
2692 %
2693 %    PointMethod: Select the target pixel
2694 %    ReplaceMethod: Select any pixel that matches the target pixel.
2695 %    FloodfillMethod: Select the target pixel and matching neighbors.
2696 %    FillToBorderMethod: Select the target pixel and neighbors not matching
2697 %      border color.
2698 %    ResetMethod: Select all pixels.
2699 %
2700 %  The format of the DrawMatte method is:
2701 %
2702 %      void DrawMatte(DrawingWand *wand,const double x,const double y,
2703 %        const PaintMethod paint_method)
2704 %
2705 %  A description of each parameter follows:
2706 %
2707 %    o wand: the drawing wand.
2708 %
2709 %    o x: x ordinate
2710 %
2711 %    o y: y ordinate
2712 %
2713 %    o paint_method: paint method.
2714 %
2715 */
2716 WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2717   const PaintMethod paint_method)
2718 {
2719   assert(wand != (DrawingWand *) NULL);
2720   assert(wand->signature == WandSignature);
2721   if (wand->debug != MagickFalse)
2722     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2723   (void) MvgPrintf(wand,"matte %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
2724     MagickMethodOptions,(ssize_t) paint_method));
2725 }
2726 \f
2727 /*
2728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2729 %                                                                             %
2730 %                                                                             %
2731 %                                                                             %
2732 %   D r a w P a t h C l o s e                                                 %
2733 %                                                                             %
2734 %                                                                             %
2735 %                                                                             %
2736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2737 %
2738 %  DrawPathClose() adds a path element to the current path which closes the
2739 %  current subpath by drawing a straight line from the current point to the
2740 %  current subpath's most recent starting point (usually, the most recent
2741 %  moveto point).
2742 %
2743 %  The format of the DrawPathClose method is:
2744 %
2745 %      void DrawPathClose(DrawingWand *wand)
2746 %
2747 %  A description of each parameter follows:
2748 %
2749 %    o wand: the drawing wand.
2750 %
2751 */
2752 WandExport void DrawPathClose(DrawingWand *wand)
2753 {
2754   assert(wand != (DrawingWand *) NULL);
2755   assert(wand->signature == WandSignature);
2756   if (wand->debug != MagickFalse)
2757     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2758   (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2759     "Z" : "z");
2760 }
2761 \f
2762 /*
2763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2764 %                                                                             %
2765 %                                                                             %
2766 %                                                                             %
2767 %   D r a w P a t h C u r v e T o A b s o l u t e                             %
2768 %                                                                             %
2769 %                                                                             %
2770 %                                                                             %
2771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2772 %
2773 %  DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2774 %  point to (x,y) using (x1,y1) as the control point at the beginning of
2775 %  the curve and (x2,y2) as the control point at the end of the curve using
2776 %  absolute coordinates. At the end of the command, the new current point
2777 %  becomes the final (x,y) coordinate pair used in the polybezier.
2778 %
2779 %  The format of the DrawPathCurveToAbsolute method is:
2780 %
2781 %      void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2782 %        const double y1,const double x2,const double y2,const double x,
2783 %        const double y)
2784 %
2785 %  A description of each parameter follows:
2786 %
2787 %    o wand: the drawing wand.
2788 %
2789 %    o x1: x ordinate of control point for curve beginning
2790 %
2791 %    o y1: y ordinate of control point for curve beginning
2792 %
2793 %    o x2: x ordinate of control point for curve ending
2794 %
2795 %    o y2: y ordinate of control point for curve ending
2796 %
2797 %    o x: x ordinate of the end of the curve
2798 %
2799 %    o y: y ordinate of the end of the curve
2800 %
2801 */
2802
2803 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2804   const double x1,const double y1,const double x2,const double y2,
2805   const double x,const double y)
2806 {
2807   assert(wand != (DrawingWand *) NULL);
2808   assert(wand->signature == WandSignature);
2809   if (wand->debug != MagickFalse)
2810     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2811   if ((wand->path_operation != PathCurveToOperation) ||
2812       (wand->path_mode != mode))
2813     {
2814       wand->path_operation=PathCurveToOperation;
2815       wand->path_mode=mode;
2816       (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g %g,%g",
2817         mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2818     }
2819   else
2820     (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g %g,%g",x1,y1,
2821       x2,y2,x,y);
2822 }
2823
2824 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2825   const double y1,const double x2,const double y2,const double x,const double y)
2826 {
2827   assert(wand != (DrawingWand *) NULL);
2828   assert(wand->signature == WandSignature);
2829   if (wand->debug != MagickFalse)
2830     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2831   DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2832 }
2833 \f
2834 /*
2835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2836 %                                                                             %
2837 %                                                                             %
2838 %                                                                             %
2839 %   D r a w P a t h C u r v e T o R e l a t i v e                             %
2840 %                                                                             %
2841 %                                                                             %
2842 %                                                                             %
2843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2844 %
2845 %  DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2846 %  point to (x,y) using (x1,y1) as the control point at the beginning of
2847 %  the curve and (x2,y2) as the control point at the end of the curve using
2848 %  relative coordinates. At the end of the command, the new current point
2849 %  becomes the final (x,y) coordinate pair used in the polybezier.
2850 %
2851 %  The format of the DrawPathCurveToRelative method is:
2852 %
2853 %      void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2854 %        const double y1,const double x2,const double y2,const double x,
2855 %        const double y)
2856 %
2857 %  A description of each parameter follows:
2858 %
2859 %    o wand: the drawing wand.
2860 %
2861 %    o x1: x ordinate of control point for curve beginning
2862 %
2863 %    o y1: y ordinate of control point for curve beginning
2864 %
2865 %    o x2: x ordinate of control point for curve ending
2866 %
2867 %    o y2: y ordinate of control point for curve ending
2868 %
2869 %    o x: x ordinate of the end of the curve
2870 %
2871 %    o y: y ordinate of the end of the curve
2872 %
2873 */
2874 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2875   const double y1,const double x2,const double y2,const double x,const double y)
2876 {
2877   assert(wand != (DrawingWand *) NULL);
2878   assert(wand->signature == WandSignature);
2879   if (wand->debug != MagickFalse)
2880     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2881   DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2882 }
2883 \f
2884 /*
2885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2886 %                                                                             %
2887 %                                                                             %
2888 %                                                                             %
2889 %   D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r A b s o l u t e %
2890 %                                                                             %
2891 %                                                                             %
2892 %                                                                             %
2893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2894 %
2895 %  DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2896 %  from the current point to (x,y) using (x1,y1) as the control point using
2897 %  absolute coordinates. At the end of the command, the new current point
2898 %  becomes the final (x,y) coordinate pair used in the polybezier.
2899 %
2900 %  The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2901 %
2902 %      void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2903 %        const double x1,const double y1,onst double x,const double y)
2904 %
2905 %  A description of each parameter follows:
2906 %
2907 %    o wand: the drawing wand.
2908 %
2909 %    o x1: x ordinate of the control point
2910 %
2911 %    o y1: y ordinate of the control point
2912 %
2913 %    o x: x ordinate of final point
2914 %
2915 %    o y: y ordinate of final point
2916 %
2917 */
2918
2919 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2920   const PathMode mode,const double x1,double y1,const double x,const double y)
2921 {
2922   assert(wand != (DrawingWand *) NULL);
2923   assert(wand->signature == WandSignature);
2924   if (wand->debug != MagickFalse)
2925     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2926   if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2927       (wand->path_mode != mode))
2928     {
2929       wand->path_operation=PathCurveToQuadraticBezierOperation;
2930       wand->path_mode=mode;
2931       (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g",
2932          mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
2933     }
2934   else
2935     (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x1,y1,x,y);
2936 }
2937
2938 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2939   const double x1,const double y1,const double x,const double y)
2940 {
2941   assert(wand != (DrawingWand *) NULL);
2942   assert(wand->signature == WandSignature);
2943   if (wand->debug != MagickFalse)
2944     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2945   DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
2946 }
2947 \f
2948 /*
2949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2950 %                                                                             %
2951 %                                                                             %
2952 %                                                                             %
2953 %   D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r R e l a t i v e
2954 %                                                                             %
2955 %                                                                             %
2956 %                                                                             %
2957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2958 %
2959 %  DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
2960 %  from the current point to (x,y) using (x1,y1) as the control point using
2961 %  relative coordinates. At the end of the command, the new current point
2962 %  becomes the final (x,y) coordinate pair used in the polybezier.
2963 %
2964 %  The format of the DrawPathCurveToQuadraticBezierRelative method is:
2965 %
2966 %      void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2967 %        const double x1,const double y1,const double x,const double y)
2968 %
2969 %  A description of each parameter follows:
2970 %
2971 %    o wand: the drawing wand.
2972 %
2973 %    o x1: x ordinate of the control point
2974 %
2975 %    o y1: y ordinate of the control point
2976 %
2977 %    o x: x ordinate of final point
2978 %
2979 %    o y: y ordinate of final point
2980 %
2981 */
2982 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2983   const double x1,const double y1,const double x,const double y)
2984 {
2985   assert(wand != (DrawingWand *) NULL);
2986   assert(wand->signature == WandSignature);
2987   if (wand->debug != MagickFalse)
2988     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2989   DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
2990 }
2991 \f
2992 /*
2993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2994 %                                                                             %
2995 %                                                                             %
2996 %                                                                             %
2997 %   D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h   %
2998 %                                                                             %
2999 %                                                                             %
3000 %                                                                             %
3001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3002 %
3003 %  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3004 %  Bezier curve (using absolute coordinates) from the current point to
3005 %  (x,y). The control point is assumed to be the reflection of the
3006 %  control point on the previous command relative to the current
3007 %  point. (If there is no previous command or if the previous command was
3008 %  not a DrawPathCurveToQuadraticBezierAbsolute,
3009 %  DrawPathCurveToQuadraticBezierRelative,
3010 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
3011 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3012 %  is coincident with the current point.). At the end of the command, the
3013 %  new current point becomes the final (x,y) coordinate pair used in the
3014 %  polybezier.
3015 %
3016 %  The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3017 %
3018 %      void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3019 %        DrawingWand *wand,const double x,const double y)
3020 %
3021 %  A description of each parameter follows:
3022 %
3023 %    o wand: the drawing wand.
3024 %
3025 %    o x: x ordinate of final point
3026 %
3027 %    o y: y ordinate of final point
3028 %
3029 */
3030
3031 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3032   const PathMode mode,const double x,const double y)
3033 {
3034   assert(wand != (DrawingWand *) NULL);
3035   assert(wand->signature == WandSignature);
3036   if (wand->debug != MagickFalse)
3037     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3038   if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3039       (wand->path_mode != mode))
3040     {
3041       wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3042       wand->path_mode=mode;
3043       (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3044         'T' : 't',x,y);
3045     }
3046   else
3047     (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3048 }
3049
3050 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3051   const double x,const double y)
3052 {
3053   assert(wand != (DrawingWand *) NULL);
3054   assert(wand->signature == WandSignature);
3055   if (wand->debug != MagickFalse)
3056     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3057   DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3058 }
3059 \f
3060 /*
3061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3062 %                                                                             %
3063 %                                                                             %
3064 %                                                                             %
3065 %   D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h   %
3066 %                                                                             %
3067 %                                                                             %
3068 %                                                                             %
3069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3070 %
3071 %  DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3072 %  curve (using relative coordinates) from the current point to (x,y). The
3073 %  control point is assumed to be the reflection of the control point on the
3074 %  previous command relative to the current point. (If there is no previous
3075 %  command or if the previous command was not a
3076 %  DrawPathCurveToQuadraticBezierAbsolute,
3077 %  DrawPathCurveToQuadraticBezierRelative,
3078 %  DrawPathCurveToQuadraticBezierSmoothAbsolute or
3079 %  DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3080 %  coincident with the current point.). At the end of the command, the new
3081 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
3082 %
3083 %  The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3084 %
3085 %      void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3086 %        const double x,const double y)
3087 %
3088 %  A description of each parameter follows:
3089 %
3090 %    o wand: the drawing wand.
3091 %
3092 %    o x: x ordinate of final point
3093 %
3094 %    o y: y ordinate of final point
3095 %
3096 */
3097 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3098   const double x,const double y)
3099 {
3100   DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3101 }
3102 \f
3103 /*
3104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3105 %                                                                             %
3106 %                                                                             %
3107 %                                                                             %
3108 %   D r a w P a t h C u r v e T o S m o o t h A b s o l u t e                 %
3109 %                                                                             %
3110 %                                                                             %
3111 %                                                                             %
3112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3113 %
3114 %  DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3115 %  current point to (x,y) using absolute coordinates. The first control
3116 %  point is assumed to be the reflection of the second control point on
3117 %  the previous command relative to the current point. (If there is no
3118 %  previous command or if the previous command was not an
3119 %  DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3120 %  DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3121 %  the first control point is coincident with the current point.) (x2,y2)
3122 %  is the second control point (i.e., the control point at the end of the
3123 %  curve). At the end of the command, the new current point becomes the
3124 %  final (x,y) coordinate pair used in the polybezier.
3125 %
3126 %  The format of the DrawPathCurveToSmoothAbsolute method is:
3127 %
3128 %      void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3129 %        const double x2const double y2,const double x,const double y)
3130 %
3131 %  A description of each parameter follows:
3132 %
3133 %    o wand: the drawing wand.
3134 %
3135 %    o x2: x ordinate of second control point
3136 %
3137 %    o y2: y ordinate of second control point
3138 %
3139 %    o x: x ordinate of termination point
3140 %
3141 %    o y: y ordinate of termination point
3142 %
3143 */
3144
3145 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3146   const double x2,const double y2,const double x,const double y)
3147 {
3148   assert(wand != (DrawingWand *) NULL);
3149   assert(wand->signature == WandSignature);
3150   if (wand->debug != MagickFalse)
3151     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3152   if ((wand->path_operation != PathCurveToSmoothOperation) ||
3153       (wand->path_mode != mode))
3154     {
3155       wand->path_operation=PathCurveToSmoothOperation;
3156       wand->path_mode=mode;
3157       (void) MvgAutoWrapPrintf(wand,"%c%g,%g %g,%g",
3158         mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
3159     }
3160   else
3161     (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x2,y2,x,y);
3162 }
3163
3164 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3165   const double y2,const double x,const double y)
3166 {
3167   assert(wand != (DrawingWand *) NULL);
3168   assert(wand->signature == WandSignature);
3169   if (wand->debug != MagickFalse)
3170     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3171   DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3172 }
3173 \f
3174 /*
3175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3176 %                                                                             %
3177 %                                                                             %
3178 %                                                                             %
3179 %   D r a w P a t h C u r v e T o S m o o t h R e l a t i v e                 %
3180 %                                                                             %
3181 %                                                                             %
3182 %                                                                             %
3183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3184 %
3185 %  DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3186 %  point to (x,y) using relative coordinates. The first control point is
3187 %  assumed to be the reflection of the second control point on the previous
3188 %  command relative to the current point. (If there is no previous command or
3189 %  if the previous command was not an DrawPathCurveToAbsolute,
3190 %  DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3191 %  DrawPathCurveToSmoothRelative, assume the first control point is coincident
3192 %  with the current point.) (x2,y2) is the second control point (i.e., the
3193 %  control point at the end of the curve). At the end of the command, the new
3194 %  current point becomes the final (x,y) coordinate pair used in the polybezier.
3195 %
3196 %  The format of the DrawPathCurveToSmoothRelative method is:
3197 %
3198 %      void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3199 %        const double x2,const double y2,const double x,const double y)
3200 %
3201 %  A description of each parameter follows:
3202 %
3203 %    o wand: the drawing wand.
3204 %
3205 %    o x2: x ordinate of second control point
3206 %
3207 %    o y2: y ordinate of second control point
3208 %
3209 %    o x: x ordinate of termination point
3210 %
3211 %    o y: y ordinate of termination point
3212 %
3213 */
3214 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3215   const double y2,const double x,const double y)
3216 {
3217   assert(wand != (DrawingWand *) NULL);
3218   assert(wand->signature == WandSignature);
3219   if (wand->debug != MagickFalse)
3220     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3221   DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3222 }
3223 \f
3224 /*
3225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3226 %                                                                             %
3227 %                                                                             %
3228 %                                                                             %
3229 %   D r a w P a t h E l l i p t i c A r c A b s o l u t e                     %
3230 %                                                                             %
3231 %                                                                             %
3232 %                                                                             %
3233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3234 %
3235 %  DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3236 %  to (x, y) using absolute coordinates. The size and orientation of the
3237 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3238 %  indicates how the ellipse as a whole is rotated relative to the current
3239 %  coordinate system. The center (cx, cy) of the ellipse is calculated
3240 %  automagically to satisfy the constraints imposed by the other parameters.
3241 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
3242 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
3243 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
3244 %  clock-wise rotation.
3245 %
3246 %  The format of the DrawPathEllipticArcAbsolute method is:
3247 %
3248 %      void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3249 %        const double rx,const double ry,const double x_axis_rotation,
3250 %        const MagickBooleanType large_arc_flag,
3251 %        const MagickBooleanType sweep_flag,const double x,const double y)
3252 %
3253 %  A description of each parameter follows:
3254 %
3255 %    o wand: the drawing wand.
3256 %
3257 %    o rx: x radius
3258 %
3259 %    o ry: y radius
3260 %
3261 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
3262 %        relative to the current coordinate system
3263 %
3264 %    o large_arc_flag: If non-zero (true) then draw the larger of the
3265 %        available arcs
3266 %
3267 %    o sweep_flag: If non-zero (true) then draw the arc matching a
3268 %        clock-wise rotation
3269 %
3270 %
3271 */
3272
3273 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3274   const double rx,const double ry,const double x_axis_rotation,
3275   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3276   const double x,const double y)
3277 {
3278   assert(wand != (DrawingWand *) NULL);
3279   assert(wand->signature == WandSignature);
3280   if (wand->debug != MagickFalse)
3281     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3282   if ((wand->path_operation != PathEllipticArcOperation) ||
3283       (wand->path_mode != mode))
3284     {
3285       wand->path_operation=PathEllipticArcOperation;
3286       wand->path_mode=mode;
3287       (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g %u %u %g,%g",
3288         mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3289         large_arc_flag,sweep_flag,x,y);
3290     }
3291   else
3292     (void) MvgAutoWrapPrintf(wand," %g,%g %g %u %u %g,%g",rx,ry,
3293       x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3294 }
3295
3296 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3297   const double ry,const double x_axis_rotation,
3298   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3299   const double x,const double y)
3300 {
3301   assert(wand != (DrawingWand *) NULL);
3302   assert(wand->signature == WandSignature);
3303   if (wand->debug != MagickFalse)
3304     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3305   DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3306     large_arc_flag,sweep_flag,x,y);
3307 }
3308 \f
3309 /*
3310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3311 %                                                                             %
3312 %                                                                             %
3313 %                                                                             %
3314 %   D r a w P a t h E l l i p t i c A r c R e l a t i v e                     %
3315 %                                                                             %
3316 %                                                                             %
3317 %                                                                             %
3318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3319 %
3320 %  DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3321 %  to (x, y) using relative coordinates. The size and orientation of the
3322 %  ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3323 %  indicates how the ellipse as a whole is rotated relative to the current
3324 %  coordinate system. The center (cx, cy) of the ellipse is calculated
3325 %  automagically to satisfy the constraints imposed by the other parameters.
3326 %  largeArcFlag and sweepFlag contribute to the automatic calculations and help
3327 %  determine how the arc is drawn. If largeArcFlag is true then draw the larger
3328 %  of the available arcs. If sweepFlag is true, then draw the arc matching a
3329 %  clock-wise rotation.
3330 %
3331 %  The format of the DrawPathEllipticArcRelative method is:
3332 %
3333 %      void DrawPathEllipticArcRelative(DrawingWand *wand,
3334 %        const double rx,const double ry,const double x_axis_rotation,
3335 %        const MagickBooleanType large_arc_flag,
3336 %        const MagickBooleanType sweep_flag,const double x,const double y)
3337 %
3338 %  A description of each parameter follows:
3339 %
3340 %    o wand: the drawing wand.
3341 %
3342 %    o rx: x radius
3343 %
3344 %    o ry: y radius
3345 %
3346 %    o x_axis_rotation: indicates how the ellipse as a whole is rotated
3347 %                       relative to the current coordinate system
3348 %
3349 %    o large_arc_flag: If non-zero (true) then draw the larger of the
3350 %                      available arcs
3351 %
3352 %    o sweep_flag: If non-zero (true) then draw the arc matching a
3353 %                  clock-wise rotation
3354 %
3355 */
3356 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3357   const double ry,const double x_axis_rotation,
3358   const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3359   const double x,const double y)
3360 {
3361   DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3362     large_arc_flag,sweep_flag,x,y);
3363 }
3364 \f
3365 /*
3366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3367 %                                                                             %
3368 %                                                                             %
3369 %                                                                             %
3370 %   D r a w P a t h F i n i s h                                               %
3371 %                                                                             %
3372 %                                                                             %
3373 %                                                                             %
3374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3375 %
3376 %  DrawPathFinish() terminates the current path.
3377 %
3378 %  The format of the DrawPathFinish method is:
3379 %
3380 %      void DrawPathFinish(DrawingWand *wand)
3381 %
3382 %  A description of each parameter follows:
3383 %
3384 %    o wand: the drawing wand.
3385 %
3386 */
3387 WandExport void DrawPathFinish(DrawingWand *wand)
3388 {
3389   assert(wand != (DrawingWand *) NULL);
3390   assert(wand->signature == WandSignature);
3391   if (wand->debug != MagickFalse)
3392     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3393   (void) MvgPrintf(wand,"'\n");
3394   wand->path_operation=PathDefaultOperation;
3395   wand->path_mode=DefaultPathMode;
3396 }
3397 \f
3398 /*
3399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3400 %                                                                             %
3401 %                                                                             %
3402 %                                                                             %
3403 %   D r a w P a t h L i n e T o A b s o l u t e                               %
3404 %                                                                             %
3405 %                                                                             %
3406 %                                                                             %
3407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3408 %
3409 %  DrawPathLineToAbsolute() draws a line path from the current point to the
3410 %  given coordinate using absolute coordinates. The coordinate then becomes
3411 %  the new current point.
3412 %
3413 %  The format of the DrawPathLineToAbsolute method is:
3414 %
3415 %      void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3416 %        const double y)
3417 %
3418 %  A description of each parameter follows:
3419 %
3420 %    o wand: the drawing wand.
3421 %
3422 %    o x: target x ordinate
3423 %
3424 %    o y: target y ordinate
3425 %
3426 */
3427 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3428   const double x,const double y)
3429 {
3430   assert(wand != (DrawingWand *) NULL);
3431   assert(wand->signature == WandSignature);
3432   if (wand->debug != MagickFalse)
3433     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3434   if ((wand->path_operation != PathLineToOperation) ||
3435       (wand->path_mode != mode))
3436     {
3437       wand->path_operation=PathLineToOperation;
3438       wand->path_mode=mode;
3439       (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3440         'L' : 'l',x,y);
3441     }
3442   else
3443     (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3444 }
3445
3446 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3447   const double y)
3448 {
3449   assert(wand != (DrawingWand *) NULL);
3450   assert(wand->signature == WandSignature);
3451   if (wand->debug != MagickFalse)
3452     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3453   DrawPathLineTo(wand,AbsolutePathMode,x,y);
3454 }
3455 \f
3456 /*
3457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3458 %                                                                             %
3459 %                                                                             %
3460 %                                                                             %
3461 %   D r a w P a t h L i n e T o R e l a t i v e                               %
3462 %                                                                             %
3463 %                                                                             %
3464 %                                                                             %
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3466 %
3467 %  DrawPathLineToRelative() draws a line path from the current point to the
3468 %  given coordinate using relative coordinates. The coordinate then becomes
3469 %  the new current point.
3470 %
3471 %  The format of the DrawPathLineToRelative method is:
3472 %
3473 %      void DrawPathLineToRelative(DrawingWand *wand,const double x,
3474 %        const double y)
3475 %
3476 %  A description of each parameter follows:
3477 %
3478 %    o wand: the drawing wand.
3479 %
3480 %    o x: target x ordinate
3481 %
3482 %    o y: target y ordinate
3483 %
3484 */
3485 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3486   const double y)
3487 {
3488   assert(wand != (DrawingWand *) NULL);
3489   assert(wand->signature == WandSignature);
3490   if (wand->debug != MagickFalse)
3491     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3492   DrawPathLineTo(wand,RelativePathMode,x,y);
3493 }
3494 \f
3495 /*
3496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3497 %                                                                             %
3498 %                                                                             %
3499 %                                                                             %
3500 %   D r a w P a t h L i n e T o H o r i z o n t a l A b s o l u t e           %
3501 %                                                                             %
3502 %                                                                             %
3503 %                                                                             %
3504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3505 %
3506 %  DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3507 %  current point to the target point using absolute coordinates.  The target
3508 %  point then becomes the new current point.
3509 %
3510 %  The format of the DrawPathLineToHorizontalAbsolute method is:
3511 %
3512 %      void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3513 %        const PathMode mode,const double x)
3514 %
3515 %  A description of each parameter follows:
3516 %
3517 %    o wand: the drawing wand.
3518 %
3519 %    o x: target x ordinate
3520 %
3521 */
3522
3523 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3524   const double x)
3525 {
3526   assert(wand != (DrawingWand *) NULL);
3527   assert(wand->signature == WandSignature);
3528   if (wand->debug != MagickFalse)
3529     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3530   if ((wand->path_operation != PathLineToHorizontalOperation) ||
3531       (wand->path_mode != mode))
3532     {
3533       wand->path_operation=PathLineToHorizontalOperation;
3534       wand->path_mode=mode;
3535       (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3536         'H' : 'h',x);
3537     }
3538   else
3539     (void) MvgAutoWrapPrintf(wand," %g",x);
3540 }
3541
3542 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3543   const double x)
3544 {
3545   assert(wand != (DrawingWand *) NULL);
3546   assert(wand->signature == WandSignature);
3547   if (wand->debug != MagickFalse)
3548     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3549   DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3550 }
3551 \f
3552 /*
3553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3554 %                                                                             %
3555 %                                                                             %
3556 %                                                                             %
3557 %   D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e           %
3558 %                                                                             %
3559 %                                                                             %
3560 %                                                                             %
3561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3562 %
3563 %  DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3564 %  current point to the target point using relative coordinates.  The target
3565 %  point then becomes the new current point.
3566 %
3567 %  The format of the DrawPathLineToHorizontalRelative method is:
3568 %
3569 %      void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3570 %        const double x)
3571 %
3572 %  A description of each parameter follows:
3573 %
3574 %    o wand: the drawing wand.
3575 %
3576 %    o x: target x ordinate
3577 %
3578 */
3579 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3580   const double x)
3581 {
3582   DrawPathLineToHorizontal(wand,RelativePathMode,x);
3583 }
3584 \f
3585 /*
3586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3587 %                                                                             %
3588 %                                                                             %
3589 %                                                                             %
3590 %   D r a w P a t h L i n e T o V e r t i c a l A b s o l u t e               %
3591 %                                                                             %
3592 %                                                                             %
3593 %                                                                             %
3594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3595 %
3596 %  DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3597 %  current point to the target point using absolute coordinates.  The target
3598 %  point then becomes the new current point.
3599 %
3600 %  The format of the DrawPathLineToVerticalAbsolute method is:
3601 %
3602 %      void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3603 %        const double y)
3604 %
3605 %  A description of each parameter follows:
3606 %
3607 %    o wand: the drawing wand.
3608 %
3609 %    o y: target y ordinate
3610 %
3611 */
3612
3613 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3614   const double y)
3615 {
3616   assert(wand != (DrawingWand *) NULL);
3617   assert(wand->signature == WandSignature);
3618   if (wand->debug != MagickFalse)
3619     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3620   if ((wand->path_operation != PathLineToVerticalOperation) ||
3621       (wand->path_mode != mode))
3622     {
3623       wand->path_operation=PathLineToVerticalOperation;
3624       wand->path_mode=mode;
3625       (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3626         'V' : 'v',y);
3627     }
3628   else
3629     (void) MvgAutoWrapPrintf(wand," %g",y);
3630 }
3631
3632 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3633 {
3634   assert(wand != (DrawingWand *) NULL);
3635   assert(wand->signature == WandSignature);
3636   if (wand->debug != MagickFalse)
3637     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3638   DrawPathLineToVertical(wand,AbsolutePathMode,y);
3639 }
3640 \f
3641 /*
3642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3643 %                                                                             %
3644 %                                                                             %
3645 %                                                                             %
3646 %   D r a w P a t h L i n e T o V e r t i c a l R e l a t i v e               %
3647 %                                                                             %
3648 %                                                                             %
3649 %                                                                             %
3650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3651 %
3652 %  DrawPathLineToVerticalRelative() draws a vertical line path from the
3653 %  current point to the target point using relative coordinates.  The target
3654 %  point then becomes the new current point.
3655 %
3656 %  The format of the DrawPathLineToVerticalRelative method is:
3657 %
3658 %      void DrawPathLineToVerticalRelative(DrawingWand *wand,
3659 %        const double y)
3660 %
3661 %  A description of each parameter follows:
3662 %
3663 %    o wand: the drawing wand.
3664 %
3665 %    o y: target y ordinate
3666 %
3667 */
3668 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3669 {
3670   assert(wand != (DrawingWand *) NULL);
3671   assert(wand->signature == WandSignature);
3672   if (wand->debug != MagickFalse)
3673     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3674   DrawPathLineToVertical(wand,RelativePathMode,y);
3675 }
3676 /*
3677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3678 %                                                                             %
3679 %                                                                             %
3680 %                                                                             %
3681 %   D r a w P a t h M o v e T o A b s o l u t e                               %
3682 %                                                                             %
3683 %                                                                             %
3684 %                                                                             %
3685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3686 %
3687 %  DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3688 %  using absolute coordinates. The current point then becomes the
3689 %  specified coordinate.
3690 %
3691 %  The format of the DrawPathMoveToAbsolute method is:
3692 %
3693 %      void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3694 %        const double y)
3695 %
3696 %  A description of each parameter follows:
3697 %
3698 %    o wand: the drawing wand.
3699 %
3700 %    o x: target x ordinate
3701 %
3702 %    o y: target y ordinate
3703 %
3704 */
3705
3706 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3707   const double y)
3708 {
3709   assert(wand != (DrawingWand *) NULL);
3710   assert(wand->signature == WandSignature);
3711   if (wand->debug != MagickFalse)
3712     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3713   if ((wand->path_operation != PathMoveToOperation) ||
3714       (wand->path_mode != mode))
3715     {
3716       wand->path_operation=PathMoveToOperation;
3717       wand->path_mode=mode;
3718       (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3719         'M' : 'm',x,y);
3720     }
3721   else
3722     (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3723 }
3724
3725 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3726   const double y)
3727 {
3728   assert(wand != (DrawingWand *) NULL);
3729   assert(wand->signature == WandSignature);
3730   if (wand->debug != MagickFalse)
3731     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3732   DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3733 }
3734 \f
3735 /*
3736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3737 %                                                                             %
3738 %                                                                             %
3739 %                                                                             %
3740 %   D r a w P a t h M o v e T o R e l a t i v e                               %
3741 %                                                                             %
3742 %                                                                             %
3743 %                                                                             %
3744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3745 %
3746 %  DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3747 %  relative coordinates. The current point then becomes the specified
3748 %  coordinate.
3749 %
3750 %  The format of the DrawPathMoveToRelative method is:
3751 %
3752 %      void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3753 %        const double y)
3754 %
3755 %  A description of each parameter follows:
3756 %
3757 %    o wand: the drawing wand.
3758 %
3759 %    o x: target x ordinate
3760 %
3761 %    o y: target y ordinate
3762 %
3763 */
3764 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3765   const double y)
3766 {
3767   assert(wand != (DrawingWand *) NULL);
3768   assert(wand->signature == WandSignature);
3769   if (wand->debug != MagickFalse)
3770     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3771   DrawPathMoveTo(wand,RelativePathMode,x,y);
3772 }
3773 \f
3774 /*
3775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3776 %                                                                             %
3777 %                                                                             %
3778 %                                                                             %
3779 %   D r a w P a t h S t a r t                                                 %
3780 %                                                                             %
3781 %                                                                             %
3782 %                                                                             %
3783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3784 %
3785 %  DrawPathStart() declares the start of a path drawing list which is terminated
3786 %  by a matching DrawPathFinish() command. All other DrawPath commands must
3787 %  be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3788 %  is because path drawing commands are subordinate commands and they do not
3789 %  function by themselves.
3790 %
3791 %  The format of the DrawPathStart method is:
3792 %
3793 %      void DrawPathStart(DrawingWand *wand)
3794 %
3795 %  A description of each parameter follows:
3796 %
3797 %    o wand: the drawing wand.
3798 %
3799 */
3800 WandExport void DrawPathStart(DrawingWand *wand)
3801 {
3802   assert(wand != (DrawingWand *) NULL);
3803   assert(wand->signature == WandSignature);
3804   if (wand->debug != MagickFalse)
3805     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3806   (void) MvgPrintf(wand,"path '");
3807   wand->path_operation=PathDefaultOperation;
3808   wand->path_mode=DefaultPathMode;
3809 }
3810 \f
3811 /*
3812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3813 %                                                                             %
3814 %                                                                             %
3815 %                                                                             %
3816 %   D r a w P o i n t                                                         %
3817 %                                                                             %
3818 %                                                                             %
3819 %                                                                             %
3820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3821 %
3822 %  DrawPoint() draws a point using the current fill color.
3823 %
3824 %  The format of the DrawPoint method is:
3825 %
3826 %      void DrawPoint(DrawingWand *wand,const double x,const double y)
3827 %
3828 %  A description of each parameter follows:
3829 %
3830 %    o wand: the drawing wand.
3831 %
3832 %    o x: target x coordinate
3833 %
3834 %    o y: target y coordinate
3835 %
3836 */
3837 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3838 {
3839   assert(wand != (DrawingWand *) NULL);
3840   assert(wand->signature == WandSignature);
3841   if (wand->debug != MagickFalse)
3842     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3843   (void) MvgPrintf(wand,"point %g,%g\n",x,y);
3844 }
3845 \f
3846 /*
3847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3848 %                                                                             %
3849 %                                                                             %
3850 %                                                                             %
3851 %   D r a w P o l y g o n                                                     %
3852 %                                                                             %
3853 %                                                                             %
3854 %                                                                             %
3855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3856 %
3857 %  DrawPolygon() draws a polygon using the current stroke, stroke width, and
3858 %  fill color or texture, using the specified array of coordinates.
3859 %
3860 %  The format of the DrawPolygon method is:
3861 %
3862 %      void DrawPolygon(DrawingWand *wand,
3863 %        const size_t number_coordinates,const PointInfo *coordinates)
3864 %
3865 %  A description of each parameter follows:
3866 %
3867 %    o wand: the drawing wand.
3868 %
3869 %    o number_coordinates: number of coordinates
3870 %
3871 %    o coordinates: coordinate array
3872 %
3873 */
3874 WandExport void DrawPolygon(DrawingWand *wand,
3875   const size_t number_coordinates,const PointInfo *coordinates)
3876 {
3877   assert(wand != (DrawingWand *) NULL);
3878   assert(wand->signature == WandSignature);
3879   if (wand->debug != MagickFalse)
3880     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3881   MvgAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3882 }
3883 \f
3884 /*
3885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3886 %                                                                             %
3887 %                                                                             %
3888 %                                                                             %
3889 %   D r a w P o l y l i n e                                                   %
3890 %                                                                             %
3891 %                                                                             %
3892 %                                                                             %
3893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3894 %
3895 %  DrawPolyline() draws a polyline using the current stroke, stroke width, and
3896 %  fill color or texture, using the specified array of coordinates.
3897 %
3898 %  The format of the DrawPolyline method is:
3899 %
3900 %      void DrawPolyline(DrawingWand *wand,
3901 %        const size_t number_coordinates,const PointInfo *coordinates)
3902 %
3903 %  A description of each parameter follows:
3904 %
3905 %    o wand: the drawing wand.
3906 %
3907 %    o number_coordinates: number of coordinates
3908 %
3909 %    o coordinates: coordinate array
3910 %
3911 */
3912 WandExport void DrawPolyline(DrawingWand *wand,
3913   const size_t number_coordinates,const PointInfo *coordinates)
3914 {
3915   assert(wand != (DrawingWand *) NULL);
3916   assert(wand->signature == WandSignature);
3917   if (wand->debug != MagickFalse)
3918     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3919   MvgAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
3920 }
3921 \f
3922 /*
3923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3924 %                                                                             %
3925 %                                                                             %
3926 %                                                                             %
3927 %   D r a w P o p C l i p P a t h                                             %
3928 %                                                                             %
3929 %                                                                             %
3930 %                                                                             %
3931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932 %
3933 %  DrawPopClipPath() terminates a clip path definition.
3934 %
3935 %  The format of the DrawPopClipPath method is:
3936 %
3937 %      void DrawPopClipPath(DrawingWand *wand)
3938 %
3939 %  A description of each parameter follows:
3940 %
3941 %    o wand: the drawing wand.
3942 %
3943 */
3944 WandExport void DrawPopClipPath(DrawingWand *wand)
3945 {
3946   assert(wand != (DrawingWand *) NULL);
3947   assert(wand->signature == WandSignature);
3948   if (wand->debug != MagickFalse)
3949     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3950   if (wand->indent_depth > 0)
3951     wand->indent_depth--;
3952   (void) MvgPrintf(wand,"pop clip-path\n");
3953 }
3954 \f
3955 /*
3956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3957 %                                                                             %
3958 %                                                                             %
3959 %                                                                             %
3960 %   D r a w P o p D e f s                                                     %
3961 %                                                                             %
3962 %                                                                             %
3963 %                                                                             %
3964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3965 %
3966 %  DrawPopDefs() terminates a definition list.
3967 %
3968 %  The format of the DrawPopDefs method is:
3969 %
3970 %      void DrawPopDefs(DrawingWand *wand)
3971 %
3972 %  A description of each parameter follows:
3973 %
3974 %    o wand: the drawing wand.
3975 %
3976 */
3977 WandExport void DrawPopDefs(DrawingWand *wand)
3978 {
3979   assert(wand != (DrawingWand *) NULL);
3980   assert(wand->signature == WandSignature);
3981   if (wand->debug != MagickFalse)
3982     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3983   if (wand->indent_depth > 0)
3984     wand->indent_depth--;
3985   (void) MvgPrintf(wand,"pop defs\n");
3986 }
3987 \f
3988 /*
3989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3990 %                                                                             %
3991 %                                                                             %
3992 %                                                                             %
3993 %   D r a w P o p P a t t e r n                                               %
3994 %                                                                             %
3995 %                                                                             %
3996 %                                                                             %
3997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3998 %
3999 %  DrawPopPattern() terminates a pattern definition.
4000 %
4001 %  The format of the DrawPopPattern method is:
4002 %
4003 %      MagickBooleanType DrawPopPattern(DrawingWand *wand)
4004 %
4005 %  A description of each parameter follows:
4006 %
4007 %    o wand: the drawing wand.
4008 %
4009 */
4010 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4011 {
4012   char
4013     geometry[MaxTextExtent],
4014     key[MaxTextExtent];
4015
4016   assert(wand != (DrawingWand *) NULL);
4017   assert(wand->signature == WandSignature);
4018   if (wand->debug != MagickFalse)
4019     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4020   if (wand->image == (Image *) NULL)
4021     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4022   if (wand->pattern_id == (const char *) NULL)
4023     {
4024       ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4025         wand->name);
4026       return(MagickFalse);
4027     }
4028   (void) FormatMagickString(key,MaxTextExtent,"%s",wand->pattern_id);
4029   (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4030   (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
4031     (unsigned long) wand->pattern_bounds.width,(unsigned long)
4032     wand->pattern_bounds.height,(long) wand->pattern_bounds.x,
4033     (long) wand->pattern_bounds.y);
4034   (void) SetImageArtifact(wand->image,key,geometry);
4035   wand->pattern_id=DestroyString(wand->pattern_id);
4036   wand->pattern_offset=0;
4037   wand->pattern_bounds.x=0;
4038   wand->pattern_bounds.y=0;
4039   wand->pattern_bounds.width=0;
4040   wand->pattern_bounds.height=0;
4041   wand->filter_off=MagickTrue;
4042   if (wand->indent_depth > 0)
4043     wand->indent_depth--;
4044   (void) MvgPrintf(wand,"pop pattern\n");
4045   return(MagickTrue);
4046 }
4047 \f
4048 /*
4049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4050 %                                                                             %
4051 %                                                                             %
4052 %                                                                             %
4053 %   D r a w P u s h C l i p P a t h                                           %
4054 %                                                                             %
4055 %                                                                             %
4056 %                                                                             %
4057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4058 %
4059 %  DrawPushClipPath() starts a clip path definition which is comprized of any
4060 %  number of drawing commands and terminated by a DrawPopClipPath() command.
4061 %
4062 %  The format of the DrawPushClipPath method is:
4063 %
4064 %      void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4065 %
4066 %  A description of each parameter follows:
4067 %
4068 %    o wand: the drawing wand.
4069 %
4070 %    o clip_mask_id: string identifier to associate with the clip path for
4071 %      later use.
4072 %
4073 */
4074 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4075 {
4076   assert(wand != (DrawingWand *) NULL);
4077   assert(wand->signature == WandSignature);
4078   if (wand->debug != MagickFalse)
4079     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4080   assert(clip_mask_id != (const char *) NULL);
4081   (void) MvgPrintf(wand,"push clip-path %s\n",clip_mask_id);
4082   wand->indent_depth++;
4083 }
4084 \f
4085 /*
4086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4087 %                                                                             %
4088 %                                                                             %
4089 %                                                                             %
4090 %   D r a w P u s h D e f s                                                   %
4091 %                                                                             %
4092 %                                                                             %
4093 %                                                                             %
4094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4095 %
4096 %  DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4097 %  command create named elements (e.g. clip-paths, textures, etc.) which
4098 %  may safely be processed earlier for the sake of efficiency.
4099 %
4100 %  The format of the DrawPushDefs method is:
4101 %
4102 %      void DrawPushDefs(DrawingWand *wand)
4103 %
4104 %  A description of each parameter follows:
4105 %
4106 %    o wand: the drawing wand.
4107 %
4108 */
4109 WandExport void DrawPushDefs(DrawingWand *wand)
4110 {
4111   assert(wand != (DrawingWand *) NULL);
4112   assert(wand->signature == WandSignature);
4113   if (wand->debug != MagickFalse)
4114     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4115   (void) MvgPrintf(wand,"push defs\n");
4116   wand->indent_depth++;
4117 }
4118 \f
4119 /*
4120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121 %                                                                             %
4122 %                                                                             %
4123 %                                                                             %
4124 %   D r a w P u s h P a t t e r n                                             %
4125 %                                                                             %
4126 %                                                                             %
4127 %                                                                             %
4128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4129 %
4130 %  DrawPushPattern() indicates that subsequent commands up to a
4131 %  DrawPopPattern() command comprise the definition of a named pattern.
4132 %  The pattern space is assigned top left corner coordinates, a width
4133 %  and height, and becomes its own drawing space.  Anything which can
4134 %  be drawn may be used in a pattern definition.
4135 %  Named patterns may be used as stroke or brush definitions.
4136 %
4137 %  The format of the DrawPushPattern method is:
4138 %
4139 %      MagickBooleanType DrawPushPattern(DrawingWand *wand,
4140 %        const char *pattern_id,const double x,const double y,
4141 %        const double width,const double height)
4142 %
4143 %  A description of each parameter follows:
4144 %
4145 %    o wand: the drawing wand.
4146 %
4147 %    o pattern_id: pattern identification for later reference
4148 %
4149 %    o x: x ordinate of top left corner
4150 %
4151 %    o y: y ordinate of top left corner
4152 %
4153 %    o width: width of pattern space
4154 %
4155 %    o height: height of pattern space
4156 %
4157 */
4158 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4159   const char *pattern_id,const double x,const double y,const double width,
4160   const double height)
4161 {
4162   assert(wand != (DrawingWand *) NULL);
4163   assert(wand->signature == WandSignature);
4164   if (wand->debug != MagickFalse)
4165     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4166   assert(pattern_id != (const char *) NULL);
4167   if (wand->pattern_id != NULL)
4168     {
4169       ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4170         wand->pattern_id);
4171       return(MagickFalse);
4172     }
4173   wand->filter_off=MagickTrue;
4174   (void) MvgPrintf(wand,"push pattern %s %g,%g %g,%g\n",pattern_id,
4175     x,y,width,height);
4176   wand->indent_depth++;
4177   wand->pattern_id=AcquireString(pattern_id);
4178   wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
4179   wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
4180   wand->pattern_bounds.width=(size_t) floor(width+0.5);
4181   wand->pattern_bounds.height=(size_t) floor(height+0.5);
4182   wand->pattern_offset=wand->mvg_length;
4183   return(MagickTrue);
4184 }
4185 \f
4186 /*
4187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4188 %                                                                             %
4189 %                                                                             %
4190 %                                                                             %
4191 %   D r a w R e c t a n g l e                                                 %
4192 %                                                                             %
4193 %                                                                             %
4194 %                                                                             %
4195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4196 %
4197 %  DrawRectangle() draws a rectangle given two coordinates and using the
4198 %  current stroke, stroke width, and fill settings.
4199 %
4200 %  The format of the DrawRectangle method is:
4201 %
4202 %      void DrawRectangle(DrawingWand *wand,const double x1,
4203 %        const double y1,const double x2,const double y2)
4204 %
4205 %  A description of each parameter follows:
4206 %
4207 %    o x1: x ordinate of first coordinate
4208 %
4209 %    o y1: y ordinate of first coordinate
4210 %
4211 %    o x2: x ordinate of second coordinate
4212 %
4213 %    o y2: y ordinate of second coordinate
4214 %
4215 */
4216 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4217   const double x2,const double y2)
4218 {
4219   assert(wand != (DrawingWand *) NULL);
4220   assert(wand->signature == WandSignature);
4221   if (wand->debug != MagickFalse)
4222     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4223   (void) MvgPrintf(wand,"rectangle %g,%g %g,%g\n",x1,y1,x2,y2);
4224 }
4225 \f
4226 /*
4227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4228 %                                                                             %
4229 %                                                                             %
4230 %                                                                             %
4231 +   D r a w R e n d e r                                                       %
4232 %                                                                             %
4233 %                                                                             %
4234 %                                                                             %
4235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4236 %
4237 %  DrawRender() renders all preceding drawing commands onto the image.
4238 %
4239 %  The format of the DrawRender method is:
4240 %
4241 %      MagickBooleanType DrawRender(DrawingWand *wand)
4242 %
4243 %  A description of each parameter follows:
4244 %
4245 %    o wand: the drawing wand.
4246 %
4247 */
4248 WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4249 {
4250   MagickBooleanType
4251     status;
4252
4253   assert(wand != (const DrawingWand *) NULL);
4254   assert(wand->signature == WandSignature);
4255   if (wand->debug != MagickFalse)
4256     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4257   CurrentContext->primitive=wand->mvg;
4258   if (wand->debug != MagickFalse)
4259     (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4260   if (wand->image == (Image *) NULL)
4261     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4262   status=DrawImage(wand->image,CurrentContext);
4263   InheritException(wand->exception,&wand->image->exception);
4264   CurrentContext->primitive=(char *) NULL;
4265   return(status);
4266 }
4267 \f
4268 /*
4269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4270 %                                                                             %
4271 %                                                                             %
4272 %                                                                             %
4273 %   D r a w R e s e t V e c t o r G r a p h i c s                             %
4274 %                                                                             %
4275 %                                                                             %
4276 %                                                                             %
4277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4278 %
4279 %  DrawResetVectorGraphics() resets the vector graphics associated with the
4280 %  specified wand.
4281 %
4282 %  The format of the DrawResetVectorGraphics method is:
4283 %
4284 %      void DrawResetVectorGraphics(DrawingWand *wand)
4285 %
4286 %  A description of each parameter follows:
4287 %
4288 %    o wand: the drawing wand.
4289 %
4290 */
4291 WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4292 {
4293   assert(wand != (DrawingWand *) NULL);
4294   assert(wand->signature == WandSignature);
4295   if (wand->debug != MagickFalse)
4296     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4297   if (wand->mvg != (char *) NULL)
4298     wand->mvg=DestroyString(wand->mvg);
4299   wand->mvg_alloc=0;
4300   wand->mvg_length=0;
4301   wand->mvg_width=0;
4302 }
4303 \f
4304 /*
4305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4306 %                                                                             %
4307 %                                                                             %
4308 %                                                                             %
4309 %   D r a w R o t a t e                                                       %
4310 %                                                                             %
4311 %                                                                             %
4312 %                                                                             %
4313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4314 %
4315 %  DrawRotate() applies the specified rotation to the current coordinate space.
4316 %
4317 %  The format of the DrawRotate method is:
4318 %
4319 %      void DrawRotate(DrawingWand *wand,const double degrees)
4320 %
4321 %  A description of each parameter follows:
4322 %
4323 %    o wand: the drawing wand.
4324 %
4325 %    o degrees: degrees of rotation
4326 %
4327 */
4328 WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4329 {
4330   AffineMatrix
4331     affine;
4332
4333   assert(wand != (DrawingWand *) NULL);
4334   assert(wand->signature == WandSignature);
4335   if (wand->debug != MagickFalse)
4336     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4337   GetAffineMatrix(&affine);
4338   affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
4339   affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
4340   affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
4341   affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
4342   AdjustAffine(wand,&affine);
4343   (void) MvgPrintf(wand,"rotate %g\n",degrees);
4344 }
4345 \f
4346 /*
4347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4348 %                                                                             %
4349 %                                                                             %
4350 %                                                                             %
4351 %   D r a w R o u n d R e c t a n g l e                                       %
4352 %                                                                             %
4353 %                                                                             %
4354 %                                                                             %
4355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4356 %
4357 %  DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4358 %  x & y corner radiuses and using the current stroke, stroke width,
4359 %  and fill settings.
4360 %
4361 %  The format of the DrawRoundRectangle method is:
4362 %
4363 %      void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4364 %        double x2,double y2,double rx,double ry)
4365 %
4366 %  A description of each parameter follows:
4367 %
4368 %    o wand: the drawing wand.
4369 %
4370 %    o x1: x ordinate of first coordinate
4371 %
4372 %    o y1: y ordinate of first coordinate
4373 %
4374 %    o x2: x ordinate of second coordinate
4375 %
4376 %    o y2: y ordinate of second coordinate
4377 %
4378 %    o rx: radius of corner in horizontal direction
4379 %
4380 %    o ry: radius of corner in vertical direction
4381 %
4382 */
4383 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4384   double x2,double y2,double rx,double ry)
4385 {
4386   assert(wand != (DrawingWand *) NULL);
4387   assert(wand->signature == WandSignature);
4388   if (wand->debug != MagickFalse)
4389     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4390   (void) MvgPrintf(wand,"roundrectangle %g,%g %g,%g %g,%g\n",
4391     x1,y1,x2,y2,rx,ry);
4392 }
4393 \f
4394 /*
4395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4396 %                                                                             %
4397 %                                                                             %
4398 %                                                                             %
4399 %   D r a w S c a l e                                                         %
4400 %                                                                             %
4401 %                                                                             %
4402 %                                                                             %
4403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4404 %
4405 %  DrawScale() adjusts the scaling factor to apply in the horizontal and
4406 %  vertical directions to the current coordinate space.
4407 %
4408 %  The format of the DrawScale method is:
4409 %
4410 %      void DrawScale(DrawingWand *wand,const double x,const double y)
4411 %
4412 %  A description of each parameter follows:
4413 %
4414 %    o wand: the drawing wand.
4415 %
4416 %    o x: horizontal scale factor
4417 %
4418 %    o y: vertical scale factor
4419 %
4420 */
4421 WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4422 {
4423   AffineMatrix
4424     affine;
4425
4426   assert(wand != (DrawingWand *) NULL);
4427   assert(wand->signature == WandSignature);
4428   if (wand->debug != MagickFalse)
4429     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4430   GetAffineMatrix(&affine);
4431   affine.sx=x;
4432   affine.sy=y;
4433   AdjustAffine(wand,&affine);
4434   (void) MvgPrintf(wand,"scale %g,%g\n",x,y);
4435 }
4436 \f
4437 /*
4438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4439 %                                                                             %
4440 %                                                                             %
4441 %                                                                             %
4442 %   D r a w S e t B o r d e r C o l o r                                       %
4443 %                                                                             %
4444 %                                                                             %
4445 %                                                                             %
4446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4447 %
4448 %  DrawSetBorderColor() sets the border color to be used for drawing bordered
4449 %  objects.
4450 %
4451 %  The format of the DrawSetBorderColor method is:
4452 %
4453 %      void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4454 %
4455 %  A description of each parameter follows:
4456 %
4457 %    o wand: the drawing wand.
4458 %
4459 %    o border_wand: border wand.
4460 %
4461 */
4462
4463 static inline MagickBooleanType IsColorEqual(const PixelPacket *p,
4464   const PixelPacket *q)
4465 {
4466   if (p->red != q->red)
4467     return(MagickFalse);
4468   if (p->green != q->green)
4469     return(MagickFalse);
4470   if (p->blue != q->blue)
4471     return(MagickFalse);
4472   if (p->opacity != q->opacity)
4473     return(MagickFalse);
4474   return(MagickTrue);
4475 }
4476
4477 WandExport void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4478 {
4479   PixelPacket
4480     *current_border,
4481     border_color,
4482     new_border;
4483
4484   assert(wand != (DrawingWand *) NULL);
4485   assert(wand->signature == WandSignature);
4486   if (wand->debug != MagickFalse)
4487     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4488   assert(border_wand != (const PixelWand *) NULL);
4489   PixelGetQuantumColor(border_wand,&border_color);
4490   new_border=border_color;
4491   current_border=(&CurrentContext->border_color);
4492   if ((wand->filter_off != MagickFalse) ||
4493       (IsColorEqual(current_border,&new_border) == MagickFalse))
4494     {
4495       CurrentContext->border_color=new_border;
4496       (void) MvgPrintf(wand,"border-color '");
4497       MvgAppendColor(wand,&border_color);
4498       (void) MvgPrintf(wand,"'\n");
4499     }
4500 }
4501 \f
4502 /*
4503 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4504 %                                                                             %
4505 %                                                                             %
4506 %                                                                             %
4507 %   D r a w S e t C l i p P a t h                                             %
4508 %                                                                             %
4509 %                                                                             %
4510 %                                                                             %
4511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4512 %
4513 %  DrawSetClipPath() associates a named clipping path with the image.  Only
4514 %  the areas drawn on by the clipping path will be modified as ssize_t as it
4515 %  remains in effect.
4516 %
4517 %  The format of the DrawSetClipPath method is:
4518 %
4519 %      MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4520 %        const char *clip_mask)
4521 %
4522 %  A description of each parameter follows:
4523 %
4524 %    o wand: the drawing wand.
4525 %
4526 %    o clip_mask: name of clipping path to associate with image
4527 %
4528 */
4529 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4530   const char *clip_mask)
4531 {
4532   if (wand->debug != MagickFalse)
4533     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4534   assert(wand != (DrawingWand *) NULL);
4535   assert(wand->signature == WandSignature);
4536   assert(clip_mask != (const char *) NULL);
4537   if ((CurrentContext->clip_mask == (const char *) NULL) ||
4538       (wand->filter_off != MagickFalse) ||
4539       (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4540     {
4541       (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4542 #if DRAW_BINARY_IMPLEMENTATION
4543       if (wand->image == (Image *) NULL)
4544         ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4545       (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4546 #endif
4547       (void) MvgPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4548     }
4549   return(MagickTrue);
4550 }
4551 \f
4552 /*
4553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4554 %                                                                             %
4555 %                                                                             %
4556 %                                                                             %
4557 %   D r a w S e t C l i p R u l e                                             %
4558 %                                                                             %
4559 %                                                                             %
4560 %                                                                             %
4561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4562 %
4563 %  DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4564 %
4565 %  The format of the DrawSetClipRule method is:
4566 %
4567 %      void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4568 %
4569 %  A description of each parameter follows:
4570 %
4571 %    o wand: the drawing wand.
4572 %
4573 %    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4574 %
4575 */
4576 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4577 {
4578   assert(wand != (DrawingWand *) NULL);
4579   assert(wand->signature == WandSignature);
4580   if (wand->debug != MagickFalse)
4581     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4582   if ((wand->filter_off != MagickFalse) ||
4583       (CurrentContext->fill_rule != fill_rule))
4584     {
4585       CurrentContext->fill_rule=fill_rule;
4586       (void) MvgPrintf(wand, "clip-rule '%s'\n",MagickOptionToMnemonic(
4587         MagickFillRuleOptions,(ssize_t) fill_rule));
4588     }
4589 }
4590 \f
4591 /*
4592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4593 %                                                                             %
4594 %                                                                             %
4595 %                                                                             %
4596 %   D r a w S e t C l i p U n i t s                                           %
4597 %                                                                             %
4598 %                                                                             %
4599 %                                                                             %
4600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4601 %
4602 %  DrawSetClipUnits() sets the interpretation of clip path units.
4603 %
4604 %  The format of the DrawSetClipUnits method is:
4605 %
4606 %      void DrawSetClipUnits(DrawingWand *wand,
4607 %        const ClipPathUnits clip_units)
4608 %
4609 %  A description of each parameter follows:
4610 %
4611 %    o wand: the drawing wand.
4612 %
4613 %    o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4614 %      ObjectBoundingBox)
4615 %
4616 */
4617 WandExport void DrawSetClipUnits(DrawingWand *wand,
4618   const ClipPathUnits clip_units)
4619 {
4620   assert(wand != (DrawingWand *) NULL);
4621   assert(wand->signature == WandSignature);
4622   if (wand->debug != MagickFalse)
4623     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4624   if ((wand->filter_off != MagickFalse) ||
4625       (CurrentContext->clip_units != clip_units))
4626     {
4627       CurrentContext->clip_units=clip_units;
4628       if (clip_units == ObjectBoundingBox)
4629         {
4630           AffineMatrix
4631             affine;
4632
4633           GetAffineMatrix(&affine);
4634           affine.sx=CurrentContext->bounds.x2;
4635           affine.sy=CurrentContext->bounds.y2;
4636           affine.tx=CurrentContext->bounds.x1;
4637           affine.ty=CurrentContext->bounds.y1;
4638           AdjustAffine(wand,&affine);
4639         }
4640       (void) MvgPrintf(wand, "clip-units '%s'\n",MagickOptionToMnemonic(
4641         MagickClipPathOptions,(ssize_t) clip_units));
4642     }
4643 }
4644 \f
4645 /*
4646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4647 %                                                                             %
4648 %                                                                             %
4649 %                                                                             %
4650 %   D r a w S e t F i l l C o l o r                                           %
4651 %                                                                             %
4652 %                                                                             %
4653 %                                                                             %
4654 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4655 %
4656 %  DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4657 %
4658 %  The format of the DrawSetFillColor method is:
4659 %
4660 %      void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4661 %
4662 %  A description of each parameter follows:
4663 %
4664 %    o wand: the drawing wand.
4665 %
4666 %    o fill_wand: fill wand.
4667 %
4668 */
4669 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4670 {
4671   PixelPacket
4672     *current_fill,
4673     fill_color,
4674     new_fill;
4675
4676   assert(wand != (DrawingWand *) NULL);
4677   assert(wand->signature == WandSignature);
4678   if (wand->debug != MagickFalse)
4679     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4680   assert(fill_wand != (const PixelWand *) NULL);
4681   PixelGetQuantumColor(fill_wand,&fill_color);
4682   new_fill=fill_color;
4683   current_fill=(&CurrentContext->fill);
4684   if ((wand->filter_off != MagickFalse) ||
4685       (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4686     {
4687       CurrentContext->fill=new_fill;
4688       (void) MvgPrintf(wand,"fill '");
4689       MvgAppendColor(wand,&fill_color);
4690       (void) MvgPrintf(wand,"'\n");
4691     }
4692 }
4693 \f
4694 /*
4695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4696 %                                                                             %
4697 %                                                                             %
4698 %                                                                             %
4699 %   D r a w S e t F i l l O p a c i t y                                       %
4700 %                                                                             %
4701 %                                                                             %
4702 %                                                                             %
4703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4704 %
4705 %  DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4706 %  color or fill texture.  Fully opaque is 1.0.
4707 %
4708 %  The format of the DrawSetFillOpacity method is:
4709 %
4710 %      void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4711 %
4712 %  A description of each parameter follows:
4713 %
4714 %    o wand: the drawing wand.
4715 %
4716 %    o fill_opacity: fill opacity
4717 %
4718 */
4719 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4720 {
4721   Quantum
4722     opacity;
4723
4724   assert(wand != (DrawingWand *) NULL);
4725   assert(wand->signature == WandSignature);
4726   if (wand->debug != MagickFalse)
4727     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4728   opacity=ClampToQuantum((double) QuantumRange*(1.0-fill_opacity));
4729   if ((wand->filter_off != MagickFalse) ||
4730       (CurrentContext->fill.opacity != opacity))
4731     {
4732       CurrentContext->fill.opacity=opacity;
4733       (void) MvgPrintf(wand,"fill-opacity %g\n",fill_opacity);
4734     }
4735 }
4736 \f
4737 /*
4738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4739 %                                                                             %
4740 %                                                                             %
4741 %                                                                             %
4742 %   D r a w S e t O p a c i t y                                               %
4743 %                                                                             %
4744 %                                                                             %
4745 %                                                                             %
4746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4747 %
4748 %  DrawSetOpacity() sets the opacity to use when drawing using the fill or
4749 %  stroke color or texture.  Fully opaque is 1.0.
4750 %
4751 %  The format of the DrawSetOpacity method is:
4752 %
4753 %      void DrawSetOpacity(DrawingWand *wand,const double opacity)
4754 %
4755 %  A description of each parameter follows:
4756 %
4757 %    o wand: the drawing wand.
4758 %
4759 %    o opacity: fill opacity
4760 %
4761 */
4762 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4763 {
4764   Quantum
4765     quantum_opacity;
4766
4767   assert(wand != (DrawingWand *) NULL);
4768   assert(wand->signature == WandSignature);
4769   if (wand->debug != MagickFalse)
4770     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4771   quantum_opacity=ClampToQuantum((double) QuantumRange*(1.0-opacity));
4772   if ((wand->filter_off != MagickFalse) ||
4773       (CurrentContext->opacity != quantum_opacity))
4774     {
4775       CurrentContext->opacity=(Quantum) opacity;
4776       (void) MvgPrintf(wand,"opacity %g\n",opacity);
4777     }
4778 }
4779 \f
4780 /*
4781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4782 %                                                                             %
4783 %                                                                             %
4784 %                                                                             %
4785 %   D r a w S e t F i l l P a t t e r n U R L                                 %
4786 %                                                                             %
4787 %                                                                             %
4788 %                                                                             %
4789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4790 %
4791 %  DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4792 %  objects. Only local URLs ("#identifier") are supported at this time. These
4793 %  local URLs are normally created by defining a named fill pattern with
4794 %  DrawPushPattern/DrawPopPattern.
4795 %
4796 %  The format of the DrawSetFillPatternURL method is:
4797 %
4798 %      MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4799 %        const char *fill_url)
4800 %
4801 %  A description of each parameter follows:
4802 %
4803 %    o wand: the drawing wand.
4804 %
4805 %    o fill_url: URL to use to obtain fill pattern.
4806 %
4807 */
4808 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4809   const char *fill_url)
4810 {
4811   char
4812     pattern[MaxTextExtent],
4813     pattern_spec[MaxTextExtent];
4814
4815   assert(wand != (DrawingWand *) NULL);
4816   assert(wand->signature == WandSignature);
4817   if (wand->debug != MagickFalse)
4818     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4819   if (wand->image == (Image *) NULL)
4820     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4821   assert(fill_url != (const char *) NULL);
4822   if (*fill_url != '#')
4823     {
4824       ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4825       return(MagickFalse);
4826     }
4827   (void) FormatMagickString(pattern,MaxTextExtent,"%s",fill_url+1);
4828   if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4829     {
4830       ThrowDrawException(DrawError,"URLNotFound",fill_url)
4831       return(MagickFalse);
4832     }
4833   (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",fill_url);
4834 #if DRAW_BINARY_IMPLEMENTATION
4835   DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4836     &CurrentContext->fill_pattern);
4837 #endif
4838   if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4839     CurrentContext->fill.opacity=CurrentContext->opacity;
4840   (void) MvgPrintf(wand,"fill %s\n",pattern_spec);
4841   return(MagickTrue);
4842 }
4843 \f
4844 /*
4845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4846 %                                                                             %
4847 %                                                                             %
4848 %                                                                             %
4849 %   D r a w S e t F i l l R u l e                                             %
4850 %                                                                             %
4851 %                                                                             %
4852 %                                                                             %
4853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4854 %
4855 %  DrawSetFillRule() sets the fill rule to use while drawing polygons.
4856 %
4857 %  The format of the DrawSetFillRule method is:
4858 %
4859 %      void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4860 %
4861 %  A description of each parameter follows:
4862 %
4863 %    o wand: the drawing wand.
4864 %
4865 %    o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4866 %
4867 */
4868 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4869 {
4870   assert(wand != (DrawingWand *) NULL);
4871   assert(wand->signature == WandSignature);
4872   if (wand->debug != MagickFalse)
4873     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4874   if ((wand->filter_off != MagickFalse) ||
4875       (CurrentContext->fill_rule != fill_rule))
4876     {
4877       CurrentContext->fill_rule=fill_rule;
4878       (void) MvgPrintf(wand, "fill-rule '%s'\n",MagickOptionToMnemonic(
4879         MagickFillRuleOptions,(ssize_t) fill_rule));
4880     }
4881 }
4882 \f
4883 /*
4884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4885 %                                                                             %
4886 %                                                                             %
4887 %                                                                             %
4888 %   D r a w S e t F o n t                                                     %
4889 %                                                                             %
4890 %                                                                             %
4891 %                                                                             %
4892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4893 %
4894 %  DrawSetFont() sets the fully-sepecified font to use when annotating with
4895 %  text.
4896 %
4897 %  The format of the DrawSetFont method is:
4898 %
4899 %      MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4900 %
4901 %  A description of each parameter follows:
4902 %
4903 %    o wand: the drawing wand.
4904 %
4905 %    o font_name: font name
4906 %
4907 */
4908 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4909   const char *font_name)
4910 {
4911   assert(wand != (DrawingWand *) NULL);
4912   assert(wand->signature == WandSignature);
4913   if (wand->debug != MagickFalse)
4914     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4915   assert(font_name != (const char *) NULL);
4916   if ((wand->filter_off != MagickFalse) ||
4917       (CurrentContext->font == (char *) NULL) ||
4918       (LocaleCompare(CurrentContext->font,font_name) != 0))
4919     {
4920       (void) CloneString(&CurrentContext->font,font_name);
4921       (void) MvgPrintf(wand,"font '%s'\n",font_name);
4922     }
4923   return(MagickTrue);
4924 }
4925 \f
4926 /*
4927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4928 %                                                                             %
4929 %                                                                             %
4930 %                                                                             %
4931 %   D r a w S e t F o n t F a m i l y                                         %
4932 %                                                                             %
4933 %                                                                             %
4934 %                                                                             %
4935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4936 %
4937 %  DrawSetFontFamily() sets the font family to use when annotating with text.
4938 %
4939 %  The format of the DrawSetFontFamily method is:
4940 %
4941 %      MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4942 %        const char *font_family)
4943 %
4944 %  A description of each parameter follows:
4945 %
4946 %    o wand: the drawing wand.
4947 %
4948 %    o font_family: font family
4949 %
4950 */
4951 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4952   const char *font_family)
4953 {
4954   assert(wand != (DrawingWand *) NULL);
4955   assert(wand->signature == WandSignature);
4956   if (wand->debug != MagickFalse)
4957     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4958   assert(font_family != (const char *) NULL);
4959   if ((wand->filter_off != MagickFalse) ||
4960       (CurrentContext->family == (const char *) NULL) ||
4961       (LocaleCompare(CurrentContext->family,font_family) != 0))
4962     {
4963       (void) CloneString(&CurrentContext->family,font_family);
4964       (void) MvgPrintf(wand,"font-family '%s'\n",font_family);
4965     }
4966   return(MagickTrue);
4967 }
4968 \f
4969 /*
4970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4971 %                                                                             %
4972 %                                                                             %
4973 %                                                                             %
4974 %   D r a w S e t F o n t S i z e                                             %
4975 %                                                                             %
4976 %                                                                             %
4977 %                                                                             %
4978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4979 %
4980 %  DrawSetFontSize() sets the font pointsize to use when annotating with text.
4981 %
4982 %  The format of the DrawSetFontSize method is:
4983 %
4984 %      void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4985 %
4986 %  A description of each parameter follows:
4987 %
4988 %    o wand: the drawing wand.
4989 %
4990 %    o pointsize: text pointsize
4991 %
4992 */
4993 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4994 {
4995   assert(wand != (DrawingWand *) NULL);
4996   assert(wand->signature == WandSignature);
4997   if (wand->debug != MagickFalse)
4998     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4999   if ((wand->filter_off != MagickFalse) ||
5000       (fabs(CurrentContext->pointsize-pointsize) > MagickEpsilon))
5001     {
5002       CurrentContext->pointsize=pointsize;
5003       (void) MvgPrintf(wand,"font-size %g\n",pointsize);
5004     }
5005 }
5006 \f
5007 /*
5008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5009 %                                                                             %
5010 %                                                                             %
5011 %                                                                             %
5012 %   D r a w S e t F o n t S t r e t c h                                       %
5013 %                                                                             %
5014 %                                                                             %
5015 %                                                                             %
5016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5017 %
5018 %  DrawSetFontStretch() sets the font stretch to use when annotating with text.
5019 %  The AnyStretch enumeration acts as a wild-card "don't care" option.
5020 %
5021 %  The format of the DrawSetFontStretch method is:
5022 %
5023 %      void DrawSetFontStretch(DrawingWand *wand,
5024 %        const StretchType font_stretch)
5025 %
5026 %  A description of each parameter follows:
5027 %
5028 %    o wand: the drawing wand.
5029 %
5030 %    o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5031 %                    CondensedStretch, SemiCondensedStretch,
5032 %                    SemiExpandedStretch, ExpandedStretch,
5033 %                    ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5034 %
5035 */
5036 WandExport void DrawSetFontStretch(DrawingWand *wand,
5037   const StretchType font_stretch)
5038 {
5039   assert(wand != (DrawingWand *) NULL);
5040   assert(wand->signature == WandSignature);
5041   if (wand->debug != MagickFalse)
5042     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5043   if ((wand->filter_off != MagickFalse) ||
5044       (CurrentContext->stretch != font_stretch))
5045     {
5046       CurrentContext->stretch=font_stretch;
5047       (void) MvgPrintf(wand, "font-stretch '%s'\n",MagickOptionToMnemonic(
5048         MagickStretchOptions,(ssize_t) font_stretch));
5049     }
5050 }
5051 \f
5052 /*
5053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5054 %                                                                             %
5055 %                                                                             %
5056 %                                                                             %
5057 %   D r a w S e t F o n t S t y l e                                           %
5058 %                                                                             %
5059 %                                                                             %
5060 %                                                                             %
5061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5062 %
5063 %  DrawSetFontStyle() sets the font style to use when annotating with text.
5064 %  The AnyStyle enumeration acts as a wild-card "don't care" option.
5065 %
5066 %  The format of the DrawSetFontStyle method is:
5067 %
5068 %      void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5069 %
5070 %  A description of each parameter follows:
5071 %
5072 %    o wand: the drawing wand.
5073 %
5074 %    o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5075 %
5076 */
5077 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5078 {
5079   assert(wand != (DrawingWand *) NULL);
5080   assert(wand->signature == WandSignature);
5081   if (wand->debug != MagickFalse)
5082     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5083   if ((wand->filter_off != MagickFalse) ||
5084       (CurrentContext->style != style))
5085     {
5086       CurrentContext->style=style;
5087       (void) MvgPrintf(wand, "font-style '%s'\n",MagickOptionToMnemonic(
5088         MagickStyleOptions,(ssize_t) style));
5089     }
5090 }
5091 \f
5092 /*
5093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5094 %                                                                             %
5095 %                                                                             %
5096 %                                                                             %
5097 %   D r a w S e t F o n t W e i g h t                                         %
5098 %                                                                             %
5099 %                                                                             %
5100 %                                                                             %
5101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5102 %
5103 %  DrawSetFontWeight() sets the font weight to use when annotating with text.
5104 %
5105 %  The format of the DrawSetFontWeight method is:
5106 %
5107 %      void DrawSetFontWeight(DrawingWand *wand,
5108 %        const size_t font_weight)
5109 %
5110 %  A description of each parameter follows:
5111 %
5112 %    o wand: the drawing wand.
5113 %
5114 %    o font_weight: font weight (valid range 100-900)
5115 %
5116 */
5117 WandExport void DrawSetFontWeight(DrawingWand *wand,
5118   const size_t font_weight)
5119 {
5120   assert(wand != (DrawingWand *) NULL);
5121   assert(wand->signature == WandSignature);
5122   if (wand->debug != MagickFalse)
5123     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5124   if ((wand->filter_off != MagickFalse) ||
5125       (CurrentContext->weight != font_weight))
5126     {
5127       CurrentContext->weight=font_weight;
5128       (void) MvgPrintf(wand,"font-weight %lu\n",(unsigned long) font_weight);
5129     }
5130 }
5131 \f
5132 /*
5133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5134 %                                                                             %
5135 %                                                                             %
5136 %                                                                             %
5137 %   D r a w S e t G r a v i t y                                               %
5138 %                                                                             %
5139 %                                                                             %
5140 %                                                                             %
5141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5142 %
5143 %  DrawSetGravity() sets the text placement gravity to use when annotating
5144 %  with text.
5145 %
5146 %  The format of the DrawSetGravity method is:
5147 %
5148 %      void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5149 %
5150 %  A description of each parameter follows:
5151 %
5152 %    o wand: the drawing wand.
5153 %
5154 %    o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5155 %               NorthEastGravity, WestGravity, CenterGravity,
5156 %               EastGravity, SouthWestGravity, SouthGravity,
5157 %               SouthEastGravity)
5158 %
5159 */
5160 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5161 {
5162   assert(wand != (DrawingWand *) NULL);
5163   assert(wand->signature == WandSignature);
5164   if (wand->debug != MagickFalse)
5165     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5166   if ((wand->filter_off != MagickFalse) ||
5167       (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5168     {
5169       CurrentContext->gravity=gravity;
5170       (void) MvgPrintf(wand,"gravity '%s'\n",MagickOptionToMnemonic(
5171         MagickGravityOptions,(ssize_t) gravity));
5172     }
5173 }
5174 \f
5175 /*
5176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5177 %                                                                             %
5178 %                                                                             %
5179 %                                                                             %
5180 %   D r a w S e t S t r o k e C o l o r                                       %
5181 %                                                                             %
5182 %                                                                             %
5183 %                                                                             %
5184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5185 %
5186 %  DrawSetStrokeColor() sets the color used for stroking object outlines.
5187 %
5188 %  The format of the DrawSetStrokeColor method is:
5189 %
5190 %      void DrawSetStrokeColor(DrawingWand *wand,
5191 %        const PixelWand *stroke_wand)
5192 %
5193 %  A description of each parameter follows:
5194 %
5195 %    o wand: the drawing wand.
5196 %
5197 %    o stroke_wand: stroke wand.
5198 %
5199 */
5200 WandExport void DrawSetStrokeColor(DrawingWand *wand,
5201   const PixelWand *stroke_wand)
5202 {
5203   PixelPacket
5204     *current_stroke,
5205     new_stroke,
5206     stroke_color;
5207
5208   assert(wand != (DrawingWand *) NULL);
5209   assert(wand->signature == WandSignature);
5210   if (wand->debug != MagickFalse)
5211     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5212   assert(stroke_wand != (const PixelWand *) NULL);
5213   PixelGetQuantumColor(stroke_wand,&stroke_color);
5214   new_stroke=stroke_color;
5215   current_stroke=(&CurrentContext->stroke);
5216   if ((wand->filter_off != MagickFalse) ||
5217       (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5218     {
5219       CurrentContext->stroke=new_stroke;
5220       (void) MvgPrintf(wand,"stroke '");
5221       MvgAppendColor(wand,&stroke_color);
5222       (void) MvgPrintf(wand,"'\n");
5223     }
5224 }
5225 \f
5226 /*
5227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5228 %                                                                             %
5229 %                                                                             %
5230 %                                                                             %
5231 %   D r a w S e t S t r o k e P a t t e r n U R L                             %
5232 %                                                                             %
5233 %                                                                             %
5234 %                                                                             %
5235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5236 %
5237 %  DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5238 %
5239 %  The format of the DrawSetStrokePatternURL method is:
5240 %
5241 %      MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5242 %        const char *stroke_url)
5243 %
5244 %  A description of each parameter follows:
5245 %
5246 %    o wand: the drawing wand.
5247 %
5248 %    o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5249 %
5250 */
5251 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5252   const char *stroke_url)
5253 {
5254   char
5255     pattern[MaxTextExtent],
5256     pattern_spec[MaxTextExtent];
5257
5258   assert(wand != (DrawingWand *) NULL);
5259   assert(wand->signature == WandSignature);
5260   if (wand->debug != MagickFalse)
5261     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5262   if (wand->image == (Image *) NULL)
5263     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5264   assert(stroke_url != NULL);
5265   if (stroke_url[0] != '#')
5266     ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5267   (void) FormatMagickString(pattern,MaxTextExtent,"%s",stroke_url+1);
5268   if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5269     {
5270       ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5271       return(MagickFalse);
5272     }
5273   (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",stroke_url);
5274 #if DRAW_BINARY_IMPLEMENTATION
5275   DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5276     &CurrentContext->stroke_pattern);
5277 #endif
5278   if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5279     CurrentContext->stroke.opacity=CurrentContext->opacity;
5280   (void) MvgPrintf(wand,"stroke %s\n",pattern_spec);
5281   return(MagickTrue);
5282 }
5283 \f
5284 /*
5285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5286 %                                                                             %
5287 %                                                                             %
5288 %                                                                             %
5289 %   D r a w S e t S t r o k e A n t i a l i a s                               %
5290 %                                                                             %
5291 %                                                                             %
5292 %                                                                             %
5293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5294 %
5295 %  DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5296 %  Stroked outlines are antialiased by default.  When antialiasing is disabled
5297 %  stroked pixels are thresholded to determine if the stroke color or
5298 %  underlying canvas color should be used.
5299 %
5300 %  The format of the DrawSetStrokeAntialias method is:
5301 %
5302 %      void DrawSetStrokeAntialias(DrawingWand *wand,
5303 %        const MagickBooleanType stroke_antialias)
5304 %
5305 %  A description of each parameter follows:
5306 %
5307 %    o wand: the drawing wand.
5308 %
5309 %    o stroke_antialias: set to false (zero) to disable antialiasing
5310 %
5311 */
5312 WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5313   const MagickBooleanType stroke_antialias)
5314 {
5315   assert(wand != (DrawingWand *) NULL);
5316   assert(wand->signature == WandSignature);
5317   if (wand->debug != MagickFalse)
5318     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5319   if ((wand->filter_off != MagickFalse) ||
5320       (CurrentContext->stroke_antialias != stroke_antialias))
5321     {
5322       CurrentContext->stroke_antialias=stroke_antialias;
5323       (void) MvgPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5324         1 : 0);
5325     }
5326 }
5327 \f
5328 /*
5329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5330 %                                                                             %
5331 %                                                                             %
5332 %                                                                             %
5333 %   D r a w S e t S t r o k e D a s h A r r a y                               %
5334 %                                                                             %
5335 %                                                                             %
5336 %                                                                             %
5337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5338 %
5339 %  DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5340 %  stroke paths. The stroke dash array represents an array of numbers that
5341 %  specify the lengths of alternating dashes and gaps in pixels. If an odd
5342 %  number of values is provided, then the list of values is repeated to yield
5343 %  an even number of values. To remove an existing dash array, pass a zero
5344 %  number_elements argument and null dash_array.  A typical stroke dash array
5345 %  might contain the members 5 3 2.
5346 %
5347 %  The format of the DrawSetStrokeDashArray method is:
5348 %
5349 %      MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5350 %        const size_t number_elements,const double *dash_array)
5351 %
5352 %  A description of each parameter follows:
5353 %
5354 %    o wand: the drawing wand.
5355 %
5356 %    o number_elements: number of elements in dash array
5357 %
5358 %    o dash_array: dash array values
5359 %
5360 */
5361 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5362   const size_t number_elements,const double *dash_array)
5363 {
5364   MagickBooleanType
5365     update;
5366
5367   register const double
5368     *p;
5369
5370   register double
5371     *q;
5372
5373   register ssize_t
5374     i;
5375
5376   size_t
5377     n_new,
5378     n_old;
5379
5380   assert(wand != (DrawingWand *) NULL);
5381   assert(wand->signature == WandSignature);
5382   if (wand->debug != MagickFalse)
5383     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5384   n_new=number_elements;
5385   n_old=0;
5386   update=MagickFalse;
5387   q=CurrentContext->dash_pattern;
5388   if (q != (const double *) NULL)
5389     while (*q++ != 0.0)
5390       n_old++;
5391   if ((n_old == 0) && (n_new == 0))
5392     update=MagickFalse;
5393   else
5394     if (n_old != n_new)
5395       update=MagickTrue;
5396     else
5397       if ((CurrentContext->dash_pattern != (double *) NULL) &&
5398           (dash_array != (double *) NULL))
5399         {
5400           p=dash_array;
5401           q=CurrentContext->dash_pattern;
5402           for (i=0; i < (ssize_t) n_new; i++)
5403           {
5404             if (fabs((*p)-(*q)) > MagickEpsilon)
5405               {
5406                 update=MagickTrue;
5407                 break;
5408               }
5409             p++;
5410             q++;
5411           }
5412         }
5413   if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5414     {
5415       if (CurrentContext->dash_pattern != (double *) NULL)
5416         CurrentContext->dash_pattern=(double *)
5417           RelinquishMagickMemory(CurrentContext->dash_pattern);
5418       if (n_new != 0)
5419         {
5420           CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5421             n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5422           if (!CurrentContext->dash_pattern)
5423             {
5424               ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5425                 wand->name);
5426               return(MagickFalse);
5427             }
5428           q=CurrentContext->dash_pattern;
5429           p=dash_array;
5430           for (i=0; i < (ssize_t) n_new; i++)
5431             *q++=(*p++);
5432           *q=0;
5433         }
5434       (void) MvgPrintf(wand,"stroke-dasharray ");
5435       if (n_new == 0)
5436         (void) MvgPrintf(wand,"none\n");
5437       else
5438         {
5439           p=dash_array;
5440           (void) MvgPrintf(wand,"%g",*p++);
5441           for (i=1; i < (ssize_t) n_new; i++)
5442             (void) MvgPrintf(wand,",%g",*p++);
5443           (void) MvgPrintf(wand,"\n");
5444         }
5445     }
5446   return(MagickTrue);
5447 }
5448 \f
5449 /*
5450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5451 %                                                                             %
5452 %                                                                             %
5453 %                                                                             %
5454 %   D r a w S e t S t r o k e D a s h O f f s e t                             %
5455 %                                                                             %
5456 %                                                                             %
5457 %                                                                             %
5458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5459 %
5460 %  DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5461 %  start the dash.
5462 %
5463 %  The format of the DrawSetStrokeDashOffset method is:
5464 %
5465 %      void DrawSetStrokeDashOffset(DrawingWand *wand,
5466 %        const double dash_offset)
5467 %
5468 %  A description of each parameter follows:
5469 %
5470 %    o wand: the drawing wand.
5471 %
5472 %    o dash_offset: dash offset
5473 %
5474 */
5475 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5476   const double dash_offset)
5477 {
5478   assert(wand != (DrawingWand *) NULL);
5479   assert(wand->signature == WandSignature);
5480   if (wand->debug != MagickFalse)
5481     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5482   if ((wand->filter_off != MagickFalse) ||
5483      (fabs(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
5484     {
5485       CurrentContext->dash_offset=dash_offset;
5486       (void) MvgPrintf(wand,"stroke-dashoffset %g\n",dash_offset);
5487     }
5488 }
5489 \f
5490 /*
5491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5492 %                                                                             %
5493 %                                                                             %
5494 %                                                                             %
5495 %   D r a w S e t S t r o k e L i n e C a p                                   %
5496 %                                                                             %
5497 %                                                                             %
5498 %                                                                             %
5499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5500 %
5501 %  DrawSetStrokeLineCap() specifies the shape to be used at the end of
5502 %  open subpaths when they are stroked. Values of LineCap are
5503 %  UndefinedCap, ButtCap, RoundCap, and SquareCap.
5504 %
5505 %  The format of the DrawSetStrokeLineCap method is:
5506 %
5507 %      void DrawSetStrokeLineCap(DrawingWand *wand,
5508 %        const LineCap linecap)
5509 %
5510 %  A description of each parameter follows:
5511 %
5512 %    o wand: the drawing wand.
5513 %
5514 %    o linecap: linecap style
5515 %
5516 */
5517 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5518 {
5519   assert(wand != (DrawingWand *) NULL);
5520   assert(wand->signature == WandSignature);
5521   if (wand->debug != MagickFalse)
5522     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5523   if ((wand->filter_off != MagickFalse) ||
5524       (CurrentContext->linecap != linecap))
5525     {
5526       CurrentContext->linecap=linecap;
5527       (void) MvgPrintf(wand,"stroke-linecap '%s'\n",MagickOptionToMnemonic(
5528         MagickLineCapOptions,(ssize_t) linecap));
5529     }
5530 }
5531 \f
5532 /*
5533 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5534 %                                                                             %
5535 %                                                                             %
5536 %                                                                             %
5537 %   D r a w S e t S t r o k e L i n e J o i n                                 %
5538 %                                                                             %
5539 %                                                                             %
5540 %                                                                             %
5541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5542 %
5543 %  DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5544 %  paths (or other vector shapes) when they are stroked. Values of LineJoin are
5545 %  UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5546 %
5547 %  The format of the DrawSetStrokeLineJoin method is:
5548 %
5549 %      void DrawSetStrokeLineJoin(DrawingWand *wand,
5550 %        const LineJoin linejoin)
5551 %
5552 %  A description of each parameter follows:
5553 %
5554 %    o wand: the drawing wand.
5555 %
5556 %    o linejoin: line join style
5557 %
5558 */
5559 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5560 {
5561   assert(wand != (DrawingWand *) NULL);
5562   assert(wand->signature == WandSignature);
5563   if (wand->debug != MagickFalse)
5564     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5565   if ((wand->filter_off != MagickFalse) ||
5566       (CurrentContext->linejoin != linejoin))
5567     {
5568       CurrentContext->linejoin=linejoin;
5569       (void) MvgPrintf(wand, "stroke-linejoin '%s'\n",MagickOptionToMnemonic(
5570         MagickLineJoinOptions,(ssize_t) linejoin));
5571     }
5572 }
5573 \f
5574 /*
5575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5576 %                                                                             %
5577 %                                                                             %
5578 %                                                                             %
5579 %   D r a w S e t S t r o k e M i t e r L i m i t                             %
5580 %                                                                             %
5581 %                                                                             %
5582 %                                                                             %
5583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5584 %
5585 %  DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5586 %  segments meet at a sharp angle and miter joins have been specified for
5587 %  'lineJoin', it is possible for the miter to extend far beyond the
5588 %  thickness of the line stroking the path. The miterLimit' imposes a
5589 %  limit on the ratio of the miter length to the 'lineWidth'.
5590 %
5591 %  The format of the DrawSetStrokeMiterLimit method is:
5592 %
5593 %      void DrawSetStrokeMiterLimit(DrawingWand *wand,
5594 %        const size_t miterlimit)
5595 %
5596 %  A description of each parameter follows:
5597 %
5598 %    o wand: the drawing wand.
5599 %
5600 %    o miterlimit: miter limit
5601 %
5602 */
5603 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
5604   const size_t miterlimit)
5605 {
5606   assert(wand != (DrawingWand *) NULL);
5607   assert(wand->signature == WandSignature);
5608   if (wand->debug != MagickFalse)
5609     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5610   if (CurrentContext->miterlimit != miterlimit)
5611     {
5612       CurrentContext->miterlimit=miterlimit;
5613       (void) MvgPrintf(wand,"stroke-miterlimit %lu\n",(unsigned long)
5614         miterlimit);
5615     }
5616 }
5617 \f
5618 /*
5619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5620 %                                                                             %
5621 %                                                                             %
5622 %                                                                             %
5623 %   D r a w S e t S t r o k e O p a c i t y                                   %
5624 %                                                                             %
5625 %                                                                             %
5626 %                                                                             %
5627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5628 %
5629 %  DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5630 %
5631 %  The format of the DrawSetStrokeOpacity method is:
5632 %
5633 %      void DrawSetStrokeOpacity(DrawingWand *wand,
5634 %        const double stroke_opacity)
5635 %
5636 %  A description of each parameter follows:
5637 %
5638 %    o wand: the drawing wand.
5639 %
5640 %    o stroke_opacity: stroke opacity.  The value 1.0 is opaque.
5641 %
5642 */
5643 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5644   const double stroke_opacity)
5645 {
5646   Quantum
5647     opacity;
5648
5649   assert(wand != (DrawingWand *) NULL);
5650   assert(wand->signature == WandSignature);
5651   if (wand->debug != MagickFalse)
5652     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5653   opacity=ClampToQuantum((double) QuantumRange*(1.0-stroke_opacity));
5654   if ((wand->filter_off != MagickFalse) ||
5655       (CurrentContext->stroke.opacity != opacity))
5656     {
5657       CurrentContext->stroke.opacity=opacity;
5658       (void) MvgPrintf(wand,"stroke-opacity %g\n",stroke_opacity);
5659     }
5660 }
5661 \f
5662 /*
5663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5664 %                                                                             %
5665 %                                                                             %
5666 %                                                                             %
5667 %   D r a w S e t S t r o k e W i d t h                                       %
5668 %                                                                             %
5669 %                                                                             %
5670 %                                                                             %
5671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5672 %
5673 %  DrawSetStrokeWidth() sets the width of the stroke used to draw object
5674 %  outlines.
5675 %
5676 %  The format of the DrawSetStrokeWidth method is:
5677 %
5678 %      void DrawSetStrokeWidth(DrawingWand *wand,
5679 %        const double stroke_width)
5680 %
5681 %  A description of each parameter follows:
5682 %
5683 %    o wand: the drawing wand.
5684 %
5685 %    o stroke_width: stroke width
5686 %
5687 */
5688 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5689 {
5690   assert(wand != (DrawingWand *) NULL);
5691   assert(wand->signature == WandSignature);
5692   if (wand->debug != MagickFalse)
5693     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5694   if ((wand->filter_off != MagickFalse) ||
5695       (fabs(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
5696     {
5697       CurrentContext->stroke_width=stroke_width;
5698       (void) MvgPrintf(wand,"stroke-width %g\n",stroke_width);
5699     }
5700 }
5701 \f
5702 /*
5703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5704 %                                                                             %
5705 %                                                                             %
5706 %                                                                             %
5707 %   D r a w S e t T e x t A l i g n m e n t                                   %
5708 %                                                                             %
5709 %                                                                             %
5710 %                                                                             %
5711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5712 %
5713 %  DrawSetTextAlignment() specifies a text alignment to be applied when
5714 %  annotating with text.
5715 %
5716 %  The format of the DrawSetTextAlignment method is:
5717 %
5718 %      void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5719 %
5720 %  A description of each parameter follows:
5721 %
5722 %    o wand: the drawing wand.
5723 %
5724 %    o alignment: text alignment.  One of UndefinedAlign, LeftAlign,
5725 %      CenterAlign, or RightAlign.
5726 %
5727 */
5728 WandExport void DrawSetTextAlignment(DrawingWand *wand,
5729   const AlignType alignment)
5730 {
5731   assert(wand != (DrawingWand *) NULL);
5732   assert(wand->signature == WandSignature);
5733   if (wand->debug != MagickFalse)
5734     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5735   if ((wand->filter_off != MagickFalse) ||
5736       (CurrentContext->align != alignment))
5737     {
5738       CurrentContext->align=alignment;
5739       (void) MvgPrintf(wand,"text-align '%s'\n",MagickOptionToMnemonic(
5740         MagickAlignOptions,(ssize_t) alignment));
5741     }
5742 }
5743 \f
5744 /*
5745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5746 %                                                                             %
5747 %                                                                             %
5748 %                                                                             %
5749 %   D r a w S e t T e x t A n t i a l i a s                                   %
5750 %                                                                             %
5751 %                                                                             %
5752 %                                                                             %
5753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5754 %
5755 %  DrawSetTextAntialias() controls whether text is antialiased.  Text is
5756 %  antialiased by default.
5757 %
5758 %  The format of the DrawSetTextAntialias method is:
5759 %
5760 %      void DrawSetTextAntialias(DrawingWand *wand,
5761 %        const MagickBooleanType text_antialias)
5762 %
5763 %  A description of each parameter follows:
5764 %
5765 %    o wand: the drawing wand.
5766 %
5767 %    o text_antialias: antialias boolean. Set to false (0) to disable
5768 %      antialiasing.
5769 %
5770 */
5771 WandExport void DrawSetTextAntialias(DrawingWand *wand,
5772   const MagickBooleanType text_antialias)
5773 {
5774   assert(wand != (DrawingWand *) NULL);
5775   assert(wand->signature == WandSignature);
5776   if (wand->debug != MagickFalse)
5777     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5778   if ((wand->filter_off != MagickFalse) ||
5779       (CurrentContext->text_antialias != text_antialias))
5780     {
5781       CurrentContext->text_antialias=text_antialias;
5782       (void) MvgPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5783     }
5784 }
5785 \f
5786 /*
5787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5788 %                                                                             %
5789 %                                                                             %
5790 %                                                                             %
5791 %   D r a w S e t T e x t D e c o r a t i o n                                 %
5792 %                                                                             %
5793 %                                                                             %
5794 %                                                                             %
5795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5796 %
5797 %  DrawSetTextDecoration() specifies a decoration to be applied when
5798 %  annotating with text.
5799 %
5800 %  The format of the DrawSetTextDecoration method is:
5801 %
5802 %      void DrawSetTextDecoration(DrawingWand *wand,
5803 %        const DecorationType decoration)
5804 %
5805 %  A description of each parameter follows:
5806 %
5807 %    o wand: the drawing wand.
5808 %
5809 %    o decoration: text decoration.  One of NoDecoration, UnderlineDecoration,
5810 %      OverlineDecoration, or LineThroughDecoration
5811 %
5812 */
5813 WandExport void DrawSetTextDecoration(DrawingWand *wand,
5814   const DecorationType decoration)
5815 {
5816   assert(wand != (DrawingWand *) NULL);
5817   assert(wand->signature == WandSignature);
5818   if (wand->debug != MagickFalse)
5819     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5820   if ((wand->filter_off != MagickFalse) ||
5821       (CurrentContext->decorate != decoration))
5822     {
5823       CurrentContext->decorate=decoration;
5824       (void) MvgPrintf(wand,"decorate '%s'\n",MagickOptionToMnemonic(
5825         MagickDecorateOptions,(ssize_t) decoration));
5826     }
5827 }
5828 \f
5829 /*
5830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5831 %                                                                             %
5832 %                                                                             %
5833 %                                                                             %
5834 %   D r a w S e t T e x t E n c o d i n g                                     %
5835 %                                                                             %
5836 %                                                                             %
5837 %                                                                             %
5838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5839 %
5840 %  DrawSetTextEncoding() specifies the code set to use for text
5841 %  annotations. The only character encoding which may be specified
5842 %  at this time is "UTF-8" for representing Unicode as a sequence of
5843 %  bytes. Specify an empty string to set text encoding to the system's
5844 %  default. Successful text annotation using Unicode may require fonts
5845 %  designed to support Unicode.
5846 %
5847 %  The format of the DrawSetTextEncoding method is:
5848 %
5849 %      void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5850 %
5851 %  A description of each parameter follows:
5852 %
5853 %    o wand: the drawing wand.
5854 %
5855 %    o encoding: character string specifying text encoding
5856 %
5857 */
5858 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5859 {
5860   assert(wand != (DrawingWand *) NULL);
5861   assert(wand->signature == WandSignature);
5862   if (wand->debug != MagickFalse)
5863     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5864   assert(encoding != (char *) NULL);
5865   if ((wand->filter_off != MagickFalse) ||
5866       (CurrentContext->encoding == (char *) NULL) ||
5867       (LocaleCompare(CurrentContext->encoding,encoding) != 0))
5868     {
5869       (void) CloneString(&CurrentContext->encoding,encoding);
5870       (void) MvgPrintf(wand,"encoding '%s'\n",encoding);
5871     }
5872 }
5873 \f
5874 /*
5875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5876 %                                                                             %
5877 %                                                                             %
5878 %                                                                             %
5879 %   D r a w S e t T e x t K e r n i n g                                       %
5880 %                                                                             %
5881 %                                                                             %
5882 %                                                                             %
5883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5884 %
5885 %  DrawSetTextKerning() sets the spacing between characters in text.
5886 %
5887 %  The format of the DrawSetTextKerning method is:
5888 %
5889 %      void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5890 %
5891 %  A description of each parameter follows:
5892 %
5893 %    o wand: the drawing wand.
5894 %
5895 %    o kerning: text kerning
5896 %
5897 */
5898 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5899 {
5900   assert(wand != (DrawingWand *) NULL);
5901   assert(wand->signature == WandSignature);
5902
5903   if (wand->debug != MagickFalse)
5904     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5905   if ((wand->filter_off != MagickFalse) &&
5906       (CurrentContext->kerning != kerning))
5907     {
5908       CurrentContext->kerning=kerning;
5909       (void) MvgPrintf(wand,"kerning %lf\n",kerning);
5910     }
5911 }
5912 \f
5913 /*
5914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5915 %                                                                             %
5916 %                                                                             %
5917 %                                                                             %
5918 %   D r a w S e t T e x t I n t e r L i n e S p a c i n g                     %
5919 %                                                                             %
5920 %                                                                             %
5921 %                                                                             %
5922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5923 %
5924 %  DrawSetTextInterwordSpacing() sets the spacing between line in text.
5925 %
5926 %  The format of the DrawSetInterwordSpacing method is:
5927 %
5928 %      void DrawSetTextInterwordSpacing(DrawingWand *wand,
5929 %        const double interline_spacing)
5930 %
5931 %  A description of each parameter follows:
5932 %
5933 %    o wand: the drawing wand.
5934 %
5935 %    o interline_spacing: text line spacing
5936 %
5937 */
5938 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
5939   const double interline_spacing)
5940 {
5941   assert(wand != (DrawingWand *) NULL);
5942   assert(wand->signature == WandSignature);
5943
5944   if (wand->debug != MagickFalse)
5945     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5946   if ((wand->filter_off != MagickFalse) &&
5947       (CurrentContext->interline_spacing != interline_spacing))
5948     {
5949       CurrentContext->interline_spacing=interline_spacing;
5950       (void) MvgPrintf(wand,"interline-spacing %lf\n",interline_spacing);
5951     }
5952 }
5953 \f
5954 /*
5955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5956 %                                                                             %
5957 %                                                                             %
5958 %                                                                             %
5959 %   D r a w S e t T e x t I n t e r w o r d S p a c i n g                     %
5960 %                                                                             %
5961 %                                                                             %
5962 %                                                                             %
5963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5964 %
5965 %  DrawSetTextInterwordSpacing() sets the spacing between words in text.
5966 %
5967 %  The format of the DrawSetInterwordSpacing method is:
5968 %
5969 %      void DrawSetTextInterwordSpacing(DrawingWand *wand,
5970 %        const double interword_spacing)
5971 %
5972 %  A description of each parameter follows:
5973 %
5974 %    o wand: the drawing wand.
5975 %
5976 %    o interword_spacing: text word spacing
5977 %
5978 */
5979 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
5980   const double interword_spacing)
5981 {
5982   assert(wand != (DrawingWand *) NULL);
5983   assert(wand->signature == WandSignature);
5984
5985   if (wand->debug != MagickFalse)
5986     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5987   if ((wand->filter_off != MagickFalse) &&
5988       (CurrentContext->interword_spacing != interword_spacing))
5989     {
5990       CurrentContext->interword_spacing=interword_spacing;
5991       (void) MvgPrintf(wand,"interword-spacing %lf\n",interword_spacing);
5992     }
5993 }
5994 \f
5995 /*
5996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5997 %                                                                             %
5998 %                                                                             %
5999 %                                                                             %
6000 %   D r a w S e t T e x t U n d e r C o l o r                                 %
6001 %                                                                             %
6002 %                                                                             %
6003 %                                                                             %
6004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6005 %
6006 %  DrawSetTextUnderColor() specifies the color of a background rectangle
6007 %  to place under text annotations.
6008 %
6009 %  The format of the DrawSetTextUnderColor method is:
6010 %
6011 %      void DrawSetTextUnderColor(DrawingWand *wand,
6012 %        const PixelWand *under_wand)
6013 %
6014 %  A description of each parameter follows:
6015 %
6016 %    o wand: the drawing wand.
6017 %
6018 %    o under_wand: text under wand.
6019 %
6020 */
6021 WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6022   const PixelWand *under_wand)
6023 {
6024   PixelPacket
6025     under_color;
6026
6027   assert(wand != (DrawingWand *) NULL);
6028   assert(wand->signature == WandSignature);
6029   if (wand->debug != MagickFalse)
6030     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6031   assert(under_wand != (const PixelWand *) NULL);
6032   PixelGetQuantumColor(under_wand,&under_color);
6033   if ((wand->filter_off != MagickFalse) ||
6034       (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6035     {
6036       CurrentContext->undercolor=under_color;
6037       (void) MvgPrintf(wand,"text-undercolor '");
6038       MvgAppendColor(wand,&under_color);
6039       (void) MvgPrintf(wand,"'\n");
6040     }
6041 }
6042 \f
6043 /*
6044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6045 %                                                                             %
6046 %                                                                             %
6047 %                                                                             %
6048 %   D r a w S e t V e c t o r G r a p h i c s                                 %
6049 %                                                                             %
6050 %                                                                             %
6051 %                                                                             %
6052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6053 %
6054 %  DrawSetVectorGraphics() sets the vector graphics associated with the
6055 %  specified wand.  Use this method with DrawGetVectorGraphics() as a method
6056 %  to persist the vector graphics state.
6057 %
6058 %  The format of the DrawSetVectorGraphics method is:
6059 %
6060 %      MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6061 %        const char *xml)
6062 %
6063 %  A description of each parameter follows:
6064 %
6065 %    o wand: the drawing wand.
6066 %
6067 %    o xml: the drawing wand XML.
6068 %
6069 */
6070
6071 static inline MagickBooleanType IsPoint(const char *point)
6072 {
6073   char
6074     *p;
6075
6076   long
6077     value;
6078
6079   value=strtol(point,&p,10);
6080   return(p != point ? MagickTrue : MagickFalse);
6081 }
6082
6083 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6084   const char *xml)
6085 {
6086   const char
6087     *value;
6088
6089   XMLTreeInfo
6090     *child,
6091     *xml_info;
6092
6093   assert(wand != (DrawingWand *) NULL);
6094   assert(wand->signature == WandSignature);
6095   if (wand->debug != MagickFalse)
6096     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6097   CurrentContext=DestroyDrawInfo(CurrentContext);
6098   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6099   if (xml == (const char *) NULL)
6100     return(MagickFalse);
6101   xml_info=NewXMLTree(xml,wand->exception);
6102   if (xml_info == (XMLTreeInfo *) NULL)
6103     return(MagickFalse);
6104   child=GetXMLTreeChild(xml_info,"clip-path");
6105   if (child != (XMLTreeInfo *) NULL)
6106     (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6107   child=GetXMLTreeChild(xml_info,"clip-units");
6108   if (child != (XMLTreeInfo *) NULL)
6109     {
6110       value=GetXMLTreeContent(child);
6111       if (value != (const char *) NULL)
6112         CurrentContext->clip_units=(ClipPathUnits) ParseMagickOption(
6113           MagickClipPathOptions,MagickFalse,value);
6114     }
6115   child=GetXMLTreeChild(xml_info,"decorate");
6116   if (child != (XMLTreeInfo *) NULL)
6117     {
6118       value=GetXMLTreeContent(child);
6119       if (value != (const char *) NULL)
6120         CurrentContext->decorate=(DecorationType) ParseMagickOption(
6121           MagickDecorateOptions,MagickFalse,value);
6122     }
6123   child=GetXMLTreeChild(xml_info,"encoding");
6124   if (child != (XMLTreeInfo *) NULL)
6125     (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6126   child=GetXMLTreeChild(xml_info,"fill");
6127   if (child != (XMLTreeInfo *) NULL)
6128     {
6129       value=GetXMLTreeContent(child);
6130       if (value != (const char *) NULL)
6131         (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6132     }
6133   child=GetXMLTreeChild(xml_info,"fill-opacity");
6134   if (child != (XMLTreeInfo *) NULL)
6135     {
6136       value=GetXMLTreeContent(child);
6137       if (value != (const char *) NULL)
6138         CurrentContext->fill.opacity=ClampToQuantum((MagickRealType)
6139           QuantumRange*(1.0-StringToDouble(value)));
6140     }
6141   child=GetXMLTreeChild(xml_info,"fill-rule");
6142   if (child != (XMLTreeInfo *) NULL)
6143     {
6144       value=GetXMLTreeContent(child);
6145       if (value != (const char *) NULL)
6146         CurrentContext->fill_rule=(FillRule) ParseMagickOption(
6147           MagickFillRuleOptions,MagickFalse,value);
6148     }
6149   child=GetXMLTreeChild(xml_info,"font");
6150   if (child != (XMLTreeInfo *) NULL)
6151     (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6152   child=GetXMLTreeChild(xml_info,"font-family");
6153   if (child != (XMLTreeInfo *) NULL)
6154     (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6155   child=GetXMLTreeChild(xml_info,"font-size");
6156   if (child != (XMLTreeInfo *) NULL)
6157     {
6158       value=GetXMLTreeContent(child);
6159       if (value != (const char *) NULL)
6160         CurrentContext->pointsize=StringToDouble(value);
6161     }
6162   child=GetXMLTreeChild(xml_info,"font-stretch");
6163   if (child != (XMLTreeInfo *) NULL)
6164     {
6165       value=GetXMLTreeContent(child);
6166       if (value != (const char *) NULL)
6167         CurrentContext->stretch=(StretchType) ParseMagickOption(
6168           MagickStretchOptions,MagickFalse,value);
6169     }
6170   child=GetXMLTreeChild(xml_info,"font-style");
6171   if (child != (XMLTreeInfo *) NULL)
6172     {
6173       value=GetXMLTreeContent(child);
6174       if (value != (const char *) NULL)
6175         CurrentContext->style=(StyleType) ParseMagickOption(MagickStyleOptions,
6176           MagickFalse,value);
6177     }
6178   child=GetXMLTreeChild(xml_info,"font-weight");
6179   if (child != (XMLTreeInfo *) NULL)
6180     {
6181       value=GetXMLTreeContent(child);
6182       if (value != (const char *) NULL)
6183         CurrentContext->weight=StringToUnsignedLong(value);
6184     }
6185   child=GetXMLTreeChild(xml_info,"gravity");
6186   if (child != (XMLTreeInfo *) NULL)
6187     {
6188       value=GetXMLTreeContent(child);
6189       if (value != (const char *) NULL)
6190         CurrentContext->gravity=(GravityType) ParseMagickOption(
6191           MagickGravityOptions,MagickFalse,value);
6192     }
6193   child=GetXMLTreeChild(xml_info,"stroke");
6194   if (child != (XMLTreeInfo *) NULL)
6195     {
6196       value=GetXMLTreeContent(child);
6197       if (value != (const char *) NULL)
6198         (void) QueryColorDatabase(value,&CurrentContext->stroke,
6199           wand->exception);
6200     }
6201   child=GetXMLTreeChild(xml_info,"stroke-antialias");
6202   if (child != (XMLTreeInfo *) NULL)
6203     {
6204       value=GetXMLTreeContent(child);
6205       if (value != (const char *) NULL)
6206         CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6207           MagickFalse;
6208     }
6209   child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6210   if (child != (XMLTreeInfo *) NULL)
6211     {
6212       char
6213         token[MaxTextExtent];
6214
6215       const char
6216         *q;
6217
6218       ssize_t
6219         j;
6220
6221       register ssize_t
6222         x;
6223
6224       value=GetXMLTreeContent(child);
6225       if (value != (const char *) NULL)
6226         {
6227           if (CurrentContext->dash_pattern != (double *) NULL)
6228             CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6229               CurrentContext->dash_pattern);
6230           q=(char *) value;
6231           if (IsPoint(q) != MagickFalse)
6232             {
6233               const char
6234                 *p;
6235
6236               p=q;
6237               GetMagickToken(p,&p,token);
6238               if (*token == ',')
6239                 GetMagickToken(p,&p,token);
6240               for (x=0; IsPoint(token) != MagickFalse; x++)
6241               {
6242                 GetMagickToken(p,&p,token);
6243                 if (*token == ',')
6244                   GetMagickToken(p,&p,token);
6245               }
6246               CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6247                 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6248               if (CurrentContext->dash_pattern == (double *) NULL)
6249                 ThrowWandFatalException(ResourceLimitFatalError,
6250                   "MemoryAllocationFailed",wand->name);
6251               for (j=0; j < x; j++)
6252               {
6253                 GetMagickToken(q,&q,token);
6254                 if (*token == ',')
6255                   GetMagickToken(q,&q,token);
6256                 CurrentContext->dash_pattern[j]=StringToDouble(token);
6257               }
6258               if ((x & 0x01) != 0)
6259                 for ( ; j < (2*x); j++)
6260                   CurrentContext->dash_pattern[j]=
6261                     CurrentContext->dash_pattern[j-x];
6262               CurrentContext->dash_pattern[j]=0.0;
6263             }
6264         }
6265     }
6266   child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6267   if (child != (XMLTreeInfo *) NULL)
6268     {
6269       value=GetXMLTreeContent(child);
6270       if (value != (const char *) NULL)
6271         CurrentContext->dash_offset=StringToDouble(value);
6272     }
6273   child=GetXMLTreeChild(xml_info,"stroke-linecap");
6274   if (child != (XMLTreeInfo *) NULL)
6275     {
6276       value=GetXMLTreeContent(child);
6277       if (value != (const char *) NULL)
6278         CurrentContext->linecap=(LineCap) ParseMagickOption(
6279           MagickLineCapOptions,MagickFalse,value);
6280     }
6281   child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6282   if (child != (XMLTreeInfo *) NULL)
6283     {
6284       value=GetXMLTreeContent(child);
6285       if (value != (const char *) NULL)
6286         CurrentContext->linejoin=(LineJoin) ParseMagickOption(
6287           MagickLineJoinOptions,MagickFalse,value);
6288     }
6289   child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6290   if (child != (XMLTreeInfo *) NULL)
6291     {
6292       value=GetXMLTreeContent(child);
6293       if (value != (const char *) NULL)
6294         CurrentContext->miterlimit=StringToUnsignedLong(value);
6295     }
6296   child=GetXMLTreeChild(xml_info,"stroke-opacity");
6297   if (child != (XMLTreeInfo *) NULL)
6298     {
6299       value=GetXMLTreeContent(child);
6300       if (value != (const char *) NULL)
6301         CurrentContext->stroke.opacity=ClampToQuantum((MagickRealType)
6302           QuantumRange*(1.0-StringToDouble(value)));
6303     }
6304   child=GetXMLTreeChild(xml_info,"stroke-width");
6305   if (child != (XMLTreeInfo *) NULL)
6306     {
6307       value=GetXMLTreeContent(child);
6308       if (value != (const char *) NULL)
6309         CurrentContext->stroke_width=StringToDouble(value);
6310     }
6311   child=GetXMLTreeChild(xml_info,"text-align");
6312   if (child != (XMLTreeInfo *) NULL)
6313     {
6314       value=GetXMLTreeContent(child);
6315       if (value != (const char *) NULL)
6316         CurrentContext->align=(AlignType) ParseMagickOption(MagickAlignOptions,
6317           MagickFalse,value);
6318     }
6319   child=GetXMLTreeChild(xml_info,"text-antialias");
6320   if (child != (XMLTreeInfo *) NULL)
6321     {
6322       value=GetXMLTreeContent(child);
6323       if (value != (const char *) NULL)
6324         CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6325           MagickFalse;
6326     }
6327   child=GetXMLTreeChild(xml_info,"text-undercolor");
6328   if (child != (XMLTreeInfo *) NULL)
6329     {
6330       value=GetXMLTreeContent(child);
6331       if (value != (const char *) NULL)
6332         (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6333           wand->exception);
6334     }
6335   child=GetXMLTreeChild(xml_info,"vector-graphics");
6336   if (child != (XMLTreeInfo *) NULL)
6337     {
6338       (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6339       wand->mvg_length=strlen(wand->mvg);
6340       wand->mvg_alloc=wand->mvg_length+1;
6341     }
6342   xml_info=DestroyXMLTree(xml_info);
6343   return(MagickTrue);
6344 }
6345 \f
6346 /*
6347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6348 %                                                                             %
6349 %                                                                             %
6350 %                                                                             %
6351 %   D r a w S k e w X                                                         %
6352 %                                                                             %
6353 %                                                                             %
6354 %                                                                             %
6355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6356 %
6357 %  DrawSkewX() skews the current coordinate system in the horizontal
6358 %  direction.
6359 %
6360 %  The format of the DrawSkewX method is:
6361 %
6362 %      void DrawSkewX(DrawingWand *wand,const double degrees)
6363 %
6364 %  A description of each parameter follows:
6365 %
6366 %    o wand: the drawing wand.
6367 %
6368 %    o degrees: number of degrees to skew the coordinates
6369 %
6370 */
6371 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6372 {
6373   AffineMatrix
6374     affine;
6375
6376   assert(wand != (DrawingWand *) NULL);
6377   assert(wand->signature == WandSignature);
6378   if (wand->debug != MagickFalse)
6379     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6380   GetAffineMatrix(&affine);
6381   affine.ry=tan(DegreesToRadians(fmod(degrees,360.0)));
6382   AdjustAffine(wand,&affine);
6383   (void) MvgPrintf(wand,"skewX %g\n",degrees);
6384 }
6385 \f
6386 /*
6387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6388 %                                                                             %
6389 %                                                                             %
6390 %                                                                             %
6391 %   D r a w S k e w Y                                                         %
6392 %                                                                             %
6393 %                                                                             %
6394 %                                                                             %
6395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6396 %
6397 %  DrawSkewY() skews the current coordinate system in the vertical
6398 %  direction.
6399 %
6400 %  The format of the DrawSkewY method is:
6401 %
6402 %      void DrawSkewY(DrawingWand *wand,const double degrees)
6403 %
6404 %  A description of each parameter follows:
6405 %
6406 %    o wand: the drawing wand.
6407 %
6408 %    o degrees: number of degrees to skew the coordinates
6409 %
6410 */
6411 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6412 {
6413   AffineMatrix
6414     affine;
6415
6416   assert(wand != (DrawingWand *) NULL);
6417   assert(wand->signature == WandSignature);
6418   if (wand->debug != MagickFalse)
6419     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6420   GetAffineMatrix(&affine);
6421   affine.rx=tan(DegreesToRadians(fmod(degrees,360.0)));
6422   DrawAffine(wand,&affine);
6423   (void) MvgPrintf(wand,"skewY %g\n",degrees);
6424 }
6425 \f
6426 /*
6427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6428 %                                                                             %
6429 %                                                                             %
6430 %                                                                             %
6431 %   D r a w T r a n s l a t e                                                 %
6432 %                                                                             %
6433 %                                                                             %
6434 %                                                                             %
6435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6436 %
6437 %  DrawTranslate() applies a translation to the current coordinate
6438 %  system which moves the coordinate system origin to the specified
6439 %  coordinate.
6440 %
6441 %  The format of the DrawTranslate method is:
6442 %
6443 %      void DrawTranslate(DrawingWand *wand,const double x,
6444 %        const double y)
6445 %
6446 %  A description of each parameter follows:
6447 %
6448 %    o wand: the drawing wand.
6449 %
6450 %    o x: new x ordinate for coordinate system origin
6451 %
6452 %    o y: new y ordinate for coordinate system origin
6453 %
6454 */
6455 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6456 {
6457   AffineMatrix
6458     affine;
6459
6460   assert(wand != (DrawingWand *) NULL);
6461   assert(wand->signature == WandSignature);
6462   if (wand->debug != MagickFalse)
6463     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6464   GetAffineMatrix(&affine);
6465   affine.tx=x;
6466   affine.ty=y;
6467   AdjustAffine(wand,&affine);
6468   (void) MvgPrintf(wand,"translate %g,%g\n",x,y);
6469 }
6470 \f
6471 /*
6472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6473 %                                                                             %
6474 %                                                                             %
6475 %                                                                             %
6476 %   D r a w S e t V i e w b o x                                               %
6477 %                                                                             %
6478 %                                                                             %
6479 %                                                                             %
6480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6481 %
6482 %  DrawSetViewbox() sets the overall canvas size to be recorded with the
6483 %  drawing vector data.  Usually this will be specified using the same
6484 %  size as the canvas image.  When the vector data is saved to SVG or MVG
6485 %  formats, the viewbox is use to specify the size of the canvas image that
6486 %  a viewer will render the vector data on.
6487 %
6488 %  The format of the DrawSetViewbox method is:
6489 %
6490 %      void DrawSetViewbox(DrawingWand *wand,size_t x1,
6491 %        size_t y1,size_t x2,size_t y2)
6492 %
6493 %  A description of each parameter follows:
6494 %
6495 %    o wand: the drawing wand.
6496 %
6497 %    o x1: left x ordinate
6498 %
6499 %    o y1: top y ordinate
6500 %
6501 %    o x2: right x ordinate
6502 %
6503 %    o y2: bottom y ordinate
6504 %
6505 */
6506 WandExport void DrawSetViewbox(DrawingWand *wand,ssize_t x1,ssize_t y1,
6507   ssize_t x2,ssize_t y2)
6508 {
6509   assert(wand != (DrawingWand *) NULL);
6510   assert(wand->signature == WandSignature);
6511   if (wand->debug != MagickFalse)
6512     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6513   (void) MvgPrintf(wand,"viewbox %ld %ld %ld %ld\n",(long) x1,(long) y1,
6514     (long) x2,(long) y2);
6515 }
6516 \f
6517 /*
6518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6519 %                                                                             %
6520 %                                                                             %
6521 %                                                                             %
6522 %   I s D r a w i n g W a n d                                                 %
6523 %                                                                             %
6524 %                                                                             %
6525 %                                                                             %
6526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6527 %
6528 %  IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6529 %
6530 %  The format of the IsDrawingWand method is:
6531 %
6532 %      MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6533 %
6534 %  A description of each parameter follows:
6535 %
6536 %    o wand: the drawing wand.
6537 %
6538 */
6539 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6540 {
6541   if (wand == (const DrawingWand *) NULL)
6542     return(MagickFalse);
6543   if (wand->signature != WandSignature)
6544     return(MagickFalse);
6545   if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6546     return(MagickFalse);
6547   return(MagickTrue);
6548 }
6549 \f
6550 /*
6551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6552 %                                                                             %
6553 %                                                                             %
6554 %                                                                             %
6555 %   N e w D r a w i n g W a n d                                               %
6556 %                                                                             %
6557 %                                                                             %
6558 %                                                                             %
6559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6560 %
6561 %  NewDrawingWand() returns a drawing wand required for all other methods in
6562 %  the API.
6563 %
6564 %  The format of the NewDrawingWand method is:
6565 %
6566 %      DrawingWand NewDrawingWand(void)
6567 %
6568 */
6569 WandExport DrawingWand *NewDrawingWand(void)
6570 {
6571   const char
6572     *quantum;
6573
6574   DrawingWand
6575     *wand;
6576
6577   size_t
6578     depth;
6579
6580   quantum=GetMagickQuantumDepth(&depth);
6581   if (depth != MAGICKCORE_QUANTUM_DEPTH)
6582     ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
6583   wand=(DrawingWand *) AcquireAlignedMemory(1,sizeof(*wand));
6584   if (wand == (DrawingWand *) NULL)
6585     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6586       GetExceptionMessage(errno));
6587   (void) ResetMagickMemory(wand,0,sizeof(*wand));
6588   wand->id=AcquireWandId();
6589   (void) FormatMagickString(wand->name,MaxTextExtent,"%s-%lu",DrawingWandId,
6590     (unsigned long) wand->id);
6591   if (wand->debug != MagickFalse)
6592     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6593   wand->mvg=(char *) NULL;
6594   wand->mvg_alloc=0;
6595   wand->mvg_length=0;
6596   wand->mvg_width=0;
6597   wand->pattern_id=(char *) NULL;
6598   wand->pattern_offset=0;
6599   wand->pattern_bounds.x=0;
6600   wand->pattern_bounds.y=0;
6601   wand->pattern_bounds.width=0;
6602   wand->pattern_bounds.height=0;
6603   wand->index=0;
6604   wand->graphic_context=(DrawInfo **) AcquireAlignedMemory(1,sizeof(
6605     *wand->graphic_context));
6606   if (wand->graphic_context == (DrawInfo **) NULL)
6607     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6608       GetExceptionMessage(errno));
6609   wand->filter_off=MagickTrue;
6610   wand->indent_depth=0;
6611   wand->path_operation=PathDefaultOperation;
6612   wand->path_mode=DefaultPathMode;
6613   wand->image=AcquireImage((const ImageInfo *) NULL);
6614   wand->exception=AcquireExceptionInfo();
6615   wand->destroy=MagickTrue;
6616   wand->debug=IsEventLogging();
6617   wand->signature=WandSignature;
6618   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6619   return(wand);
6620 }
6621 \f
6622 /*
6623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6624 %                                                                             %
6625 %                                                                             %
6626 %                                                                             %
6627 %   P e e k D r a w i n g W a n d                                             %
6628 %                                                                             %
6629 %                                                                             %
6630 %                                                                             %
6631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6632 %
6633 %  PeekDrawingWand() returns the current drawing wand.
6634 %
6635 %  The format of the PeekDrawingWand method is:
6636 %
6637 %      DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6638 %
6639 %  A description of each parameter follows:
6640 %
6641 %    o wand: the drawing wand.
6642 %
6643 */
6644 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6645 {
6646   DrawInfo
6647     *draw_info;
6648
6649   assert(wand != (const DrawingWand *) NULL);
6650   assert(wand->signature == WandSignature);
6651   if (wand->debug != MagickFalse)
6652     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6653   draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6654   GetAffineMatrix(&draw_info->affine);
6655   (void) CloneString(&draw_info->primitive,wand->mvg);
6656   return(draw_info);
6657 }
6658 \f
6659 /*
6660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6661 %                                                                             %
6662 %                                                                             %
6663 %                                                                             %
6664 %   P o p D r a w i n g W a n d                                               %
6665 %                                                                             %
6666 %                                                                             %
6667 %                                                                             %
6668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6669 %
6670 %  PopDrawingWand() destroys the current drawing wand and returns to the
6671 %  previously pushed drawing wand. Multiple drawing wands may exist. It is an
6672 %  error to attempt to pop more drawing wands than have been pushed, and it is
6673 %  proper form to pop all drawing wands which have been pushed.
6674 %
6675 %  The format of the PopDrawingWand method is:
6676 %
6677 %      MagickBooleanType PopDrawingWand(DrawingWand *wand)
6678 %
6679 %  A description of each parameter follows:
6680 %
6681 %    o wand: the drawing wand.
6682 %
6683 */
6684 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6685 {
6686   assert(wand != (DrawingWand *) NULL);
6687   assert(wand->signature == WandSignature);
6688   if (wand->debug != MagickFalse)
6689     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6690   if (wand->index == 0)
6691     {
6692       ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6693       return(MagickFalse);
6694     }
6695   /*
6696     Destroy clip path if not same in preceding wand.
6697   */
6698 #if DRAW_BINARY_IMPLEMENTATION
6699   if (wand->image == (Image *) NULL)
6700     ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6701   if (CurrentContext->clip_mask != (char *) NULL)
6702     if (LocaleCompare(CurrentContext->clip_mask,
6703         wand->graphic_context[wand->index-1]->clip_mask) != 0)
6704       (void) SetImageClipMask(wand->image,(Image *) NULL);
6705 #endif
6706   CurrentContext=DestroyDrawInfo(CurrentContext);
6707   wand->index--;
6708   if (wand->indent_depth > 0)
6709     wand->indent_depth--;
6710   (void) MvgPrintf(wand,"pop graphic-context\n");
6711   return(MagickTrue);
6712 }
6713 \f
6714 /*
6715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6716 %                                                                             %
6717 %                                                                             %
6718 %                                                                             %
6719 %   P u s h D r a w i n g W a n d                                             %
6720 %                                                                             %
6721 %                                                                             %
6722 %                                                                             %
6723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6724 %
6725 %  PushDrawingWand() clones the current drawing wand to create a new drawing
6726 %  wand.  The original drawing wand(s) may be returned to by invoking
6727 %  PopDrawingWand().  The drawing wands are stored on a drawing wand stack.
6728 %  For every Pop there must have already been an equivalent Push.
6729 %
6730 %  The format of the PushDrawingWand method is:
6731 %
6732 %      MagickBooleanType PushDrawingWand(DrawingWand *wand)
6733 %
6734 %  A description of each parameter follows:
6735 %
6736 %    o wand: the drawing wand.
6737 %
6738 */
6739 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6740 {
6741   assert(wand != (DrawingWand *) NULL);
6742   assert(wand->signature == WandSignature);
6743   if (wand->debug != MagickFalse)
6744     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6745   wand->index++;
6746   wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6747     (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6748   if (wand->graphic_context == (DrawInfo **) NULL)
6749     {
6750       ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6751         wand->name);
6752       return(MagickFalse);
6753     }
6754   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6755     wand->graphic_context[wand->index-1]);
6756   (void) MvgPrintf(wand,"push graphic-context\n");
6757   wand->indent_depth++;
6758   return(MagickTrue);
6759 }