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