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