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