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 @ 2002 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+=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 double
1921 *dasharray;
1922
1923 const double
1924 *p;
1925
1926 double
1927 *q;
1928
1929 ssize_t
1930 i;
1931
1932 size_t
1933 n;
1934
1935 assert(wand != (const DrawingWand *) NULL);
1936 assert(wand->signature == MagickWandSignature);
1937 if (wand->debug != MagickFalse)
1938 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1939 assert(number_elements != (size_t *) NULL);
1940 n=0;
1941 p=CurrentContext->dash_pattern;
1942 if (p != (const double *) NULL)
1943 while (fabs(*p++) >= MagickEpsilon)
1944 n++;
1945 *number_elements=n;
1946 dasharray=(double *) NULL;
1947 if (n != 0)
1948 {
1949 dasharray=(double *) AcquireQuantumMemory((size_t) n+1UL,
1950 sizeof(*dasharray));
1951 if (dasharray != (double *) NULL)
1952 {
1953 p=CurrentContext->dash_pattern;
1954 q=dasharray;
1955 for (i=0; i < (ssize_t) n; i++)
1956 *q++=(*p++);
1957 *q=0.0;
1958 }
1959 }
1960 return(dasharray);
1961}
1962
1963/*
1964%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1965% %
1966% %
1967% %
1968% D r a w G e t S t r o k e D a s h O f f s e t %
1969% %
1970% %
1971% %
1972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1973%
1974% DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1975% start the dash.
1976%
1977% The format of the DrawGetStrokeDashOffset method is:
1978%
1979% double DrawGetStrokeDashOffset(const DrawingWand *wand)
1980%
1981% A description of each parameter follows:
1982%
1983% o wand: the drawing wand.
1984%
1985*/
1986WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1987{
1988 assert(wand != (const DrawingWand *) NULL);
1989 assert(wand->signature == MagickWandSignature);
1990 if (wand->debug != MagickFalse)
1991 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1992 return(CurrentContext->dash_offset);
1993}
1994
1995/*
1996%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1997% %
1998% %
1999% %
2000% D r a w G e t S t r o k e L i n e C a p %
2001% %
2002% %
2003% %
2004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005%
2006% DrawGetStrokeLineCap() returns the shape to be used at the end of
2007% open subpaths when they are stroked. Values of LineCap are
2008% UndefinedCap, ButtCap, RoundCap, and SquareCap.
2009%
2010% The format of the DrawGetStrokeLineCap method is:
2011%
2012% LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2013%
2014% A description of each parameter follows:
2015%
2016% o wand: the drawing wand.
2017%
2018*/
2019WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2020{
2021 assert(wand != (const DrawingWand *) NULL);
2022 assert(wand->signature == MagickWandSignature);
2023 if (wand->debug != MagickFalse)
2024 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2025 return(CurrentContext->linecap);
2026}
2027
2028/*
2029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2030% %
2031% %
2032% %
2033% D r a w G e t S t r o k e L i n e J o i n %
2034% %
2035% %
2036% %
2037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2038%
2039% DrawGetStrokeLineJoin() returns the shape to be used at the
2040% corners of paths (or other vector shapes) when they are
2041% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
2042% and BevelJoin.
2043%
2044% The format of the DrawGetStrokeLineJoin method is:
2045%
2046% LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2047%
2048% A description of each parameter follows:
2049%
2050% o wand: the drawing wand.
2051%
2052*/
2053WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2054{
2055 assert(wand != (const DrawingWand *) NULL);
2056 assert(wand->signature == MagickWandSignature);
2057 if (wand->debug != MagickFalse)
2058 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2059 return(CurrentContext->linejoin);
2060}
2061
2062/*
2063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2064% %
2065% %
2066% %
2067% D r a w G e t S t r o k e M i t e r L i m i t %
2068% %
2069% %
2070% %
2071%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2072%
2073% DrawGetStrokeMiterLimit() returns the miter limit. When two line
2074% segments meet at a sharp angle and miter joins have been specified for
2075% 'lineJoin', it is possible for the miter to extend far beyond the
2076% thickness of the line stroking the path. The miterLimit' imposes a
2077% limit on the ratio of the miter length to the 'lineWidth'.
2078%
2079% The format of the DrawGetStrokeMiterLimit method is:
2080%
2081% size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2082%
2083% A description of each parameter follows:
2084%
2085% o wand: the drawing wand.
2086%
2087*/
2088WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2089{
2090 assert(wand != (const DrawingWand *) NULL);
2091 assert(wand->signature == MagickWandSignature);
2092 if (wand->debug != MagickFalse)
2093 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2094 return CurrentContext->miterlimit;
2095}
2096
2097/*
2098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2099% %
2100% %
2101% %
2102% D r a w G e t S t r o k e O p a c i t y %
2103% %
2104% %
2105% %
2106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2107%
2108% DrawGetStrokeOpacity() returns the alpha of stroked object outlines.
2109%
2110% The format of the DrawGetStrokeOpacity method is:
2111%
2112% double DrawGetStrokeOpacity(const DrawingWand *wand)
2113%
2114% A description of each parameter follows:
2115%
2116% o wand: the drawing wand.
2117%
2118*/
2119WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2120{
2121 double
2122 alpha;
2123
2124 assert(wand != (const DrawingWand *) NULL);
2125 assert(wand->signature == MagickWandSignature);
2126 if (wand->debug != MagickFalse)
2127 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2128 alpha=(double) QuantumScale*CurrentContext->stroke.alpha;
2129 return(alpha);
2130}
2131
2132/*
2133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2134% %
2135% %
2136% %
2137% D r a w G e t S t r o k e W i d t h %
2138% %
2139% %
2140% %
2141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2142%
2143% DrawGetStrokeWidth() returns the width of the stroke used to draw object
2144% outlines.
2145%
2146% The format of the DrawGetStrokeWidth method is:
2147%
2148% double DrawGetStrokeWidth(const DrawingWand *wand)
2149%
2150% A description of each parameter follows:
2151%
2152% o wand: the drawing wand.
2153%
2154*/
2155WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2156{
2157 assert(wand != (const DrawingWand *) NULL);
2158 assert(wand->signature == MagickWandSignature);
2159 if (wand->debug != MagickFalse)
2160 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2161 return(CurrentContext->stroke_width);
2162}
2163
2164/*
2165%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2166% %
2167% %
2168% %
2169% D r a w G e t T e x t A l i g n m e n t %
2170% %
2171% %
2172% %
2173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2174%
2175% DrawGetTextAlignment() returns the alignment applied when annotating with
2176% text.
2177%
2178% The format of the DrawGetTextAlignment method is:
2179%
2180% AlignType DrawGetTextAlignment(const DrawingWand *wand)
2181%
2182% A description of each parameter follows:
2183%
2184% o wand: the drawing wand.
2185%
2186*/
2187WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2188{
2189 assert(wand != (const DrawingWand *) NULL);
2190 assert(wand->signature == MagickWandSignature);
2191 if (wand->debug != MagickFalse)
2192 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2193 return(CurrentContext->align);
2194}
2195
2196/*
2197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2198% %
2199% %
2200% %
2201% D r a w G e t T e x t A n t i a l i a s %
2202% %
2203% %
2204% %
2205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2206%
2207% DrawGetTextAntialias() returns the current text antialias setting, which
2208% determines whether text is antialiased. Text is antialiased by default.
2209%
2210% The format of the DrawGetTextAntialias method is:
2211%
2212% MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2213%
2214% A description of each parameter follows:
2215%
2216% o wand: the drawing wand.
2217%
2218*/
2219WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2220{
2221 assert(wand != (const DrawingWand *) NULL);
2222 assert(wand->signature == MagickWandSignature);
2223 if (wand->debug != MagickFalse)
2224 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2225 return(CurrentContext->text_antialias);
2226}
2227
2228/*
2229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2230% %
2231% %
2232% %
2233% D r a w G e t T e x t D e c o r a t i o n %
2234% %
2235% %
2236% %
2237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238%
2239% DrawGetTextDecoration() returns the decoration applied when annotating with
2240% text.
2241%
2242% The format of the DrawGetTextDecoration method is:
2243%
2244% DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2245%
2246% A description of each parameter follows:
2247%
2248% o wand: the drawing wand.
2249%
2250*/
2251WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2252{
2253 assert(wand != (const DrawingWand *) NULL);
2254 assert(wand->signature == MagickWandSignature);
2255 if (wand->debug != MagickFalse)
2256 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2257 return(CurrentContext->decorate);
2258}
2259
2260/*
2261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2262% %
2263% %
2264% %
2265% D r a w G e t T e x t D i r e c t i o n %
2266% %
2267% %
2268% %
2269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2270%
2271% DrawGetTextDirection() returns the direction that will be used when
2272% annotating with text.
2273%
2274% The format of the DrawGetTextDirection method is:
2275%
2276% DirectionType DrawGetTextDirection(const DrawingWand *wand)
2277%
2278% A description of each parameter follows:
2279%
2280% o wand: the drawing wand.
2281%
2282*/
2283WandExport DirectionType DrawGetTextDirection(const DrawingWand *wand)
2284{
2285 assert(wand != (const DrawingWand *) NULL);
2286 assert(wand->signature == MagickWandSignature);
2287 if (wand->debug != MagickFalse)
2288 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2289 return(CurrentContext->direction);
2290}
2291
2292/*
2293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2294% %
2295% %
2296% %
2297% D r a w G e t T e x t E n c o d i n g %
2298% %
2299% %
2300% %
2301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2302%
2303% DrawGetTextEncoding() returns a null-terminated string which specifies the
2304% code set used for text annotations. The string must be freed by the user
2305% once it is no longer required.
2306%
2307% The format of the DrawGetTextEncoding method is:
2308%
2309% char *DrawGetTextEncoding(const DrawingWand *wand)
2310%
2311% A description of each parameter follows:
2312%
2313% o wand: the drawing wand.
2314%
2315*/
2316WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2317{
2318 assert(wand != (const DrawingWand *) NULL);
2319 assert(wand->signature == MagickWandSignature);
2320 if (wand->debug != MagickFalse)
2321 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2322 if (CurrentContext->encoding != (char *) NULL)
2323 return((char *) AcquireString(CurrentContext->encoding));
2324 return((char *) NULL);
2325}
2326
2327/*
2328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2329% %
2330% %
2331% %
2332% D r a w G e t T e x t K e r n i n g %
2333% %
2334% %
2335% %
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337%
2338% DrawGetTextKerning() gets the spacing between characters in text.
2339%
2340% The format of the DrawSetFontKerning method is:
2341%
2342% double DrawGetTextKerning(DrawingWand *wand)
2343%
2344% A description of each parameter follows:
2345%
2346% o wand: the drawing wand.
2347%
2348*/
2349WandExport double DrawGetTextKerning(DrawingWand *wand)
2350{
2351 assert(wand != (DrawingWand *) NULL);
2352 assert(wand->signature == MagickWandSignature);
2353
2354 if (wand->debug != MagickFalse)
2355 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2356 return(CurrentContext->kerning);
2357}
2358
2359/*
2360%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2361% %
2362% %
2363% %
2364% 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 %
2365% %
2366% %
2367% %
2368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2369%
2370% DrawGetTextInterlineSpacing() gets the spacing between lines in text.
2371%
2372% The format of the DrawGetTextInterlineSpacing method is:
2373%
2374% double DrawGetTextInterlineSpacing(DrawingWand *wand)
2375%
2376% A description of each parameter follows:
2377%
2378% o wand: the drawing wand.
2379%
2380*/
2381WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2382{
2383 assert(wand != (DrawingWand *) NULL);
2384 assert(wand->signature == MagickWandSignature);
2385 if (wand->debug != MagickFalse)
2386 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2387 return(CurrentContext->interline_spacing);
2388}
2389
2390/*
2391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2392% %
2393% %
2394% %
2395% 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 %
2396% %
2397% %
2398% %
2399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2400%
2401% DrawGetTextInterwordSpacing() gets the spacing between words in text.
2402%
2403% The format of the DrawSetFontKerning method is:
2404%
2405% double DrawGetTextInterwordSpacing(DrawingWand *wand)
2406%
2407% A description of each parameter follows:
2408%
2409% o wand: the drawing wand.
2410%
2411*/
2412WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2413{
2414 assert(wand != (DrawingWand *) NULL);
2415 assert(wand->signature == MagickWandSignature);
2416 if (wand->debug != MagickFalse)
2417 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2418 return(CurrentContext->interword_spacing);
2419}
2420
2421/*
2422%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2423% %
2424% %
2425% %
2426% D r a w G e t T y p e M e t r i c s %
2427% %
2428% %
2429% %
2430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2431%
2432% DrawGetTypeMetrics() returns the following information for the specified
2433% font and text:
2434%
2435% character width
2436% character height
2437% ascender
2438% descender
2439% text width
2440% text height
2441% maximum horizontal advance
2442% bounds: x1
2443% bounds: y1
2444% bounds: x2
2445% bounds: y2
2446% origin: x
2447% origin: y
2448% underline position
2449% underline thickness
2450%
2451% The format of the DrawGetTypeMetrics method is:
2452%
2453% MagickBooleanType DrawGetTypeMetrics(const DrawingWand *wand,
2454% const char *text,MagickBooleanType ignore_newlines,
2455$ TypeMetric *metrics)
2456%
2457% A description of each parameter follows:
2458%
2459% o wand: the drawing wand.
2460%
2461% o text: text to draw.
2462%
2463% o metrics: Return the font metrics in this structure.
2464%
2465% o ignore_newlines: indicates whether newlines should be ignored.
2466%
2467% o metrics: Return the font metrics in this structure.
2468%
2469*/
2470WandExport MagickBooleanType DrawGetTypeMetrics(const DrawingWand *wand,
2471 const char *text,MagickBooleanType ignore_newlines,TypeMetric *metrics)
2472{
2473 DrawInfo
2474 *draw_info;
2475
2476 MagickBooleanType
2477 status;
2478
2479 assert(wand != (const DrawingWand *) NULL);
2480 assert(wand->signature == MagickWandSignature);
2481 if (wand->debug != MagickFalse)
2482 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2483 draw_info=PeekDrawingWand(wand);
2484 if (draw_info == (DrawInfo *) NULL)
2485 return(MagickFalse);
2486 (void) CloneString(&draw_info->text,text);
2487 if (ignore_newlines != MagickFalse)
2488 status=GetTypeMetrics(wand->image,draw_info,metrics,wand->exception);
2489 else
2490 status=GetMultilineTypeMetrics(wand->image,draw_info,metrics,
2491 wand->exception);
2492 draw_info=DestroyDrawInfo(draw_info);
2493 return(status);
2494}
2495
2496/*
2497%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2498% %
2499% %
2500% %
2501% D r a w G e t V e c t o r G r a p h i c s %
2502% %
2503% %
2504% %
2505%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2506%
2507% DrawGetVectorGraphics() returns a null-terminated string which specifies the
2508% vector graphics generated by any graphics calls made since the wand was
2509% instantiated. The string must be freed by the user once it is no longer
2510% required.
2511%
2512% The format of the DrawGetVectorGraphics method is:
2513%
2514% char *DrawGetVectorGraphics(DrawingWand *wand)
2515%
2516% A description of each parameter follows:
2517%
2518% o wand: the drawing wand.
2519%
2520*/
2521WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2522{
2523 char
2524 value[MagickPathExtent],
2525 *xml;
2526
2527 PixelInfo
2528 pixel;
2529
2530 ssize_t
2531 i;
2532
2533 XMLTreeInfo
2534 *child,
2535 *xml_info;
2536
2537 assert(wand != (const DrawingWand *) NULL);
2538 assert(wand->signature == MagickWandSignature);
2539 if (wand->debug != MagickFalse)
2540 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2541 xml_info=NewXMLTreeTag("drawing-wand");
2542 if (xml_info == (XMLTreeInfo *) NULL)
2543 return((char *) NULL);
2544 (void) SetXMLTreeContent(xml_info," ");
2545 GetPixelInfo(wand->image,&pixel);
2546 child=AddChildToXMLTree(xml_info,"clip-path",0);
2547 if (child != (XMLTreeInfo *) NULL)
2548 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2549 child=AddChildToXMLTree(xml_info,"clip-units",0);
2550 if (child != (XMLTreeInfo *) NULL)
2551 {
2552 (void) CopyMagickString(value,CommandOptionToMnemonic(
2553 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),
2554 MagickPathExtent);
2555 (void) SetXMLTreeContent(child,value);
2556 }
2557 child=AddChildToXMLTree(xml_info,"decorate",0);
2558 if (child != (XMLTreeInfo *) NULL)
2559 {
2560 (void) CopyMagickString(value,CommandOptionToMnemonic(
2561 MagickDecorateOptions,(ssize_t) CurrentContext->decorate),
2562 MagickPathExtent);
2563 (void) SetXMLTreeContent(child,value);
2564 }
2565 child=AddChildToXMLTree(xml_info,"encoding",0);
2566 if (child != (XMLTreeInfo *) NULL)
2567 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2568 child=AddChildToXMLTree(xml_info,"fill",0);
2569 if (child != (XMLTreeInfo *) NULL)
2570 {
2571 if (CurrentContext->fill.alpha != (double) OpaqueAlpha)
2572 pixel.alpha_trait=CurrentContext->fill.alpha != (double) OpaqueAlpha ?
2573 BlendPixelTrait : UndefinedPixelTrait;
2574 pixel=CurrentContext->fill;
2575 GetColorTuple(&pixel,MagickTrue,value);
2576 (void) SetXMLTreeContent(child,value);
2577 }
2578 child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2579 if (child != (XMLTreeInfo *) NULL)
2580 {
2581 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
2582 (double) (QuantumScale*CurrentContext->fill.alpha));
2583 (void) SetXMLTreeContent(child,value);
2584 }
2585 child=AddChildToXMLTree(xml_info,"fill-rule",0);
2586 if (child != (XMLTreeInfo *) NULL)
2587 {
2588 (void) CopyMagickString(value,CommandOptionToMnemonic(
2589 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),
2590 MagickPathExtent);
2591 (void) SetXMLTreeContent(child,value);
2592 }
2593 child=AddChildToXMLTree(xml_info,"font",0);
2594 if (child != (XMLTreeInfo *) NULL)
2595 (void) SetXMLTreeContent(child,CurrentContext->font);
2596 child=AddChildToXMLTree(xml_info,"font-family",0);
2597 if (child != (XMLTreeInfo *) NULL)
2598 (void) SetXMLTreeContent(child,CurrentContext->family);
2599 child=AddChildToXMLTree(xml_info,"font-size",0);
2600 if (child != (XMLTreeInfo *) NULL)
2601 {
2602 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
2603 CurrentContext->pointsize);
2604 (void) SetXMLTreeContent(child,value);
2605 }
2606 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2607 if (child != (XMLTreeInfo *) NULL)
2608 {
2609 (void) CopyMagickString(value,CommandOptionToMnemonic(
2610 MagickStretchOptions,(ssize_t) CurrentContext->stretch),
2611 MagickPathExtent);
2612 (void) SetXMLTreeContent(child,value);
2613 }
2614 child=AddChildToXMLTree(xml_info,"font-style",0);
2615 if (child != (XMLTreeInfo *) NULL)
2616 {
2617 (void) CopyMagickString(value,CommandOptionToMnemonic(
2618 MagickStyleOptions,(ssize_t) CurrentContext->style),MagickPathExtent);
2619 (void) SetXMLTreeContent(child,value);
2620 }
2621 child=AddChildToXMLTree(xml_info,"font-weight",0);
2622 if (child != (XMLTreeInfo *) NULL)
2623 {
2624 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
2625 CurrentContext->weight);
2626 (void) SetXMLTreeContent(child,value);
2627 }
2628 child=AddChildToXMLTree(xml_info,"gravity",0);
2629 if (child != (XMLTreeInfo *) NULL)
2630 {
2631 (void) CopyMagickString(value,CommandOptionToMnemonic(
2632 MagickGravityOptions,(ssize_t) CurrentContext->gravity),
2633 MagickPathExtent);
2634 (void) SetXMLTreeContent(child,value);
2635 }
2636 child=AddChildToXMLTree(xml_info,"stroke",0);
2637 if (child != (XMLTreeInfo *) NULL)
2638 {
2639 if (CurrentContext->stroke.alpha != (double) OpaqueAlpha)
2640 pixel.alpha_trait=CurrentContext->stroke.alpha != (double) OpaqueAlpha ?
2641 BlendPixelTrait : UndefinedPixelTrait;
2642 pixel=CurrentContext->stroke;
2643 GetColorTuple(&pixel,MagickTrue,value);
2644 (void) SetXMLTreeContent(child,value);
2645 }
2646 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2647 if (child != (XMLTreeInfo *) NULL)
2648 {
2649 (void) FormatLocaleString(value,MagickPathExtent,"%d",
2650 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2651 (void) SetXMLTreeContent(child,value);
2652 }
2653 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2654 if ((child != (XMLTreeInfo *) NULL) &&
2655 (CurrentContext->dash_pattern != (double *) NULL))
2656 {
2657 char
2658 *dash_pattern;
2659
2660 dash_pattern=AcquireString((char *) NULL);
2661 for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++)
2662 {
2663 if (i != 0)
2664 (void) ConcatenateString(&dash_pattern,",");
2665 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
2666 CurrentContext->dash_pattern[i]);
2667 (void) ConcatenateString(&dash_pattern,value);
2668 }
2669 (void) SetXMLTreeContent(child,dash_pattern);
2670 dash_pattern=DestroyString(dash_pattern);
2671 }
2672 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2673 if (child != (XMLTreeInfo *) NULL)
2674 {
2675 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
2676 CurrentContext->dash_offset);
2677 (void) SetXMLTreeContent(child,value);
2678 }
2679 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2680 if (child != (XMLTreeInfo *) NULL)
2681 {
2682 (void) CopyMagickString(value,CommandOptionToMnemonic(
2683 MagickLineCapOptions,(ssize_t) CurrentContext->linecap),
2684 MagickPathExtent);
2685 (void) SetXMLTreeContent(child,value);
2686 }
2687 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2688 if (child != (XMLTreeInfo *) NULL)
2689 {
2690 (void) CopyMagickString(value,CommandOptionToMnemonic(
2691 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2692 MagickPathExtent);
2693 (void) SetXMLTreeContent(child,value);
2694 }
2695 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2696 if (child != (XMLTreeInfo *) NULL)
2697 {
2698 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
2699 CurrentContext->miterlimit);
2700 (void) SetXMLTreeContent(child,value);
2701 }
2702 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2703 if (child != (XMLTreeInfo *) NULL)
2704 {
2705 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
2706 (double) (QuantumScale*CurrentContext->stroke.alpha));
2707 (void) SetXMLTreeContent(child,value);
2708 }
2709 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2710 if (child != (XMLTreeInfo *) NULL)
2711 {
2712 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
2713 CurrentContext->stroke_width);
2714 (void) SetXMLTreeContent(child,value);
2715 }
2716 child=AddChildToXMLTree(xml_info,"text-align",0);
2717 if (child != (XMLTreeInfo *) NULL)
2718 {
2719 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
2720 (ssize_t) CurrentContext->align),MagickPathExtent);
2721 (void) SetXMLTreeContent(child,value);
2722 }
2723 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2724 if (child != (XMLTreeInfo *) NULL)
2725 {
2726 (void) FormatLocaleString(value,MagickPathExtent,"%d",
2727 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2728 (void) SetXMLTreeContent(child,value);
2729 }
2730 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2731 if (child != (XMLTreeInfo *) NULL)
2732 {
2733 if (CurrentContext->undercolor.alpha != (double) OpaqueAlpha)
2734 pixel.alpha_trait=CurrentContext->undercolor.alpha != (double) OpaqueAlpha ?
2735 BlendPixelTrait : UndefinedPixelTrait;
2736 pixel=CurrentContext->undercolor;
2737 GetColorTuple(&pixel,MagickTrue,value);
2738 (void) SetXMLTreeContent(child,value);
2739 }
2740 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2741 if (child != (XMLTreeInfo *) NULL)
2742 (void) SetXMLTreeContent(child,wand->mvg);
2743 xml=XMLTreeInfoToXML(xml_info);
2744 xml_info=DestroyXMLTree(xml_info);
2745 return(xml);
2746}
2747
2748/*
2749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2750% %
2751% %
2752% %
2753% D r a w G e t T e x t U n d e r C o l o r %
2754% %
2755% %
2756% %
2757%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2758%
2759% DrawGetTextUnderColor() returns the color of a background rectangle
2760% to place under text annotations.
2761%
2762% The format of the DrawGetTextUnderColor method is:
2763%
2764% void DrawGetTextUnderColor(const DrawingWand *wand,
2765% PixelWand *under_color)
2766%
2767% A description of each parameter follows:
2768%
2769% o wand: the drawing wand.
2770%
2771% o under_color: Return the under color.
2772%
2773*/
2774WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2775 PixelWand *under_color)
2776{
2777 assert(wand != (const DrawingWand *) NULL);
2778 assert(wand->signature == MagickWandSignature);
2779 assert(under_color != (PixelWand *) NULL);
2780 if (wand->debug != MagickFalse)
2781 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2782 PixelSetPixelColor(under_color,&CurrentContext->undercolor);
2783}
2784
2785/*
2786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2787% %
2788% %
2789% %
2790% D r a w L i n e %
2791% %
2792% %
2793% %
2794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2795%
2796% DrawLine() draws a line on the image using the current stroke color,
2797% stroke alpha, and stroke width.
2798%
2799% The format of the DrawLine method is:
2800%
2801% void DrawLine(DrawingWand *wand,const double sx,const double sy,
2802% const double ex,const double ey)
2803%
2804% A description of each parameter follows:
2805%
2806% o wand: the drawing wand.
2807%
2808% o sx: starting x ordinate
2809%
2810% o sy: starting y ordinate
2811%
2812% o ex: ending x ordinate
2813%
2814% o ey: ending y ordinate
2815%
2816*/
2817WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2818 const double ex,const double ey)
2819{
2820 assert(wand != (DrawingWand *) NULL);
2821 assert(wand->signature == MagickWandSignature);
2822 if (wand->debug != MagickFalse)
2823 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2824 (void) MVGPrintf(wand,"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey);
2825}
2826
2827/*
2828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2829% %
2830% %
2831% %
2832% D r a w P a t h C l o s e %
2833% %
2834% %
2835% %
2836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2837%
2838% DrawPathClose() adds a path element to the current path which closes the
2839% current subpath by drawing a straight line from the current point to the
2840% current subpath's most recent starting point (usually, the most recent
2841% moveto point).
2842%
2843% The format of the DrawPathClose method is:
2844%
2845% void DrawPathClose(DrawingWand *wand)
2846%
2847% A description of each parameter follows:
2848%
2849% o wand: the drawing wand.
2850%
2851*/
2852WandExport void DrawPathClose(DrawingWand *wand)
2853{
2854 assert(wand != (DrawingWand *) NULL);
2855 assert(wand->signature == MagickWandSignature);
2856 if (wand->debug != MagickFalse)
2857 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2858 (void) MVGAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2859 "Z" : "z");
2860}
2861
2862/*
2863%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2864% %
2865% %
2866% %
2867% D r a w P a t h C u r v e T o A b s o l u t e %
2868% %
2869% %
2870% %
2871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2872%
2873% DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2874% point to (x,y) using (x1,y1) as the control point at the beginning of
2875% the curve and (x2,y2) as the control point at the end of the curve using
2876% absolute coordinates. At the end of the command, the new current point
2877% becomes the final (x,y) coordinate pair used in the polybezier.
2878%
2879% The format of the DrawPathCurveToAbsolute method is:
2880%
2881% void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2882% const double y1,const double x2,const double y2,const double x,
2883% const double y)
2884%
2885% A description of each parameter follows:
2886%
2887% o wand: the drawing wand.
2888%
2889% o x1: x ordinate of control point for curve beginning
2890%
2891% o y1: y ordinate of control point for curve beginning
2892%
2893% o x2: x ordinate of control point for curve ending
2894%
2895% o y2: y ordinate of control point for curve ending
2896%
2897% o x: x ordinate of the end of the curve
2898%
2899% o y: y ordinate of the end of the curve
2900%
2901*/
2902
2903static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2904 const double x1,const double y1,const double x2,const double y2,
2905 const double x,const double y)
2906{
2907 assert(wand != (DrawingWand *) NULL);
2908 assert(wand->signature == MagickWandSignature);
2909 if (wand->debug != MagickFalse)
2910 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2911 if ((wand->path_operation != PathCurveToOperation) ||
2912 (wand->path_mode != mode))
2913 {
2914 wand->path_operation=PathCurveToOperation;
2915 wand->path_mode=mode;
2916 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g %.20g %.20g",
2917 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2918 }
2919 else
2920 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1,
2921 x2,y2,x,y);
2922}
2923
2924WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2925 const double y1,const double x2,const double y2,const double x,const double y)
2926{
2927 assert(wand != (DrawingWand *) NULL);
2928 assert(wand->signature == MagickWandSignature);
2929 if (wand->debug != MagickFalse)
2930 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2931 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2932}
2933
2934/*
2935%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2936% %
2937% %
2938% %
2939% D r a w P a t h C u r v e T o R e l a t i v e %
2940% %
2941% %
2942% %
2943%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2944%
2945% DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2946% point to (x,y) using (x1,y1) as the control point at the beginning of
2947% the curve and (x2,y2) as the control point at the end of the curve using
2948% relative coordinates. At the end of the command, the new current point
2949% becomes the final (x,y) coordinate pair used in the polybezier.
2950%
2951% The format of the DrawPathCurveToRelative method is:
2952%
2953% void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2954% const double y1,const double x2,const double y2,const double x,
2955% const double y)
2956%
2957% A description of each parameter follows:
2958%
2959% o wand: the drawing wand.
2960%
2961% o x1: x ordinate of control point for curve beginning
2962%
2963% o y1: y ordinate of control point for curve beginning
2964%
2965% o x2: x ordinate of control point for curve ending
2966%
2967% o y2: y ordinate of control point for curve ending
2968%
2969% o x: x ordinate of the end of the curve
2970%
2971% o y: y ordinate of the end of the curve
2972%
2973*/
2974WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2975 const double y1,const double x2,const double y2,const double x,const double y)
2976{
2977 assert(wand != (DrawingWand *) NULL);
2978 assert(wand->signature == MagickWandSignature);
2979 if (wand->debug != MagickFalse)
2980 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2981 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2982}
2983
2984/*
2985%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2986% %
2987% %
2988% %
2989% 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 %
2990% %
2991% %
2992% %
2993%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2994%
2995% DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2996% from the current point to (x,y) using (x1,y1) as the control point using
2997% absolute coordinates. At the end of the command, the new current point
2998% becomes the final (x,y) coordinate pair used in the polybezier.
2999%
3000% The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
3001%
3002% void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
3003% const double x1,const double y1,const double x,const double y)
3004%
3005% A description of each parameter follows:
3006%
3007% o wand: the drawing wand.
3008%
3009% o x1: x ordinate of the control point
3010%
3011% o y1: y ordinate of the control point
3012%
3013% o x: x ordinate of final point
3014%
3015% o y: y ordinate of final point
3016%
3017*/
3018
3019static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
3020 const PathMode mode,const double x1,double y1,const double x,const double y)
3021{
3022 assert(wand != (DrawingWand *) NULL);
3023 assert(wand->signature == MagickWandSignature);
3024 if (wand->debug != MagickFalse)
3025 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3026 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
3027 (wand->path_mode != mode))
3028 {
3029 wand->path_operation=PathCurveToQuadraticBezierOperation;
3030 wand->path_mode=mode;
3031 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g",
3032 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
3033 }
3034 else
3035 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x1,y1,x,y);
3036}
3037
3038WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
3039 const double x1,const double y1,const double x,const double y)
3040{
3041 assert(wand != (DrawingWand *) NULL);
3042 assert(wand->signature == MagickWandSignature);
3043 if (wand->debug != MagickFalse)
3044 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3045 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
3046}
3047
3048/*
3049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3050% %
3051% %
3052% %
3053% 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 %
3054% %
3055% %
3056% %
3057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3058%
3059% DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
3060% from the current point to (x,y) using (x1,y1) as the control point using
3061% relative coordinates. At the end of the command, the new current point
3062% becomes the final (x,y) coordinate pair used in the polybezier.
3063%
3064% The format of the DrawPathCurveToQuadraticBezierRelative method is:
3065%
3066% void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3067% const double x1,const double y1,const double x,const double y)
3068%
3069% A description of each parameter follows:
3070%
3071% o wand: the drawing wand.
3072%
3073% o x1: x ordinate of the control point
3074%
3075% o y1: y ordinate of the control point
3076%
3077% o x: x ordinate of final point
3078%
3079% o y: y ordinate of final point
3080%
3081*/
3082WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3083 const double x1,const double y1,const double x,const double y)
3084{
3085 assert(wand != (DrawingWand *) NULL);
3086 assert(wand->signature == MagickWandSignature);
3087 if (wand->debug != MagickFalse)
3088 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3089 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
3090}
3091
3092/*
3093%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3094% %
3095% %
3096% %
3097% 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 %
3098% %
3099% %
3100% %
3101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3102%
3103% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3104% Bezier curve (using absolute coordinates) from the current point to
3105% (x,y). The control point is assumed to be the reflection of the
3106% control point on the previous command relative to the current
3107% point. (If there is no previous command or if the previous command was
3108% not a DrawPathCurveToQuadraticBezierAbsolute,
3109% DrawPathCurveToQuadraticBezierRelative,
3110% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3111% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3112% is coincident with the current point.). At the end of the command, the
3113% new current point becomes the final (x,y) coordinate pair used in the
3114% polybezier.
3115%
3116% The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3117%
3118% void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3119% DrawingWand *wand,const double x,const double y)
3120%
3121% A description of each parameter follows:
3122%
3123% o wand: the drawing wand.
3124%
3125% o x: x ordinate of final point
3126%
3127% o y: y ordinate of final point
3128%
3129*/
3130
3131static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3132 const PathMode mode,const double x,const double y)
3133{
3134 assert(wand != (DrawingWand *) NULL);
3135 assert(wand->signature == MagickWandSignature);
3136 if (wand->debug != MagickFalse)
3137 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3138 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3139 (wand->path_mode != mode))
3140 {
3141 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3142 wand->path_mode=mode;
3143 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
3144 'T' : 't',x,y);
3145 }
3146 else
3147 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
3148}
3149
3150WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3151 const double x,const double y)
3152{
3153 assert(wand != (DrawingWand *) NULL);
3154 assert(wand->signature == MagickWandSignature);
3155 if (wand->debug != MagickFalse)
3156 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3157 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3158}
3159
3160/*
3161%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3162% %
3163% %
3164% %
3165% 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 %
3166% %
3167% %
3168% %
3169%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3170%
3171% DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic Bezier
3172% curve (using relative coordinates) from the current point to (x,y). The
3173% control point is assumed to be the reflection of the control point on the
3174% previous command relative to the current point. (If there is no previous
3175% command or if the previous command was not a
3176% DrawPathCurveToQuadraticBezierAbsolute,
3177% DrawPathCurveToQuadraticBezierRelative,
3178% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3179% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3180% coincident with the current point.). At the end of the command, the new
3181% current point becomes the final (x,y) coordinate pair used in the polybezier.
3182%
3183% The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3184%
3185% void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3186% const double x,const double y)
3187%
3188% A description of each parameter follows:
3189%
3190% o wand: the drawing wand.
3191%
3192% o x: x ordinate of final point
3193%
3194% o y: y ordinate of final point
3195%
3196*/
3197WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3198 const double x,const double y)
3199{
3200 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3201}
3202
3203/*
3204%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3205% %
3206% %
3207% %
3208% 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 %
3209% %
3210% %
3211% %
3212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3213%
3214% DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3215% current point to (x,y) using absolute coordinates. The first control
3216% point is assumed to be the reflection of the second control point on
3217% the previous command relative to the current point. (If there is no
3218% previous command or if the previous command was not an
3219% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3220% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3221% the first control point is coincident with the current point.) (x2,y2)
3222% is the second control point (i.e., the control point at the end of the
3223% curve). At the end of the command, the new current point becomes the
3224% final (x,y) coordinate pair used in the polybezier.
3225%
3226% The format of the DrawPathCurveToSmoothAbsolute method is:
3227%
3228% void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3229% const double x2,const double y2,const double x,const double y)
3230%
3231% A description of each parameter follows:
3232%
3233% o wand: the drawing wand.
3234%
3235% o x2: x ordinate of second control point
3236%
3237% o y2: y ordinate of second control point
3238%
3239% o x: x ordinate of termination point
3240%
3241% o y: y ordinate of termination point
3242%
3243*/
3244
3245static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3246 const double x2,const double y2,const double x,const double y)
3247{
3248 assert(wand != (DrawingWand *) NULL);
3249 assert(wand->signature == MagickWandSignature);
3250 if (wand->debug != MagickFalse)
3251 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3252 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3253 (wand->path_mode != mode))
3254 {
3255 wand->path_operation=PathCurveToSmoothOperation;
3256 wand->path_mode=mode;
3257 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g %.20g %.20g",
3258 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
3259 }
3260 else
3261 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x2,y2,x,y);
3262}
3263
3264WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3265 const double y2,const double x,const double y)
3266{
3267 assert(wand != (DrawingWand *) NULL);
3268 assert(wand->signature == MagickWandSignature);
3269 if (wand->debug != MagickFalse)
3270 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3271 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3272}
3273
3274/*
3275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3276% %
3277% %
3278% %
3279% 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 %
3280% %
3281% %
3282% %
3283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3284%
3285% DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3286% point to (x,y) using relative coordinates. The first control point is
3287% assumed to be the reflection of the second control point on the previous
3288% command relative to the current point. (If there is no previous command or
3289% if the previous command was not an DrawPathCurveToAbsolute,
3290% DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3291% DrawPathCurveToSmoothRelative, assume the first control point is coincident
3292% with the current point.) (x2,y2) is the second control point (i.e., the
3293% control point at the end of the curve). At the end of the command, the new
3294% current point becomes the final (x,y) coordinate pair used in the polybezier.
3295%
3296% The format of the DrawPathCurveToSmoothRelative method is:
3297%
3298% void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3299% const double x2,const double y2,const double x,const double y)
3300%
3301% A description of each parameter follows:
3302%
3303% o wand: the drawing wand.
3304%
3305% o x2: x ordinate of second control point
3306%
3307% o y2: y ordinate of second control point
3308%
3309% o x: x ordinate of termination point
3310%
3311% o y: y ordinate of termination point
3312%
3313*/
3314WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3315 const double y2,const double x,const double y)
3316{
3317 assert(wand != (DrawingWand *) NULL);
3318 assert(wand->signature == MagickWandSignature);
3319 if (wand->debug != MagickFalse)
3320 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3321 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3322}
3323
3324/*
3325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3326% %
3327% %
3328% %
3329% 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 %
3330% %
3331% %
3332% %
3333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3334%
3335% DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3336% to (x, y) using absolute coordinates. The size and orientation of the
3337% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3338% indicates how the ellipse as a whole is rotated relative to the current
3339% coordinate system. The center (cx, cy) of the ellipse is calculated
3340% automagically to satisfy the constraints imposed by the other parameters.
3341% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3342% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3343% of the available arcs. If sweepFlag is true, then draw the arc matching a
3344% clock-wise rotation.
3345%
3346% The format of the DrawPathEllipticArcAbsolute method is:
3347%
3348% void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3349% const double rx,const double ry,const double x_axis_rotation,
3350% const MagickBooleanType large_arc_flag,
3351% const MagickBooleanType sweep_flag,const double x,const double y)
3352%
3353% A description of each parameter follows:
3354%
3355% o wand: the drawing wand.
3356%
3357% o rx: x radius
3358%
3359% o ry: y radius
3360%
3361% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3362% relative to the current coordinate system
3363%
3364% o large_arc_flag: If non-zero (true) then draw the larger of the
3365% available arcs
3366%
3367% o sweep_flag: If non-zero (true) then draw the arc matching a
3368% clock-wise rotation
3369%
3370%
3371*/
3372
3373static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3374 const double rx,const double ry,const double x_axis_rotation,
3375 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3376 const double x,const double y)
3377{
3378 assert(wand != (DrawingWand *) NULL);
3379 assert(wand->signature == MagickWandSignature);
3380 if (wand->debug != MagickFalse)
3381 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3382 if ((wand->path_operation != PathEllipticArcOperation) ||
3383 (wand->path_mode != mode))
3384 {
3385 wand->path_operation=PathEllipticArcOperation;
3386 wand->path_mode=mode;
3387 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %u %u %.20g %.20g",
3388 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3389 large_arc_flag,sweep_flag,x,y);
3390 }
3391 else
3392 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry,
3393 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3394}
3395
3396WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3397 const double ry,const double x_axis_rotation,
3398 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3399 const double x,const double y)
3400{
3401 assert(wand != (DrawingWand *) NULL);
3402 assert(wand->signature == MagickWandSignature);
3403 if (wand->debug != MagickFalse)
3404 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3405 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3406 large_arc_flag,sweep_flag,x,y);
3407}
3408
3409/*
3410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3411% %
3412% %
3413% %
3414% 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 %
3415% %
3416% %
3417% %
3418%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3419%
3420% DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3421% to (x, y) using relative coordinates. The size and orientation of the
3422% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3423% indicates how the ellipse as a whole is rotated relative to the current
3424% coordinate system. The center (cx, cy) of the ellipse is calculated
3425% automagically to satisfy the constraints imposed by the other parameters.
3426% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3427% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3428% of the available arcs. If sweepFlag is true, then draw the arc matching a
3429% clock-wise rotation.
3430%
3431% The format of the DrawPathEllipticArcRelative method is:
3432%
3433% void DrawPathEllipticArcRelative(DrawingWand *wand,
3434% const double rx,const double ry,const double x_axis_rotation,
3435% const MagickBooleanType large_arc_flag,
3436% const MagickBooleanType sweep_flag,const double x,const double y)
3437%
3438% A description of each parameter follows:
3439%
3440% o wand: the drawing wand.
3441%
3442% o rx: x radius
3443%
3444% o ry: y radius
3445%
3446% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3447% relative to the current coordinate system
3448%
3449% o large_arc_flag: If non-zero (true) then draw the larger of the
3450% available arcs
3451%
3452% o sweep_flag: If non-zero (true) then draw the arc matching a
3453% clock-wise rotation
3454%
3455*/
3456WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3457 const double ry,const double x_axis_rotation,
3458 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3459 const double x,const double y)
3460{
3461 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3462 large_arc_flag,sweep_flag,x,y);
3463}
3464
3465/*
3466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3467% %
3468% %
3469% %
3470% D r a w P a t h F i n i s h %
3471% %
3472% %
3473% %
3474%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3475%
3476% DrawPathFinish() terminates the current path.
3477%
3478% The format of the DrawPathFinish method is:
3479%
3480% void DrawPathFinish(DrawingWand *wand)
3481%
3482% A description of each parameter follows:
3483%
3484% o wand: the drawing wand.
3485%
3486*/
3487WandExport void DrawPathFinish(DrawingWand *wand)
3488{
3489 assert(wand != (DrawingWand *) NULL);
3490 assert(wand->signature == MagickWandSignature);
3491 if (wand->debug != MagickFalse)
3492 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3493 (void) MVGPrintf(wand,"'\n");
3494 wand->path_operation=PathDefaultOperation;
3495 wand->path_mode=DefaultPathMode;
3496}
3497
3498/*
3499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3500% %
3501% %
3502% %
3503% D r a w P a t h L i n e T o A b s o l u t e %
3504% %
3505% %
3506% %
3507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3508%
3509% DrawPathLineToAbsolute() draws a line path from the current point to the
3510% given coordinate using absolute coordinates. The coordinate then becomes
3511% the new current point.
3512%
3513% The format of the DrawPathLineToAbsolute method is:
3514%
3515% void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3516% const double y)
3517%
3518% A description of each parameter follows:
3519%
3520% o wand: the drawing wand.
3521%
3522% o x: target x ordinate
3523%
3524% o y: target y ordinate
3525%
3526*/
3527static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3528 const double x,const double y)
3529{
3530 assert(wand != (DrawingWand *) NULL);
3531 assert(wand->signature == MagickWandSignature);
3532 if (wand->debug != MagickFalse)
3533 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3534 if ((wand->path_operation != PathLineToOperation) ||
3535 (wand->path_mode != mode))
3536 {
3537 wand->path_operation=PathLineToOperation;
3538 wand->path_mode=mode;
3539 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
3540 'L' : 'l',x,y);
3541 }
3542 else
3543 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
3544}
3545
3546WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3547 const double y)
3548{
3549 assert(wand != (DrawingWand *) NULL);
3550 assert(wand->signature == MagickWandSignature);
3551 if (wand->debug != MagickFalse)
3552 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3553 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3554}
3555
3556/*
3557%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3558% %
3559% %
3560% %
3561% D r a w P a t h L i n e T o R e l a t i v e %
3562% %
3563% %
3564% %
3565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3566%
3567% DrawPathLineToRelative() draws a line path from the current point to the
3568% given coordinate using relative coordinates. The coordinate then becomes
3569% the new current point.
3570%
3571% The format of the DrawPathLineToRelative method is:
3572%
3573% void DrawPathLineToRelative(DrawingWand *wand,const double x,
3574% const double y)
3575%
3576% A description of each parameter follows:
3577%
3578% o wand: the drawing wand.
3579%
3580% o x: target x ordinate
3581%
3582% o y: target y ordinate
3583%
3584*/
3585WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3586 const double y)
3587{
3588 assert(wand != (DrawingWand *) NULL);
3589 assert(wand->signature == MagickWandSignature);
3590 if (wand->debug != MagickFalse)
3591 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3592 DrawPathLineTo(wand,RelativePathMode,x,y);
3593}
3594
3595/*
3596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3597% %
3598% %
3599% %
3600% 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 %
3601% %
3602% %
3603% %
3604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3605%
3606% DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3607% current point to the target point using absolute coordinates. The target
3608% point then becomes the new current point.
3609%
3610% The format of the DrawPathLineToHorizontalAbsolute method is:
3611%
3612% void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,const double x)
3613%
3614% A description of each parameter follows:
3615%
3616% o wand: the drawing wand.
3617%
3618% o x: target x ordinate
3619%
3620*/
3621
3622static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3623 const double x)
3624{
3625 assert(wand != (DrawingWand *) NULL);
3626 assert(wand->signature == MagickWandSignature);
3627 if (wand->debug != MagickFalse)
3628 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3629 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3630 (wand->path_mode != mode))
3631 {
3632 wand->path_operation=PathLineToHorizontalOperation;
3633 wand->path_mode=mode;
3634 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
3635 'H' : 'h',x);
3636 }
3637 else
3638 (void) MVGAutoWrapPrintf(wand," %.20g",x);
3639}
3640
3641WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3642 const double x)
3643{
3644 assert(wand != (DrawingWand *) NULL);
3645 assert(wand->signature == MagickWandSignature);
3646 if (wand->debug != MagickFalse)
3647 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3648 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3649}
3650
3651/*
3652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3653% %
3654% %
3655% %
3656% 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 %
3657% %
3658% %
3659% %
3660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3661%
3662% DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3663% current point to the target point using relative coordinates. The target
3664% point then becomes the new current point.
3665%
3666% The format of the DrawPathLineToHorizontalRelative method is:
3667%
3668% void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3669% const double x)
3670%
3671% A description of each parameter follows:
3672%
3673% o wand: the drawing wand.
3674%
3675% o x: target x ordinate
3676%
3677*/
3678WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3679 const double x)
3680{
3681 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3682}
3683
3684/*
3685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3686% %
3687% %
3688% %
3689% 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 %
3690% %
3691% %
3692% %
3693%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3694%
3695% DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3696% current point to the target point using absolute coordinates. The target
3697% point then becomes the new current point.
3698%
3699% The format of the DrawPathLineToVerticalAbsolute method is:
3700%
3701% void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3702% const double y)
3703%
3704% A description of each parameter follows:
3705%
3706% o wand: the drawing wand.
3707%
3708% o y: target y ordinate
3709%
3710*/
3711
3712static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3713 const double y)
3714{
3715 assert(wand != (DrawingWand *) NULL);
3716 assert(wand->signature == MagickWandSignature);
3717 if (wand->debug != MagickFalse)
3718 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3719 if ((wand->path_operation != PathLineToVerticalOperation) ||
3720 (wand->path_mode != mode))
3721 {
3722 wand->path_operation=PathLineToVerticalOperation;
3723 wand->path_mode=mode;
3724 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
3725 'V' : 'v',y);
3726 }
3727 else
3728 (void) MVGAutoWrapPrintf(wand," %.20g",y);
3729}
3730
3731WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3732{
3733 assert(wand != (DrawingWand *) NULL);
3734 assert(wand->signature == MagickWandSignature);
3735 if (wand->debug != MagickFalse)
3736 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3737 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3738}
3739
3740/*
3741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3742% %
3743% %
3744% %
3745% 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 %
3746% %
3747% %
3748% %
3749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3750%
3751% DrawPathLineToVerticalRelative() draws a vertical line path from the
3752% current point to the target point using relative coordinates. The target
3753% point then becomes the new current point.
3754%
3755% The format of the DrawPathLineToVerticalRelative method is:
3756%
3757% void DrawPathLineToVerticalRelative(DrawingWand *wand,
3758% const double y)
3759%
3760% A description of each parameter follows:
3761%
3762% o wand: the drawing wand.
3763%
3764% o y: target y ordinate
3765%
3766*/
3767WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3768{
3769 assert(wand != (DrawingWand *) NULL);
3770 assert(wand->signature == MagickWandSignature);
3771 if (wand->debug != MagickFalse)
3772 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3773 DrawPathLineToVertical(wand,RelativePathMode,y);
3774}
3775/*
3776%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3777% %
3778% %
3779% %
3780% D r a w P a t h M o v e T o A b s o l u t e %
3781% %
3782% %
3783% %
3784%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3785%
3786% DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3787% using absolute coordinates. The current point then becomes the
3788% specified coordinate.
3789%
3790% The format of the DrawPathMoveToAbsolute method is:
3791%
3792% void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3793% const double y)
3794%
3795% A description of each parameter follows:
3796%
3797% o wand: the drawing wand.
3798%
3799% o x: target x ordinate
3800%
3801% o y: target y ordinate
3802%
3803*/
3804
3805static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3806 const double y)
3807{
3808 assert(wand != (DrawingWand *) NULL);
3809 assert(wand->signature == MagickWandSignature);
3810 if (wand->debug != MagickFalse)
3811 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3812 if ((wand->path_operation != PathMoveToOperation) ||
3813 (wand->path_mode != mode))
3814 {
3815 wand->path_operation=PathMoveToOperation;
3816 wand->path_mode=mode;
3817 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
3818 'M' : 'm',x,y);
3819 }
3820 else
3821 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
3822}
3823
3824WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3825 const double y)
3826{
3827 assert(wand != (DrawingWand *) NULL);
3828 assert(wand->signature == MagickWandSignature);
3829 if (wand->debug != MagickFalse)
3830 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3831 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3832}
3833
3834/*
3835%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3836% %
3837% %
3838% %
3839% D r a w P a t h M o v e T o R e l a t i v e %
3840% %
3841% %
3842% %
3843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3844%
3845% DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3846% relative coordinates. The current point then becomes the specified
3847% coordinate.
3848%
3849% The format of the DrawPathMoveToRelative method is:
3850%
3851% void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3852% const double y)
3853%
3854% A description of each parameter follows:
3855%
3856% o wand: the drawing wand.
3857%
3858% o x: target x ordinate
3859%
3860% o y: target y ordinate
3861%
3862*/
3863WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3864 const double y)
3865{
3866 assert(wand != (DrawingWand *) NULL);
3867 assert(wand->signature == MagickWandSignature);
3868 if (wand->debug != MagickFalse)
3869 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3870 DrawPathMoveTo(wand,RelativePathMode,x,y);
3871}
3872
3873/*
3874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3875% %
3876% %
3877% %
3878% D r a w P a t h S t a r t %
3879% %
3880% %
3881% %
3882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3883%
3884% DrawPathStart() declares the start of a path drawing list which is terminated
3885% by a matching DrawPathFinish() command. All other DrawPath commands must
3886% be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3887% is because path drawing commands are subordinate commands and they do not
3888% function by themselves.
3889%
3890% The format of the DrawPathStart method is:
3891%
3892% void DrawPathStart(DrawingWand *wand)
3893%
3894% A description of each parameter follows:
3895%
3896% o wand: the drawing wand.
3897%
3898*/
3899WandExport void DrawPathStart(DrawingWand *wand)
3900{
3901 assert(wand != (DrawingWand *) NULL);
3902 assert(wand->signature == MagickWandSignature);
3903 if (wand->debug != MagickFalse)
3904 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3905 (void) MVGPrintf(wand,"path '");
3906 wand->path_operation=PathDefaultOperation;
3907 wand->path_mode=DefaultPathMode;
3908}
3909
3910/*
3911%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3912% %
3913% %
3914% %
3915% D r a w P o i n t %
3916% %
3917% %
3918% %
3919%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3920%
3921% DrawPoint() draws a point using the current fill color.
3922%
3923% The format of the DrawPoint method is:
3924%
3925% void DrawPoint(DrawingWand *wand,const double x,const double y)
3926%
3927% A description of each parameter follows:
3928%
3929% o wand: the drawing wand.
3930%
3931% o x: target x coordinate
3932%
3933% o y: target y coordinate
3934%
3935*/
3936WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3937{
3938 assert(wand != (DrawingWand *) NULL);
3939 assert(wand->signature == MagickWandSignature);
3940 if (wand->debug != MagickFalse)
3941 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3942 (void) MVGPrintf(wand,"point %.20g %.20g\n",x,y);
3943}
3944
3945/*
3946%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3947% %
3948% %
3949% %
3950% D r a w P o l y g o n %
3951% %
3952% %
3953% %
3954%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3955%
3956% DrawPolygon() draws a polygon using the current stroke, stroke width, and
3957% fill color or texture, using the specified array of coordinates.
3958%
3959% The format of the DrawPolygon method is:
3960%
3961% void DrawPolygon(DrawingWand *wand,
3962% const size_t number_coordinates,const PointInfo *coordinates)
3963%
3964% A description of each parameter follows:
3965%
3966% o wand: the drawing wand.
3967%
3968% o number_coordinates: number of coordinates
3969%
3970% o coordinates: coordinate array
3971%
3972*/
3973WandExport void DrawPolygon(DrawingWand *wand,
3974 const size_t number_coordinates,const PointInfo *coordinates)
3975{
3976 assert(wand != (DrawingWand *) NULL);
3977 assert(wand->signature == MagickWandSignature);
3978 if (wand->debug != MagickFalse)
3979 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3980 MVGAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3981}
3982
3983/*
3984%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3985% %
3986% %
3987% %
3988% D r a w P o l y l i n e %
3989% %
3990% %
3991% %
3992%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3993%
3994% DrawPolyline() draws a polyline using the current stroke, stroke width, and
3995% fill color or texture, using the specified array of coordinates.
3996%
3997% The format of the DrawPolyline method is:
3998%
3999% void DrawPolyline(DrawingWand *wand,
4000% const size_t number_coordinates,const PointInfo *coordinates)
4001%
4002% A description of each parameter follows:
4003%
4004% o wand: the drawing wand.
4005%
4006% o number_coordinates: number of coordinates
4007%
4008% o coordinates: coordinate array
4009%
4010*/
4011WandExport void DrawPolyline(DrawingWand *wand,
4012 const size_t number_coordinates,const PointInfo *coordinates)
4013{
4014 assert(wand != (DrawingWand *) NULL);
4015 assert(wand->signature == MagickWandSignature);
4016 if (wand->debug != MagickFalse)
4017 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4018 MVGAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
4019}
4020
4021/*
4022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4023% %
4024% %
4025% %
4026% D r a w P o p C l i p P a t h %
4027% %
4028% %
4029% %
4030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4031%
4032% DrawPopClipPath() terminates a clip path definition.
4033%
4034% The format of the DrawPopClipPath method is:
4035%
4036% void DrawPopClipPath(DrawingWand *wand)
4037%
4038% A description of each parameter follows:
4039%
4040% o wand: the drawing wand.
4041%
4042*/
4043WandExport void DrawPopClipPath(DrawingWand *wand)
4044{
4045 assert(wand != (DrawingWand *) NULL);
4046 assert(wand->signature == MagickWandSignature);
4047 if (wand->debug != MagickFalse)
4048 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4049 if (wand->indent_depth > 0)
4050 wand->indent_depth--;
4051 (void) MVGPrintf(wand,"pop clip-path\n");
4052}
4053
4054/*
4055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4056% %
4057% %
4058% %
4059% D r a w P o p D e f s %
4060% %
4061% %
4062% %
4063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4064%
4065% DrawPopDefs() terminates a definition list.
4066%
4067% The format of the DrawPopDefs method is:
4068%
4069% void DrawPopDefs(DrawingWand *wand)
4070%
4071% A description of each parameter follows:
4072%
4073% o wand: the drawing wand.
4074%
4075*/
4076WandExport void DrawPopDefs(DrawingWand *wand)
4077{
4078 assert(wand != (DrawingWand *) NULL);
4079 assert(wand->signature == MagickWandSignature);
4080 if (wand->debug != MagickFalse)
4081 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4082 if (wand->indent_depth > 0)
4083 wand->indent_depth--;
4084 (void) MVGPrintf(wand,"pop defs\n");
4085}
4086
4087/*
4088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4089% %
4090% %
4091% %
4092% D r a w P o p P a t t e r n %
4093% %
4094% %
4095% %
4096%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4097%
4098% DrawPopPattern() terminates a pattern definition.
4099%
4100% The format of the DrawPopPattern method is:
4101%
4102% MagickBooleanType DrawPopPattern(DrawingWand *wand)
4103%
4104% A description of each parameter follows:
4105%
4106% o wand: the drawing wand.
4107%
4108*/
4109WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4110{
4111 char
4112 geometry[MagickPathExtent],
4113 key[MagickPathExtent];
4114
4115 assert(wand != (DrawingWand *) NULL);
4116 assert(wand->signature == MagickWandSignature);
4117 if (wand->debug != MagickFalse)
4118 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4119 if (wand->image == (Image *) NULL)
4120 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4121 if (wand->pattern_id == (const char *) NULL)
4122 {
4123 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4124 wand->name);
4125 return(MagickFalse);
4126 }
4127 (void) FormatLocaleString(key,MagickPathExtent,"%s",wand->pattern_id);
4128 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4129 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g%+.20g%+.20g",
4130 (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
4131 (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
4132 (void) SetImageArtifact(wand->image,key,geometry);
4133 wand->pattern_id=DestroyString(wand->pattern_id);
4134 wand->pattern_offset=0;
4135 wand->pattern_bounds.x=0;
4136 wand->pattern_bounds.y=0;
4137 wand->pattern_bounds.width=0;
4138 wand->pattern_bounds.height=0;
4139 wand->filter_off=MagickTrue;
4140 if (wand->indent_depth > 0)
4141 wand->indent_depth--;
4142 (void) MVGPrintf(wand,"pop pattern\n");
4143 return(MagickTrue);
4144}
4145
4146/*
4147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4148% %
4149% %
4150% %
4151% D r a w P u s h C l i p P a t h %
4152% %
4153% %
4154% %
4155%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4156%
4157% DrawPushClipPath() starts a clip path definition which is comprized of any
4158% number of drawing commands and terminated by a DrawPopClipPath() command.
4159%
4160% The format of the DrawPushClipPath method is:
4161%
4162% void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4163%
4164% A description of each parameter follows:
4165%
4166% o wand: the drawing wand.
4167%
4168% o clip_mask_id: string identifier to associate with the clip path for
4169% later use.
4170%
4171*/
4172WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4173{
4174 assert(wand != (DrawingWand *) NULL);
4175 assert(wand->signature == MagickWandSignature);
4176 if (wand->debug != MagickFalse)
4177 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4178 assert(clip_mask_id != (const char *) NULL);
4179 (void) MVGPrintf(wand,"push clip-path \"%s\"\n",clip_mask_id);
4180 wand->indent_depth++;
4181}
4182
4183/*
4184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4185% %
4186% %
4187% %
4188% D r a w P u s h D e f s %
4189% %
4190% %
4191% %
4192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4193%
4194% DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4195% command create named elements (e.g. clip-paths, textures, etc.) which
4196% may safely be processed earlier for the sake of efficiency.
4197%
4198% The format of the DrawPushDefs method is:
4199%
4200% void DrawPushDefs(DrawingWand *wand)
4201%
4202% A description of each parameter follows:
4203%
4204% o wand: the drawing wand.
4205%
4206*/
4207WandExport void DrawPushDefs(DrawingWand *wand)
4208{
4209 assert(wand != (DrawingWand *) NULL);
4210 assert(wand->signature == MagickWandSignature);
4211 if (wand->debug != MagickFalse)
4212 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4213 (void) MVGPrintf(wand,"push defs\n");
4214 wand->indent_depth++;
4215}
4216
4217/*
4218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4219% %
4220% %
4221% %
4222% D r a w P u s h P a t t e r n %
4223% %
4224% %
4225% %
4226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4227%
4228% DrawPushPattern() indicates that subsequent commands up to a
4229% DrawPopPattern() command comprise the definition of a named pattern.
4230% The pattern space is assigned top left corner coordinates, a width
4231% and height, and becomes its own drawing space. Anything which can
4232% be drawn may be used in a pattern definition.
4233% Named patterns may be used as stroke or brush definitions.
4234%
4235% The format of the DrawPushPattern method is:
4236%
4237% MagickBooleanType DrawPushPattern(DrawingWand *wand,
4238% const char *pattern_id,const double x,const double y,
4239% const double width,const double height)
4240%
4241% A description of each parameter follows:
4242%
4243% o wand: the drawing wand.
4244%
4245% o pattern_id: pattern identification for later reference
4246%
4247% o x: x ordinate of top left corner
4248%
4249% o y: y ordinate of top left corner
4250%
4251% o width: width of pattern space
4252%
4253% o height: height of pattern space
4254%
4255*/
4256WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4257 const char *pattern_id,const double x,const double y,const double width,
4258 const double height)
4259{
4260 assert(wand != (DrawingWand *) NULL);
4261 assert(wand->signature == MagickWandSignature);
4262 if (wand->debug != MagickFalse)
4263 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4264 assert(pattern_id != (const char *) NULL);
4265 if (wand->pattern_id != NULL)
4266 {
4267 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4268 wand->pattern_id);
4269 return(MagickFalse);
4270 }
4271 wand->filter_off=MagickTrue;
4272 (void) MVGPrintf(wand,"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id,
4273 x,y,width,height);
4274 wand->indent_depth++;
4275 wand->pattern_id=AcquireString(pattern_id);
4276 wand->pattern_bounds.x=CastDoubleToLong(ceil(x-0.5));
4277 wand->pattern_bounds.y=CastDoubleToLong(ceil(y-0.5));
4278 wand->pattern_bounds.width=(size_t) CastDoubleToLong(floor(width+0.5));
4279 wand->pattern_bounds.height=(size_t) CastDoubleToLong(floor(height+0.5));
4280 wand->pattern_offset=wand->mvg_length;
4281 return(MagickTrue);
4282}
4283
4284/*
4285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4286% %
4287% %
4288% %
4289% D r a w R e c t a n g l e %
4290% %
4291% %
4292% %
4293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4294%
4295% DrawRectangle() draws a rectangle given two coordinates and using the
4296% current stroke, stroke width, and fill settings.
4297%
4298% The format of the DrawRectangle method is:
4299%
4300% void DrawRectangle(DrawingWand *wand,const double x1,
4301% const double y1,const double x2,const double y2)
4302%
4303% A description of each parameter follows:
4304%
4305% o x1: x ordinate of first coordinate
4306%
4307% o y1: y ordinate of first coordinate
4308%
4309% o x2: x ordinate of second coordinate
4310%
4311% o y2: y ordinate of second coordinate
4312%
4313*/
4314WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4315 const double x2,const double y2)
4316{
4317 assert(wand != (DrawingWand *) NULL);
4318 assert(wand->signature == MagickWandSignature);
4319 if (wand->debug != MagickFalse)
4320 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4321 if ((fabs(x2-x1) < MagickEpsilon) && (fabs(y2-y1) < MagickEpsilon))
4322 (void) MVGPrintf(wand,"point %.20g %.20g\n",x1,y1);
4323 else
4324 (void) MVGPrintf(wand,"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
4325}
4326
4327/*
4328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4329% %
4330% %
4331% %
4332+ D r a w R e n d e r %
4333% %
4334% %
4335% %
4336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4337%
4338% DrawRender() renders all preceding drawing commands onto the image.
4339%
4340% The format of the DrawRender method is:
4341%
4342% MagickBooleanType DrawRender(DrawingWand *wand)
4343%
4344% A description of each parameter follows:
4345%
4346% o wand: the drawing wand.
4347%
4348*/
4349WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4350{
4351 MagickBooleanType
4352 status;
4353
4354 assert(wand != (const DrawingWand *) NULL);
4355 assert(wand->signature == MagickWandSignature);
4356 if (wand->debug != MagickFalse)
4357 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4358 CurrentContext->primitive=wand->mvg;
4359 if (wand->debug != MagickFalse)
4360 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4361 if (wand->image == (Image *) NULL)
4362 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4363 status=DrawImage(wand->image,CurrentContext,wand->exception);
4364 CurrentContext->primitive=(char *) NULL;
4365 return(status);
4366}
4367
4368/*
4369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4370% %
4371% %
4372% %
4373% D r a w R e s e t V e c t o r G r a p h i c s %
4374% %
4375% %
4376% %
4377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4378%
4379% DrawResetVectorGraphics() resets the vector graphics associated with the
4380% specified wand.
4381%
4382% The format of the DrawResetVectorGraphics method is:
4383%
4384% void DrawResetVectorGraphics(DrawingWand *wand)
4385%
4386% A description of each parameter follows:
4387%
4388% o wand: the drawing wand.
4389%
4390*/
4391WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4392{
4393 assert(wand != (DrawingWand *) NULL);
4394 assert(wand->signature == MagickWandSignature);
4395 if (wand->debug != MagickFalse)
4396 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4397 if (wand->mvg != (char *) NULL)
4398 wand->mvg=DestroyString(wand->mvg);
4399 wand->mvg_alloc=0;
4400 wand->mvg_length=0;
4401 wand->mvg_width=0;
4402}
4403
4404/*
4405%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4406% %
4407% %
4408% %
4409% D r a w R o t a t e %
4410% %
4411% %
4412% %
4413%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4414%
4415% DrawRotate() applies the specified rotation to the current coordinate space.
4416%
4417% The format of the DrawRotate method is:
4418%
4419% void DrawRotate(DrawingWand *wand,const double degrees)
4420%
4421% A description of each parameter follows:
4422%
4423% o wand: the drawing wand.
4424%
4425% o degrees: degrees of rotation
4426%
4427*/
4428WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4429{
4430 assert(wand != (DrawingWand *) NULL);
4431 assert(wand->signature == MagickWandSignature);
4432 if (wand->debug != MagickFalse)
4433 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4434 (void) MVGPrintf(wand,"rotate %.20g\n",degrees);
4435}
4436
4437/*
4438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4439% %
4440% %
4441% %
4442% D r a w R o u n d R e c t a n g l e %
4443% %
4444% %
4445% %
4446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4447%
4448% DrawRoundRectangle() draws a rounded rectangle given two coordinates,
4449% x & y corner radiuses and using the current stroke, stroke width,
4450% and fill settings.
4451%
4452% The format of the DrawRoundRectangle method is:
4453%
4454% void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4455% double x2,double y2,double rx,double ry)
4456%
4457% A description of each parameter follows:
4458%
4459% o wand: the drawing wand.
4460%
4461% o x1: x ordinate of first coordinate
4462%
4463% o y1: y ordinate of first coordinate
4464%
4465% o x2: x ordinate of second coordinate
4466%
4467% o y2: y ordinate of second coordinate
4468%
4469% o rx: radius of corner in horizontal direction
4470%
4471% o ry: radius of corner in vertical direction
4472%
4473*/
4474WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4475 double x2,double y2,double rx,double ry)
4476{
4477 assert(wand != (DrawingWand *) NULL);
4478 assert(wand->signature == MagickWandSignature);
4479 if (wand->debug != MagickFalse)
4480 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4481 (void) MVGPrintf(wand,"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n",
4482 x1,y1,x2,y2,rx,ry);
4483}
4484
4485/*
4486%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4487% %
4488% %
4489% %
4490% D r a w S c a l e %
4491% %
4492% %
4493% %
4494%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4495%
4496% DrawScale() adjusts the scaling factor to apply in the horizontal and
4497% vertical directions to the current coordinate space.
4498%
4499% The format of the DrawScale method is:
4500%
4501% void DrawScale(DrawingWand *wand,const double x,const double y)
4502%
4503% A description of each parameter follows:
4504%
4505% o wand: the drawing wand.
4506%
4507% o x: horizontal scale factor
4508%
4509% o y: vertical scale factor
4510%
4511*/
4512WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4513{
4514 assert(wand != (DrawingWand *) NULL);
4515 assert(wand->signature == MagickWandSignature);
4516 if (wand->debug != MagickFalse)
4517 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4518 (void) MVGPrintf(wand,"scale %.20g %.20g\n",x,y);
4519}
4520
4521/*
4522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4523% %
4524% %
4525% %
4526% D r a w S e t B o r d e r C o l o r %
4527% %
4528% %
4529% %
4530%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4531%
4532% DrawSetBorderColor() sets the border color to be used for drawing bordered
4533% objects.
4534%
4535% The format of the DrawSetBorderColor method is:
4536%
4537% void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4538%
4539% A description of each parameter follows:
4540%
4541% o wand: the drawing wand.
4542%
4543% o border_wand: border wand.
4544%
4545*/
4546WandExport void DrawSetBorderColor(DrawingWand *wand,
4547 const PixelWand *border_wand)
4548{
4549 PixelInfo
4550 *current_border,
4551 border_color,
4552 new_border;
4553
4554 assert(wand != (DrawingWand *) NULL);
4555 assert(wand->signature == MagickWandSignature);
4556 if (wand->debug != MagickFalse)
4557 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4558 assert(border_wand != (const PixelWand *) NULL);
4559 PixelGetQuantumPacket(border_wand,&border_color);
4560 new_border=border_color;
4561 current_border=(&CurrentContext->border_color);
4562 if ((wand->filter_off != MagickFalse) ||
4563 (IsPixelInfoEquivalent(current_border,&new_border) == MagickFalse))
4564 {
4565 CurrentContext->border_color=new_border;
4566 (void) MVGPrintf(wand,"border-color '");
4567 MVGAppendColor(wand,&border_color);
4568 (void) MVGPrintf(wand,"'\n");
4569 }
4570}
4571
4572/*
4573%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4574% %
4575% %
4576% %
4577% D r a w S e t C l i p P a t h %
4578% %
4579% %
4580% %
4581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4582%
4583% DrawSetClipPath() associates a named clipping path with the image. Only
4584% the areas drawn on by the clipping path will be modified as ssize_t as it
4585% remains in effect.
4586%
4587% The format of the DrawSetClipPath method is:
4588%
4589% MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4590% const char *clip_mask)
4591%
4592% A description of each parameter follows:
4593%
4594% o wand: the drawing wand.
4595%
4596% o clip_mask: name of clipping path to associate with image
4597%
4598*/
4599WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4600 const char *clip_mask)
4601{
4602 assert(wand != (DrawingWand *) NULL);
4603 if (wand->debug != MagickFalse)
4604 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4605 assert(wand->signature == MagickWandSignature);
4606 assert(clip_mask != (const char *) NULL);
4607 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4608 (wand->filter_off != MagickFalse) ||
4609 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4610 {
4611 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4612#if DRAW_BINARY_IMPLEMENTATION
4613 if (wand->image == (Image *) NULL)
4614 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4615 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask,
4616 wand->exception);
4617#endif
4618 (void) MVGPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4619 }
4620 return(MagickTrue);
4621}
4622
4623/*
4624%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4625% %
4626% %
4627% %
4628% D r a w S e t C l i p R u l e %
4629% %
4630% %
4631% %
4632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4633%
4634% DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4635%
4636% The format of the DrawSetClipRule method is:
4637%
4638% void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4639%
4640% A description of each parameter follows:
4641%
4642% o wand: the drawing wand.
4643%
4644% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4645%
4646*/
4647WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4648{
4649 assert(wand != (DrawingWand *) NULL);
4650 assert(wand->signature == MagickWandSignature);
4651 if (wand->debug != MagickFalse)
4652 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4653 if ((wand->filter_off != MagickFalse) ||
4654 (CurrentContext->fill_rule != fill_rule))
4655 {
4656 CurrentContext->fill_rule=fill_rule;
4657 (void) MVGPrintf(wand, "clip-rule '%s'\n",CommandOptionToMnemonic(
4658 MagickFillRuleOptions,(ssize_t) fill_rule));
4659 }
4660}
4661
4662/*
4663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4664% %
4665% %
4666% %
4667% D r a w S e t C l i p U n i t s %
4668% %
4669% %
4670% %
4671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4672%
4673% DrawSetClipUnits() sets the interpretation of clip path units.
4674%
4675% The format of the DrawSetClipUnits method is:
4676%
4677% void DrawSetClipUnits(DrawingWand *wand,
4678% const ClipPathUnits clip_units)
4679%
4680% A description of each parameter follows:
4681%
4682% o wand: the drawing wand.
4683%
4684% o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4685% ObjectBoundingBox)
4686%
4687*/
4688WandExport void DrawSetClipUnits(DrawingWand *wand,
4689 const ClipPathUnits clip_units)
4690{
4691 assert(wand != (DrawingWand *) NULL);
4692 assert(wand->signature == MagickWandSignature);
4693 if (wand->debug != MagickFalse)
4694 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4695 if ((wand->filter_off != MagickFalse) ||
4696 (CurrentContext->clip_units != clip_units))
4697 {
4698 CurrentContext->clip_units=clip_units;
4699 if (clip_units == ObjectBoundingBox)
4700 {
4701 AffineMatrix
4702 affine;
4703
4704 GetAffineMatrix(&affine);
4705 affine.sx=CurrentContext->bounds.x2;
4706 affine.sy=CurrentContext->bounds.y2;
4707 affine.tx=CurrentContext->bounds.x1;
4708 affine.ty=CurrentContext->bounds.y1;
4709 AdjustAffine(wand,&affine);
4710 }
4711 (void) MVGPrintf(wand, "clip-units '%s'\n",CommandOptionToMnemonic(
4712 MagickClipPathOptions,(ssize_t) clip_units));
4713 }
4714}
4715
4716/*
4717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4718% %
4719% %
4720% %
4721% D r a w S e t D e n s i t y %
4722% %
4723% %
4724% %
4725%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4726%
4727% DrawSetDensity() sets the vertical and horizontal resolution.
4728%
4729% The format of the DrawSetDensity method is:
4730%
4731% MagickBooleanType DrawSetDensity(DrawingWand *wand,
4732% const char *density)
4733%
4734% A description of each parameter follows:
4735%
4736% o wand: the drawing wand.
4737%
4738% o density: the vertical and horizontal resolution.
4739%
4740*/
4741WandExport MagickBooleanType DrawSetDensity(DrawingWand *wand,
4742 const char *density)
4743{
4744 assert(wand != (DrawingWand *) NULL);
4745 if (wand->debug != MagickFalse)
4746 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",density);
4747 assert(wand->signature == MagickWandSignature);
4748 assert(density != (const char *) NULL);
4749 if ((CurrentContext->density == (const char *) NULL) ||
4750 (wand->filter_off != MagickFalse) ||
4751 (LocaleCompare(CurrentContext->density,density) != 0))
4752 {
4753 (void) CloneString(&CurrentContext->density,density);
4754 (void) MVGPrintf(wand,"density '%s'\n",density);
4755 }
4756 return(MagickTrue);
4757}
4758
4759/*
4760%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4761% %
4762% %
4763% %
4764% D r a w S e t F i l l C o l o r %
4765% %
4766% %
4767% %
4768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4769%
4770% DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4771%
4772% The format of the DrawSetFillColor method is:
4773%
4774% void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4775%
4776% A description of each parameter follows:
4777%
4778% o wand: the drawing wand.
4779%
4780% o fill_wand: fill wand.
4781%
4782*/
4783WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4784{
4785 PixelInfo
4786 *current_fill,
4787 fill_color,
4788 new_fill;
4789
4790 assert(wand != (DrawingWand *) NULL);
4791 assert(wand->signature == MagickWandSignature);
4792 if (wand->debug != MagickFalse)
4793 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4794 assert(fill_wand != (const PixelWand *) NULL);
4795 PixelGetQuantumPacket(fill_wand,&fill_color);
4796 new_fill=fill_color;
4797 current_fill=(&CurrentContext->fill);
4798 if ((wand->filter_off != MagickFalse) ||
4799 (IsPixelInfoEquivalent(current_fill,&new_fill) == MagickFalse))
4800 {
4801 CurrentContext->fill=new_fill;
4802 (void) MVGPrintf(wand,"fill '");
4803 MVGAppendColor(wand,&fill_color);
4804 (void) MVGPrintf(wand,"'\n");
4805 }
4806}
4807
4808/*
4809%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4810% %
4811% %
4812% %
4813% D r a w S e t F i l l O p a c i t y %
4814% %
4815% %
4816% %
4817%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4818%
4819% DrawSetFillOpacity() sets the alpha to use when drawing using the fill
4820% color or fill texture. Fully opaque is 1.0.
4821%
4822% The format of the DrawSetFillOpacity method is:
4823%
4824% void DrawSetFillOpacity(DrawingWand *wand,const double fill_alpha)
4825%
4826% A description of each parameter follows:
4827%
4828% o wand: the drawing wand.
4829%
4830% o fill_opacity: fill opacity
4831%
4832*/
4833WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4834{
4835 double
4836 alpha;
4837
4838 assert(wand != (DrawingWand *) NULL);
4839 assert(wand->signature == MagickWandSignature);
4840 if (wand->debug != MagickFalse)
4841 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4842 alpha=(double) ClampToQuantum((double) QuantumRange*fill_opacity);
4843 if ((wand->filter_off != MagickFalse) ||
4844 (CurrentContext->fill.alpha != alpha))
4845 {
4846 CurrentContext->fill.alpha=alpha;
4847 (void) MVGPrintf(wand,"fill-opacity %.20g\n",fill_opacity);
4848 }
4849}
4850
4851/*
4852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4853% %
4854% %
4855% %
4856% D r a w S e t F o n t R e s o l u t i o n %
4857% %
4858% %
4859% %
4860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4861%
4862% DrawSetFontResolution() sets the image resolution.
4863%
4864% The format of the DrawSetFontResolution method is:
4865%
4866% MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
4867% const double x_resolution,const double y_resolution)
4868%
4869% A description of each parameter follows:
4870%
4871% o wand: the magick wand.
4872%
4873% o x_resolution: the image x resolution.
4874%
4875% o y_resolution: the image y resolution.
4876%
4877*/
4878WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
4879 const double x_resolution,const double y_resolution)
4880{
4881 char
4882 density[MagickPathExtent];
4883
4884 assert(wand != (DrawingWand *) NULL);
4885 assert(wand->signature == MagickWandSignature);
4886 if (wand->debug != MagickFalse)
4887 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4888 (void) FormatLocaleString(density,MagickPathExtent,"%.20gx%.20g",x_resolution,
4889 y_resolution);
4890 (void) CloneString(&CurrentContext->density,density);
4891 return(MagickTrue);
4892}
4893
4894/*
4895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4896% %
4897% %
4898% %
4899% D r a w S e t O p a c i t y %
4900% %
4901% %
4902% %
4903%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4904%
4905% DrawSetOpacity() sets the alpha to use when drawing using the fill or
4906% stroke color or texture. Fully opaque is 1.0.
4907%
4908% The format of the DrawSetOpacity method is:
4909%
4910% void DrawSetOpacity(DrawingWand *wand,const double alpha)
4911%
4912% A description of each parameter follows:
4913%
4914% o wand: the drawing wand.
4915%
4916% o opacity: fill and stroke opacity. The value 1.0 is opaque.
4917%
4918*/
4919WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4920{
4921 Quantum
4922 quantum_alpha;
4923
4924 assert(wand != (DrawingWand *) NULL);
4925 assert(wand->signature == MagickWandSignature);
4926 if (wand->debug != MagickFalse)
4927 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4928 quantum_alpha=ClampToQuantum((double) QuantumRange*opacity);
4929 if ((wand->filter_off != MagickFalse) ||
4930 (CurrentContext->alpha != quantum_alpha))
4931 {
4932 CurrentContext->alpha=quantum_alpha;
4933 (void) MVGPrintf(wand,"opacity %.20g\n",opacity);
4934 }
4935}
4936
4937/*
4938%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4939% %
4940% %
4941% %
4942% D r a w S e t F i l l P a t t e r n U R L %
4943% %
4944% %
4945% %
4946%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4947%
4948% DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4949% objects. Only local URLs ("#identifier") are supported at this time. These
4950% local URLs are normally created by defining a named fill pattern with
4951% DrawPushPattern/DrawPopPattern.
4952%
4953% The format of the DrawSetFillPatternURL method is:
4954%
4955% MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4956% const char *fill_url)
4957%
4958% A description of each parameter follows:
4959%
4960% o wand: the drawing wand.
4961%
4962% o fill_url: URL to use to obtain fill pattern.
4963%
4964*/
4965WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4966 const char *fill_url)
4967{
4968 char
4969 pattern[MagickPathExtent],
4970 pattern_spec[MagickPathExtent];
4971
4972 assert(wand != (DrawingWand *) NULL);
4973 assert(wand->signature == MagickWandSignature);
4974 if (wand->debug != MagickFalse)
4975 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4976 if (wand->image == (Image *) NULL)
4977 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4978 assert(fill_url != (const char *) NULL);
4979 if (*fill_url != '#')
4980 {
4981 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4982 return(MagickFalse);
4983 }
4984 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",fill_url+1);
4985 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4986 {
4987 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4988 return(MagickFalse);
4989 }
4990 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",fill_url);
4991#if DRAW_BINARY_IMPLEMENTATION
4992 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4993 &CurrentContext->fill_pattern,wand->exception);
4994#endif
4995 if (CurrentContext->fill.alpha != (double) TransparentAlpha)
4996 CurrentContext->fill.alpha=(double) CurrentContext->alpha;
4997 (void) MVGPrintf(wand,"fill %s\n",pattern_spec);
4998 return(MagickTrue);
4999}
5000
5001/*
5002%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5003% %
5004% %
5005% %
5006% D r a w S e t F i l l R u l e %
5007% %
5008% %
5009% %
5010%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5011%
5012% DrawSetFillRule() sets the fill rule to use while drawing polygons.
5013%
5014% The format of the DrawSetFillRule method is:
5015%
5016% void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
5017%
5018% A description of each parameter follows:
5019%
5020% o wand: the drawing wand.
5021%
5022% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
5023%
5024*/
5025WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
5026{
5027 assert(wand != (DrawingWand *) NULL);
5028 assert(wand->signature == MagickWandSignature);
5029 if (wand->debug != MagickFalse)
5030 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5031 if ((wand->filter_off != MagickFalse) ||
5032 (CurrentContext->fill_rule != fill_rule))
5033 {
5034 CurrentContext->fill_rule=fill_rule;
5035 (void) MVGPrintf(wand, "fill-rule '%s'\n",CommandOptionToMnemonic(
5036 MagickFillRuleOptions,(ssize_t) fill_rule));
5037 }
5038}
5039
5040/*
5041%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5042% %
5043% %
5044% %
5045% D r a w S e t F o n t %
5046% %
5047% %
5048% %
5049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5050%
5051% DrawSetFont() sets the fully-specified font to use when annotating with
5052% text.
5053%
5054% The format of the DrawSetFont method is:
5055%
5056% MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
5057%
5058% A description of each parameter follows:
5059%
5060% o wand: the drawing wand.
5061%
5062% o font_name: font name
5063%
5064*/
5065WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
5066 const char *font_name)
5067{
5068 assert(wand != (DrawingWand *) NULL);
5069 assert(wand->signature == MagickWandSignature);
5070 if (wand->debug != MagickFalse)
5071 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5072 assert(font_name != (const char *) NULL);
5073 if ((wand->filter_off != MagickFalse) ||
5074 (CurrentContext->font == (char *) NULL) ||
5075 (LocaleCompare(CurrentContext->font,font_name) != 0))
5076 {
5077 (void) CloneString(&CurrentContext->font,font_name);
5078 (void) MVGPrintf(wand,"font '%s'\n",font_name);
5079 }
5080 return(MagickTrue);
5081}
5082
5083/*
5084%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5085% %
5086% %
5087% %
5088% D r a w S e t F o n t F a m i l y %
5089% %
5090% %
5091% %
5092%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5093%
5094% DrawSetFontFamily() sets the font family to use when annotating with text.
5095%
5096% The format of the DrawSetFontFamily method is:
5097%
5098% MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5099% const char *font_family)
5100%
5101% A description of each parameter follows:
5102%
5103% o wand: the drawing wand.
5104%
5105% o font_family: font family
5106%
5107*/
5108WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5109 const char *font_family)
5110{
5111 assert(wand != (DrawingWand *) NULL);
5112 assert(wand->signature == MagickWandSignature);
5113 if (wand->debug != MagickFalse)
5114 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5115 assert(font_family != (const char *) NULL);
5116 if ((wand->filter_off != MagickFalse) ||
5117 (CurrentContext->family == (const char *) NULL) ||
5118 (LocaleCompare(CurrentContext->family,font_family) != 0))
5119 {
5120 (void) CloneString(&CurrentContext->family,font_family);
5121 (void) MVGPrintf(wand,"font-family '%s'\n",font_family);
5122 }
5123 return(MagickTrue);
5124}
5125
5126/*
5127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5128% %
5129% %
5130% %
5131% D r a w S e t F o n t S i z e %
5132% %
5133% %
5134% %
5135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5136%
5137% DrawSetFontSize() sets the font pointsize to use when annotating with text.
5138%
5139% The format of the DrawSetFontSize method is:
5140%
5141% void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5142%
5143% A description of each parameter follows:
5144%
5145% o wand: the drawing wand.
5146%
5147% o pointsize: text pointsize
5148%
5149*/
5150WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5151{
5152 assert(wand != (DrawingWand *) NULL);
5153 assert(wand->signature == MagickWandSignature);
5154 if (wand->debug != MagickFalse)
5155 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5156 if ((wand->filter_off != MagickFalse) ||
5157 (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon))
5158 {
5159 CurrentContext->pointsize=pointsize;
5160 (void) MVGPrintf(wand,"font-size %.20g\n",pointsize);
5161 }
5162}
5163
5164/*
5165%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5166% %
5167% %
5168% %
5169% D r a w S e t F o n t S t r e t c h %
5170% %
5171% %
5172% %
5173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5174%
5175% DrawSetFontStretch() sets the font stretch to use when annotating with text.
5176% The AnyStretch enumeration acts as a wild-card "don't care" option.
5177%
5178% The format of the DrawSetFontStretch method is:
5179%
5180% void DrawSetFontStretch(DrawingWand *wand,
5181% const StretchType font_stretch)
5182%
5183% A description of each parameter follows:
5184%
5185% o wand: the drawing wand.
5186%
5187% o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5188% CondensedStretch, SemiCondensedStretch,
5189% SemiExpandedStretch, ExpandedStretch,
5190% ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5191%
5192*/
5193WandExport void DrawSetFontStretch(DrawingWand *wand,
5194 const StretchType font_stretch)
5195{
5196 assert(wand != (DrawingWand *) NULL);
5197 assert(wand->signature == MagickWandSignature);
5198 if (wand->debug != MagickFalse)
5199 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5200 if ((wand->filter_off != MagickFalse) ||
5201 (CurrentContext->stretch != font_stretch))
5202 {
5203 CurrentContext->stretch=font_stretch;
5204 (void) MVGPrintf(wand, "font-stretch '%s'\n",CommandOptionToMnemonic(
5205 MagickStretchOptions,(ssize_t) font_stretch));
5206 }
5207}
5208
5209/*
5210%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5211% %
5212% %
5213% %
5214% D r a w S e t F o n t S t y l e %
5215% %
5216% %
5217% %
5218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5219%
5220% DrawSetFontStyle() sets the font style to use when annotating with text.
5221% The AnyStyle enumeration acts as a wild-card "don't care" option.
5222%
5223% The format of the DrawSetFontStyle method is:
5224%
5225% void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5226%
5227% A description of each parameter follows:
5228%
5229% o wand: the drawing wand.
5230%
5231% o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5232%
5233*/
5234WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5235{
5236 assert(wand != (DrawingWand *) NULL);
5237 assert(wand->signature == MagickWandSignature);
5238 if (wand->debug != MagickFalse)
5239 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5240 if ((wand->filter_off != MagickFalse) ||
5241 (CurrentContext->style != style))
5242 {
5243 CurrentContext->style=style;
5244 (void) MVGPrintf(wand, "font-style '%s'\n",CommandOptionToMnemonic(
5245 MagickStyleOptions,(ssize_t) style));
5246 }
5247}
5248
5249/*
5250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5251% %
5252% %
5253% %
5254% D r a w S e t F o n t W e i g h t %
5255% %
5256% %
5257% %
5258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5259%
5260% DrawSetFontWeight() sets the font weight to use when annotating with text.
5261%
5262% The format of the DrawSetFontWeight method is:
5263%
5264% void DrawSetFontWeight(DrawingWand *wand,
5265% const size_t font_weight)
5266%
5267% A description of each parameter follows:
5268%
5269% o wand: the drawing wand.
5270%
5271% o font_weight: font weight (valid range 100-900)
5272%
5273*/
5274WandExport void DrawSetFontWeight(DrawingWand *wand,
5275 const size_t font_weight)
5276{
5277 assert(wand != (DrawingWand *) NULL);
5278 assert(wand->signature == MagickWandSignature);
5279 if (wand->debug != MagickFalse)
5280 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5281 if ((wand->filter_off != MagickFalse) ||
5282 (CurrentContext->weight != font_weight))
5283 {
5284 CurrentContext->weight=font_weight;
5285 (void) MVGPrintf(wand,"font-weight %.20g\n",(double) font_weight);
5286 }
5287}
5288
5289/*
5290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5291% %
5292% %
5293% %
5294% D r a w S e t G r a v i t y %
5295% %
5296% %
5297% %
5298%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5299%
5300% DrawSetGravity() sets the text placement gravity to use when annotating
5301% with text.
5302%
5303% The format of the DrawSetGravity method is:
5304%
5305% void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5306%
5307% A description of each parameter follows:
5308%
5309% o wand: the drawing wand.
5310%
5311% o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5312% NorthEastGravity, WestGravity, CenterGravity,
5313% EastGravity, SouthWestGravity, SouthGravity,
5314% SouthEastGravity)
5315%
5316*/
5317WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5318{
5319 assert(wand != (DrawingWand *) NULL);
5320 assert(wand->signature == MagickWandSignature);
5321 if (wand->debug != MagickFalse)
5322 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5323 if ((wand->filter_off != MagickFalse) ||
5324 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5325 {
5326 CurrentContext->gravity=gravity;
5327 (void) MVGPrintf(wand,"gravity '%s'\n",CommandOptionToMnemonic(
5328 MagickGravityOptions,(ssize_t) gravity));
5329 }
5330}
5331
5332/*
5333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5334% %
5335% %
5336% %
5337% D r a w S e t S t r o k e C o l o r %
5338% %
5339% %
5340% %
5341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5342%
5343% DrawSetStrokeColor() sets the color used for stroking object outlines.
5344%
5345% The format of the DrawSetStrokeColor method is:
5346%
5347% void DrawSetStrokeColor(DrawingWand *wand,
5348% const PixelWand *stroke_wand)
5349%
5350% A description of each parameter follows:
5351%
5352% o wand: the drawing wand.
5353%
5354% o stroke_wand: stroke wand.
5355%
5356*/
5357WandExport void DrawSetStrokeColor(DrawingWand *wand,
5358 const PixelWand *stroke_wand)
5359{
5360 PixelInfo
5361 *current_stroke,
5362 new_stroke,
5363 stroke_color;
5364
5365 assert(wand != (DrawingWand *) NULL);
5366 assert(wand->signature == MagickWandSignature);
5367 if (wand->debug != MagickFalse)
5368 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5369 assert(stroke_wand != (const PixelWand *) NULL);
5370 PixelGetQuantumPacket(stroke_wand,&stroke_color);
5371 new_stroke=stroke_color;
5372 current_stroke=(&CurrentContext->stroke);
5373 if ((wand->filter_off != MagickFalse) ||
5374 (IsPixelInfoEquivalent(current_stroke,&new_stroke) == MagickFalse))
5375 {
5376 CurrentContext->stroke=new_stroke;
5377 (void) MVGPrintf(wand,"stroke '");
5378 MVGAppendColor(wand,&stroke_color);
5379 (void) MVGPrintf(wand,"'\n");
5380 }
5381}
5382
5383/*
5384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5385% %
5386% %
5387% %
5388% D r a w S e t S t r o k e P a t t e r n U R L %
5389% %
5390% %
5391% %
5392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5393%
5394% DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5395%
5396% The format of the DrawSetStrokePatternURL method is:
5397%
5398% MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5399% const char *stroke_url)
5400%
5401% A description of each parameter follows:
5402%
5403% o wand: the drawing wand.
5404%
5405% o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5406%
5407*/
5408WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5409 const char *stroke_url)
5410{
5411 char
5412 pattern[MagickPathExtent],
5413 pattern_spec[MagickPathExtent];
5414
5415 assert(wand != (DrawingWand *) NULL);
5416 assert(wand->signature == MagickWandSignature);
5417 if (wand->debug != MagickFalse)
5418 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5419 if (wand->image == (Image *) NULL)
5420 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5421 assert(stroke_url != NULL);
5422 if (stroke_url[0] != '#')
5423 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5424 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",stroke_url+1);
5425 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5426 {
5427 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5428 return(MagickFalse);
5429 }
5430 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",stroke_url);
5431#if DRAW_BINARY_IMPLEMENTATION
5432 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5433 &CurrentContext->stroke_pattern,wand->exception);
5434#endif
5435 if (CurrentContext->stroke.alpha != (double) TransparentAlpha)
5436 CurrentContext->stroke.alpha=(double) CurrentContext->alpha;
5437 (void) MVGPrintf(wand,"stroke %s\n",pattern_spec);
5438 return(MagickTrue);
5439}
5440
5441/*
5442%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5443% %
5444% %
5445% %
5446% D r a w S e t S t r o k e A n t i a l i a s %
5447% %
5448% %
5449% %
5450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5451%
5452% DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5453% Stroked outlines are antialiased by default. When antialiasing is disabled
5454% stroked pixels are thresholded to determine if the stroke color or
5455% underlying canvas color should be used.
5456%
5457% The format of the DrawSetStrokeAntialias method is:
5458%
5459% void DrawSetStrokeAntialias(DrawingWand *wand,
5460% const MagickBooleanType stroke_antialias)
5461%
5462% A description of each parameter follows:
5463%
5464% o wand: the drawing wand.
5465%
5466% o stroke_antialias: set to false (zero) to disable antialiasing
5467%
5468*/
5469WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5470 const MagickBooleanType stroke_antialias)
5471{
5472 assert(wand != (DrawingWand *) NULL);
5473 assert(wand->signature == MagickWandSignature);
5474 if (wand->debug != MagickFalse)
5475 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5476 if ((wand->filter_off != MagickFalse) ||
5477 (CurrentContext->stroke_antialias != stroke_antialias))
5478 {
5479 CurrentContext->stroke_antialias=stroke_antialias;
5480 (void) MVGPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5481 1 : 0);
5482 }
5483}
5484
5485/*
5486%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5487% %
5488% %
5489% %
5490% D r a w S e t S t r o k e D a s h A r r a y %
5491% %
5492% %
5493% %
5494%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5495%
5496% DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5497% stroke paths. The stroke dash array represents an array of numbers that
5498% specify the lengths of alternating dashes and gaps in pixels. If an odd
5499% number of values is provided, then the list of values is repeated to yield
5500% an even number of values. To remove an existing dash array, pass a zero
5501% number_elements argument and null dasharray. A typical stroke dash array
5502% might contain the members 5 3 2.
5503%
5504% The format of the DrawSetStrokeDashArray method is:
5505%
5506% MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5507% const size_t number_elements,const double *dasharray)
5508%
5509% A description of each parameter follows:
5510%
5511% o wand: the drawing wand.
5512%
5513% o number_elements: number of elements in dash array
5514%
5515% o dasharray: dash array values
5516%
5517*/
5518WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5519 const size_t number_elements,const double *dasharray)
5520{
5521 MagickBooleanType
5522 update;
5523
5524 const double
5525 *p;
5526
5527 double
5528 *q;
5529
5530 ssize_t
5531 i;
5532
5533 size_t
5534 n_new,
5535 n_old;
5536
5537 assert(wand != (DrawingWand *) NULL);
5538 assert(wand->signature == MagickWandSignature);
5539 if (wand->debug != MagickFalse)
5540 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5541 n_new=number_elements;
5542 if (dasharray == (const double *) NULL)
5543 n_new=0;
5544 n_old=0;
5545 update=MagickFalse;
5546 q=CurrentContext->dash_pattern;
5547 if (q != (const double *) NULL)
5548 while (fabs(*q++) < MagickEpsilon)
5549 n_old++;
5550 if ((n_old == 0) && (n_new == 0))
5551 update=MagickFalse;
5552 else
5553 if (n_old != n_new)
5554 update=MagickTrue;
5555 else
5556 if ((CurrentContext->dash_pattern != (double *) NULL) &&
5557 (dasharray != (double *) NULL))
5558 {
5559 p=dasharray;
5560 q=CurrentContext->dash_pattern;
5561 for (i=0; i < (ssize_t) n_new; i++)
5562 {
5563 if (fabs((*p)-(*q)) >= MagickEpsilon)
5564 {
5565 update=MagickTrue;
5566 break;
5567 }
5568 p++;
5569 q++;
5570 }
5571 }
5572 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5573 {
5574 if (CurrentContext->dash_pattern != (double *) NULL)
5575 CurrentContext->dash_pattern=(double *)
5576 RelinquishMagickMemory(CurrentContext->dash_pattern);
5577 if (n_new != 0)
5578 {
5579 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5580 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5581 if (CurrentContext->dash_pattern == (double *) NULL)
5582 {
5583 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5584 wand->name);
5585 return(MagickFalse);
5586 }
5587 for (i=0; i < (ssize_t) n_new; i++)
5588 {
5589 CurrentContext->dash_pattern[i]=0.0;
5590 if (dasharray != (double *) NULL)
5591 CurrentContext->dash_pattern[i]=dasharray[i];
5592 }
5593 CurrentContext->dash_pattern[n_new]=0.0;
5594 }
5595 (void) MVGPrintf(wand,"stroke-dasharray ");
5596 if (n_new == 0)
5597 (void) MVGPrintf(wand,"none\n");
5598 else
5599 if (dasharray != (double *) NULL)
5600 {
5601 for (i=0; i < (ssize_t) n_new; i++)
5602 {
5603 if (i != 0)
5604 (void) MVGPrintf(wand,",");
5605 (void) MVGPrintf(wand,"%.20g",dasharray[i]);
5606 }
5607 (void) MVGPrintf(wand,"\n");
5608 }
5609 }
5610 return(MagickTrue);
5611}
5612
5613/*
5614%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5615% %
5616% %
5617% %
5618% D r a w S e t S t r o k e D a s h O f f s e t %
5619% %
5620% %
5621% %
5622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5623%
5624% DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5625% start the dash.
5626%
5627% The format of the DrawSetStrokeDashOffset method is:
5628%
5629% void DrawSetStrokeDashOffset(DrawingWand *wand,
5630% const double dash_offset)
5631%
5632% A description of each parameter follows:
5633%
5634% o wand: the drawing wand.
5635%
5636% o dash_offset: dash offset
5637%
5638*/
5639WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5640 const double dash_offset)
5641{
5642 assert(wand != (DrawingWand *) NULL);
5643 assert(wand->signature == MagickWandSignature);
5644 if (wand->debug != MagickFalse)
5645 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5646 if ((wand->filter_off != MagickFalse) ||
5647 (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon))
5648 {
5649 CurrentContext->dash_offset=dash_offset;
5650 (void) MVGPrintf(wand,"stroke-dashoffset %.20g\n",dash_offset);
5651 }
5652}
5653
5654/*
5655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5656% %
5657% %
5658% %
5659% D r a w S e t S t r o k e L i n e C a p %
5660% %
5661% %
5662% %
5663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5664%
5665% DrawSetStrokeLineCap() specifies the shape to be used at the end of
5666% open subpaths when they are stroked. Values of LineCap are
5667% UndefinedCap, ButtCap, RoundCap, and SquareCap.
5668%
5669% The format of the DrawSetStrokeLineCap method is:
5670%
5671% void DrawSetStrokeLineCap(DrawingWand *wand,
5672% const LineCap linecap)
5673%
5674% A description of each parameter follows:
5675%
5676% o wand: the drawing wand.
5677%
5678% o linecap: linecap style
5679%
5680*/
5681WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5682{
5683 assert(wand != (DrawingWand *) NULL);
5684 assert(wand->signature == MagickWandSignature);
5685 if (wand->debug != MagickFalse)
5686 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5687 if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap))
5688 {
5689 CurrentContext->linecap=linecap;
5690 (void) MVGPrintf(wand,"stroke-linecap '%s'\n",CommandOptionToMnemonic(
5691 MagickLineCapOptions,(ssize_t) linecap));
5692 }
5693}
5694
5695/*
5696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5697% %
5698% %
5699% %
5700% D r a w S e t S t r o k e L i n e J o i n %
5701% %
5702% %
5703% %
5704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5705%
5706% DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5707% paths (or other vector shapes) when they are stroked. Values of LineJoin are
5708% UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5709%
5710% The format of the DrawSetStrokeLineJoin method is:
5711%
5712% void DrawSetStrokeLineJoin(DrawingWand *wand,
5713% const LineJoin linejoin)
5714%
5715% A description of each parameter follows:
5716%
5717% o wand: the drawing wand.
5718%
5719% o linejoin: line join style
5720%
5721*/
5722WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5723{
5724 assert(wand != (DrawingWand *) NULL);
5725 assert(wand->signature == MagickWandSignature);
5726 if (wand->debug != MagickFalse)
5727 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5728 if ((wand->filter_off != MagickFalse) ||
5729 (CurrentContext->linejoin != linejoin))
5730 {
5731 CurrentContext->linejoin=linejoin;
5732 (void) MVGPrintf(wand, "stroke-linejoin '%s'\n",CommandOptionToMnemonic(
5733 MagickLineJoinOptions,(ssize_t) linejoin));
5734 }
5735}
5736
5737/*
5738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5739% %
5740% %
5741% %
5742% D r a w S e t S t r o k e M i t e r L i m i t %
5743% %
5744% %
5745% %
5746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5747%
5748% DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5749% segments meet at a sharp angle and miter joins have been specified for
5750% 'lineJoin', it is possible for the miter to extend far beyond the
5751% thickness of the line stroking the path. The miterLimit' imposes a
5752% limit on the ratio of the miter length to the 'lineWidth'.
5753%
5754% The format of the DrawSetStrokeMiterLimit method is:
5755%
5756% void DrawSetStrokeMiterLimit(DrawingWand *wand,
5757% const size_t miterlimit)
5758%
5759% A description of each parameter follows:
5760%
5761% o wand: the drawing wand.
5762%
5763% o miterlimit: miter limit
5764%
5765*/
5766WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
5767 const size_t miterlimit)
5768{
5769 assert(wand != (DrawingWand *) NULL);
5770 assert(wand->signature == MagickWandSignature);
5771 if (wand->debug != MagickFalse)
5772 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5773 if (CurrentContext->miterlimit != miterlimit)
5774 {
5775 CurrentContext->miterlimit=miterlimit;
5776 (void) MVGPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit);
5777 }
5778}
5779
5780/*
5781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5782% %
5783% %
5784% %
5785% D r a w S e t S t r o k e O p a c i t y %
5786% %
5787% %
5788% %
5789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5790%
5791% DrawSetStrokeOpacity() specifies the alpha of stroked object outlines.
5792%
5793% The format of the DrawSetStrokeOpacity method is:
5794%
5795% void DrawSetStrokeOpacity(DrawingWand *wand,
5796% const double stroke_alpha)
5797%
5798% A description of each parameter follows:
5799%
5800% o wand: the drawing wand.
5801%
5802% o opacity: stroke opacity. The value 1.0 is opaque.
5803%
5804*/
5805WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5806 const double opacity)
5807{
5808 double
5809 alpha;
5810
5811 assert(wand != (DrawingWand *) NULL);
5812 assert(wand->signature == MagickWandSignature);
5813 if (wand->debug != MagickFalse)
5814 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5815 alpha=(double) ClampToQuantum((double) QuantumRange*opacity);
5816 if ((wand->filter_off != MagickFalse) ||
5817 (CurrentContext->stroke.alpha != alpha))
5818 {
5819 CurrentContext->stroke.alpha=alpha;
5820 (void) MVGPrintf(wand,"stroke-opacity %.20g\n",opacity);
5821 }
5822}
5823
5824/*
5825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5826% %
5827% %
5828% %
5829% D r a w S e t S t r o k e W i d t h %
5830% %
5831% %
5832% %
5833%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5834%
5835% DrawSetStrokeWidth() sets the width of the stroke used to draw object
5836% outlines.
5837%
5838% The format of the DrawSetStrokeWidth method is:
5839%
5840% void DrawSetStrokeWidth(DrawingWand *wand,
5841% const double stroke_width)
5842%
5843% A description of each parameter follows:
5844%
5845% o wand: the drawing wand.
5846%
5847% o stroke_width: stroke width
5848%
5849*/
5850WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5851{
5852 assert(wand != (DrawingWand *) NULL);
5853 assert(wand->signature == MagickWandSignature);
5854 if (wand->debug != MagickFalse)
5855 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5856 if ((wand->filter_off != MagickFalse) ||
5857 (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon))
5858 {
5859 CurrentContext->stroke_width=stroke_width;
5860 (void) MVGPrintf(wand,"stroke-width %.20g\n",stroke_width);
5861 }
5862}
5863
5864/*
5865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5866% %
5867% %
5868% %
5869% D r a w S e t T e x t A l i g n m e n t %
5870% %
5871% %
5872% %
5873%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5874%
5875% DrawSetTextAlignment() specifies a text alignment to be applied when
5876% annotating with text.
5877%
5878% The format of the DrawSetTextAlignment method is:
5879%
5880% void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5881%
5882% A description of each parameter follows:
5883%
5884% o wand: the drawing wand.
5885%
5886% o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5887% CenterAlign, or RightAlign.
5888%
5889*/
5890WandExport void DrawSetTextAlignment(DrawingWand *wand,
5891 const AlignType alignment)
5892{
5893 assert(wand != (DrawingWand *) NULL);
5894 assert(wand->signature == MagickWandSignature);
5895 if (wand->debug != MagickFalse)
5896 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5897 if ((wand->filter_off != MagickFalse) ||
5898 (CurrentContext->align != alignment))
5899 {
5900 CurrentContext->align=alignment;
5901 (void) MVGPrintf(wand,"text-align '%s'\n",CommandOptionToMnemonic(
5902 MagickAlignOptions,(ssize_t) alignment));
5903 }
5904}
5905
5906/*
5907%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5908% %
5909% %
5910% %
5911% D r a w S e t T e x t A n t i a l i a s %
5912% %
5913% %
5914% %
5915%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5916%
5917% DrawSetTextAntialias() controls whether text is antialiased. Text is
5918% antialiased by default.
5919%
5920% The format of the DrawSetTextAntialias method is:
5921%
5922% void DrawSetTextAntialias(DrawingWand *wand,
5923% const MagickBooleanType text_antialias)
5924%
5925% A description of each parameter follows:
5926%
5927% o wand: the drawing wand.
5928%
5929% o text_antialias: antialias boolean. Set to false (0) to disable
5930% antialiasing.
5931%
5932*/
5933WandExport void DrawSetTextAntialias(DrawingWand *wand,
5934 const MagickBooleanType text_antialias)
5935{
5936 assert(wand != (DrawingWand *) NULL);
5937 assert(wand->signature == MagickWandSignature);
5938 if (wand->debug != MagickFalse)
5939 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5940 if ((wand->filter_off != MagickFalse) ||
5941 (CurrentContext->text_antialias != text_antialias))
5942 {
5943 CurrentContext->text_antialias=text_antialias;
5944 (void) MVGPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5945 }
5946}
5947
5948/*
5949%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5950% %
5951% %
5952% %
5953% D r a w S e t T e x t D e c o r a t i o n %
5954% %
5955% %
5956% %
5957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5958%
5959% DrawSetTextDecoration() specifies a decoration to be applied when
5960% annotating with text.
5961%
5962% The format of the DrawSetTextDecoration method is:
5963%
5964% void DrawSetTextDecoration(DrawingWand *wand,
5965% const DecorationType decoration)
5966%
5967% A description of each parameter follows:
5968%
5969% o wand: the drawing wand.
5970%
5971% o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5972% OverlineDecoration, or LineThroughDecoration
5973%
5974*/
5975WandExport void DrawSetTextDecoration(DrawingWand *wand,
5976 const DecorationType decoration)
5977{
5978 assert(wand != (DrawingWand *) NULL);
5979 assert(wand->signature == MagickWandSignature);
5980 if (wand->debug != MagickFalse)
5981 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5982 if ((wand->filter_off != MagickFalse) ||
5983 (CurrentContext->decorate != decoration))
5984 {
5985 CurrentContext->decorate=decoration;
5986 (void) MVGPrintf(wand,"decorate '%s'\n",CommandOptionToMnemonic(
5987 MagickDecorateOptions,(ssize_t) decoration));
5988 }
5989}
5990
5991/*
5992%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5993% %
5994% %
5995% %
5996% D r a w S e t T e x t D i r e c t i o n %
5997% %
5998% %
5999% %
6000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6001%
6002% DrawSetTextDirection() specifies the direction to be used when
6003% annotating with text.
6004%
6005% The format of the DrawSetTextDirection method is:
6006%
6007% void DrawSetTextDirection(DrawingWand *wand,
6008% const DirectionType direction)
6009%
6010% A description of each parameter follows:
6011%
6012% o wand: the drawing wand.
6013%
6014% o direction: text direction. One of RightToLeftDirection,
6015% LeftToRightDirection
6016%
6017*/
6018WandExport void DrawSetTextDirection(DrawingWand *wand,
6019 const DirectionType direction)
6020{
6021 assert(wand != (DrawingWand *) NULL);
6022 assert(wand->signature == MagickWandSignature);
6023
6024 if (wand->debug != MagickFalse)
6025 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6026 if ((wand->filter_off != MagickFalse) ||
6027 (CurrentContext->direction != direction))
6028 {
6029 CurrentContext->direction=direction;
6030 (void) MVGPrintf(wand,"direction '%s'\n",CommandOptionToMnemonic(
6031 MagickDirectionOptions,(ssize_t) direction));
6032 }
6033}
6034
6035/*
6036%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6037% %
6038% %
6039% %
6040% D r a w S e t T e x t E n c o d i n g %
6041% %
6042% %
6043% %
6044%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6045%
6046% DrawSetTextEncoding() specifies the code set to use for text
6047% annotations. The only character encoding which may be specified
6048% at this time is "UTF-8" for representing Unicode as a sequence of
6049% bytes. Specify an empty string to set text encoding to the system's
6050% default. Successful text annotation using Unicode may require fonts
6051% designed to support Unicode.
6052%
6053% The format of the DrawSetTextEncoding method is:
6054%
6055% void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
6056%
6057% A description of each parameter follows:
6058%
6059% o wand: the drawing wand.
6060%
6061% o encoding: character string specifying text encoding
6062%
6063*/
6064WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
6065{
6066 assert(wand != (DrawingWand *) NULL);
6067 assert(wand->signature == MagickWandSignature);
6068 if (wand->debug != MagickFalse)
6069 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6070 assert(encoding != (char *) NULL);
6071 if ((wand->filter_off != MagickFalse) ||
6072 (CurrentContext->encoding == (char *) NULL) ||
6073 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
6074 {
6075 (void) CloneString(&CurrentContext->encoding,encoding);
6076 (void) MVGPrintf(wand,"encoding '%s'\n",encoding);
6077 }
6078}
6079
6080/*
6081%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6082% %
6083% %
6084% %
6085% D r a w S e t T e x t K e r n i n g %
6086% %
6087% %
6088% %
6089%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6090%
6091% DrawSetTextKerning() sets the spacing between characters in text.
6092%
6093% The format of the DrawSetTextKerning method is:
6094%
6095% void DrawSetTextKerning(DrawingWand *wand,const double kerning)
6096%
6097% A description of each parameter follows:
6098%
6099% o wand: the drawing wand.
6100%
6101% o kerning: text kerning
6102%
6103*/
6104WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
6105{
6106 assert(wand != (DrawingWand *) NULL);
6107 assert(wand->signature == MagickWandSignature);
6108
6109 if (wand->debug != MagickFalse)
6110 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6111 if ((wand->filter_off != MagickFalse) &&
6112 (fabs((CurrentContext->kerning-kerning)) >= MagickEpsilon))
6113 {
6114 CurrentContext->kerning=kerning;
6115 (void) MVGPrintf(wand,"kerning %lf\n",kerning);
6116 }
6117}
6118
6119/*
6120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6121% %
6122% %
6123% %
6124% 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 %
6125% %
6126% %
6127% %
6128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6129%
6130% DrawSetTextInterlineSpacing() sets the spacing between line in text.
6131%
6132% The format of the DrawSetInterlineSpacing method is:
6133%
6134% void DrawSetTextInterlineSpacing(DrawingWand *wand,
6135% const double interline_spacing)
6136%
6137% A description of each parameter follows:
6138%
6139% o wand: the drawing wand.
6140%
6141% o interline_spacing: text line spacing
6142%
6143*/
6144WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
6145 const double interline_spacing)
6146{
6147 assert(wand != (DrawingWand *) NULL);
6148 assert(wand->signature == MagickWandSignature);
6149
6150 if (wand->debug != MagickFalse)
6151 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6152 if ((wand->filter_off != MagickFalse) ||
6153 (fabs((CurrentContext->interline_spacing-
6154 interline_spacing)) >= MagickEpsilon))
6155 {
6156 CurrentContext->interline_spacing=interline_spacing;
6157 (void) MVGPrintf(wand,"interline-spacing %lf\n",interline_spacing);
6158 }
6159}
6160
6161/*
6162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6163% %
6164% %
6165% %
6166% 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 %
6167% %
6168% %
6169% %
6170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6171%
6172% DrawSetTextInterwordSpacing() sets the spacing between words in text.
6173%
6174% The format of the DrawSetInterwordSpacing method is:
6175%
6176% void DrawSetTextInterwordSpacing(DrawingWand *wand,
6177% const double interword_spacing)
6178%
6179% A description of each parameter follows:
6180%
6181% o wand: the drawing wand.
6182%
6183% o interword_spacing: text word spacing
6184%
6185*/
6186WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
6187 const double interword_spacing)
6188{
6189 assert(wand != (DrawingWand *) NULL);
6190 assert(wand->signature == MagickWandSignature);
6191
6192 if (wand->debug != MagickFalse)
6193 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6194 if ((wand->filter_off != MagickFalse) ||
6195 (fabs((CurrentContext->interword_spacing-
6196 interword_spacing)) >= MagickEpsilon))
6197 {
6198 CurrentContext->interword_spacing=interword_spacing;
6199 (void) MVGPrintf(wand,"interword-spacing %lf\n",interword_spacing);
6200 }
6201}
6202
6203/*
6204%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6205% %
6206% %
6207% %
6208% D r a w S e t T e x t U n d e r C o l o r %
6209% %
6210% %
6211% %
6212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6213%
6214% DrawSetTextUnderColor() specifies the color of a background rectangle
6215% to place under text annotations.
6216%
6217% The format of the DrawSetTextUnderColor method is:
6218%
6219% void DrawSetTextUnderColor(DrawingWand *wand,
6220% const PixelWand *under_wand)
6221%
6222% A description of each parameter follows:
6223%
6224% o wand: the drawing wand.
6225%
6226% o under_wand: text under wand.
6227%
6228*/
6229WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6230 const PixelWand *under_wand)
6231{
6232 PixelInfo
6233 under_color;
6234
6235 assert(wand != (DrawingWand *) NULL);
6236 assert(wand->signature == MagickWandSignature);
6237 if (wand->debug != MagickFalse)
6238 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6239 assert(under_wand != (const PixelWand *) NULL);
6240 PixelGetQuantumPacket(under_wand,&under_color);
6241 if ((wand->filter_off != MagickFalse) ||
6242 (IsPixelInfoEquivalent(&CurrentContext->undercolor,&under_color) == MagickFalse))
6243 {
6244 CurrentContext->undercolor=under_color;
6245 (void) MVGPrintf(wand,"text-undercolor '");
6246 MVGAppendColor(wand,&under_color);
6247 (void) MVGPrintf(wand,"'\n");
6248 }
6249}
6250
6251/*
6252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6253% %
6254% %
6255% %
6256% D r a w S e t V e c t o r G r a p h i c s %
6257% %
6258% %
6259% %
6260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6261%
6262% DrawSetVectorGraphics() sets the vector graphics associated with the
6263% specified wand. Use this method with DrawGetVectorGraphics() as a method
6264% to persist the vector graphics state.
6265%
6266% The format of the DrawSetVectorGraphics method is:
6267%
6268% MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6269% const char *xml)
6270%
6271% A description of each parameter follows:
6272%
6273% o wand: the drawing wand.
6274%
6275% o xml: the drawing wand XML.
6276%
6277*/
6278
6279static inline MagickBooleanType IsPoint(const char *point)
6280{
6281 char
6282 *p;
6283
6284 long
6285 value;
6286
6287 value=strtol(point,&p,10);
6288 (void) value;
6289 return(p != point ? MagickTrue : MagickFalse);
6290}
6291
6292WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6293 const char *xml)
6294{
6295 const char
6296 *value;
6297
6298 XMLTreeInfo
6299 *child,
6300 *xml_info;
6301
6302 assert(wand != (DrawingWand *) NULL);
6303 assert(wand->signature == MagickWandSignature);
6304 if (wand->debug != MagickFalse)
6305 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6306 CurrentContext=DestroyDrawInfo(CurrentContext);
6307 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6308 if (xml == (const char *) NULL)
6309 return(MagickFalse);
6310 xml_info=NewXMLTree(xml,wand->exception);
6311 if (xml_info == (XMLTreeInfo *) NULL)
6312 return(MagickFalse);
6313 child=GetXMLTreeChild(xml_info,"clip-path");
6314 if (child != (XMLTreeInfo *) NULL)
6315 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6316 child=GetXMLTreeChild(xml_info,"clip-units");
6317 if (child != (XMLTreeInfo *) NULL)
6318 {
6319 value=GetXMLTreeContent(child);
6320 if (value != (const char *) NULL)
6321 CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption(
6322 MagickClipPathOptions,MagickFalse,value);
6323 }
6324 child=GetXMLTreeChild(xml_info,"decorate");
6325 if (child != (XMLTreeInfo *) NULL)
6326 {
6327 value=GetXMLTreeContent(child);
6328 if (value != (const char *) NULL)
6329 CurrentContext->decorate=(DecorationType) ParseCommandOption(
6330 MagickDecorateOptions,MagickFalse,value);
6331 }
6332 child=GetXMLTreeChild(xml_info,"encoding");
6333 if (child != (XMLTreeInfo *) NULL)
6334 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6335 child=GetXMLTreeChild(xml_info,"fill");
6336 if (child != (XMLTreeInfo *) NULL)
6337 {
6338 value=GetXMLTreeContent(child);
6339 if (value != (const char *) NULL)
6340 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->fill,
6341 wand->exception);
6342 }
6343 child=GetXMLTreeChild(xml_info,"fill-opacity");
6344 if (child != (XMLTreeInfo *) NULL)
6345 {
6346 value=GetXMLTreeContent(child);
6347 if (value != (const char *) NULL)
6348 CurrentContext->fill.alpha=(double) ClampToQuantum((double)
6349 QuantumRange*(1.0-StringToDouble(value,(char **) NULL)));
6350 }
6351 child=GetXMLTreeChild(xml_info,"fill-rule");
6352 if (child != (XMLTreeInfo *) NULL)
6353 {
6354 value=GetXMLTreeContent(child);
6355 if (value != (const char *) NULL)
6356 CurrentContext->fill_rule=(FillRule) ParseCommandOption(
6357 MagickFillRuleOptions,MagickFalse,value);
6358 }
6359 child=GetXMLTreeChild(xml_info,"font");
6360 if (child != (XMLTreeInfo *) NULL)
6361 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6362 child=GetXMLTreeChild(xml_info,"font-family");
6363 if (child != (XMLTreeInfo *) NULL)
6364 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6365 child=GetXMLTreeChild(xml_info,"font-size");
6366 if (child != (XMLTreeInfo *) NULL)
6367 {
6368 value=GetXMLTreeContent(child);
6369 if (value != (const char *) NULL)
6370 CurrentContext->pointsize=StringToDouble(value,(char **) NULL);
6371 }
6372 child=GetXMLTreeChild(xml_info,"font-stretch");
6373 if (child != (XMLTreeInfo *) NULL)
6374 {
6375 value=GetXMLTreeContent(child);
6376 if (value != (const char *) NULL)
6377 CurrentContext->stretch=(StretchType) ParseCommandOption(
6378 MagickStretchOptions,MagickFalse,value);
6379 }
6380 child=GetXMLTreeChild(xml_info,"font-style");
6381 if (child != (XMLTreeInfo *) NULL)
6382 {
6383 value=GetXMLTreeContent(child);
6384 if (value != (const char *) NULL)
6385 CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
6386 MagickFalse,value);
6387 }
6388 child=GetXMLTreeChild(xml_info,"font-weight");
6389 if (child != (XMLTreeInfo *) NULL)
6390 {
6391 value=GetXMLTreeContent(child);
6392 if (value != (const char *) NULL)
6393 {
6394 ssize_t
6395 weight;
6396
6397 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
6398 if (weight == -1)
6399 weight=(ssize_t) StringToUnsignedLong(value);
6400 CurrentContext->weight=(size_t) weight;
6401 }
6402 }
6403 child=GetXMLTreeChild(xml_info,"gravity");
6404 if (child != (XMLTreeInfo *) NULL)
6405 {
6406 value=GetXMLTreeContent(child);
6407 if (value != (const char *) NULL)
6408 CurrentContext->gravity=(GravityType) ParseCommandOption(
6409 MagickGravityOptions,MagickFalse,value);
6410 }
6411 child=GetXMLTreeChild(xml_info,"stroke");
6412 if (child != (XMLTreeInfo *) NULL)
6413 {
6414 value=GetXMLTreeContent(child);
6415 if (value != (const char *) NULL)
6416 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->stroke,
6417 wand->exception);
6418 }
6419 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6420 if (child != (XMLTreeInfo *) NULL)
6421 {
6422 value=GetXMLTreeContent(child);
6423 if (value != (const char *) NULL)
6424 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6425 MagickFalse;
6426 }
6427 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6428 if (child != (XMLTreeInfo *) NULL)
6429 {
6430 char
6431 token[MagickPathExtent];
6432
6433 const char
6434 *q;
6435
6436 ssize_t
6437 x;
6438
6439 ssize_t
6440 j;
6441
6442 value=GetXMLTreeContent(child);
6443 if (value != (const char *) NULL)
6444 {
6445 if (CurrentContext->dash_pattern != (double *) NULL)
6446 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6447 CurrentContext->dash_pattern);
6448 q=(char *) value;
6449 if (IsPoint(q) != MagickFalse)
6450 {
6451 const char
6452 *p;
6453
6454 p=q;
6455 (void) GetNextToken(p,&p,MagickPathExtent,token);
6456 if (*token == ',')
6457 (void) GetNextToken(p,&p,MagickPathExtent,token);
6458 for (x=0; IsPoint(token) != MagickFalse; x++)
6459 {
6460 (void) GetNextToken(p,&p,MagickPathExtent,token);
6461 if (*token == ',')
6462 (void) GetNextToken(p,&p,MagickPathExtent,token);
6463 }
6464 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6465 (size_t) (2*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6466 if (CurrentContext->dash_pattern == (double *) NULL)
6467 ThrowWandFatalException(ResourceLimitFatalError,
6468 "MemoryAllocationFailed",wand->name);
6469 for (j=0; j < x; j++)
6470 {
6471 (void) GetNextToken(q,&q,MagickPathExtent,token);
6472 if (*token == ',')
6473 (void) GetNextToken(q,&q,MagickPathExtent,token);
6474 CurrentContext->dash_pattern[j]=StringToDouble(token,
6475 (char **) NULL);
6476 }
6477 if ((x & 0x01) != 0)
6478 for ( ; j < (2*x); j++)
6479 CurrentContext->dash_pattern[j]=
6480 CurrentContext->dash_pattern[j-x];
6481 CurrentContext->dash_pattern[j]=0.0;
6482 }
6483 }
6484 }
6485 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6486 if (child != (XMLTreeInfo *) NULL)
6487 {
6488 value=GetXMLTreeContent(child);
6489 if (value != (const char *) NULL)
6490 CurrentContext->dash_offset=StringToDouble(value,(char **) NULL);
6491 }
6492 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6493 if (child != (XMLTreeInfo *) NULL)
6494 {
6495 value=GetXMLTreeContent(child);
6496 if (value != (const char *) NULL)
6497 CurrentContext->linecap=(LineCap) ParseCommandOption(
6498 MagickLineCapOptions,MagickFalse,value);
6499 }
6500 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6501 if (child != (XMLTreeInfo *) NULL)
6502 {
6503 value=GetXMLTreeContent(child);
6504 if (value != (const char *) NULL)
6505 CurrentContext->linejoin=(LineJoin) ParseCommandOption(
6506 MagickLineJoinOptions,MagickFalse,value);
6507 }
6508 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6509 if (child != (XMLTreeInfo *) NULL)
6510 {
6511 value=GetXMLTreeContent(child);
6512 if (value != (const char *) NULL)
6513 CurrentContext->miterlimit=StringToUnsignedLong(value);
6514 }
6515 child=GetXMLTreeChild(xml_info,"stroke-opacity");
6516 if (child != (XMLTreeInfo *) NULL)
6517 {
6518 value=GetXMLTreeContent(child);
6519 if (value != (const char *) NULL)
6520 CurrentContext->stroke.alpha=(double) ClampToQuantum((double)
6521 QuantumRange*(1.0-StringToDouble(value,(char **) NULL)));
6522 }
6523 child=GetXMLTreeChild(xml_info,"stroke-width");
6524 if (child != (XMLTreeInfo *) NULL)
6525 {
6526 value=GetXMLTreeContent(child);
6527 if (value != (const char *) NULL)
6528 {
6529 ssize_t
6530 weight;
6531
6532 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
6533 if (weight == -1)
6534 weight=(ssize_t) StringToUnsignedLong(value);
6535 CurrentContext->stroke_width=(double) weight;
6536 }
6537 }
6538 child=GetXMLTreeChild(xml_info,"text-align");
6539 if (child != (XMLTreeInfo *) NULL)
6540 {
6541 value=GetXMLTreeContent(child);
6542 if (value != (const char *) NULL)
6543 CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
6544 MagickFalse,value);
6545 }
6546 child=GetXMLTreeChild(xml_info,"text-antialias");
6547 if (child != (XMLTreeInfo *) NULL)
6548 {
6549 value=GetXMLTreeContent(child);
6550 if (value != (const char *) NULL)
6551 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6552 MagickFalse;
6553 }
6554 child=GetXMLTreeChild(xml_info,"text-undercolor");
6555 if (child != (XMLTreeInfo *) NULL)
6556 {
6557 value=GetXMLTreeContent(child);
6558 if (value != (const char *) NULL)
6559 (void) QueryColorCompliance(value,AllCompliance,
6560 &CurrentContext->undercolor,wand->exception);
6561 }
6562 child=GetXMLTreeChild(xml_info,"vector-graphics");
6563 if (child != (XMLTreeInfo *) NULL)
6564 {
6565 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6566 wand->mvg_length=strlen(wand->mvg);
6567 wand->mvg_alloc=wand->mvg_length+1;
6568 }
6569 xml_info=DestroyXMLTree(xml_info);
6570 return(MagickTrue);
6571}
6572
6573/*
6574%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6575% %
6576% %
6577% %
6578% D r a w S k e w X %
6579% %
6580% %
6581% %
6582%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6583%
6584% DrawSkewX() skews the current coordinate system in the horizontal
6585% direction.
6586%
6587% The format of the DrawSkewX method is:
6588%
6589% void DrawSkewX(DrawingWand *wand,const double degrees)
6590%
6591% A description of each parameter follows:
6592%
6593% o wand: the drawing wand.
6594%
6595% o degrees: number of degrees to skew the coordinates
6596%
6597*/
6598WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6599{
6600 assert(wand != (DrawingWand *) NULL);
6601 assert(wand->signature == MagickWandSignature);
6602 if (wand->debug != MagickFalse)
6603 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6604 (void) MVGPrintf(wand,"skewX %.20g\n",degrees);
6605}
6606
6607/*
6608%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6609% %
6610% %
6611% %
6612% D r a w S k e w Y %
6613% %
6614% %
6615% %
6616%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6617%
6618% DrawSkewY() skews the current coordinate system in the vertical
6619% direction.
6620%
6621% The format of the DrawSkewY method is:
6622%
6623% void DrawSkewY(DrawingWand *wand,const double degrees)
6624%
6625% A description of each parameter follows:
6626%
6627% o wand: the drawing wand.
6628%
6629% o degrees: number of degrees to skew the coordinates
6630%
6631*/
6632WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6633{
6634 assert(wand != (DrawingWand *) NULL);
6635 assert(wand->signature == MagickWandSignature);
6636 if (wand->debug != MagickFalse)
6637 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6638 (void) MVGPrintf(wand,"skewY %.20g\n",degrees);
6639}
6640
6641/*
6642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6643% %
6644% %
6645% %
6646% D r a w T r a n s l a t e %
6647% %
6648% %
6649% %
6650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6651%
6652% DrawTranslate() applies a translation to the current coordinate
6653% system which moves the coordinate system origin to the specified
6654% coordinate.
6655%
6656% The format of the DrawTranslate method is:
6657%
6658% void DrawTranslate(DrawingWand *wand,const double x,
6659% const double y)
6660%
6661% A description of each parameter follows:
6662%
6663% o wand: the drawing wand.
6664%
6665% o x: new x ordinate for coordinate system origin
6666%
6667% o y: new y ordinate for coordinate system origin
6668%
6669*/
6670WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6671{
6672 assert(wand != (DrawingWand *) NULL);
6673 assert(wand->signature == MagickWandSignature);
6674 if (wand->debug != MagickFalse)
6675 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6676 (void) MVGPrintf(wand,"translate %.20g %.20g\n",x,y);
6677}
6678
6679/*
6680%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6681% %
6682% %
6683% %
6684% D r a w S e t V i e w b o x %
6685% %
6686% %
6687% %
6688%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6689%
6690% DrawSetViewbox() sets the overall canvas size to be recorded with the
6691% drawing vector data. Usually this will be specified using the same
6692% size as the canvas image. When the vector data is saved to SVG or MVG
6693% formats, the viewbox is use to specify the size of the canvas image that
6694% a viewer will render the vector data on.
6695%
6696% The format of the DrawSetViewbox method is:
6697%
6698% void DrawSetViewbox(DrawingWand *wand,const double x1,const double y1,
6699% const double x2,const double y2)
6700%
6701% A description of each parameter follows:
6702%
6703% o wand: the drawing wand.
6704%
6705% o x1: left x ordinate
6706%
6707% o y1: top y ordinate
6708%
6709% o x2: right x ordinate
6710%
6711% o y2: bottom y ordinate
6712%
6713*/
6714WandExport void DrawSetViewbox(DrawingWand *wand,const double x1,
6715 const double y1,const double x2,const double y2)
6716{
6717 assert(wand != (DrawingWand *) NULL);
6718 assert(wand->signature == MagickWandSignature);
6719 if (wand->debug != MagickFalse)
6720 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6721 (void) MVGPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
6722}
6723
6724/*
6725%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6726% %
6727% %
6728% %
6729% I s D r a w i n g W a n d %
6730% %
6731% %
6732% %
6733%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6734%
6735% IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6736%
6737% The format of the IsDrawingWand method is:
6738%
6739% MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6740%
6741% A description of each parameter follows:
6742%
6743% o wand: the drawing wand.
6744%
6745*/
6746WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6747{
6748 if (wand == (const DrawingWand *) NULL)
6749 return(MagickFalse);
6750 if (wand->signature != MagickWandSignature)
6751 return(MagickFalse);
6752 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6753 return(MagickFalse);
6754 return(MagickTrue);
6755}
6756
6757/*
6758%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6759% %
6760% %
6761% %
6762% N e w D r a w i n g W a n d %
6763% %
6764% %
6765% %
6766%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6767%
6768% NewDrawingWand() returns a drawing wand required for all other methods in
6769% the API.
6770%
6771% The format of the NewDrawingWand method is:
6772%
6773% DrawingWand *NewDrawingWand(void)
6774%
6775*/
6776WandExport DrawingWand *NewDrawingWand(void)
6777{
6779 *wand;
6780
6781 CheckMagickCoreCompatibility();
6782 wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand));
6783 if (wand == (DrawingWand *) NULL)
6784 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6785 GetExceptionMessage(errno));
6786 (void) memset(wand,0,sizeof(*wand));
6787 wand->id=AcquireWandId();
6788 (void) FormatLocaleString(wand->name,MagickPathExtent,"%s-%.20g",
6789 DrawingWandId,(double) wand->id);
6790 if (wand->debug != MagickFalse)
6791 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6792 wand->mvg=(char *) NULL;
6793 wand->mvg_alloc=0;
6794 wand->mvg_length=0;
6795 wand->mvg_width=0;
6796 wand->pattern_id=(char *) NULL;
6797 wand->pattern_offset=0;
6798 wand->pattern_bounds.x=0;
6799 wand->pattern_bounds.y=0;
6800 wand->pattern_bounds.width=0;
6801 wand->pattern_bounds.height=0;
6802 wand->index=0;
6803 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(
6804 *wand->graphic_context));
6805 if (wand->graphic_context == (DrawInfo **) NULL)
6806 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6807 GetExceptionMessage(errno));
6808 wand->filter_off=MagickTrue;
6809 wand->indent_depth=0;
6810 wand->path_operation=PathDefaultOperation;
6811 wand->path_mode=DefaultPathMode;
6812 wand->exception=AcquireExceptionInfo();
6813 wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception);
6814 wand->destroy=MagickTrue;
6815 wand->debug=IsEventLogging();
6816 wand->signature=MagickWandSignature;
6817 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6818 return(wand);
6819}
6820
6821/*
6822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6823% %
6824% %
6825% %
6826% P e e k D r a w i n g W a n d %
6827% %
6828% %
6829% %
6830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6831%
6832% PeekDrawingWand() returns the current drawing wand.
6833%
6834% The format of the PeekDrawingWand method is:
6835%
6836% DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6837%
6838% A description of each parameter follows:
6839%
6840% o wand: the drawing wand.
6841%
6842*/
6843WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6844{
6845 DrawInfo
6846 *draw_info;
6847
6848 assert(wand != (const DrawingWand *) NULL);
6849 assert(wand->signature == MagickWandSignature);
6850 if (wand->debug != MagickFalse)
6851 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6852 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6853 (void) CloneString(&draw_info->primitive,wand->mvg);
6854 return(draw_info);
6855}
6856
6857/*
6858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6859% %
6860% %
6861% %
6862% P o p D r a w i n g W a n d %
6863% %
6864% %
6865% %
6866%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6867%
6868% PopDrawingWand() destroys the current drawing wand and returns to the
6869% previously pushed drawing wand. Multiple drawing wands may exist. It is an
6870% error to attempt to pop more drawing wands than have been pushed, and it is
6871% proper form to pop all drawing wands which have been pushed.
6872%
6873% The format of the PopDrawingWand method is:
6874%
6875% MagickBooleanType PopDrawingWand(DrawingWand *wand)
6876%
6877% A description of each parameter follows:
6878%
6879% o wand: the drawing wand.
6880%
6881*/
6882WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6883{
6884 assert(wand != (DrawingWand *) NULL);
6885 assert(wand->signature == MagickWandSignature);
6886 if (wand->debug != MagickFalse)
6887 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6888 if (wand->index == 0)
6889 {
6890 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6891 return(MagickFalse);
6892 }
6893 /*
6894 Destroy clip path if not same in preceding wand.
6895 */
6896#if DRAW_BINARY_IMPLEMENTATION
6897 if (wand->image == (Image *) NULL)
6898 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6899 if (CurrentContext->clip_mask != (char *) NULL)
6900 if (LocaleCompare(CurrentContext->clip_mask,
6901 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6902 (void) SetImageMask(wand->image,WritePixelMask,(Image *) NULL,
6903 wand->exception);
6904#endif
6905 CurrentContext=DestroyDrawInfo(CurrentContext);
6906 wand->index--;
6907 if (wand->indent_depth > 0)
6908 wand->indent_depth--;
6909 (void) MVGPrintf(wand,"pop graphic-context\n");
6910 return(MagickTrue);
6911}
6912
6913/*
6914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6915% %
6916% %
6917% %
6918% P u s h D r a w i n g W a n d %
6919% %
6920% %
6921% %
6922%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6923%
6924% PushDrawingWand() clones the current drawing wand to create a new drawing
6925% wand. The original drawing wand(s) may be returned to by invoking
6926% PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6927% For every Pop there must have already been an equivalent Push.
6928%
6929% The format of the PushDrawingWand method is:
6930%
6931% MagickBooleanType PushDrawingWand(DrawingWand *wand)
6932%
6933% A description of each parameter follows:
6934%
6935% o wand: the drawing wand.
6936%
6937*/
6938WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6939{
6940 assert(wand != (DrawingWand *) NULL);
6941 assert(wand->signature == MagickWandSignature);
6942 if (wand->debug != MagickFalse)
6943 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6944 wand->index++;
6945 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6946 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6947 if (wand->graphic_context == (DrawInfo **) NULL)
6948 {
6949 wand->index--;
6950 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6951 wand->name);
6952 return(MagickFalse);
6953 }
6954 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6955 wand->graphic_context[wand->index-1]);
6956 (void) MVGPrintf(wand,"push graphic-context\n");
6957 wand->indent_depth++;
6958 return(MagickTrue);
6959}