blob: a7b188980fcafa88e07f84f3acfd0bbbed9c075e [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% %
Cristy7ce65e72015-12-12 18:03:16 -050026% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000027% 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% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42%
43%
44*/
45
46/*
47 Include declarations.
48*/
cristy4c08aed2011-07-01 19:47:50 +000049#include "MagickWand/studio.h"
50#include "MagickWand/MagickWand.h"
51#include "MagickWand/magick-wand-private.h"
52#include "MagickWand/wand.h"
53#include "MagickCore/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000054
55/*
56 Define declarations.
57*/
58#define DRAW_BINARY_IMPLEMENTATION 0
59
60#define CurrentContext (wand->graphic_context[wand->index])
61#define DrawingWandId "DrawingWand"
62#define ThrowDrawException(severity,tag,reason) (void) ThrowMagickException( \
cristyefe601c2013-01-05 17:51:12 +000063 wand->exception,GetMagickModule(),severity,tag,"`%s'",reason);
cristy3ed852e2009-09-05 21:47:34 +000064
65/*
66 Typedef declarations.
67*/
68typedef enum
69{
70 PathDefaultOperation,
71 PathCloseOperation, /* Z|z (none) */
72 PathCurveToOperation, /* C|c (x1 y1 x2 y2 x y)+ */
73 PathCurveToQuadraticBezierOperation, /* Q|q (x1 y1 x y)+ */
74 PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
75 PathCurveToSmoothOperation, /* S|s (x2 y2 x y)+ */
76 PathEllipticArcOperation, /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
77 PathLineToHorizontalOperation, /* H|h x+ */
78 PathLineToOperation, /* L|l (x y)+ */
79 PathLineToVerticalOperation, /* V|v y+ */
80 PathMoveToOperation /* M|m (x y)+ */
81} PathOperation;
82
83typedef enum
84{
85 DefaultPathMode,
86 AbsolutePathMode,
87 RelativePathMode
88} PathMode;
89
90struct _DrawingWand
91{
cristybb503372010-05-27 20:51:26 +000092 size_t
cristy3ed852e2009-09-05 21:47:34 +000093 id;
94
95 char
cristy151b66d2015-04-15 10:50:31 +000096 name[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +000097
98 /* Support structures */
99 Image
100 *image;
101
102 ExceptionInfo
103 *exception;
104
105 /* MVG output string and housekeeping */
106 char
107 *mvg; /* MVG data */
108
109 size_t
110 mvg_alloc, /* total allocated memory */
111 mvg_length; /* total MVG length */
112
cristybb503372010-05-27 20:51:26 +0000113 size_t
cristy3ed852e2009-09-05 21:47:34 +0000114 mvg_width; /* current line width */
115
116 /* Pattern support */
117 char
118 *pattern_id;
119
120 RectangleInfo
121 pattern_bounds;
122
123 size_t
124 pattern_offset;
125
126 /* Graphic wand */
cristybb503372010-05-27 20:51:26 +0000127 size_t
cristy3ed852e2009-09-05 21:47:34 +0000128 index; /* array index */
129
130 DrawInfo
131 **graphic_context;
132
133 MagickBooleanType
134 filter_off; /* true if not filtering attributes */
135
136 /* Pretty-printing depth */
cristybb503372010-05-27 20:51:26 +0000137 size_t
cristy3ed852e2009-09-05 21:47:34 +0000138 indent_depth; /* number of left-hand pad characters */
139
140 /* Path operation support */
141 PathOperation
142 path_operation;
143
144 PathMode
145 path_mode;
146
147 MagickBooleanType
148 destroy,
149 debug;
150
cristybb503372010-05-27 20:51:26 +0000151 size_t
cristy3ed852e2009-09-05 21:47:34 +0000152 signature;
153};
154
cristy3ed852e2009-09-05 21:47:34 +0000155/*
156 Forward declarations.
157*/
158static int
Cristybd0db062015-12-26 10:33:53 -0500159 MVGPrintf(DrawingWand *,const char *,...) wand_attribute((format
cristy3ed852e2009-09-05 21:47:34 +0000160 (printf,2,3))),
Cristybd0db062015-12-26 10:33:53 -0500161 MVGAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format
cristy3ed852e2009-09-05 21:47:34 +0000162 (printf,2,3)));
163
164static void
Cristybd0db062015-12-26 10:33:53 -0500165 MVGAppendColor(DrawingWand *,const PixelInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000166
167/*
168 "Printf" for MVG commands
169*/
Cristybd0db062015-12-26 10:33:53 -0500170static int MVGPrintf(DrawingWand *wand,const char *format,...)
cristy3ed852e2009-09-05 21:47:34 +0000171{
172 size_t
cristy53a8bc92011-01-10 19:15:17 +0000173 extent;
cristy3ed852e2009-09-05 21:47:34 +0000174
175 if (wand->debug != MagickFalse)
176 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format);
177 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000178 assert(wand->signature == MagickWandSignature);
cristy151b66d2015-04-15 10:50:31 +0000179 extent=20UL*MagickPathExtent;
cristy3ed852e2009-09-05 21:47:34 +0000180 if (wand->mvg == (char *) NULL)
181 {
cristy53a8bc92011-01-10 19:15:17 +0000182 wand->mvg=(char *) AcquireQuantumMemory(extent,sizeof(*wand->mvg));
cristy3ed852e2009-09-05 21:47:34 +0000183 if (wand->mvg == (char *) NULL)
184 {
185 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
186 wand->name);
187 return(-1);
188 }
cristy53a8bc92011-01-10 19:15:17 +0000189 wand->mvg_alloc=extent;
cristy3ed852e2009-09-05 21:47:34 +0000190 wand->mvg_length=0;
191 }
cristy151b66d2015-04-15 10:50:31 +0000192 if (wand->mvg_alloc < (wand->mvg_length+10*MagickPathExtent))
cristy3ed852e2009-09-05 21:47:34 +0000193 {
cristy53a8bc92011-01-10 19:15:17 +0000194 extent+=wand->mvg_alloc;
195 wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,extent,
cristy3ed852e2009-09-05 21:47:34 +0000196 sizeof(*wand->mvg));
197 if (wand->mvg == (char *) NULL)
198 {
199 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
200 wand->name);
cristy53a8bc92011-01-10 19:15:17 +0000201 return(-1);
cristy3ed852e2009-09-05 21:47:34 +0000202 }
cristy53a8bc92011-01-10 19:15:17 +0000203 wand->mvg_alloc=extent;
cristy3ed852e2009-09-05 21:47:34 +0000204 }
205 {
206 int
cristy53a8bc92011-01-10 19:15:17 +0000207 count;
208
209 ssize_t
210 offset;
cristy3ed852e2009-09-05 21:47:34 +0000211
212 va_list
213 argp;
214
215 while (wand->mvg_width < wand->indent_depth)
216 {
217 wand->mvg[wand->mvg_length]=' ';
218 wand->mvg_length++;
219 wand->mvg_width++;
220 }
221 wand->mvg[wand->mvg_length]='\0';
cristy53a8bc92011-01-10 19:15:17 +0000222 count=(-1);
223 offset=(ssize_t) wand->mvg_alloc-wand->mvg_length-1;
224 if (offset > 0)
225 {
226 va_start(argp,format);
cristy3ed852e2009-09-05 21:47:34 +0000227#if defined(MAGICKCORE_HAVE_VSNPRINTF)
cristyf1356c72011-02-01 13:52:20 +0000228 count=vsnprintf(wand->mvg+wand->mvg_length,(size_t) offset,format,argp);
cristy3ed852e2009-09-05 21:47:34 +0000229#else
cristy53a8bc92011-01-10 19:15:17 +0000230 count=vsprintf(wand->mvg+wand->mvg_length,format,argp);
cristy3ed852e2009-09-05 21:47:34 +0000231#endif
cristy53a8bc92011-01-10 19:15:17 +0000232 va_end(argp);
233 }
234 if ((count < 0) || (count > (int) offset))
cristy3ed852e2009-09-05 21:47:34 +0000235 ThrowDrawException(DrawError,"UnableToPrint",format)
236 else
237 {
cristy53a8bc92011-01-10 19:15:17 +0000238 wand->mvg_length+=count;
239 wand->mvg_width+=count;
cristy3ed852e2009-09-05 21:47:34 +0000240 }
241 wand->mvg[wand->mvg_length]='\0';
cristy9bc59b22011-01-28 00:35:31 +0000242 if ((wand->mvg_length > 1) && (wand->mvg[wand->mvg_length-1] == '\n'))
cristy3ed852e2009-09-05 21:47:34 +0000243 wand->mvg_width=0;
244 assert((wand->mvg_length+1) < wand->mvg_alloc);
cristy53a8bc92011-01-10 19:15:17 +0000245 return(count);
cristy3ed852e2009-09-05 21:47:34 +0000246 }
247}
248
Cristybd0db062015-12-26 10:33:53 -0500249static int MVGAutoWrapPrintf(DrawingWand *wand,const char *format,...)
cristy3ed852e2009-09-05 21:47:34 +0000250{
251 char
cristy151b66d2015-04-15 10:50:31 +0000252 buffer[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +0000253
254 int
cristy53a8bc92011-01-10 19:15:17 +0000255 count;
cristy3ed852e2009-09-05 21:47:34 +0000256
257 va_list
258 argp;
259
260 va_start(argp,format);
261#if defined(MAGICKCORE_HAVE_VSNPRINTF)
cristy53a8bc92011-01-10 19:15:17 +0000262 count=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
cristy3ed852e2009-09-05 21:47:34 +0000263#else
cristy53a8bc92011-01-10 19:15:17 +0000264 count=vsprintf(buffer,format,argp);
cristy3ed852e2009-09-05 21:47:34 +0000265#endif
266 va_end(argp);
cristy9bc59b22011-01-28 00:35:31 +0000267 buffer[sizeof(buffer)-1]='\0';
cristy53a8bc92011-01-10 19:15:17 +0000268 if (count < 0)
cristy3ed852e2009-09-05 21:47:34 +0000269 ThrowDrawException(DrawError,"UnableToPrint",format)
270 else
271 {
cristy9bc59b22011-01-28 00:35:31 +0000272 if (((wand->mvg_width + count) > 78) && (buffer[count-1] != '\n'))
Cristybd0db062015-12-26 10:33:53 -0500273 (void) MVGPrintf(wand, "\n");
274 (void) MVGPrintf(wand,"%s",buffer);
cristy3ed852e2009-09-05 21:47:34 +0000275 }
cristy53a8bc92011-01-10 19:15:17 +0000276 return(count);
cristy3ed852e2009-09-05 21:47:34 +0000277}
278
Cristybd0db062015-12-26 10:33:53 -0500279static void MVGAppendColor(DrawingWand *wand,const PixelInfo *packet)
cristy3ed852e2009-09-05 21:47:34 +0000280{
cristy4c08aed2011-07-01 19:47:50 +0000281 if ((packet->red == 0) && (packet->green == 0) && (packet->blue == 0) &&
282 (packet->alpha == (Quantum) TransparentAlpha))
Cristybd0db062015-12-26 10:33:53 -0500283 (void) MVGPrintf(wand,"none");
cristy3ed852e2009-09-05 21:47:34 +0000284 else
285 {
286 char
cristy151b66d2015-04-15 10:50:31 +0000287 tuple[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +0000288
cristy4c08aed2011-07-01 19:47:50 +0000289 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +0000290 pixel;
291
cristy4c08aed2011-07-01 19:47:50 +0000292 GetPixelInfo(wand->image,&pixel);
cristy7020ae62012-04-18 12:58:34 +0000293 pixel.colorspace=sRGBColorspace;
cristyb0a657e2012-08-29 00:45:37 +0000294 pixel.alpha_trait=packet->alpha != OpaqueAlpha ? BlendPixelTrait :
295 UndefinedPixelTrait;
cristya19f1d72012-08-07 18:24:38 +0000296 pixel.red=(double) packet->red;
297 pixel.green=(double) packet->green;
298 pixel.blue=(double) packet->blue;
299 pixel.alpha=(double) packet->alpha;
cristy3ed852e2009-09-05 21:47:34 +0000300 GetColorTuple(&pixel,MagickTrue,tuple);
Cristybd0db062015-12-26 10:33:53 -0500301 (void) MVGPrintf(wand,"%s",tuple);
cristy3ed852e2009-09-05 21:47:34 +0000302 }
303}
304
Cristybd0db062015-12-26 10:33:53 -0500305static void MVGAppendPointsCommand(DrawingWand *wand,const char *command,
cristybb503372010-05-27 20:51:26 +0000306 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +0000307{
308 const PointInfo
309 *coordinate;
310
cristybb503372010-05-27 20:51:26 +0000311 size_t
cristy3ed852e2009-09-05 21:47:34 +0000312 i;
313
Cristybd0db062015-12-26 10:33:53 -0500314 (void) MVGPrintf(wand,"%s",command);
cristy3ed852e2009-09-05 21:47:34 +0000315 for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
316 {
Cristybd0db062015-12-26 10:33:53 -0500317 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",coordinate->x,coordinate->y);
cristy3ed852e2009-09-05 21:47:34 +0000318 coordinate++;
319 }
Cristybd0db062015-12-26 10:33:53 -0500320 (void) MVGPrintf(wand, "\n");
cristy3ed852e2009-09-05 21:47:34 +0000321}
322
323static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine)
324{
325 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000326 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000327 if (wand->debug != MagickFalse)
328 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
329 if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
330 (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
331 {
332 AffineMatrix
333 current;
334
335 current=CurrentContext->affine;
cristyef7c8a52010-10-10 13:46:51 +0000336 CurrentContext->affine.sx=affine->sx*current.sx+affine->ry*current.rx;
337 CurrentContext->affine.rx=affine->rx*current.sx+affine->sy*current.rx;
338 CurrentContext->affine.ry=affine->sx*current.ry+affine->ry*current.sy;
339 CurrentContext->affine.sy=affine->rx*current.ry+affine->sy*current.sy;
340 CurrentContext->affine.tx=affine->sx*current.tx+affine->ry*current.ty+
341 affine->tx;
342 CurrentContext->affine.ty=affine->rx*current.tx+affine->sy*current.ty+
343 affine->ty;
cristy3ed852e2009-09-05 21:47:34 +0000344 }
345}
346
347/*
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349% %
350% %
351% %
Cristyd9d2c0d2015-12-25 08:15:09 -0500352+ A c q u i r e D r a w i n g W a n d %
353% %
354% %
355% %
356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357%
358% AcquireDrawingWand() allocates an initial drawing wand which is an opaque
359% handle required by the remaining drawing methods.
360%
361% The format of the AcquireDrawingWand method is:
362%
363% DrawingWand AcquireDrawingWand(const DrawInfo *draw_info,Image *image)
364%
365% A description of each parameter follows:
366%
367% o draw_info: Initial drawing defaults. Set to NULL to use defaults.
368%
369% o image: the image to draw on.
370%
371*/
372WandExport DrawingWand *AcquireDrawingWand(const DrawInfo *draw_info,
373 Image *image)
374{
375 DrawingWand
376 *wand;
377
378 wand=NewDrawingWand();
379 if (draw_info != (const DrawInfo *) NULL)
380 {
381 CurrentContext=DestroyDrawInfo(CurrentContext);
382 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
383 }
384 if (image != (Image *) NULL)
385 {
386 wand->image=DestroyImage(wand->image);
387 wand->destroy=MagickFalse;
388 }
389 wand->image=image;
390 return(wand);
391}
392
393/*
394%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395% %
396% %
397% %
cristy3ed852e2009-09-05 21:47:34 +0000398% C l e a r D r a w i n g W a n d %
399% %
400% %
401% %
402%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403%
cristy9cedaa32011-05-03 15:59:37 +0000404% ClearDrawingWand() clears resources associated with the drawing wand.
cristy3ed852e2009-09-05 21:47:34 +0000405%
406% The format of the ClearDrawingWand method is:
407%
cristy9cedaa32011-05-03 15:59:37 +0000408% void ClearDrawingWand(DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +0000409%
410% A description of each parameter follows:
411%
cristy9cedaa32011-05-03 15:59:37 +0000412% o wand: the drawing wand to clear.
cristy3ed852e2009-09-05 21:47:34 +0000413%
414*/
415WandExport void ClearDrawingWand(DrawingWand *wand)
416{
417 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000418 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000419 if (wand->debug != MagickFalse)
420 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
421 for ( ; wand->index > 0; wand->index--)
422 CurrentContext=DestroyDrawInfo(CurrentContext);
423 CurrentContext=DestroyDrawInfo(CurrentContext);
424 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
425 wand->graphic_context);
426 if (wand->pattern_id != (char *) NULL)
427 wand->pattern_id=DestroyString(wand->pattern_id);
428 wand->mvg=DestroyString(wand->mvg);
429 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
430 wand->image=DestroyImage(wand->image);
431 else
432 wand->image=(Image *) NULL;
433 wand->mvg=(char *) NULL;
434 wand->mvg_alloc=0;
435 wand->mvg_length=0;
436 wand->mvg_width=0;
437 wand->pattern_id=(char *) NULL;
438 wand->pattern_offset=0;
439 wand->pattern_bounds.x=0;
440 wand->pattern_bounds.y=0;
441 wand->pattern_bounds.width=0;
442 wand->pattern_bounds.height=0;
443 wand->index=0;
444 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
445 sizeof(*wand->graphic_context));
446 if (wand->graphic_context == (DrawInfo **) NULL)
447 {
448 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
449 wand->name);
450 return;
451 }
452 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
453 wand->filter_off=MagickTrue;
454 wand->indent_depth=0;
455 wand->path_operation=PathDefaultOperation;
456 wand->path_mode=DefaultPathMode;
cristy9950d572011-10-01 18:22:35 +0000457 wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception);
cristy3ed852e2009-09-05 21:47:34 +0000458 ClearMagickException(wand->exception);
459 wand->destroy=MagickTrue;
460 wand->debug=IsEventLogging();
461}
462
463/*
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465% %
466% %
467% %
468% C l o n e D r a w i n g W a n d %
469% %
470% %
471% %
472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473%
474% CloneDrawingWand() makes an exact copy of the specified wand.
475%
476% The format of the CloneDrawingWand method is:
477%
478% DrawingWand *CloneDrawingWand(const DrawingWand *wand)
479%
480% A description of each parameter follows:
481%
482% o wand: the magick wand.
483%
484*/
485WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
486{
487 DrawingWand
488 *clone_wand;
489
cristybb503372010-05-27 20:51:26 +0000490 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000491 i;
492
493 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000494 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000495 if (wand->debug != MagickFalse)
496 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy73bd4a52010-10-05 11:24:23 +0000497 clone_wand=(DrawingWand *) AcquireMagickMemory(sizeof(*clone_wand));
cristy3ed852e2009-09-05 21:47:34 +0000498 if (clone_wand == (DrawingWand *) NULL)
499 ThrowWandFatalException(ResourceLimitFatalError,
500 "MemoryAllocationFailed",GetExceptionMessage(errno));
501 (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
502 clone_wand->id=AcquireWandId();
Cristybd0db062015-12-26 10:33:53 -0500503 (void) FormatLocaleString(clone_wand->name,MagickPathExtent,
504 "DrawingWand-%.20g",(double) clone_wand->id);
cristy3ed852e2009-09-05 21:47:34 +0000505 clone_wand->exception=AcquireExceptionInfo();
506 InheritException(clone_wand->exception,wand->exception);
507 clone_wand->mvg=AcquireString(wand->mvg);
508 clone_wand->mvg_length=strlen(clone_wand->mvg);
509 clone_wand->mvg_alloc=wand->mvg_length+1;
510 clone_wand->mvg_width=wand->mvg_width;
511 clone_wand->pattern_id=AcquireString(wand->pattern_id);
512 clone_wand->pattern_offset=wand->pattern_offset;
513 clone_wand->pattern_bounds=wand->pattern_bounds;
514 clone_wand->index=wand->index;
515 clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((size_t)
516 wand->index+1UL,sizeof(*wand->graphic_context));
517 if (clone_wand->graphic_context == (DrawInfo **) NULL)
518 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
519 GetExceptionMessage(errno));
cristybb503372010-05-27 20:51:26 +0000520 for (i=0; i <= (ssize_t) wand->index; i++)
Cristybd0db062015-12-26 10:33:53 -0500521 clone_wand->graphic_context[i]=CloneDrawInfo((ImageInfo *) NULL,
522 wand->graphic_context[i]);
cristy3ed852e2009-09-05 21:47:34 +0000523 clone_wand->filter_off=wand->filter_off;
524 clone_wand->indent_depth=wand->indent_depth;
525 clone_wand->path_operation=wand->path_operation;
526 clone_wand->path_mode=wand->path_mode;
527 clone_wand->image=wand->image;
528 if (wand->image != (Image *) NULL)
529 clone_wand->image=CloneImage(wand->image,0,0,MagickTrue,
530 clone_wand->exception);
531 clone_wand->destroy=MagickTrue;
532 clone_wand->debug=IsEventLogging();
533 if (clone_wand->debug != MagickFalse)
534 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
cristye1c94d92015-06-28 12:16:33 +0000535 clone_wand->signature=MagickWandSignature;
cristy3ed852e2009-09-05 21:47:34 +0000536 return(clone_wand);
537}
538
539/*
540%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
541% %
542% %
543% %
544% D e s t r o y D r a w i n g W a n d %
545% %
546% %
547% %
548%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
549%
550% DestroyDrawingWand() frees all resources associated with the drawing wand.
551% Once the drawing wand has been freed, it should not be used and further
552% unless it re-allocated.
553%
554% The format of the DestroyDrawingWand method is:
555%
556% DrawingWand *DestroyDrawingWand(DrawingWand *wand)
557%
558% A description of each parameter follows:
559%
cristy9cedaa32011-05-03 15:59:37 +0000560% o wand: the drawing wand to destroy.
cristy3ed852e2009-09-05 21:47:34 +0000561%
562*/
563WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
564{
565 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000566 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000567 if (wand->debug != MagickFalse)
568 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
569 for ( ; wand->index > 0; wand->index--)
570 CurrentContext=DestroyDrawInfo(CurrentContext);
571 CurrentContext=DestroyDrawInfo(CurrentContext);
572 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
573 wand->graphic_context);
574 if (wand->pattern_id != (char *) NULL)
575 wand->pattern_id=DestroyString(wand->pattern_id);
576 wand->mvg=DestroyString(wand->mvg);
577 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
578 wand->image=DestroyImage(wand->image);
579 wand->image=(Image *) NULL;
580 wand->exception=DestroyExceptionInfo(wand->exception);
cristye1c94d92015-06-28 12:16:33 +0000581 wand->signature=(~MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000582 RelinquishWandId(wand->id);
583 wand=(DrawingWand *) RelinquishMagickMemory(wand);
584 return(wand);
585}
586
587/*
588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589% %
590% %
591% %
592% D r a w A f f i n e %
593% %
594% %
595% %
596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597%
598% DrawAffine() adjusts the current affine transformation matrix with
599% the specified affine transformation matrix. Note that the current affine
600% transform is adjusted rather than replaced.
601%
602% The format of the DrawAffine method is:
603%
604% void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
605%
606% A description of each parameter follows:
607%
608% o wand: Drawing wand
609%
610% o affine: Affine matrix parameters
611%
612*/
613WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
614{
615 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000616 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000617 if (wand->debug != MagickFalse)
618 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
619 assert(affine != (const AffineMatrix *) NULL);
620 AdjustAffine(wand,affine);
Cristybd0db062015-12-26 10:33:53 -0500621 (void) MVGPrintf(wand,"affine %.20g %.20g %.20g %.20g %.20g %.20g\n",
cristy8cd5b312010-01-07 01:10:24 +0000622 affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
cristy3ed852e2009-09-05 21:47:34 +0000623}
624
625/*
626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
627% %
628% %
629% %
dirk34e1a212015-03-22 16:45:12 +0000630% D r a w A l p h a %
631% %
632% %
633% %
634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635%
636% DrawAlpha() paints on the image's alpha channel in order to set effected
dirk03c2ebf2015-12-26 14:51:51 +0100637% pixels to transparent. The available paint methods are:
dirk34e1a212015-03-22 16:45:12 +0000638%
639% PointMethod: Select the target pixel
640% ReplaceMethod: Select any pixel that matches the target pixel.
641% FloodfillMethod: Select the target pixel and matching neighbors.
642% FillToBorderMethod: Select the target pixel and neighbors not matching
643% border color.
644% ResetMethod: Select all pixels.
645%
646% The format of the DrawAlpha method is:
647%
648% void DrawAlpha(DrawingWand *wand,const double x,const double y,
649% const PaintMethod paint_method)
650%
651% A description of each parameter follows:
652%
653% o wand: the drawing wand.
654%
655% o x: x ordinate
656%
657% o y: y ordinate
658%
659% o paint_method: paint method.
660%
661*/
662WandExport void DrawAlpha(DrawingWand *wand,const double x,const double y,
663 const PaintMethod paint_method)
664{
665 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000666 assert(wand->signature == MagickWandSignature);
dirk34e1a212015-03-22 16:45:12 +0000667 if (wand->debug != MagickFalse)
668 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -0500669 (void) MVGPrintf(wand,"alpha %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
dirk34e1a212015-03-22 16:45:12 +0000670 MagickMethodOptions,(ssize_t) paint_method));
671}
672
673/*
674%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
675% %
676% %
677% %
cristy3ed852e2009-09-05 21:47:34 +0000678% D r a w A n n o t a t i o n %
679% %
680% %
681% %
682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683%
684% DrawAnnotation() draws text on the image.
685%
686% The format of the DrawAnnotation method is:
687%
688% void DrawAnnotation(DrawingWand *wand,const double x,
689% const double y,const unsigned char *text)
690%
691% A description of each parameter follows:
692%
693% o wand: the drawing wand.
694%
695% o x: x ordinate to left of text
696%
697% o y: y ordinate to text baseline
698%
699% o text: text to draw
700%
701*/
702WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y,
703 const unsigned char *text)
704{
705 char
706 *escaped_text;
707
708 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000709 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000710 if (wand->debug != MagickFalse)
711 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
712 assert(text != (const unsigned char *) NULL);
713 escaped_text=EscapeString((const char *) text,'\'');
cristy53a8bc92011-01-10 19:15:17 +0000714 if (escaped_text != (char *) NULL)
715 {
Cristybd0db062015-12-26 10:33:53 -0500716 (void) MVGPrintf(wand,"text %.20g %.20g '%s'\n",x,y,escaped_text);
cristy53a8bc92011-01-10 19:15:17 +0000717 escaped_text=DestroyString(escaped_text);
718 }
cristy3ed852e2009-09-05 21:47:34 +0000719}
720
721/*
722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723% %
724% %
725% %
726% D r a w A r c %
727% %
728% %
729% %
730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731%
732% DrawArc() draws an arc falling within a specified bounding rectangle on the
733% image.
734%
735% The format of the DrawArc method is:
736%
737% void DrawArc(DrawingWand *wand,const double sx,const double sy,
738% const double ex,const double ey,const double sd,const double ed)
739%
740% A description of each parameter follows:
741%
742% o wand: the drawing wand.
743%
744% o sx: starting x ordinate of bounding rectangle
745%
746% o sy: starting y ordinate of bounding rectangle
747%
748% o ex: ending x ordinate of bounding rectangle
749%
750% o ey: ending y ordinate of bounding rectangle
751%
752% o sd: starting degrees of rotation
753%
754% o ed: ending degrees of rotation
755%
756*/
757WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy,
758 const double ex,const double ey,const double sd,const double ed)
759{
760 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000761 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000762 if (wand->debug != MagickFalse)
763 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -0500764 (void) MVGPrintf(wand,"arc %.20g %.20g %.20g %.20g %.20g %.20g\n",sx,sy,ex,
cristy8cd5b312010-01-07 01:10:24 +0000765 ey,sd,ed);
cristy3ed852e2009-09-05 21:47:34 +0000766}
767
768/*
769%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
770% %
771% %
772% %
773% D r a w B e z i e r %
774% %
775% %
776% %
777%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
778%
779% DrawBezier() draws a bezier curve through a set of points on the image.
780%
781% The format of the DrawBezier method is:
782%
783% void DrawBezier(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +0000784% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +0000785%
786% A description of each parameter follows:
787%
788% o wand: the drawing wand.
789%
790% o number_coordinates: number of coordinates
791%
792% o coordinates: coordinates
793%
794*/
795WandExport void DrawBezier(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +0000796 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +0000797{
798 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000799 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000800 if (wand->debug != MagickFalse)
801 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
802 assert(coordinates != (const PointInfo *) NULL);
Cristybd0db062015-12-26 10:33:53 -0500803 MVGAppendPointsCommand(wand,"bezier",number_coordinates,coordinates);
cristy3ed852e2009-09-05 21:47:34 +0000804}
805
806/*
807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
808% %
809% %
810% %
811% D r a w C i r c l e %
812% %
813% %
814% %
815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816%
817% DrawCircle() draws a circle on the image.
818%
819% The format of the DrawCircle method is:
820%
821% void DrawCircle(DrawingWand *wand,const double ox,
822% const double oy,const double px, const double py)
823%
824% A description of each parameter follows:
825%
826% o wand: the drawing wand.
827%
828% o ox: origin x ordinate
829%
830% o oy: origin y ordinate
831%
832% o px: perimeter x ordinate
833%
834% o py: perimeter y ordinate
835%
836*/
837WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
838 const double px,const double py)
839{
840 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000841 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000842 if (wand->debug != MagickFalse)
843 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -0500844 (void) MVGPrintf(wand,"circle %.20g %.20g %.20g %.20g\n",ox,oy,px,py);
cristy3ed852e2009-09-05 21:47:34 +0000845}
846
847/*
848%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
849% %
850% %
851% %
852% D r a w C l e a r E x c e p t i o n %
853% %
854% %
855% %
856%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
857%
858% DrawClearException() clear any exceptions associated with the wand.
859%
860% The format of the DrawClearException method is:
861%
862% MagickBooleanType DrawClearException(DrawWand *wand)
863%
864% A description of each parameter follows:
865%
866% o wand: the drawing wand.
867%
868*/
869WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
870{
871 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000872 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +0000873 if (wand->debug != MagickFalse)
874 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
875 ClearMagickException(wand->exception);
876 return(MagickTrue);
877}
dirk1940fe02013-12-07 19:19:26 +0000878
879/*
880%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881% %
882% %
883% %
884% D r a w C l o n e E x c e p t i o n I n f o %
885% %
886% %
887% %
888%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889%
890% DrawCloneExceptionInfo() clones the ExceptionInfo structure within the wand.
891%
892% The format of the DrawCloneExceptionInfo method is:
893%
894% ExceptionInfo *DrawCloneExceptionInfo(DrawWand *wand)
895%
896% A description of each parameter follows:
897%
898% o wand: the drawing wand.
899%
900*/
901WandExport ExceptionInfo *DrawCloneExceptionInfo(const DrawingWand *wand)
902{
903 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000904 assert(wand->signature == MagickWandSignature);
dirk1940fe02013-12-07 19:19:26 +0000905 if (wand->exception == (ExceptionInfo*) NULL)
906 return (ExceptionInfo*) NULL;
907 return CloneExceptionInfo(wand->exception);
908}
dirk03c2ebf2015-12-26 14:51:51 +0100909
910/*
911%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
912% %
913% %
914% %
915% D r a w C o l o r %
916% %
917% %
918% %
919%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
920%
921% DrawColor() draws color on image using the current fill color, starting at
922% specified position, and using specified paint method. The available paint
923% methods are:
924%
925% PointMethod: Recolors the target pixel
926% ReplaceMethod: Recolor any pixel that matches the target pixel.
927% FloodfillMethod: Recolors target pixels and matching neighbors.
928% ResetMethod: Recolor all pixels.
929%
930% The format of the DrawColor method is:
931%
932% void DrawColor(DrawingWand *wand,const double x,const double y,
933% const PaintMethod paint_method)
934%
935% A description of each parameter follows:
936%
937% o wand: the drawing wand.
938%
939% o x: x ordinate.
940%
941% o y: y ordinate.
942%
943% o paint_method: paint method.
944%
945*/
946WandExport void DrawColor(DrawingWand *wand, const double x, const double y,
947 const PaintMethod paint_method)
948{
949 assert(wand != (DrawingWand *)NULL);
950 assert(wand->signature == MagickWandSignature);
951 if (wand->debug != MagickFalse)
952 (void) LogMagickEvent(WandEvent, GetMagickModule(), "%s", wand->name);
Cristybd0db062015-12-26 10:33:53 -0500953 (void) MVGPrintf(wand, "color %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
954 MagickMethodOptions,(ssize_t) paint_method));
dirk03c2ebf2015-12-26 14:51:51 +0100955}
cristy3ed852e2009-09-05 21:47:34 +0000956
957/*
958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959% %
960% %
961% %
962% D r a w C o m p o s i t e %
963% %
964% %
965% %
966%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967%
968% DrawComposite() composites an image onto the current image, using the
969% specified composition operator, specified position, and at the specified
970% size.
971%
972% The format of the DrawComposite method is:
973%
974% MagickBooleanType DrawComposite(DrawingWand *wand,
975% const CompositeOperator compose,const double x,
976% const double y,const double width,const double height,
977% MagickWand *magick_wand)
978%
979% A description of each parameter follows:
980%
981% o wand: the drawing wand.
982%
983% o compose: composition operator
984%
985% o x: x ordinate of top left corner
986%
987% o y: y ordinate of top left corner
988%
989% o width: Width to resize image to prior to compositing. Specify zero to
990% use existing width.
991%
992% o height: Height to resize image to prior to compositing. Specify zero
993% to use existing height.
994%
995% o magick_wand: Image to composite is obtained from this wand.
996%
997*/
998WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
999 const CompositeOperator compose,const double x,const double y,
1000 const double width,const double height,MagickWand *magick_wand)
cristy3ed852e2009-09-05 21:47:34 +00001001{
1002 char
1003 *base64,
1004 *media_type;
1005
1006 const char
1007 *mode;
1008
1009 ImageInfo
1010 *image_info;
1011
1012 Image
1013 *clone_image,
1014 *image;
1015
1016 register char
1017 *p;
1018
cristybb503372010-05-27 20:51:26 +00001019 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001020 i;
1021
1022 size_t
1023 blob_length,
1024 encoded_length;
1025
1026 unsigned char
1027 *blob;
1028
1029 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001030 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001031 if (wand->debug != MagickFalse)
1032 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1033 assert(magick_wand != (MagickWand *) NULL);
1034 image=GetImageFromMagickWand(magick_wand);
1035 if (image == (Image *) NULL)
1036 return(MagickFalse);
1037 clone_image=CloneImage(image,0,0,MagickTrue,wand->exception);
1038 if (clone_image == (Image *) NULL)
1039 return(MagickFalse);
1040 image_info=AcquireImageInfo();
cristy151b66d2015-04-15 10:50:31 +00001041 (void) CopyMagickString(image_info->magick,"MIFF",MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00001042 blob_length=2048;
1043 blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
1044 wand->exception);
1045 image_info=DestroyImageInfo(image_info);
1046 clone_image=DestroyImageList(clone_image);
1047 if (blob == (void *) NULL)
1048 return(MagickFalse);
1049 encoded_length=0;
1050 base64=Base64Encode(blob,blob_length,&encoded_length);
1051 blob=(unsigned char *) RelinquishMagickMemory(blob);
1052 if (base64 == (char *) NULL)
1053 {
1054 char
cristy151b66d2015-04-15 10:50:31 +00001055 buffer[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00001056
cristy151b66d2015-04-15 10:50:31 +00001057 (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g bytes",(double)
cristy3ed852e2009-09-05 21:47:34 +00001058 (4L*blob_length/3L+4L));
1059 ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
1060 wand->name);
1061 return(MagickFalse);
1062 }
cristy042ee782011-04-22 18:48:30 +00001063 mode=CommandOptionToMnemonic(MagickComposeOptions,(ssize_t) compose);
cristy3ed852e2009-09-05 21:47:34 +00001064 media_type=MagickToMime(image->magick);
Cristybd0db062015-12-26 10:33:53 -05001065 (void) MVGPrintf(wand,"image %s %.20g %.20g %.20g %.20g 'data:%s;base64,\n",
cristy8cd5b312010-01-07 01:10:24 +00001066 mode,x,y,width,height,media_type);
cristy3ed852e2009-09-05 21:47:34 +00001067 p=base64;
cristybb503372010-05-27 20:51:26 +00001068 for (i=(ssize_t) encoded_length; i > 0; i-=76)
cristy3ed852e2009-09-05 21:47:34 +00001069 {
Cristybd0db062015-12-26 10:33:53 -05001070 (void) MVGPrintf(wand,"%.76s",p);
cristy3ed852e2009-09-05 21:47:34 +00001071 p+=76;
1072 if (i > 76)
Cristybd0db062015-12-26 10:33:53 -05001073 (void) MVGPrintf(wand,"\n");
cristy3ed852e2009-09-05 21:47:34 +00001074 }
Cristybd0db062015-12-26 10:33:53 -05001075 (void) MVGPrintf(wand,"'\n");
cristy3ed852e2009-09-05 21:47:34 +00001076 media_type=DestroyString(media_type);
1077 base64=DestroyString(base64);
1078 return(MagickTrue);
1079}
1080
1081/*
1082%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083% %
1084% %
1085% %
cristy3ed852e2009-09-05 21:47:34 +00001086% D r a w C o m m e n t %
1087% %
1088% %
1089% %
1090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1091%
1092% DrawComment() adds a comment to a vector output stream.
1093%
1094% The format of the DrawComment method is:
1095%
1096% void DrawComment(DrawingWand *wand,const char *comment)
1097%
1098% A description of each parameter follows:
1099%
1100% o wand: the drawing wand.
1101%
1102% o comment: comment text
1103%
1104*/
1105WandExport void DrawComment(DrawingWand *wand,const char *comment)
1106{
Cristybd0db062015-12-26 10:33:53 -05001107 (void) MVGPrintf(wand,"#%s\n",comment);
cristy3ed852e2009-09-05 21:47:34 +00001108}
1109
1110/*
1111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1112% %
1113% %
1114% %
1115% D r a w E l l i p s e %
1116% %
1117% %
1118% %
1119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120%
1121% DrawEllipse() draws an ellipse on the image.
1122%
1123% The format of the DrawEllipse method is:
1124%
1125% void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1126% const double rx,const double ry,const double start,const double end)
1127%
1128% A description of each parameter follows:
1129%
1130% o wand: the drawing wand.
1131%
1132% o ox: origin x ordinate
1133%
1134% o oy: origin y ordinate
1135%
1136% o rx: radius in x
1137%
1138% o ry: radius in y
1139%
1140% o start: starting rotation in degrees
1141%
1142% o end: ending rotation in degrees
1143%
1144*/
1145WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1146 const double rx,const double ry,const double start,const double end)
1147{
1148 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001149 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001150 if (wand->debug != MagickFalse)
1151 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05001152 (void) MVGPrintf(wand,"ellipse %.20g %.20g %.20g %.20g %.20g %.20g\n",ox,oy,
cristy8cd5b312010-01-07 01:10:24 +00001153 rx,ry,start,end);
cristy3ed852e2009-09-05 21:47:34 +00001154}
1155
1156/*
1157%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1158% %
1159% %
1160% %
1161% D r a w G e t B o r d e r C o l o r %
1162% %
1163% %
1164% %
1165%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1166%
1167% DrawGetBorderColor() returns the border color used for drawing bordered
1168% objects.
1169%
1170% The format of the DrawGetBorderColor method is:
1171%
1172% void DrawGetBorderColor(const DrawingWand *wand,
1173% PixelWand *border_color)
1174%
1175% A description of each parameter follows:
1176%
1177% o wand: the drawing wand.
1178%
1179% o border_color: Return the border color.
1180%
1181*/
1182WandExport void DrawGetBorderColor(const DrawingWand *wand,
1183 PixelWand *border_color)
1184{
1185 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001186 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001187 assert(border_color != (PixelWand *) NULL);
1188 if (wand->debug != MagickFalse)
1189 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyf82c4a02011-12-15 02:43:44 +00001190 PixelSetPixelColor(border_color,&CurrentContext->border_color);
cristy3ed852e2009-09-05 21:47:34 +00001191}
1192
1193/*
1194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1195% %
1196% %
1197% %
1198% D r a w G e t C l i p P a t h %
1199% %
1200% %
1201% %
1202%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1203%
1204% DrawGetClipPath() obtains the current clipping path ID. The value returned
cristya03e7992010-06-25 12:18:06 +00001205% must be deallocated by the user when it is no longer needed.
cristy3ed852e2009-09-05 21:47:34 +00001206%
1207% The format of the DrawGetClipPath method is:
1208%
1209% char *DrawGetClipPath(const DrawingWand *wand)
1210%
1211% A description of each parameter follows:
1212%
1213% o wand: the drawing wand.
1214%
1215*/
1216WandExport char *DrawGetClipPath(const DrawingWand *wand)
1217{
1218 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001219 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001220 if (wand->debug != MagickFalse)
1221 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1222 if (CurrentContext->clip_mask != (char *) NULL)
1223 return((char *) AcquireString(CurrentContext->clip_mask));
1224 return((char *) NULL);
1225}
1226
1227/*
1228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1229% %
1230% %
1231% %
1232% D r a w G e t C l i p R u l e %
1233% %
1234% %
1235% %
1236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1237%
1238% DrawGetClipRule() returns the current polygon fill rule to be used by the
1239% clipping path.
1240%
1241% The format of the DrawGetClipRule method is:
1242%
1243% FillRule DrawGetClipRule(const DrawingWand *wand)
1244%
1245% A description of each parameter follows:
1246%
1247% o wand: the drawing wand.
1248%
1249*/
1250WandExport FillRule DrawGetClipRule(const DrawingWand *wand)
1251{
1252 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001253 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001254 if (wand->debug != MagickFalse)
1255 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1256 return(CurrentContext->fill_rule);
1257}
1258
1259/*
1260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1261% %
1262% %
1263% %
1264% D r a w G e t C l i p U n i t s %
1265% %
1266% %
1267% %
1268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1269%
1270% DrawGetClipUnits() returns the interpretation of clip path units.
1271%
1272% The format of the DrawGetClipUnits method is:
1273%
1274% ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1275%
1276% A description of each parameter follows:
1277%
1278% o wand: the drawing wand.
1279%
1280*/
1281WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1282{
1283 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001284 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001285 if (wand->debug != MagickFalse)
1286 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1287 return(CurrentContext->clip_units);
1288}
Cristybd0db062015-12-26 10:33:53 -05001289
dirk47778472015-07-11 10:20:41 +00001290/*
1291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1292% %
1293% %
1294% %
1295% D r a w G e t D e n s i t y %
1296% %
1297% %
1298% %
1299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1300%
1301% DrawGetDensity() obtains the vertical and horizontal resolution. The value
1302% returned must be deallocated by the user when it is no longer needed.
1303%
1304% The format of the DrawGetDensity method is:
1305%
1306% char *DrawGetDensity(const DrawingWand *wand)
1307%
1308% A description of each parameter follows:
1309%
1310% o wand: the drawing wand.
1311%
1312*/
1313WandExport char *DrawGetDensity(const DrawingWand *wand)
1314{
1315 assert(wand != (const DrawingWand *) NULL);
1316 assert(wand->signature == MagickWandSignature);
1317 if (wand->debug != MagickFalse)
1318 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1319 if (CurrentContext->density != (char *) NULL)
1320 return((char *) AcquireString(CurrentContext->density));
1321 return((char *) NULL);
1322}
Cristybd0db062015-12-26 10:33:53 -05001323
cristy3ed852e2009-09-05 21:47:34 +00001324/*
1325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326% %
1327% %
1328% %
1329% D r a w G e t E x c e p t i o n %
1330% %
1331% %
1332% %
1333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1334%
1335% DrawGetException() returns the severity, reason, and description of any
1336% error that occurs when using other methods in this API.
1337%
1338% The format of the DrawGetException method is:
1339%
1340% char *DrawGetException(const DrawWand *wand,
1341% ExceptionType *severity)
1342%
1343% A description of each parameter follows:
1344%
1345% o wand: the drawing wand.
1346%
1347% o severity: the severity of the error is returned here.
1348%
1349*/
1350WandExport char *DrawGetException(const DrawingWand *wand,
1351 ExceptionType *severity)
1352{
1353 char
1354 *description;
1355
1356 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001357 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001358 if (wand->debug != MagickFalse)
1359 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1360 assert(severity != (ExceptionType *) NULL);
1361 *severity=wand->exception->severity;
cristy151b66d2015-04-15 10:50:31 +00001362 description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +00001363 sizeof(*description));
1364 if (description == (char *) NULL)
1365 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1366 wand->name);
1367 *description='\0';
1368 if (wand->exception->reason != (char *) NULL)
1369 (void) CopyMagickString(description,GetLocaleExceptionMessage(
1370 wand->exception->severity,wand->exception->reason),
cristy151b66d2015-04-15 10:50:31 +00001371 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00001372 if (wand->exception->description != (char *) NULL)
1373 {
cristy151b66d2015-04-15 10:50:31 +00001374 (void) ConcatenateMagickString(description," (",MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00001375 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
1376 wand->exception->severity,wand->exception->description),
cristy151b66d2015-04-15 10:50:31 +00001377 MagickPathExtent);
1378 (void) ConcatenateMagickString(description,")",MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00001379 }
1380 return(description);
1381}
1382
1383/*
1384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1385% %
1386% %
1387% %
1388% P i x e l G e t E x c e p t i o n T y p e %
1389% %
1390% %
1391% %
1392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1393%
1394% DrawGetExceptionType() the exception type associated with the wand. If
1395% no exception has occurred, UndefinedExceptionType is returned.
1396%
1397% The format of the DrawGetExceptionType method is:
1398%
1399% ExceptionType DrawGetExceptionType(const DrawWand *wand)
1400%
1401% A description of each parameter follows:
1402%
1403% o wand: the magick wand.
1404%
1405*/
1406WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand)
1407{
1408 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001409 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001410 if (wand->debug != MagickFalse)
1411 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1412 return(wand->exception->severity);
1413}
1414
1415/*
1416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417% %
1418% %
1419% %
1420% D r a w G e t F i l l C o l o r %
1421% %
1422% %
1423% %
1424%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1425%
1426% DrawGetFillColor() returns the fill color used for drawing filled objects.
1427%
1428% The format of the DrawGetFillColor method is:
1429%
1430% void DrawGetFillColor(const DrawingWand *wand,
1431% PixelWand *fill_color)
1432%
1433% A description of each parameter follows:
1434%
1435% o wand: the drawing wand.
1436%
1437% o fill_color: Return the fill color.
1438%
1439*/
1440WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color)
1441{
1442 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001443 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001444 assert(fill_color != (PixelWand *) NULL);
1445 if (wand->debug != MagickFalse)
1446 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyf82c4a02011-12-15 02:43:44 +00001447 PixelSetPixelColor(fill_color,&CurrentContext->fill);
cristy3ed852e2009-09-05 21:47:34 +00001448}
1449
1450/*
1451%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1452% %
1453% %
1454% %
1455% D r a w G e t F i l l O p a c i t y %
1456% %
1457% %
1458% %
1459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460%
dirkc8e845f2015-04-07 19:32:12 +00001461% DrawGetFillOpacity() returns the alpha used when drawing using the fill
cristy3ed852e2009-09-05 21:47:34 +00001462% color or fill texture. Fully opaque is 1.0.
1463%
dirkc8e845f2015-04-07 19:32:12 +00001464% The format of the DrawGetFillOpacity method is:
cristy3ed852e2009-09-05 21:47:34 +00001465%
dirkc8e845f2015-04-07 19:32:12 +00001466% double DrawGetFillOpacity(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001467%
1468% A description of each parameter follows:
1469%
1470% o wand: the drawing wand.
1471%
1472*/
dirkc8e845f2015-04-07 19:32:12 +00001473WandExport double DrawGetFillOpacity(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001474{
1475 double
1476 alpha;
1477
1478 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001479 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001480 if (wand->debug != MagickFalse)
1481 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy4c08aed2011-07-01 19:47:50 +00001482 alpha=(double) QuantumScale*CurrentContext->fill.alpha;
cristy3ed852e2009-09-05 21:47:34 +00001483 return(alpha);
1484}
1485
1486/*
1487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1488% %
1489% %
1490% %
1491% D r a w G e t F i l l R u l e %
1492% %
1493% %
1494% %
1495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1496%
1497% DrawGetFillRule() returns the fill rule used while drawing polygons.
1498%
1499% The format of the DrawGetFillRule method is:
1500%
1501% FillRule DrawGetFillRule(const DrawingWand *wand)
1502%
1503% A description of each parameter follows:
1504%
1505% o wand: the drawing wand.
1506%
1507*/
1508WandExport FillRule DrawGetFillRule(const DrawingWand *wand)
1509{
1510 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001511 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001512 if (wand->debug != MagickFalse)
1513 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1514 return(CurrentContext->fill_rule);
1515}
1516
1517/*
1518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1519% %
1520% %
1521% %
1522% D r a w G e t F o n t %
1523% %
1524% %
1525% %
1526%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1527%
1528% DrawGetFont() returns a null-terminaged string specifying the font used
1529% when annotating with text. The value returned must be freed by the user
cristya03e7992010-06-25 12:18:06 +00001530% when no longer needed.
cristy3ed852e2009-09-05 21:47:34 +00001531%
1532% The format of the DrawGetFont method is:
1533%
1534% char *DrawGetFont(const DrawingWand *wand)
1535%
1536% A description of each parameter follows:
1537%
1538% o wand: the drawing wand.
1539%
1540*/
1541WandExport char *DrawGetFont(const DrawingWand *wand)
1542{
1543 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001544 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001545 if (wand->debug != MagickFalse)
1546 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1547 if (CurrentContext->font != (char *) NULL)
1548 return(AcquireString(CurrentContext->font));
1549 return((char *) NULL);
1550}
1551
1552/*
1553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1554% %
1555% %
1556% %
1557% D r a w G e t F o n t F a m i l y %
1558% %
1559% %
1560% %
1561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1562%
1563% DrawGetFontFamily() returns the font family to use when annotating with text.
cristya03e7992010-06-25 12:18:06 +00001564% The value returned must be freed by the user when it is no longer needed.
cristy3ed852e2009-09-05 21:47:34 +00001565%
1566% The format of the DrawGetFontFamily method is:
1567%
1568% char *DrawGetFontFamily(const DrawingWand *wand)
1569%
1570% A description of each parameter follows:
1571%
1572% o wand: the drawing wand.
1573%
1574*/
1575WandExport char *DrawGetFontFamily(const DrawingWand *wand)
1576{
1577 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001578 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001579 if (wand->debug != MagickFalse)
1580 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1581 if (CurrentContext->family != NULL)
1582 return(AcquireString(CurrentContext->family));
1583 return((char *) NULL);
1584}
1585
1586/*
1587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1588% %
1589% %
1590% %
cristy56375382010-11-21 23:49:30 +00001591% D r a w G e t F o n t R e s o l u t i o n %
1592% %
1593% %
1594% %
1595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596%
1597% DrawGetFontResolution() gets the image X and Y resolution.
1598%
1599% The format of the DrawGetFontResolution method is:
1600%
cristy76fa3142012-04-26 11:30:17 +00001601% MagickBooleanType DrawGetFontResolution(const DrawingWand *wand,
cristy56375382010-11-21 23:49:30 +00001602% double *x,double *y)
1603%
1604% A description of each parameter follows:
1605%
1606% o wand: the magick wand.
1607%
1608% o x: the x-resolution.
1609%
1610% o y: the y-resolution.
1611%
1612*/
1613WandExport MagickBooleanType DrawGetFontResolution(const DrawingWand *wand,
1614 double *x,double *y)
1615{
1616 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001617 assert(wand->signature == MagickWandSignature);
cristy56375382010-11-21 23:49:30 +00001618 if (wand->debug != MagickFalse)
1619 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1620 *x=72.0;
1621 *y=72.0;
1622 if (CurrentContext->density != (char *) NULL)
1623 {
1624 GeometryInfo
1625 geometry_info;
1626
1627 MagickStatusType
1628 flags;
1629
1630 flags=ParseGeometry(CurrentContext->density,&geometry_info);
1631 *x=geometry_info.rho;
1632 *y=geometry_info.sigma;
1633 if ((flags & SigmaValue) == MagickFalse)
1634 *y=(*x);
1635 }
1636 return(MagickTrue);
1637}
1638
1639/*
1640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1641% %
1642% %
1643% %
cristy3ed852e2009-09-05 21:47:34 +00001644% D r a w G e t F o n t S i z e %
1645% %
1646% %
1647% %
1648%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1649%
1650% DrawGetFontSize() returns the font pointsize used when annotating with text.
1651%
1652% The format of the DrawGetFontSize method is:
1653%
1654% double DrawGetFontSize(const DrawingWand *wand)
1655%
1656% A description of each parameter follows:
1657%
1658% o wand: the drawing wand.
1659%
1660*/
1661WandExport double DrawGetFontSize(const DrawingWand *wand)
1662{
1663 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001664 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001665 if (wand->debug != MagickFalse)
1666 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1667 return(CurrentContext->pointsize);
1668}
1669
1670/*
1671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1672% %
1673% %
1674% %
1675% D r a w G e t F o n t S t r e t c h %
1676% %
1677% %
1678% %
1679%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1680%
1681% DrawGetFontStretch() returns the font stretch used when annotating with text.
1682%
1683% The format of the DrawGetFontStretch method is:
1684%
1685% StretchType DrawGetFontStretch(const DrawingWand *wand)
1686%
1687% A description of each parameter follows:
1688%
1689% o wand: the drawing wand.
1690%
1691*/
1692WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1693{
1694 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001695 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001696 if (wand->debug != MagickFalse)
1697 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1698 return(CurrentContext->stretch);
1699}
1700
1701/*
1702%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1703% %
1704% %
1705% %
1706% D r a w G e t F o n t S t y l e %
1707% %
1708% %
1709% %
1710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1711%
1712% DrawGetFontStyle() returns the font style used when annotating with text.
1713%
1714% The format of the DrawGetFontStyle method is:
1715%
1716% StyleType DrawGetFontStyle(const DrawingWand *wand)
1717%
1718% A description of each parameter follows:
1719%
1720% o wand: the drawing wand.
1721%
1722*/
1723WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1724{
1725 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001726 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001727 if (wand->debug != MagickFalse)
1728 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1729 return(CurrentContext->style);
1730}
1731
1732/*
1733%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1734% %
1735% %
1736% %
1737% D r a w G e t F o n t W e i g h t %
1738% %
1739% %
1740% %
1741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1742%
1743% DrawGetFontWeight() returns the font weight used when annotating with text.
1744%
1745% The format of the DrawGetFontWeight method is:
1746%
cristybb503372010-05-27 20:51:26 +00001747% size_t DrawGetFontWeight(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001748%
1749% A description of each parameter follows:
1750%
1751% o wand: the drawing wand.
1752%
1753*/
cristybb503372010-05-27 20:51:26 +00001754WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001755{
1756 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001757 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001758 if (wand->debug != MagickFalse)
1759 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1760 return(CurrentContext->weight);
1761}
1762
1763/*
1764%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1765% %
1766% %
1767% %
1768% D r a w G e t G r a v i t y %
1769% %
1770% %
1771% %
1772%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1773%
1774% DrawGetGravity() returns the text placement gravity used when annotating
1775% with text.
1776%
1777% The format of the DrawGetGravity method is:
1778%
1779% GravityType DrawGetGravity(const DrawingWand *wand)
1780%
1781% A description of each parameter follows:
1782%
1783% o wand: the drawing wand.
1784%
1785*/
1786WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1787{
1788 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001789 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001790 if (wand->debug != MagickFalse)
1791 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1792 return(CurrentContext->gravity);
1793}
1794
1795/*
1796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1797% %
1798% %
1799% %
1800% D r a w G e t O p a c i t y %
1801% %
1802% %
1803% %
1804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1805%
dirkc8e845f2015-04-07 19:32:12 +00001806% DrawGetOpacity() returns the alpha used when drawing with the fill
cristy3ed852e2009-09-05 21:47:34 +00001807% or stroke color or texture. Fully opaque is 1.0.
1808%
dirkc8e845f2015-04-07 19:32:12 +00001809% The format of the DrawGetOpacity method is:
cristy3ed852e2009-09-05 21:47:34 +00001810%
dirkc8e845f2015-04-07 19:32:12 +00001811% double DrawGetOpacity(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001812%
1813% A description of each parameter follows:
1814%
1815% o wand: the drawing wand.
1816%
1817*/
dirkc8e845f2015-04-07 19:32:12 +00001818WandExport double DrawGetOpacity(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00001819{
1820 double
1821 alpha;
1822
1823 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001824 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001825 if (wand->debug != MagickFalse)
1826 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy4c08aed2011-07-01 19:47:50 +00001827 alpha=(double) QuantumScale*CurrentContext->alpha;
cristy3ed852e2009-09-05 21:47:34 +00001828 return(alpha);
1829}
1830
1831/*
1832%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1833% %
1834% %
1835% %
1836% D r a w G e t S t r o k e A n t i a l i a s %
1837% %
1838% %
1839% %
1840%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1841%
1842% DrawGetStrokeAntialias() returns the current stroke antialias setting.
1843% Stroked outlines are antialiased by default. When antialiasing is disabled
1844% stroked pixels are thresholded to determine if the stroke color or
1845% underlying canvas color should be used.
1846%
1847% The format of the DrawGetStrokeAntialias method is:
1848%
1849% MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1850%
1851% A description of each parameter follows:
1852%
1853% o wand: the drawing wand.
1854%
1855*/
1856WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1857{
1858 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001859 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001860 if (wand->debug != MagickFalse)
1861 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1862 return(CurrentContext->stroke_antialias);
1863}
1864
1865/*
1866%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1867% %
1868% %
1869% %
1870% D r a w G e t S t r o k e C o l o r %
1871% %
1872% %
1873% %
1874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1875%
1876% DrawGetStrokeColor() returns the color used for stroking object outlines.
1877%
1878% The format of the DrawGetStrokeColor method is:
1879%
1880% void DrawGetStrokeColor(const DrawingWand *wand,
cristy76fa3142012-04-26 11:30:17 +00001881% PixelWand *stroke_color)
cristy3ed852e2009-09-05 21:47:34 +00001882%
1883% A description of each parameter follows:
1884%
1885% o wand: the drawing wand.
1886%
1887% o stroke_color: Return the stroke color.
1888%
1889*/
1890WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1891 PixelWand *stroke_color)
1892{
1893 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001894 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001895 assert(stroke_color != (PixelWand *) NULL);
1896 if (wand->debug != MagickFalse)
1897 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyf82c4a02011-12-15 02:43:44 +00001898 PixelSetPixelColor(stroke_color,&CurrentContext->stroke);
cristy3ed852e2009-09-05 21:47:34 +00001899}
1900
1901/*
1902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1903% %
1904% %
1905% %
1906% D r a w G e t S t r o k e D a s h A r r a y %
1907% %
1908% %
1909% %
1910%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1911%
1912% DrawGetStrokeDashArray() returns an array representing the pattern of
1913% dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
cristya03e7992010-06-25 12:18:06 +00001914% array must be freed once it is no longer required by the user.
cristy3ed852e2009-09-05 21:47:34 +00001915%
1916% The format of the DrawGetStrokeDashArray method is:
1917%
1918% double *DrawGetStrokeDashArray(const DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00001919% size_t *number_elements)
cristy3ed852e2009-09-05 21:47:34 +00001920%
1921% A description of each parameter follows:
1922%
1923% o wand: the drawing wand.
1924%
1925% o number_elements: address to place number of elements in dash array
1926%
1927*/
1928WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00001929 size_t *number_elements)
cristy3ed852e2009-09-05 21:47:34 +00001930{
1931 double
cristy6145b192013-12-15 23:58:29 +00001932 *dasharray;
cristy3ed852e2009-09-05 21:47:34 +00001933
1934 register const double
1935 *p;
1936
1937 register double
1938 *q;
1939
cristybb503372010-05-27 20:51:26 +00001940 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001941 i;
1942
cristybb503372010-05-27 20:51:26 +00001943 size_t
cristy3ed852e2009-09-05 21:47:34 +00001944 n;
1945
1946 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001947 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001948 if (wand->debug != MagickFalse)
1949 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristybb503372010-05-27 20:51:26 +00001950 assert(number_elements != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001951 n=0;
1952 p=CurrentContext->dash_pattern;
1953 if (p != (const double *) NULL)
cristy5f07f702011-09-26 17:29:10 +00001954 while (fabs(*p++) >= MagickEpsilon)
cristy3ed852e2009-09-05 21:47:34 +00001955 n++;
1956 *number_elements=n;
cristy6145b192013-12-15 23:58:29 +00001957 dasharray=(double *) NULL;
cristy3ed852e2009-09-05 21:47:34 +00001958 if (n != 0)
1959 {
cristy6145b192013-12-15 23:58:29 +00001960 dasharray=(double *) AcquireQuantumMemory((size_t) n+1UL,
1961 sizeof(*dasharray));
cristy3ed852e2009-09-05 21:47:34 +00001962 p=CurrentContext->dash_pattern;
cristy6145b192013-12-15 23:58:29 +00001963 q=dasharray;
cristybb503372010-05-27 20:51:26 +00001964 for (i=0; i < (ssize_t) n; i++)
cristy3ed852e2009-09-05 21:47:34 +00001965 *q++=(*p++);
cristyacac4a32013-11-30 23:50:01 +00001966 *q=0.0;
cristy3ed852e2009-09-05 21:47:34 +00001967 }
cristy6145b192013-12-15 23:58:29 +00001968 return(dasharray);
cristy3ed852e2009-09-05 21:47:34 +00001969}
1970
1971/*
1972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1973% %
1974% %
1975% %
1976% D r a w G e t S t r o k e D a s h O f f s e t %
1977% %
1978% %
1979% %
1980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1981%
1982% DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1983% start the dash.
1984%
1985% The format of the DrawGetStrokeDashOffset method is:
1986%
1987% double DrawGetStrokeDashOffset(const DrawingWand *wand)
1988%
1989% A description of each parameter follows:
1990%
1991% o wand: the drawing wand.
1992%
1993*/
1994WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1995{
1996 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001997 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00001998 if (wand->debug != MagickFalse)
1999 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2000 return(CurrentContext->dash_offset);
2001}
2002
2003/*
2004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005% %
2006% %
2007% %
2008% D r a w G e t S t r o k e L i n e C a p %
2009% %
2010% %
2011% %
2012%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2013%
2014% DrawGetStrokeLineCap() returns the shape to be used at the end of
2015% open subpaths when they are stroked. Values of LineCap are
2016% UndefinedCap, ButtCap, RoundCap, and SquareCap.
2017%
2018% The format of the DrawGetStrokeLineCap method is:
2019%
2020% LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2021%
2022% A description of each parameter follows:
2023%
2024% o wand: the drawing wand.
2025%
2026*/
2027WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2028{
2029 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002030 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002031 if (wand->debug != MagickFalse)
2032 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2033 return(CurrentContext->linecap);
2034}
2035
2036/*
2037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2038% %
2039% %
2040% %
2041% D r a w G e t S t r o k e L i n e J o i n %
2042% %
2043% %
2044% %
2045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2046%
2047% DrawGetStrokeLineJoin() returns the shape to be used at the
2048% corners of paths (or other vector shapes) when they are
2049% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
2050% and BevelJoin.
2051%
2052% The format of the DrawGetStrokeLineJoin method is:
2053%
2054% LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2055%
2056% A description of each parameter follows:
2057%
2058% o wand: the drawing wand.
2059%
2060*/
2061WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2062{
2063 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002064 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002065 if (wand->debug != MagickFalse)
2066 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2067 return(CurrentContext->linejoin);
2068}
2069
2070/*
2071%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2072% %
2073% %
2074% %
2075% D r a w G e t S t r o k e M i t e r L i m i t %
2076% %
2077% %
2078% %
2079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2080%
2081% DrawGetStrokeMiterLimit() returns the miter limit. When two line
2082% segments meet at a sharp angle and miter joins have been specified for
2083% 'lineJoin', it is possible for the miter to extend far beyond the
2084% thickness of the line stroking the path. The miterLimit' imposes a
2085% limit on the ratio of the miter length to the 'lineWidth'.
2086%
2087% The format of the DrawGetStrokeMiterLimit method is:
2088%
cristybb503372010-05-27 20:51:26 +00002089% size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002090%
2091% A description of each parameter follows:
2092%
2093% o wand: the drawing wand.
2094%
2095*/
cristybb503372010-05-27 20:51:26 +00002096WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002097{
2098 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002099 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002100 if (wand->debug != MagickFalse)
2101 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2102 return CurrentContext->miterlimit;
2103}
2104
2105/*
2106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2107% %
2108% %
2109% %
2110% D r a w G e t S t r o k e O p a c i t y %
2111% %
2112% %
2113% %
2114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2115%
dirkc8e845f2015-04-07 19:32:12 +00002116% DrawGetStrokeOpacity() returns the alpha of stroked object outlines.
cristy3ed852e2009-09-05 21:47:34 +00002117%
dirkc8e845f2015-04-07 19:32:12 +00002118% The format of the DrawGetStrokeOpacity method is:
cristy3ed852e2009-09-05 21:47:34 +00002119%
dirkc8e845f2015-04-07 19:32:12 +00002120% double DrawGetStrokeOpacity(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002121%
2122% A description of each parameter follows:
2123%
2124% o wand: the drawing wand.
2125%
2126*/
dirkc8e845f2015-04-07 19:32:12 +00002127WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002128{
2129 double
2130 alpha;
2131
2132 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002133 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002134 if (wand->debug != MagickFalse)
2135 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy4c08aed2011-07-01 19:47:50 +00002136 alpha=(double) QuantumScale*CurrentContext->stroke.alpha;
cristy3ed852e2009-09-05 21:47:34 +00002137 return(alpha);
2138}
2139
2140/*
2141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2142% %
2143% %
2144% %
2145% D r a w G e t S t r o k e W i d t h %
2146% %
2147% %
2148% %
2149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2150%
2151% DrawGetStrokeWidth() returns the width of the stroke used to draw object
2152% outlines.
2153%
2154% The format of the DrawGetStrokeWidth method is:
2155%
2156% double DrawGetStrokeWidth(const DrawingWand *wand)
2157%
2158% A description of each parameter follows:
2159%
2160% o wand: the drawing wand.
2161%
2162*/
2163WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2164{
2165 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002166 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002167 if (wand->debug != MagickFalse)
2168 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2169 return(CurrentContext->stroke_width);
2170}
2171
2172/*
2173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2174% %
2175% %
2176% %
2177% D r a w G e t T e x t A l i g n m e n t %
2178% %
2179% %
2180% %
2181%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2182%
2183% DrawGetTextAlignment() returns the alignment applied when annotating with
2184% text.
2185%
2186% The format of the DrawGetTextAlignment method is:
2187%
cristy76fa3142012-04-26 11:30:17 +00002188% AlignType DrawGetTextAlignment(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002189%
2190% A description of each parameter follows:
2191%
2192% o wand: the drawing wand.
2193%
2194*/
2195WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2196{
2197 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002198 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002199 if (wand->debug != MagickFalse)
2200 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2201 return(CurrentContext->align);
2202}
2203
2204/*
2205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2206% %
2207% %
2208% %
2209% D r a w G e t T e x t A n t i a l i a s %
2210% %
2211% %
2212% %
2213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2214%
2215% DrawGetTextAntialias() returns the current text antialias setting, which
2216% determines whether text is antialiased. Text is antialiased by default.
2217%
2218% The format of the DrawGetTextAntialias method is:
2219%
2220% MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2221%
2222% A description of each parameter follows:
2223%
2224% o wand: the drawing wand.
2225%
2226*/
2227WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2228{
2229 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002230 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002231 if (wand->debug != MagickFalse)
2232 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2233 return(CurrentContext->text_antialias);
2234}
2235
2236/*
2237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238% %
2239% %
2240% %
2241% D r a w G e t T e x t D e c o r a t i o n %
2242% %
2243% %
2244% %
2245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2246%
2247% DrawGetTextDecoration() returns the decoration applied when annotating with
2248% text.
2249%
2250% The format of the DrawGetTextDecoration method is:
2251%
cristy76fa3142012-04-26 11:30:17 +00002252% DecorationType DrawGetTextDecoration(const DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002253%
2254% A description of each parameter follows:
2255%
2256% o wand: the drawing wand.
2257%
2258*/
2259WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2260{
2261 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002262 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002263 if (wand->debug != MagickFalse)
2264 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2265 return(CurrentContext->decorate);
2266}
2267
2268/*
2269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2270% %
2271% %
2272% %
dirkc084d392014-01-27 19:08:45 +00002273% D r a w G e t T e x t D i r e c t i o n %
2274% %
2275% %
2276% %
2277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2278%
2279% DrawGetTextDirection() returns the direction that will be used when
2280% annotating with text.
2281%
2282% The format of the DrawGetTextDirection method is:
2283%
2284% DirectionType DrawGetTextDirection(const DrawingWand *wand)
2285%
2286% A description of each parameter follows:
2287%
2288% o wand: the drawing wand.
2289%
2290*/
2291WandExport DirectionType DrawGetTextDirection(const DrawingWand *wand)
2292{
2293 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002294 assert(wand->signature == MagickWandSignature);
dirkc084d392014-01-27 19:08:45 +00002295 if (wand->debug != MagickFalse)
2296 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2297 return(CurrentContext->direction);
2298}
2299
2300/*
2301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2302% %
2303% %
2304% %
cristy3ed852e2009-09-05 21:47:34 +00002305% D r a w G e t T e x t E n c o d i n g %
2306% %
2307% %
2308% %
2309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2310%
2311% DrawGetTextEncoding() returns a null-terminated string which specifies the
2312% code set used for text annotations. The string must be freed by the user
cristya03e7992010-06-25 12:18:06 +00002313% once it is no longer required.
cristy3ed852e2009-09-05 21:47:34 +00002314%
2315% The format of the DrawGetTextEncoding method is:
2316%
2317% char *DrawGetTextEncoding(const DrawingWand *wand)
2318%
2319% A description of each parameter follows:
2320%
2321% o wand: the drawing wand.
2322%
2323*/
2324WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2325{
2326 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002327 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002328 if (wand->debug != MagickFalse)
2329 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2330 if (CurrentContext->encoding != (char *) NULL)
2331 return((char *) AcquireString(CurrentContext->encoding));
2332 return((char *) NULL);
2333}
2334
2335/*
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337% %
2338% %
2339% %
2340% D r a w G e t T e x t K e r n i n g %
2341% %
2342% %
2343% %
2344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2345%
2346% DrawGetTextKerning() gets the spacing between characters in text.
2347%
2348% The format of the DrawSetFontKerning method is:
2349%
2350% double DrawGetTextKerning(DrawingWand *wand)
2351%
2352% A description of each parameter follows:
2353%
2354% o wand: the drawing wand.
2355%
2356*/
2357WandExport double DrawGetTextKerning(DrawingWand *wand)
2358{
2359 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002360 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002361
2362 if (wand->debug != MagickFalse)
2363 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2364 return(CurrentContext->kerning);
2365}
2366
2367/*
2368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2369% %
2370% %
2371% %
cristy76fa3142012-04-26 11:30:17 +00002372% 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 %
cristyb32b90a2009-09-07 21:45:48 +00002373% %
2374% %
2375% %
2376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2377%
cristy76fa3142012-04-26 11:30:17 +00002378% DrawGetTextInterlineSpacing() gets the spacing between lines in text.
cristyb32b90a2009-09-07 21:45:48 +00002379%
cristy76fa3142012-04-26 11:30:17 +00002380% The format of the DrawGetTextInterlineSpacing method is:
cristyb32b90a2009-09-07 21:45:48 +00002381%
cristy76fa3142012-04-26 11:30:17 +00002382% double DrawGetTextInterlineSpacing(DrawingWand *wand)
cristyb32b90a2009-09-07 21:45:48 +00002383%
2384% A description of each parameter follows:
2385%
2386% o wand: the drawing wand.
2387%
2388*/
2389WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2390{
2391 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002392 assert(wand->signature == MagickWandSignature);
cristyb32b90a2009-09-07 21:45:48 +00002393 if (wand->debug != MagickFalse)
2394 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2395 return(CurrentContext->interline_spacing);
2396}
2397
2398/*
2399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2400% %
2401% %
2402% %
cristy3ed852e2009-09-05 21:47:34 +00002403% 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 %
2404% %
2405% %
2406% %
2407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2408%
2409% DrawGetTextInterwordSpacing() gets the spacing between words in text.
2410%
2411% The format of the DrawSetFontKerning method is:
2412%
2413% double DrawGetTextInterwordSpacing(DrawingWand *wand)
2414%
2415% A description of each parameter follows:
2416%
2417% o wand: the drawing wand.
2418%
2419*/
2420WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2421{
2422 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002423 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002424 if (wand->debug != MagickFalse)
2425 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2426 return(CurrentContext->interword_spacing);
2427}
2428
2429/*
2430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2431% %
2432% %
2433% %
2434% D r a w G e t V e c t o r G r a p h i c s %
2435% %
2436% %
2437% %
2438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2439%
2440% DrawGetVectorGraphics() returns a null-terminated string which specifies the
2441% vector graphics generated by any graphics calls made since the wand was
cristya03e7992010-06-25 12:18:06 +00002442% instantiated. The string must be freed by the user once it is no longer
cristy3ed852e2009-09-05 21:47:34 +00002443% required.
2444%
2445% The format of the DrawGetVectorGraphics method is:
2446%
cristy76fa3142012-04-26 11:30:17 +00002447% char *DrawGetVectorGraphics(DrawingWand *wand)
cristy3ed852e2009-09-05 21:47:34 +00002448%
2449% A description of each parameter follows:
2450%
2451% o wand: the drawing wand.
2452%
2453*/
cristy3ed852e2009-09-05 21:47:34 +00002454WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2455{
2456 char
cristy151b66d2015-04-15 10:50:31 +00002457 value[MagickPathExtent],
cristy3ed852e2009-09-05 21:47:34 +00002458 *xml;
2459
cristy4c08aed2011-07-01 19:47:50 +00002460 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00002461 pixel;
2462
cristybb503372010-05-27 20:51:26 +00002463 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002464 i;
2465
2466 XMLTreeInfo
2467 *child,
2468 *xml_info;
2469
2470 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002471 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002472 if (wand->debug != MagickFalse)
2473 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2474 xml_info=NewXMLTreeTag("drawing-wand");
2475 if (xml_info == (XMLTreeInfo *) NULL)
cristyb73762e2015-06-03 13:53:05 +00002476 return((char *) NULL);
2477 (void) SetXMLTreeContent(xml_info," ");
cristy4c08aed2011-07-01 19:47:50 +00002478 GetPixelInfo(wand->image,&pixel);
cristy3ed852e2009-09-05 21:47:34 +00002479 child=AddChildToXMLTree(xml_info,"clip-path",0);
2480 if (child != (XMLTreeInfo *) NULL)
2481 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2482 child=AddChildToXMLTree(xml_info,"clip-units",0);
2483 if (child != (XMLTreeInfo *) NULL)
2484 {
cristy042ee782011-04-22 18:48:30 +00002485 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristy4c08aed2011-07-01 19:47:50 +00002486 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),
cristy151b66d2015-04-15 10:50:31 +00002487 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002488 (void) SetXMLTreeContent(child,value);
2489 }
2490 child=AddChildToXMLTree(xml_info,"decorate",0);
2491 if (child != (XMLTreeInfo *) NULL)
2492 {
cristy042ee782011-04-22 18:48:30 +00002493 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristy4c08aed2011-07-01 19:47:50 +00002494 MagickDecorateOptions,(ssize_t) CurrentContext->decorate),
cristy151b66d2015-04-15 10:50:31 +00002495 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002496 (void) SetXMLTreeContent(child,value);
2497 }
2498 child=AddChildToXMLTree(xml_info,"encoding",0);
2499 if (child != (XMLTreeInfo *) NULL)
2500 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2501 child=AddChildToXMLTree(xml_info,"fill",0);
2502 if (child != (XMLTreeInfo *) NULL)
2503 {
cristy4c08aed2011-07-01 19:47:50 +00002504 if (CurrentContext->fill.alpha != OpaqueAlpha)
cristy8a46d822012-08-28 23:32:39 +00002505 pixel.alpha_trait=CurrentContext->fill.alpha != OpaqueAlpha ?
cristyb0a657e2012-08-29 00:45:37 +00002506 BlendPixelTrait : UndefinedPixelTrait;
cristy9d8c8ce2011-10-25 16:13:52 +00002507 pixel=CurrentContext->fill;
cristy3ed852e2009-09-05 21:47:34 +00002508 GetColorTuple(&pixel,MagickTrue,value);
2509 (void) SetXMLTreeContent(child,value);
2510 }
dirkc8e845f2015-04-07 19:32:12 +00002511 child=AddChildToXMLTree(xml_info,"fill-opacity",0);
cristy3ed852e2009-09-05 21:47:34 +00002512 if (child != (XMLTreeInfo *) NULL)
2513 {
cristy151b66d2015-04-15 10:50:31 +00002514 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristybd33da02014-08-26 11:26:30 +00002515 (double) (QuantumScale*CurrentContext->fill.alpha));
cristy3ed852e2009-09-05 21:47:34 +00002516 (void) SetXMLTreeContent(child,value);
2517 }
2518 child=AddChildToXMLTree(xml_info,"fill-rule",0);
2519 if (child != (XMLTreeInfo *) NULL)
2520 {
cristy042ee782011-04-22 18:48:30 +00002521 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristy14388de2011-05-15 14:57:16 +00002522 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),
cristy151b66d2015-04-15 10:50:31 +00002523 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002524 (void) SetXMLTreeContent(child,value);
2525 }
2526 child=AddChildToXMLTree(xml_info,"font",0);
2527 if (child != (XMLTreeInfo *) NULL)
2528 (void) SetXMLTreeContent(child,CurrentContext->font);
2529 child=AddChildToXMLTree(xml_info,"font-family",0);
2530 if (child != (XMLTreeInfo *) NULL)
2531 (void) SetXMLTreeContent(child,CurrentContext->family);
2532 child=AddChildToXMLTree(xml_info,"font-size",0);
2533 if (child != (XMLTreeInfo *) NULL)
2534 {
cristy151b66d2015-04-15 10:50:31 +00002535 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristy3ed852e2009-09-05 21:47:34 +00002536 CurrentContext->pointsize);
2537 (void) SetXMLTreeContent(child,value);
2538 }
2539 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2540 if (child != (XMLTreeInfo *) NULL)
2541 {
cristy042ee782011-04-22 18:48:30 +00002542 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristyb73762e2015-06-03 13:53:05 +00002543 MagickStretchOptions,(ssize_t) CurrentContext->stretch),
2544 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002545 (void) SetXMLTreeContent(child,value);
2546 }
2547 child=AddChildToXMLTree(xml_info,"font-style",0);
2548 if (child != (XMLTreeInfo *) NULL)
2549 {
cristy042ee782011-04-22 18:48:30 +00002550 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristy151b66d2015-04-15 10:50:31 +00002551 MagickStyleOptions,(ssize_t) CurrentContext->style),MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002552 (void) SetXMLTreeContent(child,value);
2553 }
2554 child=AddChildToXMLTree(xml_info,"font-weight",0);
2555 if (child != (XMLTreeInfo *) NULL)
2556 {
cristy151b66d2015-04-15 10:50:31 +00002557 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
cristy3ed852e2009-09-05 21:47:34 +00002558 CurrentContext->weight);
2559 (void) SetXMLTreeContent(child,value);
2560 }
2561 child=AddChildToXMLTree(xml_info,"gravity",0);
2562 if (child != (XMLTreeInfo *) NULL)
2563 {
cristy4c08aed2011-07-01 19:47:50 +00002564 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristyb73762e2015-06-03 13:53:05 +00002565 MagickGravityOptions,(ssize_t) CurrentContext->gravity),
2566 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002567 (void) SetXMLTreeContent(child,value);
2568 }
2569 child=AddChildToXMLTree(xml_info,"stroke",0);
2570 if (child != (XMLTreeInfo *) NULL)
2571 {
cristy4c08aed2011-07-01 19:47:50 +00002572 if (CurrentContext->stroke.alpha != OpaqueAlpha)
cristy8a46d822012-08-28 23:32:39 +00002573 pixel.alpha_trait=CurrentContext->stroke.alpha != OpaqueAlpha ?
cristyb0a657e2012-08-29 00:45:37 +00002574 BlendPixelTrait : UndefinedPixelTrait;
cristy9d8c8ce2011-10-25 16:13:52 +00002575 pixel=CurrentContext->stroke;
cristy3ed852e2009-09-05 21:47:34 +00002576 GetColorTuple(&pixel,MagickTrue,value);
2577 (void) SetXMLTreeContent(child,value);
2578 }
2579 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2580 if (child != (XMLTreeInfo *) NULL)
2581 {
cristy151b66d2015-04-15 10:50:31 +00002582 (void) FormatLocaleString(value,MagickPathExtent,"%d",
cristy3ed852e2009-09-05 21:47:34 +00002583 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2584 (void) SetXMLTreeContent(child,value);
2585 }
2586 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2587 if ((child != (XMLTreeInfo *) NULL) &&
2588 (CurrentContext->dash_pattern != (double *) NULL))
2589 {
2590 char
2591 *dash_pattern;
2592
2593 dash_pattern=AcquireString((char *) NULL);
cristy5f07f702011-09-26 17:29:10 +00002594 for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++)
cristy3ed852e2009-09-05 21:47:34 +00002595 {
2596 if (i != 0)
2597 (void) ConcatenateString(&dash_pattern,",");
cristy151b66d2015-04-15 10:50:31 +00002598 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristy3ed852e2009-09-05 21:47:34 +00002599 CurrentContext->dash_pattern[i]);
2600 (void) ConcatenateString(&dash_pattern,value);
2601 }
2602 (void) SetXMLTreeContent(child,dash_pattern);
2603 dash_pattern=DestroyString(dash_pattern);
2604 }
2605 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2606 if (child != (XMLTreeInfo *) NULL)
2607 {
cristy151b66d2015-04-15 10:50:31 +00002608 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristy3ed852e2009-09-05 21:47:34 +00002609 CurrentContext->dash_offset);
2610 (void) SetXMLTreeContent(child,value);
2611 }
2612 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2613 if (child != (XMLTreeInfo *) NULL)
2614 {
cristyb73762e2015-06-03 13:53:05 +00002615 (void) CopyMagickString(value,CommandOptionToMnemonic(
2616 MagickLineCapOptions,(ssize_t) CurrentContext->linecap),
2617 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002618 (void) SetXMLTreeContent(child,value);
2619 }
2620 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2621 if (child != (XMLTreeInfo *) NULL)
2622 {
cristy042ee782011-04-22 18:48:30 +00002623 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristyf2faecf2010-05-28 19:19:36 +00002624 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
cristy151b66d2015-04-15 10:50:31 +00002625 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002626 (void) SetXMLTreeContent(child,value);
2627 }
2628 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2629 if (child != (XMLTreeInfo *) NULL)
2630 {
cristy151b66d2015-04-15 10:50:31 +00002631 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double)
cristy3ed852e2009-09-05 21:47:34 +00002632 CurrentContext->miterlimit);
2633 (void) SetXMLTreeContent(child,value);
2634 }
dirkc8e845f2015-04-07 19:32:12 +00002635 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
cristy3ed852e2009-09-05 21:47:34 +00002636 if (child != (XMLTreeInfo *) NULL)
2637 {
cristy151b66d2015-04-15 10:50:31 +00002638 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristybd33da02014-08-26 11:26:30 +00002639 (double) (QuantumScale*CurrentContext->stroke.alpha));
cristy3ed852e2009-09-05 21:47:34 +00002640 (void) SetXMLTreeContent(child,value);
2641 }
2642 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2643 if (child != (XMLTreeInfo *) NULL)
2644 {
cristy151b66d2015-04-15 10:50:31 +00002645 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristy3ed852e2009-09-05 21:47:34 +00002646 CurrentContext->stroke_width);
2647 (void) SetXMLTreeContent(child,value);
2648 }
2649 child=AddChildToXMLTree(xml_info,"text-align",0);
2650 if (child != (XMLTreeInfo *) NULL)
2651 {
cristy042ee782011-04-22 18:48:30 +00002652 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
cristy151b66d2015-04-15 10:50:31 +00002653 (ssize_t) CurrentContext->align),MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002654 (void) SetXMLTreeContent(child,value);
2655 }
2656 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2657 if (child != (XMLTreeInfo *) NULL)
2658 {
cristy151b66d2015-04-15 10:50:31 +00002659 (void) FormatLocaleString(value,MagickPathExtent,"%d",
cristy3ed852e2009-09-05 21:47:34 +00002660 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2661 (void) SetXMLTreeContent(child,value);
2662 }
2663 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2664 if (child != (XMLTreeInfo *) NULL)
2665 {
cristy4c08aed2011-07-01 19:47:50 +00002666 if (CurrentContext->undercolor.alpha != OpaqueAlpha)
cristy8a46d822012-08-28 23:32:39 +00002667 pixel.alpha_trait=CurrentContext->undercolor.alpha != OpaqueAlpha ?
cristyb0a657e2012-08-29 00:45:37 +00002668 BlendPixelTrait : UndefinedPixelTrait;
cristy9d8c8ce2011-10-25 16:13:52 +00002669 pixel=CurrentContext->undercolor;
cristy3ed852e2009-09-05 21:47:34 +00002670 GetColorTuple(&pixel,MagickTrue,value);
2671 (void) SetXMLTreeContent(child,value);
2672 }
2673 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2674 if (child != (XMLTreeInfo *) NULL)
2675 (void) SetXMLTreeContent(child,wand->mvg);
2676 xml=XMLTreeInfoToXML(xml_info);
2677 xml_info=DestroyXMLTree(xml_info);
2678 return(xml);
2679}
2680
2681/*
2682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2683% %
2684% %
2685% %
2686% D r a w G e t T e x t U n d e r C o l o r %
2687% %
2688% %
2689% %
2690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2691%
2692% DrawGetTextUnderColor() returns the color of a background rectangle
2693% to place under text annotations.
2694%
2695% The format of the DrawGetTextUnderColor method is:
2696%
2697% void DrawGetTextUnderColor(const DrawingWand *wand,
2698% PixelWand *under_color)
2699%
2700% A description of each parameter follows:
2701%
2702% o wand: the drawing wand.
2703%
2704% o under_color: Return the under color.
2705%
2706*/
2707WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2708 PixelWand *under_color)
2709{
2710 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002711 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002712 assert(under_color != (PixelWand *) NULL);
2713 if (wand->debug != MagickFalse)
2714 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyf82c4a02011-12-15 02:43:44 +00002715 PixelSetPixelColor(under_color,&CurrentContext->undercolor);
cristy3ed852e2009-09-05 21:47:34 +00002716}
2717
2718/*
2719%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2720% %
2721% %
2722% %
2723% D r a w L i n e %
2724% %
2725% %
2726% %
2727%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2728%
2729% DrawLine() draws a line on the image using the current stroke color,
cristyb6a294d2011-10-03 00:55:17 +00002730% stroke alpha, and stroke width.
cristy3ed852e2009-09-05 21:47:34 +00002731%
2732% The format of the DrawLine method is:
2733%
2734% void DrawLine(DrawingWand *wand,const double sx,const double sy,
2735% const double ex,const double ey)
2736%
2737% A description of each parameter follows:
2738%
2739% o wand: the drawing wand.
2740%
2741% o sx: starting x ordinate
2742%
2743% o sy: starting y ordinate
2744%
2745% o ex: ending x ordinate
2746%
2747% o ey: ending y ordinate
2748%
2749*/
2750WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2751 const double ex,const double ey)
2752{
2753 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002754 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002755 if (wand->debug != MagickFalse)
2756 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05002757 (void) MVGPrintf(wand,"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey);
cristy3ed852e2009-09-05 21:47:34 +00002758}
2759
2760/*
2761%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2762% %
2763% %
2764% %
cristy3ed852e2009-09-05 21:47:34 +00002765% D r a w P a t h C l o s e %
2766% %
2767% %
2768% %
2769%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2770%
2771% DrawPathClose() adds a path element to the current path which closes the
2772% current subpath by drawing a straight line from the current point to the
2773% current subpath's most recent starting point (usually, the most recent
2774% moveto point).
2775%
2776% The format of the DrawPathClose method is:
2777%
2778% void DrawPathClose(DrawingWand *wand)
2779%
2780% A description of each parameter follows:
2781%
2782% o wand: the drawing wand.
2783%
2784*/
2785WandExport void DrawPathClose(DrawingWand *wand)
2786{
2787 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002788 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002789 if (wand->debug != MagickFalse)
2790 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05002791 (void) MVGAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00002792 "Z" : "z");
2793}
2794
2795/*
2796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2797% %
2798% %
2799% %
2800% D r a w P a t h C u r v e T o A b s o l u t e %
2801% %
2802% %
2803% %
2804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2805%
2806% DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2807% point to (x,y) using (x1,y1) as the control point at the beginning of
2808% the curve and (x2,y2) as the control point at the end of the curve using
2809% absolute coordinates. At the end of the command, the new current point
2810% becomes the final (x,y) coordinate pair used in the polybezier.
2811%
2812% The format of the DrawPathCurveToAbsolute method is:
2813%
2814% void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2815% const double y1,const double x2,const double y2,const double x,
2816% const double y)
2817%
2818% A description of each parameter follows:
2819%
2820% o wand: the drawing wand.
2821%
2822% o x1: x ordinate of control point for curve beginning
2823%
2824% o y1: y ordinate of control point for curve beginning
2825%
2826% o x2: x ordinate of control point for curve ending
2827%
2828% o y2: y ordinate of control point for curve ending
2829%
2830% o x: x ordinate of the end of the curve
2831%
2832% o y: y ordinate of the end of the curve
2833%
2834*/
2835
2836static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2837 const double x1,const double y1,const double x2,const double y2,
2838 const double x,const double y)
2839{
2840 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002841 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002842 if (wand->debug != MagickFalse)
2843 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2844 if ((wand->path_operation != PathCurveToOperation) ||
2845 (wand->path_mode != mode))
2846 {
2847 wand->path_operation=PathCurveToOperation;
2848 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05002849 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g %.20g %.20g",
cristy3ed852e2009-09-05 21:47:34 +00002850 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2851 }
2852 else
Cristybd0db062015-12-26 10:33:53 -05002853 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1,
cristy8cd5b312010-01-07 01:10:24 +00002854 x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002855}
2856
2857WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2858 const double y1,const double x2,const double y2,const double x,const double y)
2859{
2860 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002861 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002862 if (wand->debug != MagickFalse)
2863 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2864 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2865}
2866
2867/*
2868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2869% %
2870% %
2871% %
2872% D r a w P a t h C u r v e T o R e l a t i v e %
2873% %
2874% %
2875% %
2876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2877%
2878% DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2879% point to (x,y) using (x1,y1) as the control point at the beginning of
2880% the curve and (x2,y2) as the control point at the end of the curve using
2881% relative coordinates. At the end of the command, the new current point
2882% becomes the final (x,y) coordinate pair used in the polybezier.
2883%
2884% The format of the DrawPathCurveToRelative method is:
2885%
2886% void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2887% const double y1,const double x2,const double y2,const double x,
2888% const double y)
2889%
2890% A description of each parameter follows:
2891%
2892% o wand: the drawing wand.
2893%
2894% o x1: x ordinate of control point for curve beginning
2895%
2896% o y1: y ordinate of control point for curve beginning
2897%
2898% o x2: x ordinate of control point for curve ending
2899%
2900% o y2: y ordinate of control point for curve ending
2901%
2902% o x: x ordinate of the end of the curve
2903%
2904% o y: y ordinate of the end of the curve
2905%
2906*/
2907WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2908 const double y1,const double x2,const double y2,const double x,const double y)
2909{
2910 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002911 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002912 if (wand->debug != MagickFalse)
2913 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2914 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2915}
2916
2917/*
2918%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2919% %
2920% %
2921% %
dirkb1924a12015-12-27 22:18:06 +01002922% 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 %
cristy3ed852e2009-09-05 21:47:34 +00002923% %
2924% %
2925% %
2926%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2927%
2928% DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2929% from the current point to (x,y) using (x1,y1) as the control point using
2930% absolute coordinates. At the end of the command, the new current point
2931% becomes the final (x,y) coordinate pair used in the polybezier.
2932%
2933% The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2934%
2935% void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2936% const double x1,const double y1,onst double x,const double y)
2937%
2938% A description of each parameter follows:
2939%
2940% o wand: the drawing wand.
2941%
2942% o x1: x ordinate of the control point
2943%
2944% o y1: y ordinate of the control point
2945%
2946% o x: x ordinate of final point
2947%
2948% o y: y ordinate of final point
2949%
2950*/
2951
2952static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2953 const PathMode mode,const double x1,double y1,const double x,const double y)
2954{
2955 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002956 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002957 if (wand->debug != MagickFalse)
2958 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2959 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2960 (wand->path_mode != mode))
2961 {
2962 wand->path_operation=PathCurveToQuadraticBezierOperation;
2963 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05002964 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g",
cristy8cd5b312010-01-07 01:10:24 +00002965 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002966 }
2967 else
Cristybd0db062015-12-26 10:33:53 -05002968 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x1,y1,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002969}
2970
2971WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2972 const double x1,const double y1,const double x,const double y)
2973{
2974 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002975 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00002976 if (wand->debug != MagickFalse)
2977 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2978 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
2979}
2980
2981/*
2982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2983% %
2984% %
2985% %
dirkb1924a12015-12-27 22:18:06 +01002986% 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 %
cristy3ed852e2009-09-05 21:47:34 +00002987% %
2988% %
2989% %
2990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2991%
2992% DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
2993% from the current point to (x,y) using (x1,y1) as the control point using
2994% relative coordinates. At the end of the command, the new current point
2995% becomes the final (x,y) coordinate pair used in the polybezier.
2996%
2997% The format of the DrawPathCurveToQuadraticBezierRelative method is:
2998%
2999% void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3000% const double x1,const double y1,const double x,const double y)
3001%
3002% A description of each parameter follows:
3003%
3004% o wand: the drawing wand.
3005%
3006% o x1: x ordinate of the control point
3007%
3008% o y1: y ordinate of the control point
3009%
3010% o x: x ordinate of final point
3011%
3012% o y: y ordinate of final point
3013%
3014*/
3015WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3016 const double x1,const double y1,const double x,const double y)
3017{
3018 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003019 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003020 if (wand->debug != MagickFalse)
3021 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3022 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
3023}
3024
3025/*
3026%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3027% %
3028% %
3029% %
3030% 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 %
3031% %
3032% %
3033% %
3034%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3035%
3036% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3037% Bezier curve (using absolute coordinates) from the current point to
3038% (x,y). The control point is assumed to be the reflection of the
3039% control point on the previous command relative to the current
3040% point. (If there is no previous command or if the previous command was
3041% not a DrawPathCurveToQuadraticBezierAbsolute,
3042% DrawPathCurveToQuadraticBezierRelative,
3043% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3044% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3045% is coincident with the current point.). At the end of the command, the
3046% new current point becomes the final (x,y) coordinate pair used in the
3047% polybezier.
3048%
3049% The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3050%
3051% void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3052% DrawingWand *wand,const double x,const double y)
3053%
3054% A description of each parameter follows:
3055%
3056% o wand: the drawing wand.
3057%
3058% o x: x ordinate of final point
3059%
3060% o y: y ordinate of final point
3061%
3062*/
3063
3064static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3065 const PathMode mode,const double x,const double y)
3066{
3067 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003068 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003069 if (wand->debug != MagickFalse)
3070 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3071 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3072 (wand->path_mode != mode))
3073 {
3074 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3075 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05003076 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003077 'T' : 't',x,y);
3078 }
3079 else
Cristybd0db062015-12-26 10:33:53 -05003080 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003081}
3082
3083WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3084 const double x,const double y)
3085{
3086 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003087 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003088 if (wand->debug != MagickFalse)
3089 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3090 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3091}
3092
3093/*
3094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3095% %
3096% %
3097% %
3098% 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 %
3099% %
3100% %
3101% %
3102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3103%
cristy76fa3142012-04-26 11:30:17 +00003104% DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic Bezier
cristy3ed852e2009-09-05 21:47:34 +00003105% curve (using relative coordinates) from the current point to (x,y). The
3106% control point is assumed to be the reflection of the control point on the
3107% previous command relative to the current point. (If there is no previous
3108% command or if the previous command was not a
3109% DrawPathCurveToQuadraticBezierAbsolute,
3110% DrawPathCurveToQuadraticBezierRelative,
3111% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3112% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3113% coincident with the current point.). At the end of the command, the new
3114% current point becomes the final (x,y) coordinate pair used in the polybezier.
3115%
3116% The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3117%
3118% void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3119% const double x,const double y)
3120%
3121% A description of each parameter follows:
3122%
3123% o wand: the drawing wand.
3124%
3125% o x: x ordinate of final point
3126%
3127% o y: y ordinate of final point
3128%
3129*/
3130WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3131 const double x,const double y)
3132{
3133 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3134}
3135
3136/*
3137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3138% %
3139% %
3140% %
3141% 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 %
3142% %
3143% %
3144% %
3145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3146%
3147% DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3148% current point to (x,y) using absolute coordinates. The first control
3149% point is assumed to be the reflection of the second control point on
3150% the previous command relative to the current point. (If there is no
3151% previous command or if the previous command was not an
3152% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3153% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3154% the first control point is coincident with the current point.) (x2,y2)
3155% is the second control point (i.e., the control point at the end of the
3156% curve). At the end of the command, the new current point becomes the
3157% final (x,y) coordinate pair used in the polybezier.
3158%
3159% The format of the DrawPathCurveToSmoothAbsolute method is:
3160%
3161% void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
cristy76fa3142012-04-26 11:30:17 +00003162% const double x2,const double y2,const double x,const double y)
cristy3ed852e2009-09-05 21:47:34 +00003163%
3164% A description of each parameter follows:
3165%
3166% o wand: the drawing wand.
3167%
3168% o x2: x ordinate of second control point
3169%
3170% o y2: y ordinate of second control point
3171%
3172% o x: x ordinate of termination point
3173%
3174% o y: y ordinate of termination point
3175%
3176*/
3177
3178static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3179 const double x2,const double y2,const double x,const double y)
3180{
3181 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003182 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003183 if (wand->debug != MagickFalse)
3184 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3185 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3186 (wand->path_mode != mode))
3187 {
3188 wand->path_operation=PathCurveToSmoothOperation;
3189 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05003190 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g %.20g %.20g",
cristy8cd5b312010-01-07 01:10:24 +00003191 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003192 }
3193 else
Cristybd0db062015-12-26 10:33:53 -05003194 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003195}
3196
3197WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3198 const double y2,const double x,const double y)
3199{
3200 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003201 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003202 if (wand->debug != MagickFalse)
3203 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3204 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3205}
3206
3207/*
3208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3209% %
3210% %
3211% %
3212% 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 %
3213% %
3214% %
3215% %
3216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3217%
3218% DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3219% point to (x,y) using relative coordinates. The first control point is
3220% assumed to be the reflection of the second control point on the previous
3221% command relative to the current point. (If there is no previous command or
3222% if the previous command was not an DrawPathCurveToAbsolute,
3223% DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3224% DrawPathCurveToSmoothRelative, assume the first control point is coincident
3225% with the current point.) (x2,y2) is the second control point (i.e., the
3226% control point at the end of the curve). At the end of the command, the new
3227% current point becomes the final (x,y) coordinate pair used in the polybezier.
3228%
3229% The format of the DrawPathCurveToSmoothRelative method is:
3230%
3231% void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3232% const double x2,const double y2,const double x,const double y)
3233%
3234% A description of each parameter follows:
3235%
3236% o wand: the drawing wand.
3237%
3238% o x2: x ordinate of second control point
3239%
3240% o y2: y ordinate of second control point
3241%
3242% o x: x ordinate of termination point
3243%
3244% o y: y ordinate of termination point
3245%
3246*/
3247WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3248 const double y2,const double x,const double y)
3249{
3250 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003251 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003252 if (wand->debug != MagickFalse)
3253 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3254 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3255}
3256
3257/*
3258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3259% %
3260% %
3261% %
3262% 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 %
3263% %
3264% %
3265% %
3266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3267%
3268% DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3269% to (x, y) using absolute coordinates. The size and orientation of the
3270% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3271% indicates how the ellipse as a whole is rotated relative to the current
3272% coordinate system. The center (cx, cy) of the ellipse is calculated
3273% automagically to satisfy the constraints imposed by the other parameters.
3274% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3275% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3276% of the available arcs. If sweepFlag is true, then draw the arc matching a
3277% clock-wise rotation.
3278%
3279% The format of the DrawPathEllipticArcAbsolute method is:
3280%
3281% void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3282% const double rx,const double ry,const double x_axis_rotation,
3283% const MagickBooleanType large_arc_flag,
3284% const MagickBooleanType sweep_flag,const double x,const double y)
3285%
3286% A description of each parameter follows:
3287%
3288% o wand: the drawing wand.
3289%
3290% o rx: x radius
3291%
3292% o ry: y radius
3293%
3294% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3295% relative to the current coordinate system
3296%
3297% o large_arc_flag: If non-zero (true) then draw the larger of the
3298% available arcs
3299%
3300% o sweep_flag: If non-zero (true) then draw the arc matching a
3301% clock-wise rotation
3302%
3303%
3304*/
3305
3306static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3307 const double rx,const double ry,const double x_axis_rotation,
3308 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3309 const double x,const double y)
3310{
3311 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003312 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003313 if (wand->debug != MagickFalse)
3314 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3315 if ((wand->path_operation != PathEllipticArcOperation) ||
3316 (wand->path_mode != mode))
3317 {
3318 wand->path_operation=PathEllipticArcOperation;
3319 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05003320 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %u %u %.20g %.20g",
cristy3ed852e2009-09-05 21:47:34 +00003321 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3322 large_arc_flag,sweep_flag,x,y);
3323 }
3324 else
Cristybd0db062015-12-26 10:33:53 -05003325 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry,
cristy8cd5b312010-01-07 01:10:24 +00003326 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003327}
3328
3329WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3330 const double ry,const double x_axis_rotation,
3331 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3332 const double x,const double y)
3333{
3334 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003335 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003336 if (wand->debug != MagickFalse)
3337 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3338 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3339 large_arc_flag,sweep_flag,x,y);
3340}
3341
3342/*
3343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3344% %
3345% %
3346% %
3347% 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 %
3348% %
3349% %
3350% %
3351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3352%
3353% DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3354% to (x, y) using relative coordinates. The size and orientation of the
3355% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3356% indicates how the ellipse as a whole is rotated relative to the current
3357% coordinate system. The center (cx, cy) of the ellipse is calculated
3358% automagically to satisfy the constraints imposed by the other parameters.
3359% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3360% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3361% of the available arcs. If sweepFlag is true, then draw the arc matching a
3362% clock-wise rotation.
3363%
3364% The format of the DrawPathEllipticArcRelative method is:
3365%
3366% void DrawPathEllipticArcRelative(DrawingWand *wand,
3367% const double rx,const double ry,const double x_axis_rotation,
3368% const MagickBooleanType large_arc_flag,
3369% const MagickBooleanType sweep_flag,const double x,const double y)
3370%
3371% A description of each parameter follows:
3372%
3373% o wand: the drawing wand.
3374%
3375% o rx: x radius
3376%
3377% o ry: y radius
3378%
3379% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3380% relative to the current coordinate system
3381%
3382% o large_arc_flag: If non-zero (true) then draw the larger of the
3383% available arcs
3384%
3385% o sweep_flag: If non-zero (true) then draw the arc matching a
3386% clock-wise rotation
3387%
3388*/
3389WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3390 const double ry,const double x_axis_rotation,
3391 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3392 const double x,const double y)
3393{
3394 DrawPathEllipticArc(wand,RelativePathMode,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 F i n i s h %
3404% %
3405% %
3406% %
3407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3408%
3409% DrawPathFinish() terminates the current path.
3410%
3411% The format of the DrawPathFinish method is:
3412%
3413% void DrawPathFinish(DrawingWand *wand)
3414%
3415% A description of each parameter follows:
3416%
3417% o wand: the drawing wand.
3418%
3419*/
3420WandExport void DrawPathFinish(DrawingWand *wand)
3421{
3422 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003423 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003424 if (wand->debug != MagickFalse)
3425 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05003426 (void) MVGPrintf(wand,"'\n");
cristy3ed852e2009-09-05 21:47:34 +00003427 wand->path_operation=PathDefaultOperation;
3428 wand->path_mode=DefaultPathMode;
3429}
3430
3431/*
3432%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3433% %
3434% %
3435% %
3436% D r a w P a t h L i n e T o A b s o l u t e %
3437% %
3438% %
3439% %
3440%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3441%
3442% DrawPathLineToAbsolute() draws a line path from the current point to the
3443% given coordinate using absolute coordinates. The coordinate then becomes
3444% the new current point.
3445%
3446% The format of the DrawPathLineToAbsolute method is:
3447%
3448% void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3449% const double y)
3450%
3451% A description of each parameter follows:
3452%
3453% o wand: the drawing wand.
3454%
3455% o x: target x ordinate
3456%
3457% o y: target y ordinate
3458%
3459*/
3460static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3461 const double x,const double y)
3462{
3463 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003464 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003465 if (wand->debug != MagickFalse)
3466 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3467 if ((wand->path_operation != PathLineToOperation) ||
3468 (wand->path_mode != mode))
3469 {
3470 wand->path_operation=PathLineToOperation;
3471 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05003472 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003473 'L' : 'l',x,y);
3474 }
3475 else
Cristybd0db062015-12-26 10:33:53 -05003476 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003477}
3478
3479WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3480 const double y)
3481{
3482 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003483 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003484 if (wand->debug != MagickFalse)
3485 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3486 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3487}
3488
3489/*
3490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3491% %
3492% %
3493% %
3494% D r a w P a t h L i n e T o R e l a t i v e %
3495% %
3496% %
3497% %
3498%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3499%
3500% DrawPathLineToRelative() draws a line path from the current point to the
3501% given coordinate using relative coordinates. The coordinate then becomes
3502% the new current point.
3503%
3504% The format of the DrawPathLineToRelative method is:
3505%
3506% void DrawPathLineToRelative(DrawingWand *wand,const double x,
3507% const double y)
3508%
3509% A description of each parameter follows:
3510%
3511% o wand: the drawing wand.
3512%
3513% o x: target x ordinate
3514%
3515% o y: target y ordinate
3516%
3517*/
3518WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3519 const double y)
3520{
3521 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003522 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003523 if (wand->debug != MagickFalse)
3524 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3525 DrawPathLineTo(wand,RelativePathMode,x,y);
3526}
3527
3528/*
3529%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3530% %
3531% %
3532% %
3533% 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 %
3534% %
3535% %
3536% %
3537%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3538%
3539% DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3540% current point to the target point using absolute coordinates. The target
3541% point then becomes the new current point.
3542%
3543% The format of the DrawPathLineToHorizontalAbsolute method is:
3544%
cristy76fa3142012-04-26 11:30:17 +00003545% void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,const double x)
cristy3ed852e2009-09-05 21:47:34 +00003546%
3547% A description of each parameter follows:
3548%
3549% o wand: the drawing wand.
3550%
3551% o x: target x ordinate
3552%
3553*/
3554
3555static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3556 const double x)
3557{
3558 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003559 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003560 if (wand->debug != MagickFalse)
3561 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3562 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3563 (wand->path_mode != mode))
3564 {
3565 wand->path_operation=PathLineToHorizontalOperation;
3566 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05003567 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003568 'H' : 'h',x);
3569 }
3570 else
Cristybd0db062015-12-26 10:33:53 -05003571 (void) MVGAutoWrapPrintf(wand," %.20g",x);
cristy3ed852e2009-09-05 21:47:34 +00003572}
3573
3574WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3575 const double x)
3576{
3577 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003578 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003579 if (wand->debug != MagickFalse)
3580 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3581 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
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 R e l a t i v e %
3590% %
3591% %
3592% %
3593%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3594%
3595% DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3596% current point to the target point using relative coordinates. The target
3597% point then becomes the new current point.
3598%
3599% The format of the DrawPathLineToHorizontalRelative method is:
3600%
3601% void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3602% const double x)
3603%
3604% A description of each parameter follows:
3605%
3606% o wand: the drawing wand.
3607%
3608% o x: target x ordinate
3609%
3610*/
3611WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3612 const double x)
3613{
3614 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3615}
3616
3617/*
3618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3619% %
3620% %
3621% %
3622% 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 %
3623% %
3624% %
3625% %
3626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3627%
3628% DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3629% current point to the target point using absolute coordinates. The target
3630% point then becomes the new current point.
3631%
3632% The format of the DrawPathLineToVerticalAbsolute method is:
3633%
3634% void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3635% const double y)
3636%
3637% A description of each parameter follows:
3638%
3639% o wand: the drawing wand.
3640%
3641% o y: target y ordinate
3642%
3643*/
3644
3645static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3646 const double y)
3647{
3648 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003649 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003650 if (wand->debug != MagickFalse)
3651 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3652 if ((wand->path_operation != PathLineToVerticalOperation) ||
3653 (wand->path_mode != mode))
3654 {
3655 wand->path_operation=PathLineToVerticalOperation;
3656 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05003657 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003658 'V' : 'v',y);
3659 }
3660 else
Cristybd0db062015-12-26 10:33:53 -05003661 (void) MVGAutoWrapPrintf(wand," %.20g",y);
cristy3ed852e2009-09-05 21:47:34 +00003662}
3663
3664WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3665{
3666 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003667 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003668 if (wand->debug != MagickFalse)
3669 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3670 DrawPathLineToVertical(wand,AbsolutePathMode,y);
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 R e l a t i v e %
3679% %
3680% %
3681% %
3682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3683%
3684% DrawPathLineToVerticalRelative() draws a vertical line path from the
3685% current point to the target point using relative coordinates. The target
3686% point then becomes the new current point.
3687%
3688% The format of the DrawPathLineToVerticalRelative method is:
3689%
3690% void DrawPathLineToVerticalRelative(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*/
3700WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3701{
3702 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003703 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003704 if (wand->debug != MagickFalse)
3705 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3706 DrawPathLineToVertical(wand,RelativePathMode,y);
3707}
3708/*
3709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3710% %
3711% %
3712% %
3713% D r a w P a t h M o v e T o A b s o l u t e %
3714% %
3715% %
3716% %
3717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3718%
3719% DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3720% using absolute coordinates. The current point then becomes the
3721% specified coordinate.
3722%
3723% The format of the DrawPathMoveToAbsolute method is:
3724%
3725% void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3726% const double y)
3727%
3728% A description of each parameter follows:
3729%
3730% o wand: the drawing wand.
3731%
3732% o x: target x ordinate
3733%
3734% o y: target y ordinate
3735%
3736*/
3737
3738static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3739 const double y)
3740{
3741 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003742 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003743 if (wand->debug != MagickFalse)
3744 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3745 if ((wand->path_operation != PathMoveToOperation) ||
3746 (wand->path_mode != mode))
3747 {
3748 wand->path_operation=PathMoveToOperation;
3749 wand->path_mode=mode;
Cristybd0db062015-12-26 10:33:53 -05003750 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003751 'M' : 'm',x,y);
3752 }
3753 else
Cristybd0db062015-12-26 10:33:53 -05003754 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003755}
3756
3757WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3758 const double y)
3759{
3760 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003761 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003762 if (wand->debug != MagickFalse)
3763 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3764 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3765}
3766
3767/*
3768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3769% %
3770% %
3771% %
3772% D r a w P a t h M o v e T o R e l a t i v e %
3773% %
3774% %
3775% %
3776%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3777%
3778% DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3779% relative coordinates. The current point then becomes the specified
3780% coordinate.
3781%
3782% The format of the DrawPathMoveToRelative method is:
3783%
3784% void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3785% const double y)
3786%
3787% A description of each parameter follows:
3788%
3789% o wand: the drawing wand.
3790%
3791% o x: target x ordinate
3792%
3793% o y: target y ordinate
3794%
3795*/
3796WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3797 const double y)
3798{
3799 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003800 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003801 if (wand->debug != MagickFalse)
3802 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3803 DrawPathMoveTo(wand,RelativePathMode,x,y);
3804}
3805
3806/*
3807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3808% %
3809% %
3810% %
3811% D r a w P a t h S t a r t %
3812% %
3813% %
3814% %
3815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3816%
3817% DrawPathStart() declares the start of a path drawing list which is terminated
3818% by a matching DrawPathFinish() command. All other DrawPath commands must
3819% be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3820% is because path drawing commands are subordinate commands and they do not
3821% function by themselves.
3822%
3823% The format of the DrawPathStart method is:
3824%
3825% void DrawPathStart(DrawingWand *wand)
3826%
3827% A description of each parameter follows:
3828%
3829% o wand: the drawing wand.
3830%
3831*/
3832WandExport void DrawPathStart(DrawingWand *wand)
3833{
3834 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003835 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003836 if (wand->debug != MagickFalse)
3837 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05003838 (void) MVGPrintf(wand,"path '");
cristy3ed852e2009-09-05 21:47:34 +00003839 wand->path_operation=PathDefaultOperation;
3840 wand->path_mode=DefaultPathMode;
3841}
3842
3843/*
3844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3845% %
3846% %
3847% %
3848% D r a w P o i n t %
3849% %
3850% %
3851% %
3852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3853%
3854% DrawPoint() draws a point using the current fill color.
3855%
3856% The format of the DrawPoint method is:
3857%
3858% void DrawPoint(DrawingWand *wand,const double x,const double y)
3859%
3860% A description of each parameter follows:
3861%
3862% o wand: the drawing wand.
3863%
3864% o x: target x coordinate
3865%
3866% o y: target y coordinate
3867%
3868*/
3869WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3870{
3871 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003872 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003873 if (wand->debug != MagickFalse)
3874 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05003875 (void) MVGPrintf(wand,"point %.20g %.20g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003876}
3877
3878/*
3879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3880% %
3881% %
3882% %
3883% D r a w P o l y g o n %
3884% %
3885% %
3886% %
3887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3888%
3889% DrawPolygon() draws a polygon using the current stroke, stroke width, and
3890% fill color or texture, using the specified array of coordinates.
3891%
3892% The format of the DrawPolygon method is:
3893%
3894% void DrawPolygon(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003895% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003896%
3897% A description of each parameter follows:
3898%
3899% o wand: the drawing wand.
3900%
3901% o number_coordinates: number of coordinates
3902%
3903% o coordinates: coordinate array
3904%
3905*/
3906WandExport void DrawPolygon(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003907 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003908{
3909 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003910 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003911 if (wand->debug != MagickFalse)
3912 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05003913 MVGAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
cristy3ed852e2009-09-05 21:47:34 +00003914}
3915
3916/*
3917%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3918% %
3919% %
3920% %
3921% D r a w P o l y l i n e %
3922% %
3923% %
3924% %
3925%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3926%
3927% DrawPolyline() draws a polyline using the current stroke, stroke width, and
3928% fill color or texture, using the specified array of coordinates.
3929%
3930% The format of the DrawPolyline method is:
3931%
3932% void DrawPolyline(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003933% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003934%
3935% A description of each parameter follows:
3936%
3937% o wand: the drawing wand.
3938%
3939% o number_coordinates: number of coordinates
3940%
3941% o coordinates: coordinate array
3942%
3943*/
3944WandExport void DrawPolyline(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003945 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003946{
3947 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003948 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003949 if (wand->debug != MagickFalse)
3950 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05003951 MVGAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
cristy3ed852e2009-09-05 21:47:34 +00003952}
3953
3954/*
3955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3956% %
3957% %
3958% %
3959% D r a w P o p C l i p P a t h %
3960% %
3961% %
3962% %
3963%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3964%
3965% DrawPopClipPath() terminates a clip path definition.
3966%
3967% The format of the DrawPopClipPath method is:
3968%
3969% void DrawPopClipPath(DrawingWand *wand)
3970%
3971% A description of each parameter follows:
3972%
3973% o wand: the drawing wand.
3974%
3975*/
3976WandExport void DrawPopClipPath(DrawingWand *wand)
3977{
3978 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00003979 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00003980 if (wand->debug != MagickFalse)
3981 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3982 if (wand->indent_depth > 0)
3983 wand->indent_depth--;
Cristybd0db062015-12-26 10:33:53 -05003984 (void) MVGPrintf(wand,"pop clip-path\n");
cristy3ed852e2009-09-05 21:47:34 +00003985}
3986
3987/*
3988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3989% %
3990% %
3991% %
3992% D r a w P o p D e f s %
3993% %
3994% %
3995% %
3996%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3997%
3998% DrawPopDefs() terminates a definition list.
3999%
4000% The format of the DrawPopDefs method is:
4001%
4002% void DrawPopDefs(DrawingWand *wand)
4003%
4004% A description of each parameter follows:
4005%
4006% o wand: the drawing wand.
4007%
4008*/
4009WandExport void DrawPopDefs(DrawingWand *wand)
4010{
4011 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004012 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004013 if (wand->debug != MagickFalse)
4014 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4015 if (wand->indent_depth > 0)
4016 wand->indent_depth--;
Cristybd0db062015-12-26 10:33:53 -05004017 (void) MVGPrintf(wand,"pop defs\n");
cristy3ed852e2009-09-05 21:47:34 +00004018}
4019
4020/*
4021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4022% %
4023% %
4024% %
4025% D r a w P o p P a t t e r n %
4026% %
4027% %
4028% %
4029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4030%
4031% DrawPopPattern() terminates a pattern definition.
4032%
4033% The format of the DrawPopPattern method is:
4034%
4035% MagickBooleanType DrawPopPattern(DrawingWand *wand)
4036%
4037% A description of each parameter follows:
4038%
4039% o wand: the drawing wand.
4040%
4041*/
4042WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4043{
4044 char
cristy151b66d2015-04-15 10:50:31 +00004045 geometry[MagickPathExtent],
4046 key[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00004047
4048 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004049 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004050 if (wand->debug != MagickFalse)
4051 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4052 if (wand->image == (Image *) NULL)
4053 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4054 if (wand->pattern_id == (const char *) NULL)
4055 {
4056 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4057 wand->name);
4058 return(MagickFalse);
4059 }
cristy151b66d2015-04-15 10:50:31 +00004060 (void) FormatLocaleString(key,MagickPathExtent,"%s",wand->pattern_id);
cristy3ed852e2009-09-05 21:47:34 +00004061 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
cristy151b66d2015-04-15 10:50:31 +00004062 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g%+.20g%+.20g",
cristye8c25f92010-06-03 00:53:06 +00004063 (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
4064 (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
cristy3ed852e2009-09-05 21:47:34 +00004065 (void) SetImageArtifact(wand->image,key,geometry);
4066 wand->pattern_id=DestroyString(wand->pattern_id);
4067 wand->pattern_offset=0;
4068 wand->pattern_bounds.x=0;
4069 wand->pattern_bounds.y=0;
4070 wand->pattern_bounds.width=0;
4071 wand->pattern_bounds.height=0;
4072 wand->filter_off=MagickTrue;
4073 if (wand->indent_depth > 0)
4074 wand->indent_depth--;
Cristybd0db062015-12-26 10:33:53 -05004075 (void) MVGPrintf(wand,"pop pattern\n");
cristy3ed852e2009-09-05 21:47:34 +00004076 return(MagickTrue);
4077}
4078
4079/*
4080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4081% %
4082% %
4083% %
4084% D r a w P u s h C l i p P a t h %
4085% %
4086% %
4087% %
4088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4089%
4090% DrawPushClipPath() starts a clip path definition which is comprized of any
4091% number of drawing commands and terminated by a DrawPopClipPath() command.
4092%
4093% The format of the DrawPushClipPath method is:
4094%
4095% void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4096%
4097% A description of each parameter follows:
4098%
4099% o wand: the drawing wand.
4100%
4101% o clip_mask_id: string identifier to associate with the clip path for
4102% later use.
4103%
4104*/
4105WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4106{
4107 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004108 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004109 if (wand->debug != MagickFalse)
4110 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4111 assert(clip_mask_id != (const char *) NULL);
Cristybd0db062015-12-26 10:33:53 -05004112 (void) MVGPrintf(wand,"push clip-path %s\n",clip_mask_id);
cristy3ed852e2009-09-05 21:47:34 +00004113 wand->indent_depth++;
4114}
4115
4116/*
4117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4118% %
4119% %
4120% %
4121% D r a w P u s h D e f s %
4122% %
4123% %
4124% %
4125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4126%
4127% DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4128% command create named elements (e.g. clip-paths, textures, etc.) which
4129% may safely be processed earlier for the sake of efficiency.
4130%
4131% The format of the DrawPushDefs method is:
4132%
4133% void DrawPushDefs(DrawingWand *wand)
4134%
4135% A description of each parameter follows:
4136%
4137% o wand: the drawing wand.
4138%
4139*/
4140WandExport void DrawPushDefs(DrawingWand *wand)
4141{
4142 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004143 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004144 if (wand->debug != MagickFalse)
4145 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05004146 (void) MVGPrintf(wand,"push defs\n");
cristy3ed852e2009-09-05 21:47:34 +00004147 wand->indent_depth++;
4148}
4149
4150/*
4151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4152% %
4153% %
4154% %
4155% D r a w P u s h P a t t e r n %
4156% %
4157% %
4158% %
4159%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4160%
4161% DrawPushPattern() indicates that subsequent commands up to a
4162% DrawPopPattern() command comprise the definition of a named pattern.
4163% The pattern space is assigned top left corner coordinates, a width
4164% and height, and becomes its own drawing space. Anything which can
4165% be drawn may be used in a pattern definition.
4166% Named patterns may be used as stroke or brush definitions.
4167%
4168% The format of the DrawPushPattern method is:
4169%
4170% MagickBooleanType DrawPushPattern(DrawingWand *wand,
4171% const char *pattern_id,const double x,const double y,
4172% const double width,const double height)
4173%
4174% A description of each parameter follows:
4175%
4176% o wand: the drawing wand.
4177%
4178% o pattern_id: pattern identification for later reference
4179%
4180% o x: x ordinate of top left corner
4181%
4182% o y: y ordinate of top left corner
4183%
4184% o width: width of pattern space
4185%
4186% o height: height of pattern space
4187%
4188*/
4189WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4190 const char *pattern_id,const double x,const double y,const double width,
4191 const double height)
4192{
4193 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004194 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004195 if (wand->debug != MagickFalse)
4196 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4197 assert(pattern_id != (const char *) NULL);
4198 if (wand->pattern_id != NULL)
4199 {
4200 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4201 wand->pattern_id);
4202 return(MagickFalse);
4203 }
4204 wand->filter_off=MagickTrue;
Cristybd0db062015-12-26 10:33:53 -05004205 (void) MVGPrintf(wand,"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id,
cristy8cd5b312010-01-07 01:10:24 +00004206 x,y,width,height);
cristy3ed852e2009-09-05 21:47:34 +00004207 wand->indent_depth++;
4208 wand->pattern_id=AcquireString(pattern_id);
cristybb503372010-05-27 20:51:26 +00004209 wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
4210 wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
4211 wand->pattern_bounds.width=(size_t) floor(width+0.5);
4212 wand->pattern_bounds.height=(size_t) floor(height+0.5);
cristy3ed852e2009-09-05 21:47:34 +00004213 wand->pattern_offset=wand->mvg_length;
4214 return(MagickTrue);
4215}
4216
4217/*
4218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4219% %
4220% %
4221% %
4222% D r a w R e c t a n g l e %
4223% %
4224% %
4225% %
4226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4227%
4228% DrawRectangle() draws a rectangle given two coordinates and using the
4229% current stroke, stroke width, and fill settings.
4230%
4231% The format of the DrawRectangle method is:
4232%
4233% void DrawRectangle(DrawingWand *wand,const double x1,
4234% const double y1,const double x2,const double y2)
4235%
4236% A description of each parameter follows:
4237%
4238% o x1: x ordinate of first coordinate
4239%
4240% o y1: y ordinate of first coordinate
4241%
4242% o x2: x ordinate of second coordinate
4243%
4244% o y2: y ordinate of second coordinate
4245%
4246*/
4247WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4248 const double x2,const double y2)
4249{
4250 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004251 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004252 if (wand->debug != MagickFalse)
4253 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05004254 (void) MVGPrintf(wand,"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
cristy3ed852e2009-09-05 21:47:34 +00004255}
4256
4257/*
4258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4259% %
4260% %
4261% %
4262+ D r a w R e n d e r %
4263% %
4264% %
4265% %
4266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4267%
4268% DrawRender() renders all preceding drawing commands onto the image.
4269%
4270% The format of the DrawRender method is:
4271%
4272% MagickBooleanType DrawRender(DrawingWand *wand)
4273%
4274% A description of each parameter follows:
4275%
4276% o wand: the drawing wand.
4277%
4278*/
4279WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4280{
4281 MagickBooleanType
4282 status;
4283
4284 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004285 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004286 if (wand->debug != MagickFalse)
4287 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4288 CurrentContext->primitive=wand->mvg;
4289 if (wand->debug != MagickFalse)
4290 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4291 if (wand->image == (Image *) NULL)
4292 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
cristy018f07f2011-09-04 21:15:19 +00004293 status=DrawImage(wand->image,CurrentContext,wand->exception);
cristy3ed852e2009-09-05 21:47:34 +00004294 CurrentContext->primitive=(char *) NULL;
cristy220c4d52013-11-27 19:31:32 +00004295 return(status);
cristy3ed852e2009-09-05 21:47:34 +00004296}
4297
4298/*
4299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4300% %
4301% %
4302% %
4303% D r a w R e s e t V e c t o r G r a p h i c s %
4304% %
4305% %
4306% %
4307%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4308%
4309% DrawResetVectorGraphics() resets the vector graphics associated with the
4310% specified wand.
4311%
4312% The format of the DrawResetVectorGraphics method is:
4313%
4314% void DrawResetVectorGraphics(DrawingWand *wand)
4315%
4316% A description of each parameter follows:
4317%
4318% o wand: the drawing wand.
4319%
4320*/
4321WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4322{
4323 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004324 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004325 if (wand->debug != MagickFalse)
4326 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4327 if (wand->mvg != (char *) NULL)
4328 wand->mvg=DestroyString(wand->mvg);
4329 wand->mvg_alloc=0;
4330 wand->mvg_length=0;
4331 wand->mvg_width=0;
4332}
4333
4334/*
4335%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4336% %
4337% %
4338% %
4339% D r a w R o t a t e %
4340% %
4341% %
4342% %
4343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4344%
4345% DrawRotate() applies the specified rotation to the current coordinate space.
4346%
4347% The format of the DrawRotate method is:
4348%
4349% void DrawRotate(DrawingWand *wand,const double degrees)
4350%
4351% A description of each parameter follows:
4352%
4353% o wand: the drawing wand.
4354%
4355% o degrees: degrees of rotation
4356%
4357*/
4358WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4359{
cristy3ed852e2009-09-05 21:47:34 +00004360 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004361 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004362 if (wand->debug != MagickFalse)
4363 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05004364 (void) MVGPrintf(wand,"rotate %.20g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00004365}
4366
4367/*
4368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4369% %
4370% %
4371% %
4372% D r a w R o u n d R e c t a n g l e %
4373% %
4374% %
4375% %
4376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4377%
4378% DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4379% x & y corner radiuses and using the current stroke, stroke width,
4380% and fill settings.
4381%
4382% The format of the DrawRoundRectangle method is:
4383%
4384% void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4385% double x2,double y2,double rx,double ry)
4386%
4387% A description of each parameter follows:
4388%
4389% o wand: the drawing wand.
4390%
4391% o x1: x ordinate of first coordinate
4392%
4393% o y1: y ordinate of first coordinate
4394%
4395% o x2: x ordinate of second coordinate
4396%
4397% o y2: y ordinate of second coordinate
4398%
4399% o rx: radius of corner in horizontal direction
4400%
4401% o ry: radius of corner in vertical direction
4402%
4403*/
4404WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4405 double x2,double y2,double rx,double ry)
4406{
4407 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004408 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004409 if (wand->debug != MagickFalse)
4410 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05004411 (void) MVGPrintf(wand,"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n",
cristy8cd5b312010-01-07 01:10:24 +00004412 x1,y1,x2,y2,rx,ry);
cristy3ed852e2009-09-05 21:47:34 +00004413}
4414
4415/*
4416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4417% %
4418% %
4419% %
4420% D r a w S c a l e %
4421% %
4422% %
4423% %
4424%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4425%
4426% DrawScale() adjusts the scaling factor to apply in the horizontal and
4427% vertical directions to the current coordinate space.
4428%
4429% The format of the DrawScale method is:
4430%
4431% void DrawScale(DrawingWand *wand,const double x,const double y)
4432%
4433% A description of each parameter follows:
4434%
4435% o wand: the drawing wand.
4436%
4437% o x: horizontal scale factor
4438%
4439% o y: vertical scale factor
4440%
4441*/
4442WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4443{
cristy3ed852e2009-09-05 21:47:34 +00004444 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004445 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004446 if (wand->debug != MagickFalse)
4447 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05004448 (void) MVGPrintf(wand,"scale %.20g %.20g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00004449}
4450
4451/*
4452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4453% %
4454% %
4455% %
4456% D r a w S e t B o r d e r C o l o r %
4457% %
4458% %
4459% %
4460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4461%
4462% DrawSetBorderColor() sets the border color to be used for drawing bordered
4463% objects.
4464%
4465% The format of the DrawSetBorderColor method is:
4466%
4467% void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4468%
4469% A description of each parameter follows:
4470%
4471% o wand: the drawing wand.
4472%
4473% o border_wand: border wand.
4474%
4475*/
cristy4c08aed2011-07-01 19:47:50 +00004476WandExport void DrawSetBorderColor(DrawingWand *wand,
4477 const PixelWand *border_wand)
cristy3ed852e2009-09-05 21:47:34 +00004478{
cristy101ab702011-10-13 13:06:32 +00004479 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004480 *current_border,
4481 border_color,
4482 new_border;
4483
4484 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004485 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004486 if (wand->debug != MagickFalse)
4487 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4488 assert(border_wand != (const PixelWand *) NULL);
cristy4c08aed2011-07-01 19:47:50 +00004489 PixelGetQuantumPacket(border_wand,&border_color);
cristy3ed852e2009-09-05 21:47:34 +00004490 new_border=border_color;
4491 current_border=(&CurrentContext->border_color);
4492 if ((wand->filter_off != MagickFalse) ||
cristy101ab702011-10-13 13:06:32 +00004493 (IsPixelInfoEquivalent(current_border,&new_border) == MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00004494 {
4495 CurrentContext->border_color=new_border;
Cristybd0db062015-12-26 10:33:53 -05004496 (void) MVGPrintf(wand,"border-color '");
4497 MVGAppendColor(wand,&border_color);
4498 (void) MVGPrintf(wand,"'\n");
cristy3ed852e2009-09-05 21:47:34 +00004499 }
4500}
4501
4502/*
4503%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4504% %
4505% %
4506% %
4507% D r a w S e t C l i p P a t h %
4508% %
4509% %
4510% %
4511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4512%
4513% DrawSetClipPath() associates a named clipping path with the image. Only
cristybb503372010-05-27 20:51:26 +00004514% the areas drawn on by the clipping path will be modified as ssize_t as it
cristy3ed852e2009-09-05 21:47:34 +00004515% remains in effect.
4516%
4517% The format of the DrawSetClipPath method is:
4518%
4519% MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4520% const char *clip_mask)
4521%
4522% A description of each parameter follows:
4523%
4524% o wand: the drawing wand.
4525%
4526% o clip_mask: name of clipping path to associate with image
4527%
4528*/
4529WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4530 const char *clip_mask)
4531{
4532 if (wand->debug != MagickFalse)
4533 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4534 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004535 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004536 assert(clip_mask != (const char *) NULL);
4537 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4538 (wand->filter_off != MagickFalse) ||
4539 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4540 {
4541 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4542#if DRAW_BINARY_IMPLEMENTATION
4543 if (wand->image == (Image *) NULL)
4544 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4545 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4546#endif
Cristybd0db062015-12-26 10:33:53 -05004547 (void) MVGPrintf(wand,"clip-path url(#%s)\n",clip_mask);
cristy3ed852e2009-09-05 21:47:34 +00004548 }
4549 return(MagickTrue);
4550}
4551
4552/*
4553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4554% %
4555% %
4556% %
4557% D r a w S e t C l i p R u l e %
4558% %
4559% %
4560% %
4561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4562%
4563% DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4564%
4565% The format of the DrawSetClipRule method is:
4566%
4567% void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4568%
4569% A description of each parameter follows:
4570%
4571% o wand: the drawing wand.
4572%
4573% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4574%
4575*/
4576WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4577{
4578 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004579 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004580 if (wand->debug != MagickFalse)
4581 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4582 if ((wand->filter_off != MagickFalse) ||
4583 (CurrentContext->fill_rule != fill_rule))
4584 {
4585 CurrentContext->fill_rule=fill_rule;
Cristybd0db062015-12-26 10:33:53 -05004586 (void) MVGPrintf(wand, "clip-rule '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004587 MagickFillRuleOptions,(ssize_t) fill_rule));
cristy3ed852e2009-09-05 21:47:34 +00004588 }
4589}
4590
4591/*
4592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4593% %
4594% %
4595% %
4596% D r a w S e t C l i p U n i t s %
4597% %
4598% %
4599% %
4600%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4601%
4602% DrawSetClipUnits() sets the interpretation of clip path units.
4603%
4604% The format of the DrawSetClipUnits method is:
4605%
4606% void DrawSetClipUnits(DrawingWand *wand,
4607% const ClipPathUnits clip_units)
4608%
4609% A description of each parameter follows:
4610%
4611% o wand: the drawing wand.
4612%
4613% o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4614% ObjectBoundingBox)
4615%
4616*/
4617WandExport void DrawSetClipUnits(DrawingWand *wand,
4618 const ClipPathUnits clip_units)
4619{
4620 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004621 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004622 if (wand->debug != MagickFalse)
4623 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4624 if ((wand->filter_off != MagickFalse) ||
4625 (CurrentContext->clip_units != clip_units))
4626 {
4627 CurrentContext->clip_units=clip_units;
4628 if (clip_units == ObjectBoundingBox)
4629 {
4630 AffineMatrix
4631 affine;
4632
4633 GetAffineMatrix(&affine);
4634 affine.sx=CurrentContext->bounds.x2;
4635 affine.sy=CurrentContext->bounds.y2;
4636 affine.tx=CurrentContext->bounds.x1;
4637 affine.ty=CurrentContext->bounds.y1;
4638 AdjustAffine(wand,&affine);
4639 }
Cristybd0db062015-12-26 10:33:53 -05004640 (void) MVGPrintf(wand, "clip-units '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004641 MagickClipPathOptions,(ssize_t) clip_units));
cristy3ed852e2009-09-05 21:47:34 +00004642 }
4643}
Cristybd0db062015-12-26 10:33:53 -05004644
dirk47778472015-07-11 10:20:41 +00004645/*
4646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4647% %
4648% %
4649% %
4650% D r a w S e t D e n s i t y %
4651% %
4652% %
4653% %
4654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4655%
4656% DrawSetDensity() sets the vertical and horizontal resolution.
4657%
4658% The format of the DrawSetDensity method is:
4659%
4660% MagickBooleanType DrawSetDensity(DrawingWand *wand,
4661% const char *density)
4662%
4663% A description of each parameter follows:
4664%
4665% o wand: the drawing wand.
4666%
4667% o density: the vertical and horizontal resolution.
4668%
4669*/
4670WandExport MagickBooleanType DrawSetDensity(DrawingWand *wand,
4671 const char *density)
4672{
4673 if (wand->debug != MagickFalse)
4674 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",density);
4675 assert(wand != (DrawingWand *) NULL);
4676 assert(wand->signature == MagickWandSignature);
4677 assert(density != (const char *) NULL);
4678 if ((CurrentContext->density == (const char *) NULL) ||
4679 (wand->filter_off != MagickFalse) ||
4680 (LocaleCompare(CurrentContext->density,density) != 0))
4681 {
4682 (void) CloneString(&CurrentContext->density,density);
Cristybd0db062015-12-26 10:33:53 -05004683 (void) MVGPrintf(wand,"density '%s'\n",density);
dirk47778472015-07-11 10:20:41 +00004684 }
4685 return(MagickTrue);
4686}
4687
cristy3ed852e2009-09-05 21:47:34 +00004688/*
4689%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4690% %
4691% %
4692% %
4693% D r a w S e t F i l l C o l o r %
4694% %
4695% %
4696% %
4697%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4698%
4699% DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4700%
4701% The format of the DrawSetFillColor method is:
4702%
4703% void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4704%
4705% A description of each parameter follows:
4706%
4707% o wand: the drawing wand.
4708%
4709% o fill_wand: fill wand.
4710%
4711*/
4712WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4713{
cristy101ab702011-10-13 13:06:32 +00004714 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004715 *current_fill,
4716 fill_color,
4717 new_fill;
4718
4719 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004720 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004721 if (wand->debug != MagickFalse)
4722 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4723 assert(fill_wand != (const PixelWand *) NULL);
cristy4c08aed2011-07-01 19:47:50 +00004724 PixelGetQuantumPacket(fill_wand,&fill_color);
cristy3ed852e2009-09-05 21:47:34 +00004725 new_fill=fill_color;
4726 current_fill=(&CurrentContext->fill);
4727 if ((wand->filter_off != MagickFalse) ||
cristy101ab702011-10-13 13:06:32 +00004728 (IsPixelInfoEquivalent(current_fill,&new_fill) == MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00004729 {
4730 CurrentContext->fill=new_fill;
Cristybd0db062015-12-26 10:33:53 -05004731 (void) MVGPrintf(wand,"fill '");
4732 MVGAppendColor(wand,&fill_color);
4733 (void) MVGPrintf(wand,"'\n");
cristy3ed852e2009-09-05 21:47:34 +00004734 }
4735}
4736
4737/*
4738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4739% %
4740% %
4741% %
4742% D r a w S e t F i l l O p a c i t y %
4743% %
4744% %
4745% %
4746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4747%
dirkc8e845f2015-04-07 19:32:12 +00004748% DrawSetFillOpacity() sets the alpha to use when drawing using the fill
cristy3ed852e2009-09-05 21:47:34 +00004749% color or fill texture. Fully opaque is 1.0.
4750%
dirkc8e845f2015-04-07 19:32:12 +00004751% The format of the DrawSetFillOpacity method is:
cristy3ed852e2009-09-05 21:47:34 +00004752%
dirkc8e845f2015-04-07 19:32:12 +00004753% void DrawSetFillOpacity(DrawingWand *wand,const double fill_alpha)
cristy3ed852e2009-09-05 21:47:34 +00004754%
4755% A description of each parameter follows:
4756%
4757% o wand: the drawing wand.
4758%
dirkc8e845f2015-04-07 19:32:12 +00004759% o fill_opacity: fill opacity
cristy3ed852e2009-09-05 21:47:34 +00004760%
4761*/
dirkc8e845f2015-04-07 19:32:12 +00004762WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
cristy3ed852e2009-09-05 21:47:34 +00004763{
cristye42f6582012-02-11 17:59:50 +00004764 double
cristyb6a294d2011-10-03 00:55:17 +00004765 alpha;
cristy3ed852e2009-09-05 21:47:34 +00004766
4767 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004768 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004769 if (wand->debug != MagickFalse)
4770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
dirkc8e845f2015-04-07 19:32:12 +00004771 alpha=(double) ClampToQuantum(QuantumRange*fill_opacity);
cristy3ed852e2009-09-05 21:47:34 +00004772 if ((wand->filter_off != MagickFalse) ||
cristyb6a294d2011-10-03 00:55:17 +00004773 (CurrentContext->fill.alpha != alpha))
cristy3ed852e2009-09-05 21:47:34 +00004774 {
cristyb6a294d2011-10-03 00:55:17 +00004775 CurrentContext->fill.alpha=alpha;
Cristybd0db062015-12-26 10:33:53 -05004776 (void) MVGPrintf(wand,"fill-opacity %.20g\n",fill_opacity);
cristy3ed852e2009-09-05 21:47:34 +00004777 }
4778}
4779
4780/*
4781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4782% %
4783% %
4784% %
cristy56375382010-11-21 23:49:30 +00004785% D r a w S e t F o n t R e s o l u t i o n %
4786% %
4787% %
4788% %
4789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4790%
4791% DrawSetFontResolution() sets the image resolution.
4792%
4793% The format of the DrawSetFontResolution method is:
4794%
cristy76fa3142012-04-26 11:30:17 +00004795% MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
4796% const double x_resolution,const double y_resolution)
cristy56375382010-11-21 23:49:30 +00004797%
4798% A description of each parameter follows:
4799%
4800% o wand: the magick wand.
4801%
4802% o x_resolution: the image x resolution.
4803%
4804% o y_resolution: the image y resolution.
4805%
4806*/
4807WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
4808 const double x_resolution,const double y_resolution)
4809{
4810 char
cristy151b66d2015-04-15 10:50:31 +00004811 density[MagickPathExtent];
cristy56375382010-11-21 23:49:30 +00004812
4813 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004814 assert(wand->signature == MagickWandSignature);
cristy56375382010-11-21 23:49:30 +00004815 if (wand->debug != MagickFalse)
4816 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy151b66d2015-04-15 10:50:31 +00004817 (void) FormatLocaleString(density,MagickPathExtent,"%.20gx%.20g",x_resolution,
cristy56375382010-11-21 23:49:30 +00004818 y_resolution);
4819 (void) CloneString(&CurrentContext->density,density);
4820 return(MagickTrue);
4821}
4822
4823/*
4824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4825% %
4826% %
4827% %
cristy3ed852e2009-09-05 21:47:34 +00004828% D r a w S e t O p a c i t y %
4829% %
4830% %
4831% %
4832%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4833%
cristycc29a962015-03-23 21:17:46 +00004834% DrawSetOpacity() sets the alpha to use when drawing using the fill or
cristy3ed852e2009-09-05 21:47:34 +00004835% stroke color or texture. Fully opaque is 1.0.
4836%
cristycc29a962015-03-23 21:17:46 +00004837% The format of the DrawSetOpacity method is:
cristy3ed852e2009-09-05 21:47:34 +00004838%
cristycc29a962015-03-23 21:17:46 +00004839% void DrawSetOpacity(DrawingWand *wand,const double alpha)
cristy3ed852e2009-09-05 21:47:34 +00004840%
4841% A description of each parameter follows:
4842%
4843% o wand: the drawing wand.
4844%
dirkc8e845f2015-04-07 19:32:12 +00004845% o opacity: fill and stroke opacity. The value 1.0 is opaque.
cristy3ed852e2009-09-05 21:47:34 +00004846%
4847*/
dirkc8e845f2015-04-07 19:32:12 +00004848WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
cristy3ed852e2009-09-05 21:47:34 +00004849{
4850 Quantum
cristyb6a294d2011-10-03 00:55:17 +00004851 quantum_alpha;
cristy3ed852e2009-09-05 21:47:34 +00004852
4853 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004854 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004855 if (wand->debug != MagickFalse)
4856 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
dirkc8e845f2015-04-07 19:32:12 +00004857 quantum_alpha=ClampToQuantum(QuantumRange*opacity);
cristy3ed852e2009-09-05 21:47:34 +00004858 if ((wand->filter_off != MagickFalse) ||
cristyb6a294d2011-10-03 00:55:17 +00004859 (CurrentContext->alpha != quantum_alpha))
cristy3ed852e2009-09-05 21:47:34 +00004860 {
dirkc8e845f2015-04-07 19:32:12 +00004861 CurrentContext->alpha=(Quantum) opacity;
Cristybd0db062015-12-26 10:33:53 -05004862 (void) MVGPrintf(wand,"opacity %.20g\n",opacity);
cristy3ed852e2009-09-05 21:47:34 +00004863 }
4864}
4865
4866/*
4867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4868% %
4869% %
4870% %
4871% D r a w S e t F i l l P a t t e r n U R L %
4872% %
4873% %
4874% %
4875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4876%
4877% DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4878% objects. Only local URLs ("#identifier") are supported at this time. These
4879% local URLs are normally created by defining a named fill pattern with
4880% DrawPushPattern/DrawPopPattern.
4881%
4882% The format of the DrawSetFillPatternURL method is:
4883%
4884% MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4885% const char *fill_url)
4886%
4887% A description of each parameter follows:
4888%
4889% o wand: the drawing wand.
4890%
4891% o fill_url: URL to use to obtain fill pattern.
4892%
4893*/
4894WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4895 const char *fill_url)
4896{
4897 char
cristy151b66d2015-04-15 10:50:31 +00004898 pattern[MagickPathExtent],
4899 pattern_spec[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00004900
4901 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004902 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004903 if (wand->debug != MagickFalse)
4904 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4905 if (wand->image == (Image *) NULL)
4906 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4907 assert(fill_url != (const char *) NULL);
4908 if (*fill_url != '#')
4909 {
4910 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4911 return(MagickFalse);
4912 }
cristy151b66d2015-04-15 10:50:31 +00004913 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",fill_url+1);
cristy3ed852e2009-09-05 21:47:34 +00004914 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4915 {
4916 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4917 return(MagickFalse);
4918 }
cristy151b66d2015-04-15 10:50:31 +00004919 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",fill_url);
cristy3ed852e2009-09-05 21:47:34 +00004920#if DRAW_BINARY_IMPLEMENTATION
4921 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4922 &CurrentContext->fill_pattern);
4923#endif
cristy4c08aed2011-07-01 19:47:50 +00004924 if (CurrentContext->fill.alpha != (Quantum) TransparentAlpha)
cristye42f6582012-02-11 17:59:50 +00004925 CurrentContext->fill.alpha=(double) CurrentContext->alpha;
Cristybd0db062015-12-26 10:33:53 -05004926 (void) MVGPrintf(wand,"fill %s\n",pattern_spec);
cristy3ed852e2009-09-05 21:47:34 +00004927 return(MagickTrue);
4928}
4929
4930/*
4931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4932% %
4933% %
4934% %
4935% D r a w S e t F i l l R u l e %
4936% %
4937% %
4938% %
4939%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4940%
4941% DrawSetFillRule() sets the fill rule to use while drawing polygons.
4942%
4943% The format of the DrawSetFillRule method is:
4944%
4945% void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4946%
4947% A description of each parameter follows:
4948%
4949% o wand: the drawing wand.
4950%
4951% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4952%
4953*/
4954WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4955{
4956 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004957 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004958 if (wand->debug != MagickFalse)
4959 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4960 if ((wand->filter_off != MagickFalse) ||
4961 (CurrentContext->fill_rule != fill_rule))
4962 {
4963 CurrentContext->fill_rule=fill_rule;
Cristybd0db062015-12-26 10:33:53 -05004964 (void) MVGPrintf(wand, "fill-rule '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004965 MagickFillRuleOptions,(ssize_t) fill_rule));
cristy3ed852e2009-09-05 21:47:34 +00004966 }
4967}
4968
4969/*
4970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4971% %
4972% %
4973% %
4974% D r a w S e t F o n t %
4975% %
4976% %
4977% %
4978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4979%
4980% DrawSetFont() sets the fully-sepecified font to use when annotating with
4981% text.
4982%
4983% The format of the DrawSetFont method is:
4984%
4985% MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4986%
4987% A description of each parameter follows:
4988%
4989% o wand: the drawing wand.
4990%
4991% o font_name: font name
4992%
4993*/
4994WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4995 const char *font_name)
4996{
4997 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004998 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00004999 if (wand->debug != MagickFalse)
5000 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5001 assert(font_name != (const char *) NULL);
5002 if ((wand->filter_off != MagickFalse) ||
5003 (CurrentContext->font == (char *) NULL) ||
5004 (LocaleCompare(CurrentContext->font,font_name) != 0))
5005 {
5006 (void) CloneString(&CurrentContext->font,font_name);
Cristybd0db062015-12-26 10:33:53 -05005007 (void) MVGPrintf(wand,"font '%s'\n",font_name);
cristy3ed852e2009-09-05 21:47:34 +00005008 }
5009 return(MagickTrue);
5010}
5011
5012/*
5013%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5014% %
5015% %
5016% %
5017% D r a w S e t F o n t F a m i l y %
5018% %
5019% %
5020% %
5021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5022%
5023% DrawSetFontFamily() sets the font family to use when annotating with text.
5024%
5025% The format of the DrawSetFontFamily method is:
5026%
5027% MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5028% const char *font_family)
5029%
5030% A description of each parameter follows:
5031%
5032% o wand: the drawing wand.
5033%
5034% o font_family: font family
5035%
5036*/
5037WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5038 const char *font_family)
5039{
5040 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005041 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005042 if (wand->debug != MagickFalse)
5043 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5044 assert(font_family != (const char *) NULL);
5045 if ((wand->filter_off != MagickFalse) ||
5046 (CurrentContext->family == (const char *) NULL) ||
5047 (LocaleCompare(CurrentContext->family,font_family) != 0))
5048 {
5049 (void) CloneString(&CurrentContext->family,font_family);
Cristybd0db062015-12-26 10:33:53 -05005050 (void) MVGPrintf(wand,"font-family '%s'\n",font_family);
cristy3ed852e2009-09-05 21:47:34 +00005051 }
5052 return(MagickTrue);
5053}
5054
5055/*
5056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5057% %
5058% %
5059% %
5060% D r a w S e t F o n t S i z e %
5061% %
5062% %
5063% %
5064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5065%
5066% DrawSetFontSize() sets the font pointsize to use when annotating with text.
5067%
5068% The format of the DrawSetFontSize method is:
5069%
5070% void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5071%
5072% A description of each parameter follows:
5073%
5074% o wand: the drawing wand.
5075%
5076% o pointsize: text pointsize
5077%
5078*/
5079WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5080{
5081 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005082 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005083 if (wand->debug != MagickFalse)
5084 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5085 if ((wand->filter_off != MagickFalse) ||
cristy3d2287c2012-06-04 21:26:19 +00005086 (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon))
cristy3ed852e2009-09-05 21:47:34 +00005087 {
5088 CurrentContext->pointsize=pointsize;
Cristybd0db062015-12-26 10:33:53 -05005089 (void) MVGPrintf(wand,"font-size %.20g\n",pointsize);
cristy3ed852e2009-09-05 21:47:34 +00005090 }
5091}
5092
5093/*
5094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5095% %
5096% %
5097% %
5098% D r a w S e t F o n t S t r e t c h %
5099% %
5100% %
5101% %
5102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5103%
5104% DrawSetFontStretch() sets the font stretch to use when annotating with text.
5105% The AnyStretch enumeration acts as a wild-card "don't care" option.
5106%
5107% The format of the DrawSetFontStretch method is:
5108%
5109% void DrawSetFontStretch(DrawingWand *wand,
5110% const StretchType font_stretch)
5111%
5112% A description of each parameter follows:
5113%
5114% o wand: the drawing wand.
5115%
5116% o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5117% CondensedStretch, SemiCondensedStretch,
5118% SemiExpandedStretch, ExpandedStretch,
5119% ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5120%
5121*/
5122WandExport void DrawSetFontStretch(DrawingWand *wand,
5123 const StretchType font_stretch)
5124{
5125 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005126 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005127 if (wand->debug != MagickFalse)
5128 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5129 if ((wand->filter_off != MagickFalse) ||
5130 (CurrentContext->stretch != font_stretch))
5131 {
5132 CurrentContext->stretch=font_stretch;
Cristybd0db062015-12-26 10:33:53 -05005133 (void) MVGPrintf(wand, "font-stretch '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005134 MagickStretchOptions,(ssize_t) font_stretch));
cristy3ed852e2009-09-05 21:47:34 +00005135 }
5136}
5137
5138/*
5139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5140% %
5141% %
5142% %
5143% D r a w S e t F o n t S t y l e %
5144% %
5145% %
5146% %
5147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5148%
5149% DrawSetFontStyle() sets the font style to use when annotating with text.
5150% The AnyStyle enumeration acts as a wild-card "don't care" option.
5151%
5152% The format of the DrawSetFontStyle method is:
5153%
5154% void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5155%
5156% A description of each parameter follows:
5157%
5158% o wand: the drawing wand.
5159%
5160% o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5161%
5162*/
5163WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5164{
5165 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005166 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005167 if (wand->debug != MagickFalse)
5168 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5169 if ((wand->filter_off != MagickFalse) ||
5170 (CurrentContext->style != style))
5171 {
5172 CurrentContext->style=style;
Cristybd0db062015-12-26 10:33:53 -05005173 (void) MVGPrintf(wand, "font-style '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005174 MagickStyleOptions,(ssize_t) style));
cristy3ed852e2009-09-05 21:47:34 +00005175 }
5176}
5177
5178/*
5179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5180% %
5181% %
5182% %
5183% D r a w S e t F o n t W e i g h t %
5184% %
5185% %
5186% %
5187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5188%
5189% DrawSetFontWeight() sets the font weight to use when annotating with text.
5190%
5191% The format of the DrawSetFontWeight method is:
5192%
5193% void DrawSetFontWeight(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005194% const size_t font_weight)
cristy3ed852e2009-09-05 21:47:34 +00005195%
5196% A description of each parameter follows:
5197%
5198% o wand: the drawing wand.
5199%
5200% o font_weight: font weight (valid range 100-900)
5201%
5202*/
5203WandExport void DrawSetFontWeight(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005204 const size_t font_weight)
cristy3ed852e2009-09-05 21:47:34 +00005205{
5206 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005207 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005208 if (wand->debug != MagickFalse)
5209 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5210 if ((wand->filter_off != MagickFalse) ||
5211 (CurrentContext->weight != font_weight))
5212 {
5213 CurrentContext->weight=font_weight;
Cristybd0db062015-12-26 10:33:53 -05005214 (void) MVGPrintf(wand,"font-weight %.20g\n",(double) font_weight);
cristy3ed852e2009-09-05 21:47:34 +00005215 }
5216}
5217
5218/*
5219%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5220% %
5221% %
5222% %
5223% D r a w S e t G r a v i t y %
5224% %
5225% %
5226% %
5227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5228%
5229% DrawSetGravity() sets the text placement gravity to use when annotating
5230% with text.
5231%
5232% The format of the DrawSetGravity method is:
5233%
5234% void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5235%
5236% A description of each parameter follows:
5237%
5238% o wand: the drawing wand.
5239%
5240% o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5241% NorthEastGravity, WestGravity, CenterGravity,
5242% EastGravity, SouthWestGravity, SouthGravity,
5243% SouthEastGravity)
5244%
5245*/
5246WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5247{
5248 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005249 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005250 if (wand->debug != MagickFalse)
5251 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5252 if ((wand->filter_off != MagickFalse) ||
5253 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5254 {
5255 CurrentContext->gravity=gravity;
Cristybd0db062015-12-26 10:33:53 -05005256 (void) MVGPrintf(wand,"gravity '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005257 MagickGravityOptions,(ssize_t) gravity));
cristy3ed852e2009-09-05 21:47:34 +00005258 }
5259}
5260
5261/*
5262%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5263% %
5264% %
5265% %
5266% D r a w S e t S t r o k e C o l o r %
5267% %
5268% %
5269% %
5270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5271%
5272% DrawSetStrokeColor() sets the color used for stroking object outlines.
5273%
5274% The format of the DrawSetStrokeColor method is:
5275%
5276% void DrawSetStrokeColor(DrawingWand *wand,
5277% const PixelWand *stroke_wand)
5278%
5279% A description of each parameter follows:
5280%
5281% o wand: the drawing wand.
5282%
5283% o stroke_wand: stroke wand.
5284%
5285*/
5286WandExport void DrawSetStrokeColor(DrawingWand *wand,
5287 const PixelWand *stroke_wand)
5288{
cristy101ab702011-10-13 13:06:32 +00005289 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00005290 *current_stroke,
5291 new_stroke,
5292 stroke_color;
5293
5294 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005295 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005296 if (wand->debug != MagickFalse)
5297 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5298 assert(stroke_wand != (const PixelWand *) NULL);
cristy4c08aed2011-07-01 19:47:50 +00005299 PixelGetQuantumPacket(stroke_wand,&stroke_color);
cristy3ed852e2009-09-05 21:47:34 +00005300 new_stroke=stroke_color;
5301 current_stroke=(&CurrentContext->stroke);
5302 if ((wand->filter_off != MagickFalse) ||
cristy101ab702011-10-13 13:06:32 +00005303 (IsPixelInfoEquivalent(current_stroke,&new_stroke) == MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00005304 {
5305 CurrentContext->stroke=new_stroke;
Cristybd0db062015-12-26 10:33:53 -05005306 (void) MVGPrintf(wand,"stroke '");
5307 MVGAppendColor(wand,&stroke_color);
5308 (void) MVGPrintf(wand,"'\n");
cristy3ed852e2009-09-05 21:47:34 +00005309 }
5310}
5311
5312/*
5313%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5314% %
5315% %
5316% %
5317% D r a w S e t S t r o k e P a t t e r n U R L %
5318% %
5319% %
5320% %
5321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5322%
5323% DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5324%
5325% The format of the DrawSetStrokePatternURL method is:
5326%
5327% MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5328% const char *stroke_url)
5329%
5330% A description of each parameter follows:
5331%
5332% o wand: the drawing wand.
5333%
5334% o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5335%
5336*/
5337WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5338 const char *stroke_url)
5339{
5340 char
cristy151b66d2015-04-15 10:50:31 +00005341 pattern[MagickPathExtent],
5342 pattern_spec[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00005343
5344 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005345 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005346 if (wand->debug != MagickFalse)
5347 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5348 if (wand->image == (Image *) NULL)
5349 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5350 assert(stroke_url != NULL);
5351 if (stroke_url[0] != '#')
5352 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
cristy151b66d2015-04-15 10:50:31 +00005353 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",stroke_url+1);
cristy3ed852e2009-09-05 21:47:34 +00005354 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5355 {
5356 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5357 return(MagickFalse);
5358 }
cristy151b66d2015-04-15 10:50:31 +00005359 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",stroke_url);
cristy3ed852e2009-09-05 21:47:34 +00005360#if DRAW_BINARY_IMPLEMENTATION
5361 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5362 &CurrentContext->stroke_pattern);
5363#endif
cristy4c08aed2011-07-01 19:47:50 +00005364 if (CurrentContext->stroke.alpha != (Quantum) TransparentAlpha)
cristye42f6582012-02-11 17:59:50 +00005365 CurrentContext->stroke.alpha=(double) CurrentContext->alpha;
Cristybd0db062015-12-26 10:33:53 -05005366 (void) MVGPrintf(wand,"stroke %s\n",pattern_spec);
cristy3ed852e2009-09-05 21:47:34 +00005367 return(MagickTrue);
5368}
5369
5370/*
5371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5372% %
5373% %
5374% %
5375% D r a w S e t S t r o k e A n t i a l i a s %
5376% %
5377% %
5378% %
5379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5380%
5381% DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5382% Stroked outlines are antialiased by default. When antialiasing is disabled
5383% stroked pixels are thresholded to determine if the stroke color or
5384% underlying canvas color should be used.
5385%
5386% The format of the DrawSetStrokeAntialias method is:
5387%
5388% void DrawSetStrokeAntialias(DrawingWand *wand,
5389% const MagickBooleanType stroke_antialias)
5390%
5391% A description of each parameter follows:
5392%
5393% o wand: the drawing wand.
5394%
5395% o stroke_antialias: set to false (zero) to disable antialiasing
5396%
5397*/
5398WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5399 const MagickBooleanType stroke_antialias)
5400{
5401 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005402 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005403 if (wand->debug != MagickFalse)
5404 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5405 if ((wand->filter_off != MagickFalse) ||
5406 (CurrentContext->stroke_antialias != stroke_antialias))
5407 {
5408 CurrentContext->stroke_antialias=stroke_antialias;
Cristybd0db062015-12-26 10:33:53 -05005409 (void) MVGPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
cristy3ed852e2009-09-05 21:47:34 +00005410 1 : 0);
5411 }
5412}
5413
5414/*
5415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5416% %
5417% %
5418% %
5419% D r a w S e t S t r o k e D a s h A r r a y %
5420% %
5421% %
5422% %
5423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5424%
5425% DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5426% stroke paths. The stroke dash array represents an array of numbers that
5427% specify the lengths of alternating dashes and gaps in pixels. If an odd
5428% number of values is provided, then the list of values is repeated to yield
5429% an even number of values. To remove an existing dash array, pass a zero
cristy6145b192013-12-15 23:58:29 +00005430% number_elements argument and null dasharray. A typical stroke dash array
cristy3ed852e2009-09-05 21:47:34 +00005431% might contain the members 5 3 2.
5432%
5433% The format of the DrawSetStrokeDashArray method is:
5434%
5435% MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
cristy6145b192013-12-15 23:58:29 +00005436% const size_t number_elements,const double *dasharray)
cristy3ed852e2009-09-05 21:47:34 +00005437%
5438% A description of each parameter follows:
5439%
5440% o wand: the drawing wand.
5441%
5442% o number_elements: number of elements in dash array
5443%
cristy6145b192013-12-15 23:58:29 +00005444% o dasharray: dash array values
cristy3ed852e2009-09-05 21:47:34 +00005445%
5446*/
5447WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
cristy6145b192013-12-15 23:58:29 +00005448 const size_t number_elements,const double *dasharray)
cristy3ed852e2009-09-05 21:47:34 +00005449{
5450 MagickBooleanType
5451 update;
5452
5453 register const double
5454 *p;
5455
5456 register double
5457 *q;
5458
cristybb503372010-05-27 20:51:26 +00005459 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005460 i;
5461
cristybb503372010-05-27 20:51:26 +00005462 size_t
cristy3ed852e2009-09-05 21:47:34 +00005463 n_new,
5464 n_old;
5465
5466 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005467 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005468 if (wand->debug != MagickFalse)
5469 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5470 n_new=number_elements;
cristy1d4a6952015-03-24 00:42:52 +00005471 if (dasharray == (const double *) NULL)
5472 n_new=0;
cristy3ed852e2009-09-05 21:47:34 +00005473 n_old=0;
5474 update=MagickFalse;
5475 q=CurrentContext->dash_pattern;
5476 if (q != (const double *) NULL)
cristy5f07f702011-09-26 17:29:10 +00005477 while (fabs(*q++) < MagickEpsilon)
cristy3ed852e2009-09-05 21:47:34 +00005478 n_old++;
5479 if ((n_old == 0) && (n_new == 0))
5480 update=MagickFalse;
5481 else
5482 if (n_old != n_new)
5483 update=MagickTrue;
5484 else
5485 if ((CurrentContext->dash_pattern != (double *) NULL) &&
cristy6145b192013-12-15 23:58:29 +00005486 (dasharray != (double *) NULL))
cristy3ed852e2009-09-05 21:47:34 +00005487 {
cristy6145b192013-12-15 23:58:29 +00005488 p=dasharray;
cristy3ed852e2009-09-05 21:47:34 +00005489 q=CurrentContext->dash_pattern;
cristybb503372010-05-27 20:51:26 +00005490 for (i=0; i < (ssize_t) n_new; i++)
cristy3ed852e2009-09-05 21:47:34 +00005491 {
cristy3d2287c2012-06-04 21:26:19 +00005492 if (fabs((*p)-(*q)) >= MagickEpsilon)
cristy3ed852e2009-09-05 21:47:34 +00005493 {
5494 update=MagickTrue;
5495 break;
5496 }
5497 p++;
5498 q++;
5499 }
5500 }
5501 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5502 {
5503 if (CurrentContext->dash_pattern != (double *) NULL)
5504 CurrentContext->dash_pattern=(double *)
5505 RelinquishMagickMemory(CurrentContext->dash_pattern);
5506 if (n_new != 0)
5507 {
5508 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5509 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
cristye47080a2014-01-14 23:53:40 +00005510 if (CurrentContext->dash_pattern == (double *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00005511 {
5512 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5513 wand->name);
5514 return(MagickFalse);
5515 }
cristy43602772014-01-29 14:07:29 +00005516 for (i=0; i < (ssize_t) n_new; i++)
cristy58515f32014-01-15 00:43:50 +00005517 {
5518 CurrentContext->dash_pattern[i]=0.0;
5519 if (dasharray != (double *) NULL)
5520 CurrentContext->dash_pattern[i]=dasharray[i];
5521 }
cristy6145b192013-12-15 23:58:29 +00005522 CurrentContext->dash_pattern[n_new]=0.0;
cristy3ed852e2009-09-05 21:47:34 +00005523 }
Cristybd0db062015-12-26 10:33:53 -05005524 (void) MVGPrintf(wand,"stroke-dasharray ");
cristy3ed852e2009-09-05 21:47:34 +00005525 if (n_new == 0)
Cristybd0db062015-12-26 10:33:53 -05005526 (void) MVGPrintf(wand,"none\n");
cristy3ed852e2009-09-05 21:47:34 +00005527 else
cristy40d90172014-01-15 01:22:25 +00005528 if (dasharray != (double *) NULL)
cristy6145b192013-12-15 23:58:29 +00005529 {
cristy43602772014-01-29 14:07:29 +00005530 for (i=0; i < (ssize_t) n_new; i++)
cristy40d90172014-01-15 01:22:25 +00005531 {
5532 if (i != 0)
Cristybd0db062015-12-26 10:33:53 -05005533 (void) MVGPrintf(wand,",");
5534 (void) MVGPrintf(wand,"%.20g",dasharray[i]);
cristy40d90172014-01-15 01:22:25 +00005535 }
Cristybd0db062015-12-26 10:33:53 -05005536 (void) MVGPrintf(wand,"\n");
cristy6145b192013-12-15 23:58:29 +00005537 }
cristy3ed852e2009-09-05 21:47:34 +00005538 }
5539 return(MagickTrue);
5540}
5541
5542/*
5543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5544% %
5545% %
5546% %
5547% D r a w S e t S t r o k e D a s h O f f s e t %
5548% %
5549% %
5550% %
5551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5552%
5553% DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5554% start the dash.
5555%
5556% The format of the DrawSetStrokeDashOffset method is:
5557%
5558% void DrawSetStrokeDashOffset(DrawingWand *wand,
5559% const double dash_offset)
5560%
5561% A description of each parameter follows:
5562%
5563% o wand: the drawing wand.
5564%
5565% o dash_offset: dash offset
5566%
5567*/
5568WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5569 const double dash_offset)
5570{
5571 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005572 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005573 if (wand->debug != MagickFalse)
5574 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5575 if ((wand->filter_off != MagickFalse) ||
cristy3d2287c2012-06-04 21:26:19 +00005576 (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon))
cristy3ed852e2009-09-05 21:47:34 +00005577 {
5578 CurrentContext->dash_offset=dash_offset;
Cristybd0db062015-12-26 10:33:53 -05005579 (void) MVGPrintf(wand,"stroke-dashoffset %.20g\n",dash_offset);
cristy3ed852e2009-09-05 21:47:34 +00005580 }
5581}
5582
5583/*
5584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5585% %
5586% %
5587% %
5588% D r a w S e t S t r o k e L i n e C a p %
5589% %
5590% %
5591% %
5592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5593%
5594% DrawSetStrokeLineCap() specifies the shape to be used at the end of
5595% open subpaths when they are stroked. Values of LineCap are
5596% UndefinedCap, ButtCap, RoundCap, and SquareCap.
5597%
5598% The format of the DrawSetStrokeLineCap method is:
5599%
5600% void DrawSetStrokeLineCap(DrawingWand *wand,
5601% const LineCap linecap)
5602%
5603% A description of each parameter follows:
5604%
5605% o wand: the drawing wand.
5606%
5607% o linecap: linecap style
5608%
5609*/
5610WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5611{
5612 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005613 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005614 if (wand->debug != MagickFalse)
5615 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05005616 if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap))
cristy3ed852e2009-09-05 21:47:34 +00005617 {
5618 CurrentContext->linecap=linecap;
Cristybd0db062015-12-26 10:33:53 -05005619 (void) MVGPrintf(wand,"stroke-linecap '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005620 MagickLineCapOptions,(ssize_t) linecap));
cristy3ed852e2009-09-05 21:47:34 +00005621 }
5622}
5623
5624/*
5625%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5626% %
5627% %
5628% %
5629% D r a w S e t S t r o k e L i n e J o i n %
5630% %
5631% %
5632% %
5633%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5634%
5635% DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5636% paths (or other vector shapes) when they are stroked. Values of LineJoin are
5637% UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5638%
5639% The format of the DrawSetStrokeLineJoin method is:
5640%
5641% void DrawSetStrokeLineJoin(DrawingWand *wand,
5642% const LineJoin linejoin)
5643%
5644% A description of each parameter follows:
5645%
5646% o wand: the drawing wand.
5647%
5648% o linejoin: line join style
5649%
5650*/
5651WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5652{
5653 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005654 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005655 if (wand->debug != MagickFalse)
5656 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5657 if ((wand->filter_off != MagickFalse) ||
5658 (CurrentContext->linejoin != linejoin))
5659 {
5660 CurrentContext->linejoin=linejoin;
Cristybd0db062015-12-26 10:33:53 -05005661 (void) MVGPrintf(wand, "stroke-linejoin '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005662 MagickLineJoinOptions,(ssize_t) linejoin));
cristy3ed852e2009-09-05 21:47:34 +00005663 }
5664}
5665
5666/*
5667%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5668% %
5669% %
5670% %
5671% D r a w S e t S t r o k e M i t e r L i m i t %
5672% %
5673% %
5674% %
5675%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5676%
5677% DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5678% segments meet at a sharp angle and miter joins have been specified for
5679% 'lineJoin', it is possible for the miter to extend far beyond the
5680% thickness of the line stroking the path. The miterLimit' imposes a
5681% limit on the ratio of the miter length to the 'lineWidth'.
5682%
5683% The format of the DrawSetStrokeMiterLimit method is:
5684%
5685% void DrawSetStrokeMiterLimit(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005686% const size_t miterlimit)
cristy3ed852e2009-09-05 21:47:34 +00005687%
5688% A description of each parameter follows:
5689%
5690% o wand: the drawing wand.
5691%
5692% o miterlimit: miter limit
5693%
5694*/
5695WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005696 const size_t miterlimit)
cristy3ed852e2009-09-05 21:47:34 +00005697{
5698 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005699 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005700 if (wand->debug != MagickFalse)
5701 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5702 if (CurrentContext->miterlimit != miterlimit)
5703 {
5704 CurrentContext->miterlimit=miterlimit;
Cristybd0db062015-12-26 10:33:53 -05005705 (void) MVGPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit);
cristy3ed852e2009-09-05 21:47:34 +00005706 }
5707}
5708
5709/*
5710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5711% %
5712% %
5713% %
5714% D r a w S e t S t r o k e O p a c i t y %
5715% %
5716% %
5717% %
5718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5719%
dirkc8e845f2015-04-07 19:32:12 +00005720% DrawSetStrokeOpacity() specifies the alpha of stroked object outlines.
cristy3ed852e2009-09-05 21:47:34 +00005721%
dirkc8e845f2015-04-07 19:32:12 +00005722% The format of the DrawSetStrokeOpacity method is:
cristy3ed852e2009-09-05 21:47:34 +00005723%
dirkc8e845f2015-04-07 19:32:12 +00005724% void DrawSetStrokeOpacity(DrawingWand *wand,
cristyb6a294d2011-10-03 00:55:17 +00005725% const double stroke_alpha)
cristy3ed852e2009-09-05 21:47:34 +00005726%
5727% A description of each parameter follows:
5728%
5729% o wand: the drawing wand.
5730%
dirkc8e845f2015-04-07 19:32:12 +00005731% o opacity: stroke opacity. The value 1.0 is opaque.
cristy3ed852e2009-09-05 21:47:34 +00005732%
5733*/
dirkc8e845f2015-04-07 19:32:12 +00005734WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5735 const double opacity)
cristy3ed852e2009-09-05 21:47:34 +00005736{
cristye42f6582012-02-11 17:59:50 +00005737 double
cristyb6a294d2011-10-03 00:55:17 +00005738 alpha;
cristy3ed852e2009-09-05 21:47:34 +00005739
5740 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005741 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005742 if (wand->debug != MagickFalse)
5743 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
dirkc8e845f2015-04-07 19:32:12 +00005744 alpha=(double) ClampToQuantum(QuantumRange*opacity);
cristy3ed852e2009-09-05 21:47:34 +00005745 if ((wand->filter_off != MagickFalse) ||
cristyb6a294d2011-10-03 00:55:17 +00005746 (CurrentContext->stroke.alpha != alpha))
cristy3ed852e2009-09-05 21:47:34 +00005747 {
cristyb6a294d2011-10-03 00:55:17 +00005748 CurrentContext->stroke.alpha=alpha;
Cristybd0db062015-12-26 10:33:53 -05005749 (void) MVGPrintf(wand,"stroke-opacity %.20g\n",opacity);
cristy3ed852e2009-09-05 21:47:34 +00005750 }
5751}
5752
5753/*
5754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5755% %
5756% %
5757% %
5758% D r a w S e t S t r o k e W i d t h %
5759% %
5760% %
5761% %
5762%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5763%
5764% DrawSetStrokeWidth() sets the width of the stroke used to draw object
5765% outlines.
5766%
5767% The format of the DrawSetStrokeWidth method is:
5768%
5769% void DrawSetStrokeWidth(DrawingWand *wand,
5770% const double stroke_width)
5771%
5772% A description of each parameter follows:
5773%
5774% o wand: the drawing wand.
5775%
5776% o stroke_width: stroke width
5777%
5778*/
5779WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5780{
5781 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005782 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005783 if (wand->debug != MagickFalse)
5784 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5785 if ((wand->filter_off != MagickFalse) ||
cristy3d2287c2012-06-04 21:26:19 +00005786 (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon))
cristy3ed852e2009-09-05 21:47:34 +00005787 {
5788 CurrentContext->stroke_width=stroke_width;
Cristybd0db062015-12-26 10:33:53 -05005789 (void) MVGPrintf(wand,"stroke-width %.20g\n",stroke_width);
cristy3ed852e2009-09-05 21:47:34 +00005790 }
5791}
5792
5793/*
5794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5795% %
5796% %
5797% %
5798% D r a w S e t T e x t A l i g n m e n t %
5799% %
5800% %
5801% %
5802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5803%
5804% DrawSetTextAlignment() specifies a text alignment to be applied when
5805% annotating with text.
5806%
5807% The format of the DrawSetTextAlignment method is:
5808%
5809% void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5810%
5811% A description of each parameter follows:
5812%
5813% o wand: the drawing wand.
5814%
5815% o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5816% CenterAlign, or RightAlign.
5817%
5818*/
5819WandExport void DrawSetTextAlignment(DrawingWand *wand,
5820 const AlignType alignment)
5821{
5822 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005823 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005824 if (wand->debug != MagickFalse)
5825 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5826 if ((wand->filter_off != MagickFalse) ||
5827 (CurrentContext->align != alignment))
5828 {
5829 CurrentContext->align=alignment;
Cristybd0db062015-12-26 10:33:53 -05005830 (void) MVGPrintf(wand,"text-align '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005831 MagickAlignOptions,(ssize_t) alignment));
cristy3ed852e2009-09-05 21:47:34 +00005832 }
5833}
5834
5835/*
5836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5837% %
5838% %
5839% %
5840% D r a w S e t T e x t A n t i a l i a s %
5841% %
5842% %
5843% %
5844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5845%
5846% DrawSetTextAntialias() controls whether text is antialiased. Text is
5847% antialiased by default.
5848%
5849% The format of the DrawSetTextAntialias method is:
5850%
5851% void DrawSetTextAntialias(DrawingWand *wand,
5852% const MagickBooleanType text_antialias)
5853%
5854% A description of each parameter follows:
5855%
5856% o wand: the drawing wand.
5857%
5858% o text_antialias: antialias boolean. Set to false (0) to disable
5859% antialiasing.
5860%
5861*/
5862WandExport void DrawSetTextAntialias(DrawingWand *wand,
5863 const MagickBooleanType text_antialias)
5864{
5865 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005866 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005867 if (wand->debug != MagickFalse)
5868 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5869 if ((wand->filter_off != MagickFalse) ||
5870 (CurrentContext->text_antialias != text_antialias))
5871 {
5872 CurrentContext->text_antialias=text_antialias;
Cristybd0db062015-12-26 10:33:53 -05005873 (void) MVGPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
cristy3ed852e2009-09-05 21:47:34 +00005874 }
5875}
5876
5877/*
5878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5879% %
5880% %
5881% %
5882% D r a w S e t T e x t D e c o r a t i o n %
5883% %
5884% %
5885% %
5886%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5887%
5888% DrawSetTextDecoration() specifies a decoration to be applied when
5889% annotating with text.
5890%
5891% The format of the DrawSetTextDecoration method is:
5892%
5893% void DrawSetTextDecoration(DrawingWand *wand,
5894% const DecorationType decoration)
5895%
5896% A description of each parameter follows:
5897%
5898% o wand: the drawing wand.
5899%
5900% o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5901% OverlineDecoration, or LineThroughDecoration
5902%
5903*/
5904WandExport void DrawSetTextDecoration(DrawingWand *wand,
5905 const DecorationType decoration)
5906{
5907 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005908 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005909 if (wand->debug != MagickFalse)
5910 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5911 if ((wand->filter_off != MagickFalse) ||
5912 (CurrentContext->decorate != decoration))
5913 {
5914 CurrentContext->decorate=decoration;
Cristybd0db062015-12-26 10:33:53 -05005915 (void) MVGPrintf(wand,"decorate '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005916 MagickDecorateOptions,(ssize_t) decoration));
cristy3ed852e2009-09-05 21:47:34 +00005917 }
5918}
Cristybd0db062015-12-26 10:33:53 -05005919
5920/*
dirkc084d392014-01-27 19:08:45 +00005921%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5922% %
5923% %
5924% %
5925% D r a w S e t T e x t D i r e c t i o n %
5926% %
5927% %
5928% %
5929%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5930%
5931% DrawSetTextDirection() specifies the direction to be used when
5932% annotating with text.
5933%
5934% The format of the DrawSetTextDirection method is:
5935%
5936% void DrawSetTextDirection(DrawingWand *wand,
5937% const DirectionType direction)
5938%
5939% A description of each parameter follows:
5940%
5941% o wand: the drawing wand.
5942%
5943% o direction: text direction. One of RightToLeftDirection,
5944% LeftToRightDirection
5945%
5946*/
5947WandExport void DrawSetTextDirection(DrawingWand *wand,
5948 const DirectionType direction)
5949{
5950 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005951 assert(wand->signature == MagickWandSignature);
dirkc084d392014-01-27 19:08:45 +00005952
5953 if (wand->debug != MagickFalse)
5954 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5955 if ((wand->filter_off != MagickFalse) ||
5956 (CurrentContext->direction != direction))
5957 {
5958 CurrentContext->direction=direction;
Cristybd0db062015-12-26 10:33:53 -05005959 (void) MVGPrintf(wand,"direction '%s'\n",CommandOptionToMnemonic(
dirkc084d392014-01-27 19:08:45 +00005960 MagickDirectionOptions,(ssize_t) direction));
5961 }
5962}
5963
cristy3ed852e2009-09-05 21:47:34 +00005964/*
5965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5966% %
5967% %
5968% %
5969% D r a w S e t T e x t E n c o d i n g %
5970% %
5971% %
5972% %
5973%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5974%
5975% DrawSetTextEncoding() specifies the code set to use for text
5976% annotations. The only character encoding which may be specified
5977% at this time is "UTF-8" for representing Unicode as a sequence of
5978% bytes. Specify an empty string to set text encoding to the system's
5979% default. Successful text annotation using Unicode may require fonts
5980% designed to support Unicode.
5981%
5982% The format of the DrawSetTextEncoding method is:
5983%
5984% void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5985%
5986% A description of each parameter follows:
5987%
5988% o wand: the drawing wand.
5989%
5990% o encoding: character string specifying text encoding
5991%
5992*/
5993WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5994{
5995 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005996 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00005997 if (wand->debug != MagickFalse)
5998 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5999 assert(encoding != (char *) NULL);
6000 if ((wand->filter_off != MagickFalse) ||
6001 (CurrentContext->encoding == (char *) NULL) ||
6002 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
6003 {
6004 (void) CloneString(&CurrentContext->encoding,encoding);
Cristybd0db062015-12-26 10:33:53 -05006005 (void) MVGPrintf(wand,"encoding '%s'\n",encoding);
cristy3ed852e2009-09-05 21:47:34 +00006006 }
6007}
6008
6009/*
6010%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6011% %
6012% %
6013% %
6014% D r a w S e t T e x t K e r n i n g %
6015% %
6016% %
6017% %
6018%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6019%
6020% DrawSetTextKerning() sets the spacing between characters in text.
6021%
6022% The format of the DrawSetTextKerning method is:
6023%
6024% void DrawSetTextKerning(DrawingWand *wand,const double kerning)
6025%
6026% A description of each parameter follows:
6027%
6028% o wand: the drawing wand.
6029%
6030% o kerning: text kerning
6031%
6032*/
6033WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
6034{
6035 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006036 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006037
6038 if (wand->debug != MagickFalse)
6039 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00006040 if ((wand->filter_off != MagickFalse) &&
cristy5f07f702011-09-26 17:29:10 +00006041 ((CurrentContext->kerning-kerning) >= MagickEpsilon))
cristy3ed852e2009-09-05 21:47:34 +00006042 {
6043 CurrentContext->kerning=kerning;
Cristybd0db062015-12-26 10:33:53 -05006044 (void) MVGPrintf(wand,"kerning %lf\n",kerning);
cristy3ed852e2009-09-05 21:47:34 +00006045 }
6046}
6047
6048/*
6049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6050% %
6051% %
6052% %
cristyb32b90a2009-09-07 21:45:48 +00006053% 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 %
6054% %
6055% %
6056% %
6057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6058%
cristy76fa3142012-04-26 11:30:17 +00006059% DrawSetTextInterlineSpacing() sets the spacing between line in text.
cristyb32b90a2009-09-07 21:45:48 +00006060%
cristy76fa3142012-04-26 11:30:17 +00006061% The format of the DrawSetInterlineSpacing method is:
cristyb32b90a2009-09-07 21:45:48 +00006062%
cristy76fa3142012-04-26 11:30:17 +00006063% void DrawSetTextInterlineSpacing(DrawingWand *wand,
cristyb32b90a2009-09-07 21:45:48 +00006064% const double interline_spacing)
6065%
6066% A description of each parameter follows:
6067%
6068% o wand: the drawing wand.
6069%
6070% o interline_spacing: text line spacing
6071%
6072*/
6073WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
6074 const double interline_spacing)
6075{
6076 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006077 assert(wand->signature == MagickWandSignature);
cristyb32b90a2009-09-07 21:45:48 +00006078
6079 if (wand->debug != MagickFalse)
6080 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00006081 if ((wand->filter_off != MagickFalse) &&
cristy5f07f702011-09-26 17:29:10 +00006082 ((CurrentContext->interline_spacing-interline_spacing) >= MagickEpsilon))
cristyb32b90a2009-09-07 21:45:48 +00006083 {
6084 CurrentContext->interline_spacing=interline_spacing;
Cristybd0db062015-12-26 10:33:53 -05006085 (void) MVGPrintf(wand,"interline-spacing %lf\n",interline_spacing);
cristyb32b90a2009-09-07 21:45:48 +00006086 }
6087}
6088
6089/*
6090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6091% %
6092% %
6093% %
cristy3ed852e2009-09-05 21:47:34 +00006094% 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 %
6095% %
6096% %
6097% %
6098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6099%
6100% DrawSetTextInterwordSpacing() sets the spacing between words in text.
6101%
6102% The format of the DrawSetInterwordSpacing method is:
6103%
6104% void DrawSetTextInterwordSpacing(DrawingWand *wand,
6105% const double interword_spacing)
6106%
6107% A description of each parameter follows:
6108%
6109% o wand: the drawing wand.
6110%
6111% o interword_spacing: text word spacing
6112%
6113*/
6114WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
6115 const double interword_spacing)
6116{
6117 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006118 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006119
6120 if (wand->debug != MagickFalse)
6121 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00006122 if ((wand->filter_off != MagickFalse) &&
cristy5f07f702011-09-26 17:29:10 +00006123 ((CurrentContext->interword_spacing-interword_spacing) >= MagickEpsilon))
cristy3ed852e2009-09-05 21:47:34 +00006124 {
6125 CurrentContext->interword_spacing=interword_spacing;
Cristybd0db062015-12-26 10:33:53 -05006126 (void) MVGPrintf(wand,"interword-spacing %lf\n",interword_spacing);
cristy3ed852e2009-09-05 21:47:34 +00006127 }
6128}
6129
6130/*
6131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6132% %
6133% %
6134% %
6135% D r a w S e t T e x t U n d e r C o l o r %
6136% %
6137% %
6138% %
6139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6140%
6141% DrawSetTextUnderColor() specifies the color of a background rectangle
6142% to place under text annotations.
6143%
6144% The format of the DrawSetTextUnderColor method is:
6145%
6146% void DrawSetTextUnderColor(DrawingWand *wand,
6147% const PixelWand *under_wand)
6148%
6149% A description of each parameter follows:
6150%
6151% o wand: the drawing wand.
6152%
6153% o under_wand: text under wand.
6154%
6155*/
6156WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6157 const PixelWand *under_wand)
6158{
cristy101ab702011-10-13 13:06:32 +00006159 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00006160 under_color;
6161
6162 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006163 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006164 if (wand->debug != MagickFalse)
6165 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6166 assert(under_wand != (const PixelWand *) NULL);
cristy4c08aed2011-07-01 19:47:50 +00006167 PixelGetQuantumPacket(under_wand,&under_color);
cristy3ed852e2009-09-05 21:47:34 +00006168 if ((wand->filter_off != MagickFalse) ||
cristy101ab702011-10-13 13:06:32 +00006169 (IsPixelInfoEquivalent(&CurrentContext->undercolor,&under_color) == MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00006170 {
6171 CurrentContext->undercolor=under_color;
Cristybd0db062015-12-26 10:33:53 -05006172 (void) MVGPrintf(wand,"text-undercolor '");
6173 MVGAppendColor(wand,&under_color);
6174 (void) MVGPrintf(wand,"'\n");
cristy3ed852e2009-09-05 21:47:34 +00006175 }
6176}
6177
6178/*
6179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6180% %
6181% %
6182% %
6183% D r a w S e t V e c t o r G r a p h i c s %
6184% %
6185% %
6186% %
6187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6188%
6189% DrawSetVectorGraphics() sets the vector graphics associated with the
6190% specified wand. Use this method with DrawGetVectorGraphics() as a method
6191% to persist the vector graphics state.
6192%
6193% The format of the DrawSetVectorGraphics method is:
6194%
6195% MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6196% const char *xml)
6197%
6198% A description of each parameter follows:
6199%
6200% o wand: the drawing wand.
6201%
6202% o xml: the drawing wand XML.
6203%
6204*/
6205
6206static inline MagickBooleanType IsPoint(const char *point)
6207{
6208 char
6209 *p;
6210
cristycee97112010-05-28 00:44:52 +00006211 long
cristy3ed852e2009-09-05 21:47:34 +00006212 value;
6213
6214 value=strtol(point,&p,10);
cristyda16f162011-02-19 23:52:17 +00006215 (void) value;
cristy3ed852e2009-09-05 21:47:34 +00006216 return(p != point ? MagickTrue : MagickFalse);
6217}
6218
6219WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6220 const char *xml)
6221{
6222 const char
6223 *value;
6224
6225 XMLTreeInfo
6226 *child,
6227 *xml_info;
6228
6229 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006230 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006231 if (wand->debug != MagickFalse)
6232 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6233 CurrentContext=DestroyDrawInfo(CurrentContext);
6234 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6235 if (xml == (const char *) NULL)
6236 return(MagickFalse);
6237 xml_info=NewXMLTree(xml,wand->exception);
6238 if (xml_info == (XMLTreeInfo *) NULL)
6239 return(MagickFalse);
6240 child=GetXMLTreeChild(xml_info,"clip-path");
6241 if (child != (XMLTreeInfo *) NULL)
6242 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6243 child=GetXMLTreeChild(xml_info,"clip-units");
6244 if (child != (XMLTreeInfo *) NULL)
6245 {
6246 value=GetXMLTreeContent(child);
6247 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006248 CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006249 MagickClipPathOptions,MagickFalse,value);
6250 }
6251 child=GetXMLTreeChild(xml_info,"decorate");
6252 if (child != (XMLTreeInfo *) NULL)
6253 {
6254 value=GetXMLTreeContent(child);
6255 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006256 CurrentContext->decorate=(DecorationType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006257 MagickDecorateOptions,MagickFalse,value);
6258 }
6259 child=GetXMLTreeChild(xml_info,"encoding");
6260 if (child != (XMLTreeInfo *) NULL)
6261 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6262 child=GetXMLTreeChild(xml_info,"fill");
6263 if (child != (XMLTreeInfo *) NULL)
6264 {
6265 value=GetXMLTreeContent(child);
6266 if (value != (const char *) NULL)
cristy9950d572011-10-01 18:22:35 +00006267 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->fill,
6268 wand->exception);
cristy3ed852e2009-09-05 21:47:34 +00006269 }
dirkc8e845f2015-04-07 19:32:12 +00006270 child=GetXMLTreeChild(xml_info,"fill-opacity");
cristy3ed852e2009-09-05 21:47:34 +00006271 if (child != (XMLTreeInfo *) NULL)
6272 {
6273 value=GetXMLTreeContent(child);
6274 if (value != (const char *) NULL)
cristy8cd03c32012-07-07 18:57:59 +00006275 CurrentContext->fill.alpha=(double) ClampToQuantum(QuantumRange*
6276 (1.0-StringToDouble(value,(char **) NULL)));
cristy3ed852e2009-09-05 21:47:34 +00006277 }
6278 child=GetXMLTreeChild(xml_info,"fill-rule");
6279 if (child != (XMLTreeInfo *) NULL)
6280 {
6281 value=GetXMLTreeContent(child);
6282 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006283 CurrentContext->fill_rule=(FillRule) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006284 MagickFillRuleOptions,MagickFalse,value);
6285 }
6286 child=GetXMLTreeChild(xml_info,"font");
6287 if (child != (XMLTreeInfo *) NULL)
6288 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6289 child=GetXMLTreeChild(xml_info,"font-family");
6290 if (child != (XMLTreeInfo *) NULL)
6291 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6292 child=GetXMLTreeChild(xml_info,"font-size");
6293 if (child != (XMLTreeInfo *) NULL)
6294 {
6295 value=GetXMLTreeContent(child);
6296 if (value != (const char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +00006297 CurrentContext->pointsize=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006298 }
6299 child=GetXMLTreeChild(xml_info,"font-stretch");
6300 if (child != (XMLTreeInfo *) NULL)
6301 {
6302 value=GetXMLTreeContent(child);
6303 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006304 CurrentContext->stretch=(StretchType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006305 MagickStretchOptions,MagickFalse,value);
6306 }
6307 child=GetXMLTreeChild(xml_info,"font-style");
6308 if (child != (XMLTreeInfo *) NULL)
6309 {
6310 value=GetXMLTreeContent(child);
6311 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006312 CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
cristy3ed852e2009-09-05 21:47:34 +00006313 MagickFalse,value);
6314 }
6315 child=GetXMLTreeChild(xml_info,"font-weight");
6316 if (child != (XMLTreeInfo *) NULL)
6317 {
6318 value=GetXMLTreeContent(child);
6319 if (value != (const char *) NULL)
dirk341d2ec2015-07-31 20:55:15 +00006320 {
6321 ssize_t
6322 weight;
6323
6324 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
6325 if (weight == -1)
6326 weight=StringToUnsignedLong(value);
6327 CurrentContext->weight=weight;
6328 }
cristy3ed852e2009-09-05 21:47:34 +00006329 }
6330 child=GetXMLTreeChild(xml_info,"gravity");
6331 if (child != (XMLTreeInfo *) NULL)
6332 {
6333 value=GetXMLTreeContent(child);
6334 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006335 CurrentContext->gravity=(GravityType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006336 MagickGravityOptions,MagickFalse,value);
6337 }
6338 child=GetXMLTreeChild(xml_info,"stroke");
6339 if (child != (XMLTreeInfo *) NULL)
6340 {
6341 value=GetXMLTreeContent(child);
6342 if (value != (const char *) NULL)
cristy9950d572011-10-01 18:22:35 +00006343 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->stroke,
cristy3ed852e2009-09-05 21:47:34 +00006344 wand->exception);
6345 }
6346 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6347 if (child != (XMLTreeInfo *) NULL)
6348 {
6349 value=GetXMLTreeContent(child);
6350 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006351 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
cristy3ed852e2009-09-05 21:47:34 +00006352 MagickFalse;
6353 }
6354 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6355 if (child != (XMLTreeInfo *) NULL)
6356 {
6357 char
cristy151b66d2015-04-15 10:50:31 +00006358 token[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00006359
6360 const char
6361 *q;
6362
cristybb503372010-05-27 20:51:26 +00006363 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006364 x;
6365
cristy9d314ff2011-03-09 01:30:28 +00006366 ssize_t
6367 j;
6368
cristy3ed852e2009-09-05 21:47:34 +00006369 value=GetXMLTreeContent(child);
6370 if (value != (const char *) NULL)
6371 {
6372 if (CurrentContext->dash_pattern != (double *) NULL)
6373 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6374 CurrentContext->dash_pattern);
6375 q=(char *) value;
6376 if (IsPoint(q) != MagickFalse)
6377 {
6378 const char
6379 *p;
6380
6381 p=q;
6382 GetMagickToken(p,&p,token);
6383 if (*token == ',')
6384 GetMagickToken(p,&p,token);
6385 for (x=0; IsPoint(token) != MagickFalse; x++)
6386 {
6387 GetMagickToken(p,&p,token);
6388 if (*token == ',')
6389 GetMagickToken(p,&p,token);
6390 }
6391 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6392 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6393 if (CurrentContext->dash_pattern == (double *) NULL)
6394 ThrowWandFatalException(ResourceLimitFatalError,
6395 "MemoryAllocationFailed",wand->name);
6396 for (j=0; j < x; j++)
6397 {
6398 GetMagickToken(q,&q,token);
6399 if (*token == ',')
6400 GetMagickToken(q,&q,token);
cristydbdd0e32011-11-04 23:29:40 +00006401 CurrentContext->dash_pattern[j]=StringToDouble(token,
cristyc1acd842011-05-19 23:05:47 +00006402 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006403 }
6404 if ((x & 0x01) != 0)
6405 for ( ; j < (2*x); j++)
6406 CurrentContext->dash_pattern[j]=
6407 CurrentContext->dash_pattern[j-x];
6408 CurrentContext->dash_pattern[j]=0.0;
6409 }
6410 }
6411 }
6412 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6413 if (child != (XMLTreeInfo *) NULL)
6414 {
6415 value=GetXMLTreeContent(child);
6416 if (value != (const char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +00006417 CurrentContext->dash_offset=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006418 }
6419 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6420 if (child != (XMLTreeInfo *) NULL)
6421 {
6422 value=GetXMLTreeContent(child);
6423 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006424 CurrentContext->linecap=(LineCap) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006425 MagickLineCapOptions,MagickFalse,value);
6426 }
6427 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6428 if (child != (XMLTreeInfo *) NULL)
6429 {
6430 value=GetXMLTreeContent(child);
6431 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006432 CurrentContext->linejoin=(LineJoin) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006433 MagickLineJoinOptions,MagickFalse,value);
6434 }
6435 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6436 if (child != (XMLTreeInfo *) NULL)
6437 {
6438 value=GetXMLTreeContent(child);
6439 if (value != (const char *) NULL)
cristye27293e2009-12-18 02:53:20 +00006440 CurrentContext->miterlimit=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006441 }
dirkc8e845f2015-04-07 19:32:12 +00006442 child=GetXMLTreeChild(xml_info,"stroke-opacity");
cristy3ed852e2009-09-05 21:47:34 +00006443 if (child != (XMLTreeInfo *) NULL)
6444 {
6445 value=GetXMLTreeContent(child);
6446 if (value != (const char *) NULL)
cristy8cd03c32012-07-07 18:57:59 +00006447 CurrentContext->stroke.alpha=(double) ClampToQuantum(QuantumRange*
6448 (1.0-StringToDouble(value,(char **) NULL)));
cristy3ed852e2009-09-05 21:47:34 +00006449 }
6450 child=GetXMLTreeChild(xml_info,"stroke-width");
6451 if (child != (XMLTreeInfo *) NULL)
6452 {
6453 value=GetXMLTreeContent(child);
6454 if (value != (const char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +00006455 CurrentContext->stroke_width=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006456 }
6457 child=GetXMLTreeChild(xml_info,"text-align");
6458 if (child != (XMLTreeInfo *) NULL)
6459 {
6460 value=GetXMLTreeContent(child);
6461 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006462 CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
cristy3ed852e2009-09-05 21:47:34 +00006463 MagickFalse,value);
6464 }
6465 child=GetXMLTreeChild(xml_info,"text-antialias");
6466 if (child != (XMLTreeInfo *) NULL)
6467 {
6468 value=GetXMLTreeContent(child);
6469 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006470 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
cristy3ed852e2009-09-05 21:47:34 +00006471 MagickFalse;
6472 }
6473 child=GetXMLTreeChild(xml_info,"text-undercolor");
6474 if (child != (XMLTreeInfo *) NULL)
6475 {
6476 value=GetXMLTreeContent(child);
6477 if (value != (const char *) NULL)
cristy9950d572011-10-01 18:22:35 +00006478 (void) QueryColorCompliance(value,AllCompliance,
6479 &CurrentContext->undercolor,wand->exception);
cristy3ed852e2009-09-05 21:47:34 +00006480 }
6481 child=GetXMLTreeChild(xml_info,"vector-graphics");
6482 if (child != (XMLTreeInfo *) NULL)
6483 {
6484 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6485 wand->mvg_length=strlen(wand->mvg);
6486 wand->mvg_alloc=wand->mvg_length+1;
6487 }
6488 xml_info=DestroyXMLTree(xml_info);
6489 return(MagickTrue);
6490}
6491
6492/*
6493%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6494% %
6495% %
6496% %
6497% D r a w S k e w X %
6498% %
6499% %
6500% %
6501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6502%
6503% DrawSkewX() skews the current coordinate system in the horizontal
6504% direction.
6505%
6506% The format of the DrawSkewX method is:
6507%
6508% void DrawSkewX(DrawingWand *wand,const double degrees)
6509%
6510% A description of each parameter follows:
6511%
6512% o wand: the drawing wand.
6513%
6514% o degrees: number of degrees to skew the coordinates
6515%
6516*/
6517WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6518{
cristy3ed852e2009-09-05 21:47:34 +00006519 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006520 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006521 if (wand->debug != MagickFalse)
6522 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05006523 (void) MVGPrintf(wand,"skewX %.20g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00006524}
6525
6526/*
6527%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6528% %
6529% %
6530% %
6531% D r a w S k e w Y %
6532% %
6533% %
6534% %
6535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6536%
6537% DrawSkewY() skews the current coordinate system in the vertical
6538% direction.
6539%
6540% The format of the DrawSkewY method is:
6541%
6542% void DrawSkewY(DrawingWand *wand,const double degrees)
6543%
6544% A description of each parameter follows:
6545%
6546% o wand: the drawing wand.
6547%
6548% o degrees: number of degrees to skew the coordinates
6549%
6550*/
6551WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6552{
cristy3ed852e2009-09-05 21:47:34 +00006553 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006554 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006555 if (wand->debug != MagickFalse)
6556 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05006557 (void) MVGPrintf(wand,"skewY %.20g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00006558}
6559
6560/*
6561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6562% %
6563% %
6564% %
6565% D r a w T r a n s l a t e %
6566% %
6567% %
6568% %
6569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6570%
6571% DrawTranslate() applies a translation to the current coordinate
6572% system which moves the coordinate system origin to the specified
6573% coordinate.
6574%
6575% The format of the DrawTranslate method is:
6576%
6577% void DrawTranslate(DrawingWand *wand,const double x,
6578% const double y)
6579%
6580% A description of each parameter follows:
6581%
6582% o wand: the drawing wand.
6583%
6584% o x: new x ordinate for coordinate system origin
6585%
6586% o y: new y ordinate for coordinate system origin
6587%
6588*/
6589WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6590{
cristy3ed852e2009-09-05 21:47:34 +00006591 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006592 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006593 if (wand->debug != MagickFalse)
6594 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05006595 (void) MVGPrintf(wand,"translate %.20g %.20g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00006596}
6597
6598/*
6599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6600% %
6601% %
6602% %
6603% D r a w S e t V i e w b o x %
6604% %
6605% %
6606% %
6607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6608%
6609% DrawSetViewbox() sets the overall canvas size to be recorded with the
6610% drawing vector data. Usually this will be specified using the same
6611% size as the canvas image. When the vector data is saved to SVG or MVG
6612% formats, the viewbox is use to specify the size of the canvas image that
6613% a viewer will render the vector data on.
6614%
6615% The format of the DrawSetViewbox method is:
6616%
cristy76fa3142012-04-26 11:30:17 +00006617% void DrawSetViewbox(DrawingWand *wand,const double x1,const double y1,
6618% const double x2,const double y2)
cristy3ed852e2009-09-05 21:47:34 +00006619%
6620% A description of each parameter follows:
6621%
6622% o wand: the drawing wand.
6623%
6624% o x1: left x ordinate
6625%
6626% o y1: top y ordinate
6627%
6628% o x2: right x ordinate
6629%
6630% o y2: bottom y ordinate
6631%
6632*/
cristy76fa3142012-04-26 11:30:17 +00006633WandExport void DrawSetViewbox(DrawingWand *wand,const double x1,
6634 const double y1,const double x2,const double y2)
cristy3ed852e2009-09-05 21:47:34 +00006635{
6636 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006637 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006638 if (wand->debug != MagickFalse)
6639 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
Cristybd0db062015-12-26 10:33:53 -05006640 (void) MVGPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
cristy3ed852e2009-09-05 21:47:34 +00006641}
6642
6643/*
6644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6645% %
6646% %
6647% %
6648% I s D r a w i n g W a n d %
6649% %
6650% %
6651% %
6652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6653%
6654% IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6655%
6656% The format of the IsDrawingWand method is:
6657%
6658% MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6659%
6660% A description of each parameter follows:
6661%
6662% o wand: the drawing wand.
6663%
6664*/
6665WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6666{
6667 if (wand == (const DrawingWand *) NULL)
6668 return(MagickFalse);
cristye1c94d92015-06-28 12:16:33 +00006669 if (wand->signature != MagickWandSignature)
cristy3ed852e2009-09-05 21:47:34 +00006670 return(MagickFalse);
6671 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6672 return(MagickFalse);
6673 return(MagickTrue);
6674}
6675
6676/*
6677%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6678% %
6679% %
6680% %
6681% N e w D r a w i n g W a n d %
6682% %
6683% %
6684% %
6685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6686%
6687% NewDrawingWand() returns a drawing wand required for all other methods in
6688% the API.
6689%
6690% The format of the NewDrawingWand method is:
6691%
cristy76fa3142012-04-26 11:30:17 +00006692% DrawingWand *NewDrawingWand(void)
cristy3ed852e2009-09-05 21:47:34 +00006693%
6694*/
6695WandExport DrawingWand *NewDrawingWand(void)
6696{
6697 const char
6698 *quantum;
6699
6700 DrawingWand
6701 *wand;
6702
cristybb503372010-05-27 20:51:26 +00006703 size_t
cristy3ed852e2009-09-05 21:47:34 +00006704 depth;
6705
6706 quantum=GetMagickQuantumDepth(&depth);
6707 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6708 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
cristy73bd4a52010-10-05 11:24:23 +00006709 wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand));
cristy3ed852e2009-09-05 21:47:34 +00006710 if (wand == (DrawingWand *) NULL)
6711 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6712 GetExceptionMessage(errno));
6713 (void) ResetMagickMemory(wand,0,sizeof(*wand));
6714 wand->id=AcquireWandId();
Cristybd0db062015-12-26 10:33:53 -05006715 (void) FormatLocaleString(wand->name,MagickPathExtent,"%s-%.20g",
6716 DrawingWandId,(double) wand->id);
cristy3ed852e2009-09-05 21:47:34 +00006717 if (wand->debug != MagickFalse)
6718 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6719 wand->mvg=(char *) NULL;
6720 wand->mvg_alloc=0;
6721 wand->mvg_length=0;
6722 wand->mvg_width=0;
6723 wand->pattern_id=(char *) NULL;
6724 wand->pattern_offset=0;
6725 wand->pattern_bounds.x=0;
6726 wand->pattern_bounds.y=0;
6727 wand->pattern_bounds.width=0;
6728 wand->pattern_bounds.height=0;
6729 wand->index=0;
cristy73bd4a52010-10-05 11:24:23 +00006730 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(
cristy3ed852e2009-09-05 21:47:34 +00006731 *wand->graphic_context));
6732 if (wand->graphic_context == (DrawInfo **) NULL)
6733 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6734 GetExceptionMessage(errno));
6735 wand->filter_off=MagickTrue;
6736 wand->indent_depth=0;
6737 wand->path_operation=PathDefaultOperation;
6738 wand->path_mode=DefaultPathMode;
cristy3ed852e2009-09-05 21:47:34 +00006739 wand->exception=AcquireExceptionInfo();
cristy9950d572011-10-01 18:22:35 +00006740 wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception);
cristy3ed852e2009-09-05 21:47:34 +00006741 wand->destroy=MagickTrue;
6742 wand->debug=IsEventLogging();
cristye1c94d92015-06-28 12:16:33 +00006743 wand->signature=MagickWandSignature;
cristy3ed852e2009-09-05 21:47:34 +00006744 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6745 return(wand);
6746}
6747
6748/*
6749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6750% %
6751% %
6752% %
6753% P e e k D r a w i n g W a n d %
6754% %
6755% %
6756% %
6757%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6758%
6759% PeekDrawingWand() returns the current drawing wand.
6760%
6761% The format of the PeekDrawingWand method is:
6762%
6763% DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6764%
6765% A description of each parameter follows:
6766%
6767% o wand: the drawing wand.
6768%
6769*/
6770WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6771{
6772 DrawInfo
6773 *draw_info;
6774
6775 assert(wand != (const DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006776 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006777 if (wand->debug != MagickFalse)
6778 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6779 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6780 GetAffineMatrix(&draw_info->affine);
6781 (void) CloneString(&draw_info->primitive,wand->mvg);
6782 return(draw_info);
6783}
6784
6785/*
6786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6787% %
6788% %
6789% %
6790% P o p D r a w i n g W a n d %
6791% %
6792% %
6793% %
6794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6795%
6796% PopDrawingWand() destroys the current drawing wand and returns to the
6797% previously pushed drawing wand. Multiple drawing wands may exist. It is an
6798% error to attempt to pop more drawing wands than have been pushed, and it is
6799% proper form to pop all drawing wands which have been pushed.
6800%
6801% The format of the PopDrawingWand method is:
6802%
6803% MagickBooleanType PopDrawingWand(DrawingWand *wand)
6804%
6805% A description of each parameter follows:
6806%
6807% o wand: the drawing wand.
6808%
6809*/
6810WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6811{
6812 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006813 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006814 if (wand->debug != MagickFalse)
6815 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6816 if (wand->index == 0)
6817 {
6818 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6819 return(MagickFalse);
6820 }
6821 /*
6822 Destroy clip path if not same in preceding wand.
6823 */
6824#if DRAW_BINARY_IMPLEMENTATION
6825 if (wand->image == (Image *) NULL)
6826 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6827 if (CurrentContext->clip_mask != (char *) NULL)
6828 if (LocaleCompare(CurrentContext->clip_mask,
6829 wand->graphic_context[wand->index-1]->clip_mask) != 0)
cristyacd0d4c2015-07-25 16:12:33 +00006830 (void) SetImageMask(wand->image,ReadPixelMask,(Image *) NULL,
6831 wand->exception);
cristy3ed852e2009-09-05 21:47:34 +00006832#endif
6833 CurrentContext=DestroyDrawInfo(CurrentContext);
6834 wand->index--;
6835 if (wand->indent_depth > 0)
6836 wand->indent_depth--;
Cristybd0db062015-12-26 10:33:53 -05006837 (void) MVGPrintf(wand,"pop graphic-context\n");
cristy3ed852e2009-09-05 21:47:34 +00006838 return(MagickTrue);
6839}
6840
6841/*
6842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6843% %
6844% %
6845% %
6846% P u s h D r a w i n g W a n d %
6847% %
6848% %
6849% %
6850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6851%
6852% PushDrawingWand() clones the current drawing wand to create a new drawing
6853% wand. The original drawing wand(s) may be returned to by invoking
6854% PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6855% For every Pop there must have already been an equivalent Push.
6856%
6857% The format of the PushDrawingWand method is:
6858%
6859% MagickBooleanType PushDrawingWand(DrawingWand *wand)
6860%
6861% A description of each parameter follows:
6862%
6863% o wand: the drawing wand.
6864%
6865*/
6866WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6867{
6868 assert(wand != (DrawingWand *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006869 assert(wand->signature == MagickWandSignature);
cristy3ed852e2009-09-05 21:47:34 +00006870 if (wand->debug != MagickFalse)
6871 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6872 wand->index++;
6873 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6874 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6875 if (wand->graphic_context == (DrawInfo **) NULL)
6876 {
cristy1d4a6952015-03-24 00:42:52 +00006877 wand->index--;
cristy3ed852e2009-09-05 21:47:34 +00006878 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6879 wand->name);
6880 return(MagickFalse);
6881 }
6882 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6883 wand->graphic_context[wand->index-1]);
Cristybd0db062015-12-26 10:33:53 -05006884 (void) MVGPrintf(wand,"push graphic-context\n");
cristy3ed852e2009-09-05 21:47:34 +00006885 wand->indent_depth++;
6886 return(MagickTrue);
6887}