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