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