• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
68 typedef enum
69 {
70   PathDefaultOperation,
71   PathCloseOperation,                        /* Z|z (none) */
72   PathCurveToOperation,                      /* C|c (x1 y1 x2 y2 x y)+ */
73   PathCurveToQuadraticBezierOperation,       /* Q|q (x1 y1 x y)+ */
74   PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
75   PathCurveToSmoothOperation,                /* S|s (x2 y2 x y)+ */
76   PathEllipticArcOperation,                  /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
77   PathLineToHorizontalOperation,             /* H|h x+ */
78   PathLineToOperation,                       /* L|l (x y)+ */
79   PathLineToVerticalOperation,               /* V|v y+ */
80   PathMoveToOperation                        /* M|m (x y)+ */
81 } PathOperation;
82 
83 typedef enum
84 {
85   DefaultPathMode,
86   AbsolutePathMode,
87   RelativePathMode
88 } PathMode;
89 
90 struct _DrawingWand
91 {
92   size_t
93     id;
94 
95   char
96     name[MagickPathExtent];
97 
98   /* Support structures */
99   Image
100     *image;
101 
102   ExceptionInfo
103     *exception;
104 
105   /* MVG output string and housekeeping */
106   char
107     *mvg;               /* MVG data */
108 
109   size_t
110     mvg_alloc,          /* total allocated memory */
111     mvg_length;         /* total MVG length */
112 
113   size_t
114     mvg_width;          /* current line width */
115 
116   /* Pattern support */
117   char
118     *pattern_id;
119 
120   RectangleInfo
121     pattern_bounds;
122 
123   size_t
124     pattern_offset;
125 
126   /* Graphic wand */
127   size_t
128     index;              /* array index */
129 
130   DrawInfo
131     **graphic_context;
132 
133   MagickBooleanType
134     filter_off;         /* true if not filtering attributes */
135 
136   /* Pretty-printing depth */
137   size_t
138     indent_depth;       /* number of left-hand pad characters */
139 
140   /* Path operation support */
141   PathOperation
142     path_operation;
143 
144   PathMode
145     path_mode;
146 
147   MagickBooleanType
148     destroy,
149     debug;
150 
151   size_t
152     signature;
153 };
154 
155 /*
156   Forward declarations.
157 */
158 static int
159   MVGPrintf(DrawingWand *,const char *,...) wand_attribute((format
160     (printf,2,3))),
161   MVGAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format
162     (printf,2,3)));
163 
164 static void
165   MVGAppendColor(DrawingWand *,const PixelInfo *);
166 
167 /*
168   "Printf" for MVG commands
169 */
MVGPrintf(DrawingWand * wand,const char * format,...)170 static int MVGPrintf(DrawingWand *wand,const char *format,...)
171 {
172   size_t
173     extent;
174 
175   if (wand->debug != MagickFalse)
176     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format);
177   assert(wand != (DrawingWand *) NULL);
178   assert(wand->signature == MagickWandSignature);
179   extent=20UL*MagickPathExtent;
180   if (wand->mvg == (char *) NULL)
181     {
182       wand->mvg=(char *) AcquireQuantumMemory(extent,sizeof(*wand->mvg));
183       if (wand->mvg == (char *) NULL)
184         {
185           ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
186             wand->name);
187           return(-1);
188         }
189       wand->mvg_alloc=extent;
190       wand->mvg_length=0;
191     }
192   if (wand->mvg_alloc < (wand->mvg_length+10*MagickPathExtent))
193     {
194       extent+=wand->mvg_alloc;
195       wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,extent,
196         sizeof(*wand->mvg));
197       if (wand->mvg == (char *) NULL)
198         {
199           ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
200             wand->name);
201           return(-1);
202         }
203       wand->mvg_alloc=extent;
204     }
205   {
206     int
207       count;
208 
209     ssize_t
210       offset;
211 
212     va_list
213       argp;
214 
215     while (wand->mvg_width < wand->indent_depth)
216     {
217       wand->mvg[wand->mvg_length]=' ';
218       wand->mvg_length++;
219       wand->mvg_width++;
220     }
221     wand->mvg[wand->mvg_length]='\0';
222     count=(-1);
223     offset=(ssize_t) wand->mvg_alloc-wand->mvg_length-1;
224     if (offset > 0)
225       {
226         va_start(argp,format);
227 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
228         count=vsnprintf(wand->mvg+wand->mvg_length,(size_t) offset,format,argp);
229 #else
230         count=vsprintf(wand->mvg+wand->mvg_length,format,argp);
231 #endif
232         va_end(argp);
233       }
234     if ((count < 0) || (count > (int) offset))
235       ThrowDrawException(DrawError,"UnableToPrint",format)
236     else
237       {
238         wand->mvg_length+=count;
239         wand->mvg_width+=count;
240       }
241     wand->mvg[wand->mvg_length]='\0';
242     if ((wand->mvg_length > 1) && (wand->mvg[wand->mvg_length-1] == '\n'))
243       wand->mvg_width=0;
244     assert((wand->mvg_length+1) < wand->mvg_alloc);
245     return(count);
246   }
247 }
248 
MVGAutoWrapPrintf(DrawingWand * wand,const char * format,...)249 static int MVGAutoWrapPrintf(DrawingWand *wand,const char *format,...)
250 {
251   char
252     buffer[MagickPathExtent];
253 
254   int
255     count;
256 
257   va_list
258     argp;
259 
260   va_start(argp,format);
261 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
262   count=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
263 #else
264   count=vsprintf(buffer,format,argp);
265 #endif
266   va_end(argp);
267   buffer[sizeof(buffer)-1]='\0';
268   if (count < 0)
269     ThrowDrawException(DrawError,"UnableToPrint",format)
270   else
271     {
272       if (((wand->mvg_width + count) > 78) && (buffer[count-1] != '\n'))
273         (void) MVGPrintf(wand, "\n");
274       (void) MVGPrintf(wand,"%s",buffer);
275     }
276   return(count);
277 }
278 
MVGAppendColor(DrawingWand * wand,const PixelInfo * packet)279 static void MVGAppendColor(DrawingWand *wand,const PixelInfo *packet)
280 {
281   if ((packet->red == 0) && (packet->green == 0) && (packet->blue == 0) &&
282       (packet->alpha == (Quantum) TransparentAlpha))
283     (void) MVGPrintf(wand,"none");
284   else
285     {
286       char
287         tuple[MagickPathExtent];
288 
289       PixelInfo
290         pixel;
291 
292       GetPixelInfo(wand->image,&pixel);
293       pixel.colorspace=sRGBColorspace;
294       pixel.alpha_trait=packet->alpha != OpaqueAlpha ? BlendPixelTrait :
295         UndefinedPixelTrait;
296       pixel.red=(double) packet->red;
297       pixel.green=(double) packet->green;
298       pixel.blue=(double) packet->blue;
299       pixel.alpha=(double) packet->alpha;
300       GetColorTuple(&pixel,MagickTrue,tuple);
301       (void) MVGPrintf(wand,"%s",tuple);
302     }
303 }
304 
MVGAppendPointsCommand(DrawingWand * wand,const char * command,const size_t number_coordinates,const PointInfo * coordinates)305 static void MVGAppendPointsCommand(DrawingWand *wand,const char *command,
306   const size_t number_coordinates,const PointInfo *coordinates)
307 {
308   const PointInfo
309     *coordinate;
310 
311   size_t
312     i;
313 
314   (void) MVGPrintf(wand,"%s",command);
315   for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
316   {
317     (void) MVGAutoWrapPrintf(wand," %.20g %.20g",coordinate->x,coordinate->y);
318     coordinate++;
319   }
320   (void) MVGPrintf(wand, "\n");
321 }
322 
AdjustAffine(DrawingWand * wand,const AffineMatrix * affine)323 static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine)
324 {
325   assert(wand != (DrawingWand *) NULL);
326   assert(wand->signature == MagickWandSignature);
327   if (wand->debug != MagickFalse)
328     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
329   if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
330       (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
331     {
332       AffineMatrix
333         current;
334 
335       current=CurrentContext->affine;
336       CurrentContext->affine.sx=affine->sx*current.sx+affine->ry*current.rx;
337       CurrentContext->affine.rx=affine->rx*current.sx+affine->sy*current.rx;
338       CurrentContext->affine.ry=affine->sx*current.ry+affine->ry*current.sy;
339       CurrentContext->affine.sy=affine->rx*current.ry+affine->sy*current.sy;
340       CurrentContext->affine.tx=affine->sx*current.tx+affine->ry*current.ty+
341         affine->tx;
342       CurrentContext->affine.ty=affine->rx*current.tx+affine->sy*current.ty+
343         affine->ty;
344     }
345 }
346 
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 */
AcquireDrawingWand(const DrawInfo * draw_info,Image * image)372 WandExport DrawingWand *AcquireDrawingWand(const DrawInfo *draw_info,
373   Image *image)
374 {
375   DrawingWand
376     *wand;
377 
378   wand=NewDrawingWand();
379   if (draw_info != (const DrawInfo *) NULL)
380     {
381       CurrentContext=DestroyDrawInfo(CurrentContext);
382       CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
383     }
384   if (image != (Image *) NULL)
385     {
386       wand->image=DestroyImage(wand->image);
387       wand->destroy=MagickFalse;
388     }
389   wand->image=image;
390   return(wand);
391 }
392 
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 */
ClearDrawingWand(DrawingWand * wand)415 WandExport void ClearDrawingWand(DrawingWand *wand)
416 {
417   assert(wand != (DrawingWand *) NULL);
418   assert(wand->signature == MagickWandSignature);
419   if (wand->debug != MagickFalse)
420     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
421   for ( ; wand->index > 0; wand->index--)
422     CurrentContext=DestroyDrawInfo(CurrentContext);
423   CurrentContext=DestroyDrawInfo(CurrentContext);
424   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
425     wand->graphic_context);
426   if (wand->pattern_id != (char *) NULL)
427     wand->pattern_id=DestroyString(wand->pattern_id);
428   wand->mvg=DestroyString(wand->mvg);
429   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
430     wand->image=DestroyImage(wand->image);
431   else
432     wand->image=(Image *) NULL;
433   wand->mvg=(char *) NULL;
434   wand->mvg_alloc=0;
435   wand->mvg_length=0;
436   wand->mvg_width=0;
437   wand->pattern_id=(char *) NULL;
438   wand->pattern_offset=0;
439   wand->pattern_bounds.x=0;
440   wand->pattern_bounds.y=0;
441   wand->pattern_bounds.width=0;
442   wand->pattern_bounds.height=0;
443   wand->index=0;
444   wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
445     sizeof(*wand->graphic_context));
446   if (wand->graphic_context == (DrawInfo **) NULL)
447     {
448       ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
449         wand->name);
450       return;
451     }
452   CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
453   wand->filter_off=MagickTrue;
454   wand->indent_depth=0;
455   wand->path_operation=PathDefaultOperation;
456   wand->path_mode=DefaultPathMode;
457   wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception);
458   ClearMagickException(wand->exception);
459   wand->destroy=MagickTrue;
460   wand->debug=IsEventLogging();
461 }
462 
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 */
CloneDrawingWand(const DrawingWand * wand)485 WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
486 {
487   DrawingWand
488     *clone_wand;
489 
490   register ssize_t
491     i;
492 
493   assert(wand != (DrawingWand *) NULL);
494   assert(wand->signature == MagickWandSignature);
495   if (wand->debug != MagickFalse)
496     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
497   clone_wand=(DrawingWand *) AcquireMagickMemory(sizeof(*clone_wand));
498   if (clone_wand == (DrawingWand *) NULL)
499     ThrowWandFatalException(ResourceLimitFatalError,
500       "MemoryAllocationFailed",GetExceptionMessage(errno));
501   (void) 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 */
DestroyDrawingWand(DrawingWand * wand)563 WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
564 {
565   assert(wand != (DrawingWand *) NULL);
566   assert(wand->signature == MagickWandSignature);
567   if (wand->debug != MagickFalse)
568     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
569   for ( ; wand->index > 0; wand->index--)
570     CurrentContext=DestroyDrawInfo(CurrentContext);
571   CurrentContext=DestroyDrawInfo(CurrentContext);
572   wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
573     wand->graphic_context);
574   if (wand->pattern_id != (char *) NULL)
575     wand->pattern_id=DestroyString(wand->pattern_id);
576   wand->mvg=DestroyString(wand->mvg);
577   if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
578     wand->image=DestroyImage(wand->image);
579   wand->image=(Image *) NULL;
580   wand->exception=DestroyExceptionInfo(wand->exception);
581   wand->signature=(~MagickWandSignature);
582   RelinquishWandId(wand->id);
583   wand=(DrawingWand *) RelinquishMagickMemory(wand);
584   return(wand);
585 }
586 
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 */
DrawAffine(DrawingWand * wand,const AffineMatrix * affine)613 WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
614 {
615   assert(wand != (DrawingWand *) NULL);
616   assert(wand->signature == MagickWandSignature);
617   if (wand->debug != MagickFalse)
618     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
619   assert(affine != (const AffineMatrix *) NULL);
620   AdjustAffine(wand,affine);
621   (void) MVGPrintf(wand,"affine %.20g %.20g %.20g %.20g %.20g %.20g\n",
622     affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
623 }
624 
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 */
DrawAlpha(DrawingWand * wand,const double x,const double y,const PaintMethod paint_method)662 WandExport void DrawAlpha(DrawingWand *wand,const double x,const double y,
663   const PaintMethod paint_method)
664 {
665   assert(wand != (DrawingWand *) NULL);
666   assert(wand->signature == MagickWandSignature);
667   if (wand->debug != MagickFalse)
668     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
669   (void) MVGPrintf(wand,"alpha %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
670     MagickMethodOptions,(ssize_t) paint_method));
671 }
672 
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 */
DrawAnnotation(DrawingWand * wand,const double x,const double y,const unsigned char * text)702 WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y,
703   const unsigned char *text)
704 {
705   char
706     *escaped_text;
707 
708   assert(wand != (DrawingWand *) NULL);
709   assert(wand->signature == MagickWandSignature);
710   if (wand->debug != MagickFalse)
711     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
712   assert(text != (const unsigned char *) NULL);
713   escaped_text=EscapeString((const char *) text,'\'');
714   if (escaped_text != (char *) NULL)
715     {
716       (void) MVGPrintf(wand,"text %.20g %.20g '%s'\n",x,y,escaped_text);
717       escaped_text=DestroyString(escaped_text);
718     }
719 }
720 
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 */
DrawArc(DrawingWand * wand,const double sx,const double sy,const double ex,const double ey,const double sd,const double ed)757 WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy,
758   const double ex,const double ey,const double sd,const double ed)
759 {
760   assert(wand != (DrawingWand *) NULL);
761   assert(wand->signature == MagickWandSignature);
762   if (wand->debug != MagickFalse)
763     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
764   (void) MVGPrintf(wand,"arc %.20g %.20g %.20g %.20g %.20g %.20g\n",sx,sy,ex,
765     ey,sd,ed);
766 }
767 
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 */
DrawBezier(DrawingWand * wand,const size_t number_coordinates,const PointInfo * coordinates)795 WandExport void DrawBezier(DrawingWand *wand,
796   const size_t number_coordinates,const PointInfo *coordinates)
797 {
798   assert(wand != (DrawingWand *) NULL);
799   assert(wand->signature == MagickWandSignature);
800   if (wand->debug != MagickFalse)
801     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
802   assert(coordinates != (const PointInfo *) NULL);
803   MVGAppendPointsCommand(wand,"bezier",number_coordinates,coordinates);
804 }
805 
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 */
DrawCircle(DrawingWand * wand,const double ox,const double oy,const double px,const double py)837 WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
838   const double px,const double py)
839 {
840   assert(wand != (DrawingWand *) NULL);
841   assert(wand->signature == MagickWandSignature);
842   if (wand->debug != MagickFalse)
843     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
844   (void) MVGPrintf(wand,"circle %.20g %.20g %.20g %.20g\n",ox,oy,px,py);
845 }
846 
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 */
DrawClearException(DrawingWand * wand)869 WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
870 {
871   assert(wand != (DrawingWand *) NULL);
872   assert(wand->signature == MagickWandSignature);
873   if (wand->debug != MagickFalse)
874     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
875   ClearMagickException(wand->exception);
876   return(MagickTrue);
877 }
878 
879 /*
880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881 %                                                                             %
882 %                                                                             %
883 %                                                                             %
884 %   D r a w C l o n e E x c e p t i o n I n f o                               %
885 %                                                                             %
886 %                                                                             %
887 %                                                                             %
888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889 %
890 %  DrawCloneExceptionInfo() clones the ExceptionInfo structure within the wand.
891 %
892 %  The format of the DrawCloneExceptionInfo method is:
893 %
894 %      ExceptionInfo *DrawCloneExceptionInfo(DrawWand *wand)
895 %
896 %  A description of each parameter follows:
897 %
898 %    o wand: the drawing wand.
899 %
900 */
DrawCloneExceptionInfo(const DrawingWand * wand)901 WandExport ExceptionInfo *DrawCloneExceptionInfo(const DrawingWand *wand)
902 {
903   assert(wand != (DrawingWand *) NULL);
904   assert(wand->signature == MagickWandSignature);
905   if (wand->exception == (ExceptionInfo*) NULL)
906     return (ExceptionInfo*) NULL;
907   return CloneExceptionInfo(wand->exception);
908 }
909 
910 /*
911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
912 %                                                                             %
913 %                                                                             %
914 %                                                                             %
915 %   D r a w C o l o r                                                         %
916 %                                                                             %
917 %                                                                             %
918 %                                                                             %
919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
920 %
921 %  DrawColor() draws color on image using the current fill color, starting at
922 %  specified position, and using specified paint method. The available paint
923 %  methods are:
924 %
925 %    PointMethod: Recolors the target pixel
926 %    ReplaceMethod: Recolor any pixel that matches the target pixel.
927 %    FloodfillMethod: Recolors target pixels and matching neighbors.
928 %    ResetMethod: Recolor all pixels.
929 %
930 %  The format of the DrawColor method is:
931 %
932 %      void DrawColor(DrawingWand *wand,const double x,const double y,
933 %        const PaintMethod paint_method)
934 %
935 %  A description of each parameter follows:
936 %
937 %    o wand: the drawing wand.
938 %
939 %    o x: x ordinate.
940 %
941 %    o y: y ordinate.
942 %
943 %    o paint_method: paint method.
944 %
945 */
DrawColor(DrawingWand * wand,const double x,const double y,const PaintMethod paint_method)946 WandExport void DrawColor(DrawingWand *wand, const double x, const double y,
947   const PaintMethod paint_method)
948 {
949   assert(wand != (DrawingWand *)NULL);
950   assert(wand->signature == MagickWandSignature);
951   if (wand->debug != MagickFalse)
952     (void) LogMagickEvent(WandEvent, GetMagickModule(), "%s", wand->name);
953   (void) MVGPrintf(wand, "color %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
954     MagickMethodOptions,(ssize_t) paint_method));
955 }
956 
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 */
DrawComposite(DrawingWand * wand,const CompositeOperator compose,const double x,const double y,const double width,const double height,MagickWand * magick_wand)998 WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
999   const CompositeOperator compose,const double x,const double y,
1000   const double width,const double height,MagickWand *magick_wand)
1001 {
1002   char
1003     *base64,
1004     *media_type;
1005 
1006   const char
1007     *mode;
1008 
1009   ImageInfo
1010     *image_info;
1011 
1012   Image
1013     *clone_image,
1014     *image;
1015 
1016   register char
1017     *p;
1018 
1019   register ssize_t
1020     i;
1021 
1022   size_t
1023     blob_length,
1024     encoded_length;
1025 
1026   unsigned char
1027     *blob;
1028 
1029   assert(wand != (DrawingWand *) NULL);
1030   assert(wand->signature == MagickWandSignature);
1031   if (wand->debug != MagickFalse)
1032     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1033   assert(magick_wand != (MagickWand *) NULL);
1034   image=GetImageFromMagickWand(magick_wand);
1035   if (image == (Image *) NULL)
1036     return(MagickFalse);
1037   clone_image=CloneImage(image,0,0,MagickTrue,wand->exception);
1038   if (clone_image == (Image *) NULL)
1039     return(MagickFalse);
1040   image_info=AcquireImageInfo();
1041   (void) CopyMagickString(image_info->magick,"MIFF",MagickPathExtent);
1042   blob_length=2048;
1043   blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
1044     wand->exception);
1045   image_info=DestroyImageInfo(image_info);
1046   clone_image=DestroyImageList(clone_image);
1047   if (blob == (void *) NULL)
1048     return(MagickFalse);
1049   encoded_length=0;
1050   base64=Base64Encode(blob,blob_length,&encoded_length);
1051   blob=(unsigned char *) RelinquishMagickMemory(blob);
1052   if (base64 == (char *) NULL)
1053     {
1054       char
1055         buffer[MagickPathExtent];
1056 
1057       (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g bytes",(double)
1058         (4L*blob_length/3L+4L));
1059       ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
1060         wand->name);
1061       return(MagickFalse);
1062     }
1063   mode=CommandOptionToMnemonic(MagickComposeOptions,(ssize_t) compose);
1064   media_type=MagickToMime(image->magick);
1065   (void) MVGPrintf(wand,"image %s %.20g %.20g %.20g %.20g 'data:%s;base64,\n",
1066     mode,x,y,width,height,media_type);
1067   p=base64;
1068   for (i=(ssize_t) encoded_length; i > 0; i-=76)
1069   {
1070     (void) MVGPrintf(wand,"%.76s",p);
1071     p+=76;
1072     if (i > 76)
1073       (void) MVGPrintf(wand,"\n");
1074   }
1075   (void) MVGPrintf(wand,"'\n");
1076   media_type=DestroyString(media_type);
1077   base64=DestroyString(base64);
1078   return(MagickTrue);
1079 }
1080 
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 */
DrawComment(DrawingWand * wand,const char * comment)1105 WandExport 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 */
DrawEllipse(DrawingWand * wand,const double ox,const double oy,const double rx,const double ry,const double start,const double end)1145 WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1146   const double rx,const double ry,const double start,const double end)
1147 {
1148   assert(wand != (DrawingWand *) NULL);
1149   assert(wand->signature == MagickWandSignature);
1150   if (wand->debug != MagickFalse)
1151     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1152   (void) MVGPrintf(wand,"ellipse %.20g %.20g %.20g %.20g %.20g %.20g\n",ox,oy,
1153     rx,ry,start,end);
1154 }
1155 
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 */
DrawGetBorderColor(const DrawingWand * wand,PixelWand * border_color)1182 WandExport void DrawGetBorderColor(const DrawingWand *wand,
1183   PixelWand *border_color)
1184 {
1185   assert(wand != (const DrawingWand *) NULL);
1186   assert(wand->signature == MagickWandSignature);
1187   assert(border_color != (PixelWand *) NULL);
1188   if (wand->debug != MagickFalse)
1189     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1190   PixelSetPixelColor(border_color,&CurrentContext->border_color);
1191 }
1192 
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 */
DrawGetClipPath(const DrawingWand * wand)1216 WandExport char *DrawGetClipPath(const DrawingWand *wand)
1217 {
1218   assert(wand != (const DrawingWand *) NULL);
1219   assert(wand->signature == MagickWandSignature);
1220   if (wand->debug != MagickFalse)
1221     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1222   if (CurrentContext->clip_mask != (char *) NULL)
1223     return((char *) AcquireString(CurrentContext->clip_mask));
1224   return((char *) NULL);
1225 }
1226 
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 */
DrawGetClipRule(const DrawingWand * wand)1250 WandExport FillRule DrawGetClipRule(const DrawingWand *wand)
1251 {
1252   assert(wand != (const DrawingWand *) NULL);
1253   assert(wand->signature == MagickWandSignature);
1254   if (wand->debug != MagickFalse)
1255     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1256   return(CurrentContext->fill_rule);
1257 }
1258 
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 */
DrawGetClipUnits(const DrawingWand * wand)1281 WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1282 {
1283   assert(wand != (const DrawingWand *) NULL);
1284   assert(wand->signature == MagickWandSignature);
1285   if (wand->debug != MagickFalse)
1286     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1287   return(CurrentContext->clip_units);
1288 }
1289 
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 */
DrawGetDensity(const DrawingWand * wand)1313 WandExport char *DrawGetDensity(const DrawingWand *wand)
1314 {
1315   assert(wand != (const DrawingWand *) NULL);
1316   assert(wand->signature == MagickWandSignature);
1317   if (wand->debug != MagickFalse)
1318     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1319   if (CurrentContext->density != (char *) NULL)
1320     return((char *) AcquireString(CurrentContext->density));
1321   return((char *) NULL);
1322 }
1323 
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 */
DrawGetException(const DrawingWand * wand,ExceptionType * severity)1350 WandExport char *DrawGetException(const DrawingWand *wand,
1351   ExceptionType *severity)
1352 {
1353   char
1354     *description;
1355 
1356   assert(wand != (const DrawingWand *) NULL);
1357   assert(wand->signature == MagickWandSignature);
1358   if (wand->debug != MagickFalse)
1359     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1360   assert(severity != (ExceptionType *) NULL);
1361   *severity=wand->exception->severity;
1362   description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
1363     sizeof(*description));
1364   if (description == (char *) NULL)
1365     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1366       wand->name);
1367   *description='\0';
1368   if (wand->exception->reason != (char *) NULL)
1369     (void) CopyMagickString(description,GetLocaleExceptionMessage(
1370       wand->exception->severity,wand->exception->reason),
1371       MagickPathExtent);
1372   if (wand->exception->description != (char *) NULL)
1373     {
1374       (void) ConcatenateMagickString(description," (",MagickPathExtent);
1375       (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
1376         wand->exception->severity,wand->exception->description),
1377         MagickPathExtent);
1378       (void) ConcatenateMagickString(description,")",MagickPathExtent);
1379     }
1380   return(description);
1381 }
1382 
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 */
DrawGetExceptionType(const DrawingWand * wand)1406 WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand)
1407 {
1408   assert(wand != (const DrawingWand *) NULL);
1409   assert(wand->signature == MagickWandSignature);
1410   if (wand->debug != MagickFalse)
1411     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1412   return(wand->exception->severity);
1413 }
1414 
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 */
DrawGetFillColor(const DrawingWand * wand,PixelWand * fill_color)1440 WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color)
1441 {
1442   assert(wand != (const DrawingWand *) NULL);
1443   assert(wand->signature == MagickWandSignature);
1444   assert(fill_color != (PixelWand *) NULL);
1445   if (wand->debug != MagickFalse)
1446     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1447   PixelSetPixelColor(fill_color,&CurrentContext->fill);
1448 }
1449 
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 */
DrawGetFillOpacity(const DrawingWand * wand)1473 WandExport double DrawGetFillOpacity(const DrawingWand *wand)
1474 {
1475   double
1476     alpha;
1477 
1478   assert(wand != (const DrawingWand *) NULL);
1479   assert(wand->signature == MagickWandSignature);
1480   if (wand->debug != MagickFalse)
1481     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1482   alpha=(double) QuantumScale*CurrentContext->fill.alpha;
1483   return(alpha);
1484 }
1485 
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 */
DrawGetFillRule(const DrawingWand * wand)1508 WandExport FillRule DrawGetFillRule(const DrawingWand *wand)
1509 {
1510   assert(wand != (const DrawingWand *) NULL);
1511   assert(wand->signature == MagickWandSignature);
1512   if (wand->debug != MagickFalse)
1513     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1514   return(CurrentContext->fill_rule);
1515 }
1516 
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 */
DrawGetFont(const DrawingWand * wand)1541 WandExport char *DrawGetFont(const DrawingWand *wand)
1542 {
1543   assert(wand != (const DrawingWand *) NULL);
1544   assert(wand->signature == MagickWandSignature);
1545   if (wand->debug != MagickFalse)
1546     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1547   if (CurrentContext->font != (char *) NULL)
1548     return(AcquireString(CurrentContext->font));
1549   return((char *) NULL);
1550 }
1551 
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 */
DrawGetFontFamily(const DrawingWand * wand)1575 WandExport char *DrawGetFontFamily(const DrawingWand *wand)
1576 {
1577   assert(wand != (const DrawingWand *) NULL);
1578   assert(wand->signature == MagickWandSignature);
1579   if (wand->debug != MagickFalse)
1580     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1581   if (CurrentContext->family != NULL)
1582     return(AcquireString(CurrentContext->family));
1583   return((char *) NULL);
1584 }
1585 
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 */
DrawGetFontResolution(const DrawingWand * wand,double * x,double * y)1613 WandExport MagickBooleanType DrawGetFontResolution(const DrawingWand *wand,
1614   double *x,double *y)
1615 {
1616   assert(wand != (DrawingWand *) NULL);
1617   assert(wand->signature == MagickWandSignature);
1618   if (wand->debug != MagickFalse)
1619     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1620   *x=72.0;
1621   *y=72.0;
1622   if (CurrentContext->density != (char *) NULL)
1623     {
1624       GeometryInfo
1625         geometry_info;
1626 
1627       MagickStatusType
1628         flags;
1629 
1630       flags=ParseGeometry(CurrentContext->density,&geometry_info);
1631       *x=geometry_info.rho;
1632       *y=geometry_info.sigma;
1633       if ((flags & SigmaValue) == MagickFalse)
1634         *y=(*x);
1635     }
1636   return(MagickTrue);
1637 }
1638 
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 */
DrawGetFontSize(const DrawingWand * wand)1661 WandExport double DrawGetFontSize(const DrawingWand *wand)
1662 {
1663   assert(wand != (const DrawingWand *) NULL);
1664   assert(wand->signature == MagickWandSignature);
1665   if (wand->debug != MagickFalse)
1666     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1667   return(CurrentContext->pointsize);
1668 }
1669 
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 */
DrawGetFontStretch(const DrawingWand * wand)1692 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1693 {
1694   assert(wand != (const DrawingWand *) NULL);
1695   assert(wand->signature == MagickWandSignature);
1696   if (wand->debug != MagickFalse)
1697     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1698   return(CurrentContext->stretch);
1699 }
1700 
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 */
DrawGetFontStyle(const DrawingWand * wand)1723 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1724 {
1725   assert(wand != (const DrawingWand *) NULL);
1726   assert(wand->signature == MagickWandSignature);
1727   if (wand->debug != MagickFalse)
1728     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1729   return(CurrentContext->style);
1730 }
1731 
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 */
DrawGetFontWeight(const DrawingWand * wand)1754 WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
1755 {
1756   assert(wand != (const DrawingWand *) NULL);
1757   assert(wand->signature == MagickWandSignature);
1758   if (wand->debug != MagickFalse)
1759     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1760   return(CurrentContext->weight);
1761 }
1762 
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 */
DrawGetGravity(const DrawingWand * wand)1786 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1787 {
1788   assert(wand != (const DrawingWand *) NULL);
1789   assert(wand->signature == MagickWandSignature);
1790   if (wand->debug != MagickFalse)
1791     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1792   return(CurrentContext->gravity);
1793 }
1794 
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 */
DrawGetOpacity(const DrawingWand * wand)1818 WandExport double DrawGetOpacity(const DrawingWand *wand)
1819 {
1820   double
1821     alpha;
1822 
1823   assert(wand != (const DrawingWand *) NULL);
1824   assert(wand->signature == MagickWandSignature);
1825   if (wand->debug != MagickFalse)
1826     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1827   alpha=(double) QuantumScale*CurrentContext->alpha;
1828   return(alpha);
1829 }
1830 
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 */
DrawGetStrokeAntialias(const DrawingWand * wand)1856 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1857 {
1858   assert(wand != (const DrawingWand *) NULL);
1859   assert(wand->signature == MagickWandSignature);
1860   if (wand->debug != MagickFalse)
1861     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1862   return(CurrentContext->stroke_antialias);
1863 }
1864 
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 */
DrawGetStrokeColor(const DrawingWand * wand,PixelWand * stroke_color)1890 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1891   PixelWand *stroke_color)
1892 {
1893   assert(wand != (const DrawingWand *) NULL);
1894   assert(wand->signature == MagickWandSignature);
1895   assert(stroke_color != (PixelWand *) NULL);
1896   if (wand->debug != MagickFalse)
1897     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1898   PixelSetPixelColor(stroke_color,&CurrentContext->stroke);
1899 }
1900 
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 */
DrawGetStrokeDashArray(const DrawingWand * wand,size_t * number_elements)1928 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
1929   size_t *number_elements)
1930 {
1931   double
1932     *dasharray;
1933 
1934   register const double
1935     *p;
1936 
1937   register double
1938     *q;
1939 
1940   register ssize_t
1941     i;
1942 
1943   size_t
1944     n;
1945 
1946   assert(wand != (const DrawingWand *) NULL);
1947   assert(wand->signature == MagickWandSignature);
1948   if (wand->debug != MagickFalse)
1949     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1950   assert(number_elements != (size_t *) NULL);
1951   n=0;
1952   p=CurrentContext->dash_pattern;
1953   if (p != (const double *) NULL)
1954     while (fabs(*p++) >= MagickEpsilon)
1955       n++;
1956   *number_elements=n;
1957   dasharray=(double *) NULL;
1958   if (n != 0)
1959     {
1960       dasharray=(double *) AcquireQuantumMemory((size_t) n+1UL,
1961         sizeof(*dasharray));
1962       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 */
DrawGetStrokeDashOffset(const DrawingWand * wand)1994 WandExport 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 */
DrawGetStrokeLineCap(const DrawingWand * wand)2027 WandExport 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 */
DrawGetStrokeLineJoin(const DrawingWand * wand)2061 WandExport 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 */
DrawGetStrokeMiterLimit(const DrawingWand * wand)2096 WandExport 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 */
DrawGetStrokeOpacity(const DrawingWand * wand)2127 WandExport 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 */
DrawGetStrokeWidth(const DrawingWand * wand)2163 WandExport 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 */
DrawGetTextAlignment(const DrawingWand * wand)2195 WandExport 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 */
DrawGetTextAntialias(const DrawingWand * wand)2227 WandExport 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 */
DrawGetTextDecoration(const DrawingWand * wand)2259 WandExport 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 */
DrawGetTextDirection(const DrawingWand * wand)2291 WandExport 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 */
DrawGetTextEncoding(const DrawingWand * wand)2324 WandExport 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 */
DrawGetTextKerning(DrawingWand * wand)2357 WandExport 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 */
DrawGetTextInterlineSpacing(DrawingWand * wand)2389 WandExport 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 */
DrawGetTextInterwordSpacing(DrawingWand * wand)2420 WandExport 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 */
DrawGetVectorGraphics(DrawingWand * wand)2454 WandExport 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 */
DrawGetTextUnderColor(const DrawingWand * wand,PixelWand * under_color)2707 WandExport 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 */
DrawLine(DrawingWand * wand,const double sx,const double sy,const double ex,const double ey)2750 WandExport 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 */
DrawPathClose(DrawingWand * wand)2785 WandExport 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 
DrawPathCurveTo(DrawingWand * wand,const PathMode mode,const double x1,const double y1,const double x2,const double y2,const double x,const double y)2836 static 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 
DrawPathCurveToAbsolute(DrawingWand * wand,const double x1,const double y1,const double x2,const double y2,const double x,const double y)2857 WandExport 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 */
DrawPathCurveToRelative(DrawingWand * wand,const double x1,const double y1,const double x2,const double y2,const double x,const double y)2907 WandExport 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 
DrawPathCurveToQuadraticBezier(DrawingWand * wand,const PathMode mode,const double x1,double y1,const double x,const double y)2952 static 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 
DrawPathCurveToQuadraticBezierAbsolute(DrawingWand * wand,const double x1,const double y1,const double x,const double y)2971 WandExport 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 */
DrawPathCurveToQuadraticBezierRelative(DrawingWand * wand,const double x1,const double y1,const double x,const double y)3015 WandExport 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 
DrawPathCurveToQuadraticBezierSmooth(DrawingWand * wand,const PathMode mode,const double x,const double y)3064 static 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 
DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand * wand,const double x,const double y)3083 WandExport 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 */
DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand * wand,const double x,const double y)3130 WandExport 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 
DrawPathCurveToSmooth(DrawingWand * wand,const PathMode mode,const double x2,const double y2,const double x,const double y)3178 static 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 
DrawPathCurveToSmoothAbsolute(DrawingWand * wand,const double x2,const double y2,const double x,const double y)3197 WandExport 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 */
DrawPathCurveToSmoothRelative(DrawingWand * wand,const double x2,const double y2,const double x,const double y)3247 WandExport 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 
DrawPathEllipticArc(DrawingWand * wand,const PathMode mode,const double rx,const double ry,const double x_axis_rotation,const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,const double x,const double y)3306 static 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 
DrawPathEllipticArcAbsolute(DrawingWand * wand,const double rx,const double ry,const double x_axis_rotation,const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,const double x,const double y)3329 WandExport 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 */
DrawPathEllipticArcRelative(DrawingWand * wand,const double rx,const double ry,const double x_axis_rotation,const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,const double x,const double y)3389 WandExport 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 */
DrawPathFinish(DrawingWand * wand)3420 WandExport 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 */
DrawPathLineTo(DrawingWand * wand,const PathMode mode,const double x,const double y)3460 static 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 
DrawPathLineToAbsolute(DrawingWand * wand,const double x,const double y)3479 WandExport 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 */
DrawPathLineToRelative(DrawingWand * wand,const double x,const double y)3518 WandExport 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 
DrawPathLineToHorizontal(DrawingWand * wand,const PathMode mode,const double x)3555 static 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 
DrawPathLineToHorizontalAbsolute(DrawingWand * wand,const double x)3574 WandExport 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 */
DrawPathLineToHorizontalRelative(DrawingWand * wand,const double x)3611 WandExport 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 
DrawPathLineToVertical(DrawingWand * wand,const PathMode mode,const double y)3645 static 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 
DrawPathLineToVerticalAbsolute(DrawingWand * wand,const double y)3664 WandExport 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 */
DrawPathLineToVerticalRelative(DrawingWand * wand,const double y)3700 WandExport 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 
DrawPathMoveTo(DrawingWand * wand,const PathMode mode,const double x,const double y)3738 static 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 
DrawPathMoveToAbsolute(DrawingWand * wand,const double x,const double y)3757 WandExport 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 */
DrawPathMoveToRelative(DrawingWand * wand,const double x,const double y)3796 WandExport 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 */
DrawPathStart(DrawingWand * wand)3832 WandExport 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 */
DrawPoint(DrawingWand * wand,const double x,const double y)3869 WandExport 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 */
DrawPolygon(DrawingWand * wand,const size_t number_coordinates,const PointInfo * coordinates)3906 WandExport 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 */
DrawPolyline(DrawingWand * wand,const size_t number_coordinates,const PointInfo * coordinates)3944 WandExport 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 */
DrawPopClipPath(DrawingWand * wand)3976 WandExport 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 */
DrawPopDefs(DrawingWand * wand)4009 WandExport 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 */
DrawPopPattern(DrawingWand * wand)4042 WandExport 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 */
DrawPushClipPath(DrawingWand * wand,const char * clip_mask_id)4105 WandExport 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 */
DrawPushDefs(DrawingWand * wand)4140 WandExport 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 */
DrawPushPattern(DrawingWand * wand,const char * pattern_id,const double x,const double y,const double width,const double height)4189 WandExport 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 */
DrawRectangle(DrawingWand * wand,const double x1,const double y1,const double x2,const double y2)4247 WandExport 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 */
DrawRender(DrawingWand * wand)4279 WandExport 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 */
DrawResetVectorGraphics(DrawingWand * wand)4321 WandExport 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 */
DrawRotate(DrawingWand * wand,const double degrees)4358 WandExport 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 */
DrawRoundRectangle(DrawingWand * wand,double x1,double y1,double x2,double y2,double rx,double ry)4404 WandExport 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 */
DrawScale(DrawingWand * wand,const double x,const double y)4442 WandExport 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 */
DrawSetBorderColor(DrawingWand * wand,const PixelWand * border_wand)4476 WandExport 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 */
DrawSetClipPath(DrawingWand * wand,const char * clip_mask)4529 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4530   const char *clip_mask)
4531 {
4532   if (wand->debug != MagickFalse)
4533     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4534   assert(wand != (DrawingWand *) NULL);
4535   assert(wand->signature == 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 */
DrawSetClipRule(DrawingWand * wand,const FillRule fill_rule)4576 WandExport 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 */
DrawSetClipUnits(DrawingWand * wand,const ClipPathUnits clip_units)4617 WandExport 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 */
DrawSetDensity(DrawingWand * wand,const char * density)4670 WandExport 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 */
DrawSetFillColor(DrawingWand * wand,const PixelWand * fill_wand)4712 WandExport 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 */
DrawSetFillOpacity(DrawingWand * wand,const double fill_opacity)4762 WandExport 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 */
DrawSetFontResolution(DrawingWand * wand,const double x_resolution,const double y_resolution)4807 WandExport 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 */
DrawSetOpacity(DrawingWand * wand,const double opacity)4848 WandExport 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 */
DrawSetFillPatternURL(DrawingWand * wand,const char * fill_url)4894 WandExport 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 */
DrawSetFillRule(DrawingWand * wand,const FillRule fill_rule)4954 WandExport 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 */
DrawSetFont(DrawingWand * wand,const char * font_name)4994 WandExport 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 */
DrawSetFontFamily(DrawingWand * wand,const char * font_family)5037 WandExport 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 */
DrawSetFontSize(DrawingWand * wand,const double pointsize)5079 WandExport 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 */
DrawSetFontStretch(DrawingWand * wand,const StretchType font_stretch)5122 WandExport 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 */
DrawSetFontStyle(DrawingWand * wand,const StyleType style)5163 WandExport 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 */
DrawSetFontWeight(DrawingWand * wand,const size_t font_weight)5203 WandExport 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 */
DrawSetGravity(DrawingWand * wand,const GravityType gravity)5246 WandExport 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 */
DrawSetStrokeColor(DrawingWand * wand,const PixelWand * stroke_wand)5286 WandExport 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 */
DrawSetStrokePatternURL(DrawingWand * wand,const char * stroke_url)5337 WandExport 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 */
DrawSetStrokeAntialias(DrawingWand * wand,const MagickBooleanType stroke_antialias)5398 WandExport 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 */
DrawSetStrokeDashArray(DrawingWand * wand,const size_t number_elements,const double * dasharray)5447 WandExport 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 */
DrawSetStrokeDashOffset(DrawingWand * wand,const double dash_offset)5568 WandExport 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 */
DrawSetStrokeLineCap(DrawingWand * wand,const LineCap linecap)5610 WandExport 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 */
DrawSetStrokeLineJoin(DrawingWand * wand,const LineJoin linejoin)5651 WandExport 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 */
DrawSetStrokeMiterLimit(DrawingWand * wand,const size_t miterlimit)5695 WandExport 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 */
DrawSetStrokeOpacity(DrawingWand * wand,const double opacity)5734 WandExport 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 */
DrawSetStrokeWidth(DrawingWand * wand,const double stroke_width)5779 WandExport 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 */
DrawSetTextAlignment(DrawingWand * wand,const AlignType alignment)5819 WandExport 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 */
DrawSetTextAntialias(DrawingWand * wand,const MagickBooleanType text_antialias)5862 WandExport 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 */
DrawSetTextDecoration(DrawingWand * wand,const DecorationType decoration)5904 WandExport 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 */
DrawSetTextDirection(DrawingWand * wand,const DirectionType direction)5947 WandExport 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 */
DrawSetTextEncoding(DrawingWand * wand,const char * encoding)5993 WandExport 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 */
DrawSetTextKerning(DrawingWand * wand,const double kerning)6033 WandExport 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 */
DrawSetTextInterlineSpacing(DrawingWand * wand,const double interline_spacing)6073 WandExport 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 */
DrawSetTextInterwordSpacing(DrawingWand * wand,const double interword_spacing)6114 WandExport 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 */
DrawSetTextUnderColor(DrawingWand * wand,const PixelWand * under_wand)6156 WandExport 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 
IsPoint(const char * point)6206 static 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 
DrawSetVectorGraphics(DrawingWand * wand,const char * xml)6219 WandExport 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 */
DrawSkewX(DrawingWand * wand,const double degrees)6517 WandExport 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 */
DrawSkewY(DrawingWand * wand,const double degrees)6551 WandExport 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 */
DrawTranslate(DrawingWand * wand,const double x,const double y)6589 WandExport 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 */
DrawSetViewbox(DrawingWand * wand,const double x1,const double y1,const double x2,const double y2)6633 WandExport 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 */
IsDrawingWand(const DrawingWand * wand)6665 WandExport 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 */
NewDrawingWand(void)6695 WandExport 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 */
PeekDrawingWand(const DrawingWand * wand)6770 WandExport 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 */
PopDrawingWand(DrawingWand * wand)6810 WandExport 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 */
PushDrawingWand(DrawingWand * wand)6866 WandExport 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