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