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