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