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