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