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