blob: 223aede547e6443754e4f0eac08671083ee877be [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 {
cristye7f51092010-01-17 00:39:37 +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);
cristye7f51092010-01-17 00:39:37 +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 {
778 (void) MvgPrintf(wand,"text %g,%g '%s'\n",x,y,escaped_text);
779 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);
cristye7f51092010-01-17 00:39:37 +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);
cristye7f51092010-01-17 00:39:37 +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);
cristye7f51092010-01-17 00:39:37 +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);
cristy042ee782011-04-22 18:48:30 +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);
cristye7f51092010-01-17 00:39:37 +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(
cristybb503372010-05-27 20:51:26 +00002500 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002501 (void) SetXMLTreeContent(child,value);
2502 }
2503 child=AddChildToXMLTree(xml_info,"font",0);
2504 if (child != (XMLTreeInfo *) NULL)
2505 (void) SetXMLTreeContent(child,CurrentContext->font);
2506 child=AddChildToXMLTree(xml_info,"font-family",0);
2507 if (child != (XMLTreeInfo *) NULL)
2508 (void) SetXMLTreeContent(child,CurrentContext->family);
2509 child=AddChildToXMLTree(xml_info,"font-size",0);
2510 if (child != (XMLTreeInfo *) NULL)
2511 {
cristye7f51092010-01-17 00:39:37 +00002512 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002513 CurrentContext->pointsize);
2514 (void) SetXMLTreeContent(child,value);
2515 }
2516 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2517 if (child != (XMLTreeInfo *) NULL)
2518 {
cristy042ee782011-04-22 18:48:30 +00002519 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002520 MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002521 (void) SetXMLTreeContent(child,value);
2522 }
2523 child=AddChildToXMLTree(xml_info,"font-style",0);
2524 if (child != (XMLTreeInfo *) NULL)
2525 {
cristy042ee782011-04-22 18:48:30 +00002526 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002527 MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002528 (void) SetXMLTreeContent(child,value);
2529 }
2530 child=AddChildToXMLTree(xml_info,"font-weight",0);
2531 if (child != (XMLTreeInfo *) NULL)
2532 {
cristye8c25f92010-06-03 00:53:06 +00002533 (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
cristy3ed852e2009-09-05 21:47:34 +00002534 CurrentContext->weight);
2535 (void) SetXMLTreeContent(child,value);
2536 }
2537 child=AddChildToXMLTree(xml_info,"gravity",0);
2538 if (child != (XMLTreeInfo *) NULL)
2539 {
cristy042ee782011-04-22 18:48:30 +00002540 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickGravityOptions,
cristybb503372010-05-27 20:51:26 +00002541 (ssize_t) CurrentContext->gravity),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002542 (void) SetXMLTreeContent(child,value);
2543 }
2544 child=AddChildToXMLTree(xml_info,"stroke",0);
2545 if (child != (XMLTreeInfo *) NULL)
2546 {
2547 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2548 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2549 MagickTrue : MagickFalse;
2550 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2551 (const IndexPacket *) NULL,&pixel);
2552 GetColorTuple(&pixel,MagickTrue,value);
2553 (void) SetXMLTreeContent(child,value);
2554 }
2555 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2556 if (child != (XMLTreeInfo *) NULL)
2557 {
2558 (void) FormatMagickString(value,MaxTextExtent,"%d",
2559 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2560 (void) SetXMLTreeContent(child,value);
2561 }
2562 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2563 if ((child != (XMLTreeInfo *) NULL) &&
2564 (CurrentContext->dash_pattern != (double *) NULL))
2565 {
2566 char
2567 *dash_pattern;
2568
2569 dash_pattern=AcquireString((char *) NULL);
2570 for (i=0; CurrentContext->dash_pattern[i] != 0.0; i++)
2571 {
2572 if (i != 0)
2573 (void) ConcatenateString(&dash_pattern,",");
cristye7f51092010-01-17 00:39:37 +00002574 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002575 CurrentContext->dash_pattern[i]);
2576 (void) ConcatenateString(&dash_pattern,value);
2577 }
2578 (void) SetXMLTreeContent(child,dash_pattern);
2579 dash_pattern=DestroyString(dash_pattern);
2580 }
2581 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2582 if (child != (XMLTreeInfo *) NULL)
2583 {
cristye7f51092010-01-17 00:39:37 +00002584 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002585 CurrentContext->dash_offset);
2586 (void) SetXMLTreeContent(child,value);
2587 }
2588 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2589 if (child != (XMLTreeInfo *) NULL)
2590 {
cristy042ee782011-04-22 18:48:30 +00002591 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickLineCapOptions,
cristybb503372010-05-27 20:51:26 +00002592 (ssize_t) CurrentContext->linecap),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002593 (void) SetXMLTreeContent(child,value);
2594 }
2595 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2596 if (child != (XMLTreeInfo *) NULL)
2597 {
cristy042ee782011-04-22 18:48:30 +00002598 (void) CopyMagickString(value,CommandOptionToMnemonic(
cristyf2faecf2010-05-28 19:19:36 +00002599 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2600 MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002601 (void) SetXMLTreeContent(child,value);
2602 }
2603 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2604 if (child != (XMLTreeInfo *) NULL)
2605 {
cristye8c25f92010-06-03 00:53:06 +00002606 (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
cristy3ed852e2009-09-05 21:47:34 +00002607 CurrentContext->miterlimit);
2608 (void) SetXMLTreeContent(child,value);
2609 }
2610 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2611 if (child != (XMLTreeInfo *) NULL)
2612 {
cristye7f51092010-01-17 00:39:37 +00002613 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002614 (double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity));
2615 (void) SetXMLTreeContent(child,value);
2616 }
2617 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2618 if (child != (XMLTreeInfo *) NULL)
2619 {
cristye7f51092010-01-17 00:39:37 +00002620 (void) FormatMagickString(value,MaxTextExtent,"%g",
cristy3ed852e2009-09-05 21:47:34 +00002621 CurrentContext->stroke_width);
2622 (void) SetXMLTreeContent(child,value);
2623 }
2624 child=AddChildToXMLTree(xml_info,"text-align",0);
2625 if (child != (XMLTreeInfo *) NULL)
2626 {
cristy042ee782011-04-22 18:48:30 +00002627 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
cristybb503372010-05-27 20:51:26 +00002628 (ssize_t) CurrentContext->align),MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00002629 (void) SetXMLTreeContent(child,value);
2630 }
2631 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2632 if (child != (XMLTreeInfo *) NULL)
2633 {
2634 (void) FormatMagickString(value,MaxTextExtent,"%d",
2635 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2636 (void) SetXMLTreeContent(child,value);
2637 }
2638 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2639 if (child != (XMLTreeInfo *) NULL)
2640 {
2641 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2642 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2643 MagickTrue : MagickFalse;
2644 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2645 (const IndexPacket *) NULL,&pixel);
2646 GetColorTuple(&pixel,MagickTrue,value);
2647 (void) SetXMLTreeContent(child,value);
2648 }
2649 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2650 if (child != (XMLTreeInfo *) NULL)
2651 (void) SetXMLTreeContent(child,wand->mvg);
2652 xml=XMLTreeInfoToXML(xml_info);
2653 xml_info=DestroyXMLTree(xml_info);
2654 return(xml);
2655}
2656
2657/*
2658%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2659% %
2660% %
2661% %
2662% D r a w G e t T e x t U n d e r C o l o r %
2663% %
2664% %
2665% %
2666%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2667%
2668% DrawGetTextUnderColor() returns the color of a background rectangle
2669% to place under text annotations.
2670%
2671% The format of the DrawGetTextUnderColor method is:
2672%
2673% void DrawGetTextUnderColor(const DrawingWand *wand,
2674% PixelWand *under_color)
2675%
2676% A description of each parameter follows:
2677%
2678% o wand: the drawing wand.
2679%
2680% o under_color: Return the under color.
2681%
2682*/
2683WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2684 PixelWand *under_color)
2685{
2686 assert(wand != (const DrawingWand *) NULL);
2687 assert(wand->signature == WandSignature);
2688 assert(under_color != (PixelWand *) NULL);
2689 if (wand->debug != MagickFalse)
2690 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2691 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2692}
2693
2694/*
2695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2696% %
2697% %
2698% %
2699% D r a w L i n e %
2700% %
2701% %
2702% %
2703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2704%
2705% DrawLine() draws a line on the image using the current stroke color,
2706% stroke opacity, and stroke width.
2707%
2708% The format of the DrawLine method is:
2709%
2710% void DrawLine(DrawingWand *wand,const double sx,const double sy,
2711% const double ex,const double ey)
2712%
2713% A description of each parameter follows:
2714%
2715% o wand: the drawing wand.
2716%
2717% o sx: starting x ordinate
2718%
2719% o sy: starting y ordinate
2720%
2721% o ex: ending x ordinate
2722%
2723% o ey: ending y ordinate
2724%
2725*/
2726WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2727 const double ex,const double ey)
2728{
2729 assert(wand != (DrawingWand *) NULL);
2730 assert(wand->signature == WandSignature);
2731 if (wand->debug != MagickFalse)
2732 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00002733 (void) MvgPrintf(wand,"line %g,%g %g,%g\n",sx,sy,ex,ey);
cristy3ed852e2009-09-05 21:47:34 +00002734}
2735
2736/*
2737%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2738% %
2739% %
2740% %
2741% D r a w M a t t e %
2742% %
2743% %
2744% %
2745%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2746%
2747% DrawMatte() paints on the image's opacity channel in order to set effected
2748% pixels to transparent.
2749% to influence the opacity of pixels. The available paint
2750% methods are:
2751%
2752% PointMethod: Select the target pixel
2753% ReplaceMethod: Select any pixel that matches the target pixel.
2754% FloodfillMethod: Select the target pixel and matching neighbors.
2755% FillToBorderMethod: Select the target pixel and neighbors not matching
2756% border color.
2757% ResetMethod: Select all pixels.
2758%
2759% The format of the DrawMatte method is:
2760%
2761% void DrawMatte(DrawingWand *wand,const double x,const double y,
2762% const PaintMethod paint_method)
2763%
2764% A description of each parameter follows:
2765%
2766% o wand: the drawing wand.
2767%
2768% o x: x ordinate
2769%
2770% o y: y ordinate
2771%
2772% o paint_method: paint method.
2773%
2774*/
2775WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2776 const PaintMethod paint_method)
2777{
2778 assert(wand != (DrawingWand *) NULL);
2779 assert(wand->signature == WandSignature);
2780 if (wand->debug != MagickFalse)
2781 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy042ee782011-04-22 18:48:30 +00002782 (void) MvgPrintf(wand,"matte %g,%g '%s'\n",x,y,CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00002783 MagickMethodOptions,(ssize_t) paint_method));
cristy3ed852e2009-09-05 21:47:34 +00002784}
2785
2786/*
2787%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2788% %
2789% %
2790% %
2791% D r a w P a t h C l o s e %
2792% %
2793% %
2794% %
2795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2796%
2797% DrawPathClose() adds a path element to the current path which closes the
2798% current subpath by drawing a straight line from the current point to the
2799% current subpath's most recent starting point (usually, the most recent
2800% moveto point).
2801%
2802% The format of the DrawPathClose method is:
2803%
2804% void DrawPathClose(DrawingWand *wand)
2805%
2806% A description of each parameter follows:
2807%
2808% o wand: the drawing wand.
2809%
2810*/
2811WandExport void DrawPathClose(DrawingWand *wand)
2812{
2813 assert(wand != (DrawingWand *) NULL);
2814 assert(wand->signature == WandSignature);
2815 if (wand->debug != MagickFalse)
2816 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2817 (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2818 "Z" : "z");
2819}
2820
2821/*
2822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2823% %
2824% %
2825% %
2826% D r a w P a t h C u r v e T o A b s o l u t e %
2827% %
2828% %
2829% %
2830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2831%
2832% DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2833% point to (x,y) using (x1,y1) as the control point at the beginning of
2834% the curve and (x2,y2) as the control point at the end of the curve using
2835% absolute coordinates. At the end of the command, the new current point
2836% becomes the final (x,y) coordinate pair used in the polybezier.
2837%
2838% The format of the DrawPathCurveToAbsolute method is:
2839%
2840% void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2841% const double y1,const double x2,const double y2,const double x,
2842% const double y)
2843%
2844% A description of each parameter follows:
2845%
2846% o wand: the drawing wand.
2847%
2848% o x1: x ordinate of control point for curve beginning
2849%
2850% o y1: y ordinate of control point for curve beginning
2851%
2852% o x2: x ordinate of control point for curve ending
2853%
2854% o y2: y ordinate of control point for curve ending
2855%
2856% o x: x ordinate of the end of the curve
2857%
2858% o y: y ordinate of the end of the curve
2859%
2860*/
2861
2862static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2863 const double x1,const double y1,const double x2,const double y2,
2864 const double x,const double y)
2865{
2866 assert(wand != (DrawingWand *) NULL);
2867 assert(wand->signature == WandSignature);
2868 if (wand->debug != MagickFalse)
2869 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2870 if ((wand->path_operation != PathCurveToOperation) ||
2871 (wand->path_mode != mode))
2872 {
2873 wand->path_operation=PathCurveToOperation;
2874 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00002875 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g %g,%g",
cristy3ed852e2009-09-05 21:47:34 +00002876 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2877 }
2878 else
cristye7f51092010-01-17 00:39:37 +00002879 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g %g,%g",x1,y1,
cristy8cd5b312010-01-07 01:10:24 +00002880 x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002881}
2882
2883WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2884 const double y1,const double x2,const double y2,const double x,const double y)
2885{
2886 assert(wand != (DrawingWand *) NULL);
2887 assert(wand->signature == WandSignature);
2888 if (wand->debug != MagickFalse)
2889 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2890 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2891}
2892
2893/*
2894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2895% %
2896% %
2897% %
2898% D r a w P a t h C u r v e T o R e l a t i v e %
2899% %
2900% %
2901% %
2902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2903%
2904% DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2905% point to (x,y) using (x1,y1) as the control point at the beginning of
2906% the curve and (x2,y2) as the control point at the end of the curve using
2907% relative coordinates. At the end of the command, the new current point
2908% becomes the final (x,y) coordinate pair used in the polybezier.
2909%
2910% The format of the DrawPathCurveToRelative method is:
2911%
2912% void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2913% const double y1,const double x2,const double y2,const double x,
2914% const double y)
2915%
2916% A description of each parameter follows:
2917%
2918% o wand: the drawing wand.
2919%
2920% o x1: x ordinate of control point for curve beginning
2921%
2922% o y1: y ordinate of control point for curve beginning
2923%
2924% o x2: x ordinate of control point for curve ending
2925%
2926% o y2: y ordinate of control point for curve ending
2927%
2928% o x: x ordinate of the end of the curve
2929%
2930% o y: y ordinate of the end of the curve
2931%
2932*/
2933WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2934 const double y1,const double x2,const double y2,const double x,const double y)
2935{
2936 assert(wand != (DrawingWand *) NULL);
2937 assert(wand->signature == WandSignature);
2938 if (wand->debug != MagickFalse)
2939 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2940 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2941}
2942
2943/*
2944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2945% %
2946% %
2947% %
2948% 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 %
2949% %
2950% %
2951% %
2952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2953%
2954% DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2955% from the current point to (x,y) using (x1,y1) as the control point using
2956% absolute coordinates. At the end of the command, the new current point
2957% becomes the final (x,y) coordinate pair used in the polybezier.
2958%
2959% The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2960%
2961% void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2962% const double x1,const double y1,onst double x,const double y)
2963%
2964% A description of each parameter follows:
2965%
2966% o wand: the drawing wand.
2967%
2968% o x1: x ordinate of the control point
2969%
2970% o y1: y ordinate of the control point
2971%
2972% o x: x ordinate of final point
2973%
2974% o y: y ordinate of final point
2975%
2976*/
2977
2978static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2979 const PathMode mode,const double x1,double y1,const double x,const double y)
2980{
2981 assert(wand != (DrawingWand *) NULL);
2982 assert(wand->signature == WandSignature);
2983 if (wand->debug != MagickFalse)
2984 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2985 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2986 (wand->path_mode != mode))
2987 {
2988 wand->path_operation=PathCurveToQuadraticBezierOperation;
2989 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00002990 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g",
cristy8cd5b312010-01-07 01:10:24 +00002991 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002992 }
2993 else
cristye7f51092010-01-17 00:39:37 +00002994 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x1,y1,x,y);
cristy3ed852e2009-09-05 21:47:34 +00002995}
2996
2997WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2998 const double x1,const double y1,const double x,const double y)
2999{
3000 assert(wand != (DrawingWand *) NULL);
3001 assert(wand->signature == WandSignature);
3002 if (wand->debug != MagickFalse)
3003 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3004 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
3005}
3006
3007/*
3008%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3009% %
3010% %
3011% %
3012% 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
3013% %
3014% %
3015% %
3016%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3017%
3018% DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
3019% from the current point to (x,y) using (x1,y1) as the control point using
3020% relative coordinates. At the end of the command, the new current point
3021% becomes the final (x,y) coordinate pair used in the polybezier.
3022%
3023% The format of the DrawPathCurveToQuadraticBezierRelative method is:
3024%
3025% void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3026% const double x1,const double y1,const double x,const double y)
3027%
3028% A description of each parameter follows:
3029%
3030% o wand: the drawing wand.
3031%
3032% o x1: x ordinate of the control point
3033%
3034% o y1: y ordinate of the control point
3035%
3036% o x: x ordinate of final point
3037%
3038% o y: y ordinate of final point
3039%
3040*/
3041WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3042 const double x1,const double y1,const double x,const double y)
3043{
3044 assert(wand != (DrawingWand *) NULL);
3045 assert(wand->signature == WandSignature);
3046 if (wand->debug != MagickFalse)
3047 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3048 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
3049}
3050
3051/*
3052%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3053% %
3054% %
3055% %
3056% 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 %
3057% %
3058% %
3059% %
3060%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3061%
3062% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3063% Bezier curve (using absolute coordinates) from the current point to
3064% (x,y). The control point is assumed to be the reflection of the
3065% control point on the previous command relative to the current
3066% point. (If there is no previous command or if the previous command was
3067% not a DrawPathCurveToQuadraticBezierAbsolute,
3068% DrawPathCurveToQuadraticBezierRelative,
3069% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3070% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3071% is coincident with the current point.). At the end of the command, the
3072% new current point becomes the final (x,y) coordinate pair used in the
3073% polybezier.
3074%
3075% The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3076%
3077% void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3078% DrawingWand *wand,const double x,const double y)
3079%
3080% A description of each parameter follows:
3081%
3082% o wand: the drawing wand.
3083%
3084% o x: x ordinate of final point
3085%
3086% o y: y ordinate of final point
3087%
3088*/
3089
3090static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3091 const PathMode mode,const double x,const double y)
3092{
3093 assert(wand != (DrawingWand *) NULL);
3094 assert(wand->signature == WandSignature);
3095 if (wand->debug != MagickFalse)
3096 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3097 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3098 (wand->path_mode != mode))
3099 {
3100 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3101 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003102 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003103 'T' : 't',x,y);
3104 }
3105 else
cristye7f51092010-01-17 00:39:37 +00003106 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003107}
3108
3109WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3110 const double x,const double y)
3111{
3112 assert(wand != (DrawingWand *) NULL);
3113 assert(wand->signature == WandSignature);
3114 if (wand->debug != MagickFalse)
3115 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3116 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3117}
3118
3119/*
3120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3121% %
3122% %
3123% %
3124% 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 %
3125% %
3126% %
3127% %
3128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3129%
3130% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3131% curve (using relative coordinates) from the current point to (x,y). The
3132% control point is assumed to be the reflection of the control point on the
3133% previous command relative to the current point. (If there is no previous
3134% command or if the previous command was not a
3135% DrawPathCurveToQuadraticBezierAbsolute,
3136% DrawPathCurveToQuadraticBezierRelative,
3137% DrawPathCurveToQuadraticBezierSmoothAbsolute or
3138% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3139% coincident with the current point.). At the end of the command, the new
3140% current point becomes the final (x,y) coordinate pair used in the polybezier.
3141%
3142% The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3143%
3144% void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3145% const double x,const double y)
3146%
3147% A description of each parameter follows:
3148%
3149% o wand: the drawing wand.
3150%
3151% o x: x ordinate of final point
3152%
3153% o y: y ordinate of final point
3154%
3155*/
3156WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3157 const double x,const double y)
3158{
3159 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3160}
3161
3162/*
3163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3164% %
3165% %
3166% %
3167% 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 %
3168% %
3169% %
3170% %
3171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3172%
3173% DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3174% current point to (x,y) using absolute coordinates. The first control
3175% point is assumed to be the reflection of the second control point on
3176% the previous command relative to the current point. (If there is no
3177% previous command or if the previous command was not an
3178% DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3179% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3180% the first control point is coincident with the current point.) (x2,y2)
3181% is the second control point (i.e., the control point at the end of the
3182% curve). At the end of the command, the new current point becomes the
3183% final (x,y) coordinate pair used in the polybezier.
3184%
3185% The format of the DrawPathCurveToSmoothAbsolute method is:
3186%
3187% void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3188% const double x2const double y2,const double x,const double y)
3189%
3190% A description of each parameter follows:
3191%
3192% o wand: the drawing wand.
3193%
3194% o x2: x ordinate of second control point
3195%
3196% o y2: y ordinate of second control point
3197%
3198% o x: x ordinate of termination point
3199%
3200% o y: y ordinate of termination point
3201%
3202*/
3203
3204static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3205 const double x2,const double y2,const double x,const double y)
3206{
3207 assert(wand != (DrawingWand *) NULL);
3208 assert(wand->signature == WandSignature);
3209 if (wand->debug != MagickFalse)
3210 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3211 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3212 (wand->path_mode != mode))
3213 {
3214 wand->path_operation=PathCurveToSmoothOperation;
3215 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003216 (void) MvgAutoWrapPrintf(wand,"%c%g,%g %g,%g",
cristy8cd5b312010-01-07 01:10:24 +00003217 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003218 }
3219 else
cristye7f51092010-01-17 00:39:37 +00003220 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x2,y2,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003221}
3222
3223WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3224 const double y2,const double x,const double y)
3225{
3226 assert(wand != (DrawingWand *) NULL);
3227 assert(wand->signature == WandSignature);
3228 if (wand->debug != MagickFalse)
3229 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3230 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3231}
3232
3233/*
3234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3235% %
3236% %
3237% %
3238% 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 %
3239% %
3240% %
3241% %
3242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3243%
3244% DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3245% point to (x,y) using relative coordinates. The first control point is
3246% assumed to be the reflection of the second control point on the previous
3247% command relative to the current point. (If there is no previous command or
3248% if the previous command was not an DrawPathCurveToAbsolute,
3249% DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3250% DrawPathCurveToSmoothRelative, assume the first control point is coincident
3251% with the current point.) (x2,y2) is the second control point (i.e., the
3252% control point at the end of the curve). At the end of the command, the new
3253% current point becomes the final (x,y) coordinate pair used in the polybezier.
3254%
3255% The format of the DrawPathCurveToSmoothRelative method is:
3256%
3257% void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3258% const double x2,const double y2,const double x,const double y)
3259%
3260% A description of each parameter follows:
3261%
3262% o wand: the drawing wand.
3263%
3264% o x2: x ordinate of second control point
3265%
3266% o y2: y ordinate of second control point
3267%
3268% o x: x ordinate of termination point
3269%
3270% o y: y ordinate of termination point
3271%
3272*/
3273WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3274 const double y2,const double x,const double y)
3275{
3276 assert(wand != (DrawingWand *) NULL);
3277 assert(wand->signature == WandSignature);
3278 if (wand->debug != MagickFalse)
3279 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3280 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3281}
3282
3283/*
3284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3285% %
3286% %
3287% %
3288% 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 %
3289% %
3290% %
3291% %
3292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3293%
3294% DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3295% to (x, y) using absolute coordinates. The size and orientation of the
3296% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3297% indicates how the ellipse as a whole is rotated relative to the current
3298% coordinate system. The center (cx, cy) of the ellipse is calculated
3299% automagically to satisfy the constraints imposed by the other parameters.
3300% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3301% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3302% of the available arcs. If sweepFlag is true, then draw the arc matching a
3303% clock-wise rotation.
3304%
3305% The format of the DrawPathEllipticArcAbsolute method is:
3306%
3307% void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3308% const double rx,const double ry,const double x_axis_rotation,
3309% const MagickBooleanType large_arc_flag,
3310% const MagickBooleanType sweep_flag,const double x,const double y)
3311%
3312% A description of each parameter follows:
3313%
3314% o wand: the drawing wand.
3315%
3316% o rx: x radius
3317%
3318% o ry: y radius
3319%
3320% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3321% relative to the current coordinate system
3322%
3323% o large_arc_flag: If non-zero (true) then draw the larger of the
3324% available arcs
3325%
3326% o sweep_flag: If non-zero (true) then draw the arc matching a
3327% clock-wise rotation
3328%
3329%
3330*/
3331
3332static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3333 const double rx,const double ry,const double x_axis_rotation,
3334 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3335 const double x,const double y)
3336{
3337 assert(wand != (DrawingWand *) NULL);
3338 assert(wand->signature == WandSignature);
3339 if (wand->debug != MagickFalse)
3340 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3341 if ((wand->path_operation != PathEllipticArcOperation) ||
3342 (wand->path_mode != mode))
3343 {
3344 wand->path_operation=PathEllipticArcOperation;
3345 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003346 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g %u %u %g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003347 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3348 large_arc_flag,sweep_flag,x,y);
3349 }
3350 else
cristye7f51092010-01-17 00:39:37 +00003351 (void) MvgAutoWrapPrintf(wand," %g,%g %g %u %u %g,%g",rx,ry,
cristy8cd5b312010-01-07 01:10:24 +00003352 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
cristy3ed852e2009-09-05 21:47:34 +00003353}
3354
3355WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3356 const double ry,const double x_axis_rotation,
3357 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3358 const double x,const double y)
3359{
3360 assert(wand != (DrawingWand *) NULL);
3361 assert(wand->signature == WandSignature);
3362 if (wand->debug != MagickFalse)
3363 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3364 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3365 large_arc_flag,sweep_flag,x,y);
3366}
3367
3368/*
3369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3370% %
3371% %
3372% %
3373% 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 %
3374% %
3375% %
3376% %
3377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3378%
3379% DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3380% to (x, y) using relative coordinates. The size and orientation of the
3381% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3382% indicates how the ellipse as a whole is rotated relative to the current
3383% coordinate system. The center (cx, cy) of the ellipse is calculated
3384% automagically to satisfy the constraints imposed by the other parameters.
3385% largeArcFlag and sweepFlag contribute to the automatic calculations and help
3386% determine how the arc is drawn. If largeArcFlag is true then draw the larger
3387% of the available arcs. If sweepFlag is true, then draw the arc matching a
3388% clock-wise rotation.
3389%
3390% The format of the DrawPathEllipticArcRelative method is:
3391%
3392% void DrawPathEllipticArcRelative(DrawingWand *wand,
3393% const double rx,const double ry,const double x_axis_rotation,
3394% const MagickBooleanType large_arc_flag,
3395% const MagickBooleanType sweep_flag,const double x,const double y)
3396%
3397% A description of each parameter follows:
3398%
3399% o wand: the drawing wand.
3400%
3401% o rx: x radius
3402%
3403% o ry: y radius
3404%
3405% o x_axis_rotation: indicates how the ellipse as a whole is rotated
3406% relative to the current coordinate system
3407%
3408% o large_arc_flag: If non-zero (true) then draw the larger of the
3409% available arcs
3410%
3411% o sweep_flag: If non-zero (true) then draw the arc matching a
3412% clock-wise rotation
3413%
3414*/
3415WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3416 const double ry,const double x_axis_rotation,
3417 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3418 const double x,const double y)
3419{
3420 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3421 large_arc_flag,sweep_flag,x,y);
3422}
3423
3424/*
3425%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3426% %
3427% %
3428% %
3429% D r a w P a t h F i n i s h %
3430% %
3431% %
3432% %
3433%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3434%
3435% DrawPathFinish() terminates the current path.
3436%
3437% The format of the DrawPathFinish method is:
3438%
3439% void DrawPathFinish(DrawingWand *wand)
3440%
3441% A description of each parameter follows:
3442%
3443% o wand: the drawing wand.
3444%
3445*/
3446WandExport void DrawPathFinish(DrawingWand *wand)
3447{
3448 assert(wand != (DrawingWand *) NULL);
3449 assert(wand->signature == WandSignature);
3450 if (wand->debug != MagickFalse)
3451 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3452 (void) MvgPrintf(wand,"'\n");
3453 wand->path_operation=PathDefaultOperation;
3454 wand->path_mode=DefaultPathMode;
3455}
3456
3457/*
3458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3459% %
3460% %
3461% %
3462% D r a w P a t h L i n e T o A b s o l u t e %
3463% %
3464% %
3465% %
3466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3467%
3468% DrawPathLineToAbsolute() draws a line path from the current point to the
3469% given coordinate using absolute coordinates. The coordinate then becomes
3470% the new current point.
3471%
3472% The format of the DrawPathLineToAbsolute method is:
3473%
3474% void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3475% const double y)
3476%
3477% A description of each parameter follows:
3478%
3479% o wand: the drawing wand.
3480%
3481% o x: target x ordinate
3482%
3483% o y: target y ordinate
3484%
3485*/
3486static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3487 const double x,const double y)
3488{
3489 assert(wand != (DrawingWand *) NULL);
3490 assert(wand->signature == WandSignature);
3491 if (wand->debug != MagickFalse)
3492 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3493 if ((wand->path_operation != PathLineToOperation) ||
3494 (wand->path_mode != mode))
3495 {
3496 wand->path_operation=PathLineToOperation;
3497 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003498 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003499 'L' : 'l',x,y);
3500 }
3501 else
cristye7f51092010-01-17 00:39:37 +00003502 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003503}
3504
3505WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3506 const double y)
3507{
3508 assert(wand != (DrawingWand *) NULL);
3509 assert(wand->signature == WandSignature);
3510 if (wand->debug != MagickFalse)
3511 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3512 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3513}
3514
3515/*
3516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3517% %
3518% %
3519% %
3520% D r a w P a t h L i n e T o R e l a t i v e %
3521% %
3522% %
3523% %
3524%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3525%
3526% DrawPathLineToRelative() draws a line path from the current point to the
3527% given coordinate using relative coordinates. The coordinate then becomes
3528% the new current point.
3529%
3530% The format of the DrawPathLineToRelative method is:
3531%
3532% void DrawPathLineToRelative(DrawingWand *wand,const double x,
3533% const double y)
3534%
3535% A description of each parameter follows:
3536%
3537% o wand: the drawing wand.
3538%
3539% o x: target x ordinate
3540%
3541% o y: target y ordinate
3542%
3543*/
3544WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3545 const double y)
3546{
3547 assert(wand != (DrawingWand *) NULL);
3548 assert(wand->signature == WandSignature);
3549 if (wand->debug != MagickFalse)
3550 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3551 DrawPathLineTo(wand,RelativePathMode,x,y);
3552}
3553
3554/*
3555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3556% %
3557% %
3558% %
3559% 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 %
3560% %
3561% %
3562% %
3563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3564%
3565% DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3566% current point to the target point using absolute coordinates. The target
3567% point then becomes the new current point.
3568%
3569% The format of the DrawPathLineToHorizontalAbsolute method is:
3570%
3571% void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3572% const PathMode mode,const double x)
3573%
3574% A description of each parameter follows:
3575%
3576% o wand: the drawing wand.
3577%
3578% o x: target x ordinate
3579%
3580*/
3581
3582static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3583 const double x)
3584{
3585 assert(wand != (DrawingWand *) NULL);
3586 assert(wand->signature == WandSignature);
3587 if (wand->debug != MagickFalse)
3588 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3589 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3590 (wand->path_mode != mode))
3591 {
3592 wand->path_operation=PathLineToHorizontalOperation;
3593 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003594 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003595 'H' : 'h',x);
3596 }
3597 else
cristye7f51092010-01-17 00:39:37 +00003598 (void) MvgAutoWrapPrintf(wand," %g",x);
cristy3ed852e2009-09-05 21:47:34 +00003599}
3600
3601WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3602 const double x)
3603{
3604 assert(wand != (DrawingWand *) NULL);
3605 assert(wand->signature == WandSignature);
3606 if (wand->debug != MagickFalse)
3607 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3608 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3609}
3610
3611/*
3612%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3613% %
3614% %
3615% %
3616% 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 %
3617% %
3618% %
3619% %
3620%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3621%
3622% DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3623% current point to the target point using relative coordinates. The target
3624% point then becomes the new current point.
3625%
3626% The format of the DrawPathLineToHorizontalRelative method is:
3627%
3628% void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3629% const double x)
3630%
3631% A description of each parameter follows:
3632%
3633% o wand: the drawing wand.
3634%
3635% o x: target x ordinate
3636%
3637*/
3638WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3639 const double x)
3640{
3641 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3642}
3643
3644/*
3645%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3646% %
3647% %
3648% %
3649% 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 %
3650% %
3651% %
3652% %
3653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3654%
3655% DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3656% current point to the target point using absolute coordinates. The target
3657% point then becomes the new current point.
3658%
3659% The format of the DrawPathLineToVerticalAbsolute method is:
3660%
3661% void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3662% const double y)
3663%
3664% A description of each parameter follows:
3665%
3666% o wand: the drawing wand.
3667%
3668% o y: target y ordinate
3669%
3670*/
3671
3672static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3673 const double y)
3674{
3675 assert(wand != (DrawingWand *) NULL);
3676 assert(wand->signature == WandSignature);
3677 if (wand->debug != MagickFalse)
3678 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3679 if ((wand->path_operation != PathLineToVerticalOperation) ||
3680 (wand->path_mode != mode))
3681 {
3682 wand->path_operation=PathLineToVerticalOperation;
3683 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003684 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003685 'V' : 'v',y);
3686 }
3687 else
cristye7f51092010-01-17 00:39:37 +00003688 (void) MvgAutoWrapPrintf(wand," %g",y);
cristy3ed852e2009-09-05 21:47:34 +00003689}
3690
3691WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3692{
3693 assert(wand != (DrawingWand *) NULL);
3694 assert(wand->signature == WandSignature);
3695 if (wand->debug != MagickFalse)
3696 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3697 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3698}
3699
3700/*
3701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3702% %
3703% %
3704% %
3705% 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 %
3706% %
3707% %
3708% %
3709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3710%
3711% DrawPathLineToVerticalRelative() draws a vertical line path from the
3712% current point to the target point using relative coordinates. The target
3713% point then becomes the new current point.
3714%
3715% The format of the DrawPathLineToVerticalRelative method is:
3716%
3717% void DrawPathLineToVerticalRelative(DrawingWand *wand,
3718% const double y)
3719%
3720% A description of each parameter follows:
3721%
3722% o wand: the drawing wand.
3723%
3724% o y: target y ordinate
3725%
3726*/
3727WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3728{
3729 assert(wand != (DrawingWand *) NULL);
3730 assert(wand->signature == WandSignature);
3731 if (wand->debug != MagickFalse)
3732 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3733 DrawPathLineToVertical(wand,RelativePathMode,y);
3734}
3735/*
3736%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3737% %
3738% %
3739% %
3740% D r a w P a t h M o v e T o A b s o l u t e %
3741% %
3742% %
3743% %
3744%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3745%
3746% DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3747% using absolute coordinates. The current point then becomes the
3748% specified coordinate.
3749%
3750% The format of the DrawPathMoveToAbsolute method is:
3751%
3752% void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3753% const double y)
3754%
3755% A description of each parameter follows:
3756%
3757% o wand: the drawing wand.
3758%
3759% o x: target x ordinate
3760%
3761% o y: target y ordinate
3762%
3763*/
3764
3765static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3766 const double y)
3767{
3768 assert(wand != (DrawingWand *) NULL);
3769 assert(wand->signature == WandSignature);
3770 if (wand->debug != MagickFalse)
3771 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3772 if ((wand->path_operation != PathMoveToOperation) ||
3773 (wand->path_mode != mode))
3774 {
3775 wand->path_operation=PathMoveToOperation;
3776 wand->path_mode=mode;
cristye7f51092010-01-17 00:39:37 +00003777 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
cristy3ed852e2009-09-05 21:47:34 +00003778 'M' : 'm',x,y);
3779 }
3780 else
cristye7f51092010-01-17 00:39:37 +00003781 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003782}
3783
3784WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3785 const double y)
3786{
3787 assert(wand != (DrawingWand *) NULL);
3788 assert(wand->signature == WandSignature);
3789 if (wand->debug != MagickFalse)
3790 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3791 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3792}
3793
3794/*
3795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3796% %
3797% %
3798% %
3799% D r a w P a t h M o v e T o R e l a t i v e %
3800% %
3801% %
3802% %
3803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3804%
3805% DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3806% relative coordinates. The current point then becomes the specified
3807% coordinate.
3808%
3809% The format of the DrawPathMoveToRelative method is:
3810%
3811% void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3812% const double y)
3813%
3814% A description of each parameter follows:
3815%
3816% o wand: the drawing wand.
3817%
3818% o x: target x ordinate
3819%
3820% o y: target y ordinate
3821%
3822*/
3823WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3824 const double y)
3825{
3826 assert(wand != (DrawingWand *) NULL);
3827 assert(wand->signature == WandSignature);
3828 if (wand->debug != MagickFalse)
3829 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3830 DrawPathMoveTo(wand,RelativePathMode,x,y);
3831}
3832
3833/*
3834%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3835% %
3836% %
3837% %
3838% D r a w P a t h S t a r t %
3839% %
3840% %
3841% %
3842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3843%
3844% DrawPathStart() declares the start of a path drawing list which is terminated
3845% by a matching DrawPathFinish() command. All other DrawPath commands must
3846% be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3847% is because path drawing commands are subordinate commands and they do not
3848% function by themselves.
3849%
3850% The format of the DrawPathStart method is:
3851%
3852% void DrawPathStart(DrawingWand *wand)
3853%
3854% A description of each parameter follows:
3855%
3856% o wand: the drawing wand.
3857%
3858*/
3859WandExport void DrawPathStart(DrawingWand *wand)
3860{
3861 assert(wand != (DrawingWand *) NULL);
3862 assert(wand->signature == WandSignature);
3863 if (wand->debug != MagickFalse)
3864 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3865 (void) MvgPrintf(wand,"path '");
3866 wand->path_operation=PathDefaultOperation;
3867 wand->path_mode=DefaultPathMode;
3868}
3869
3870/*
3871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3872% %
3873% %
3874% %
3875% D r a w P o i n t %
3876% %
3877% %
3878% %
3879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3880%
3881% DrawPoint() draws a point using the current fill color.
3882%
3883% The format of the DrawPoint method is:
3884%
3885% void DrawPoint(DrawingWand *wand,const double x,const double y)
3886%
3887% A description of each parameter follows:
3888%
3889% o wand: the drawing wand.
3890%
3891% o x: target x coordinate
3892%
3893% o y: target y coordinate
3894%
3895*/
3896WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3897{
3898 assert(wand != (DrawingWand *) NULL);
3899 assert(wand->signature == WandSignature);
3900 if (wand->debug != MagickFalse)
3901 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00003902 (void) MvgPrintf(wand,"point %g,%g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00003903}
3904
3905/*
3906%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3907% %
3908% %
3909% %
3910% D r a w P o l y g o n %
3911% %
3912% %
3913% %
3914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3915%
3916% DrawPolygon() draws a polygon using the current stroke, stroke width, and
3917% fill color or texture, using the specified array of coordinates.
3918%
3919% The format of the DrawPolygon method is:
3920%
3921% void DrawPolygon(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003922% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003923%
3924% A description of each parameter follows:
3925%
3926% o wand: the drawing wand.
3927%
3928% o number_coordinates: number of coordinates
3929%
3930% o coordinates: coordinate array
3931%
3932*/
3933WandExport void DrawPolygon(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003934 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003935{
3936 assert(wand != (DrawingWand *) NULL);
3937 assert(wand->signature == WandSignature);
3938 if (wand->debug != MagickFalse)
3939 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3940 MvgAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3941}
3942
3943/*
3944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3945% %
3946% %
3947% %
3948% D r a w P o l y l i n e %
3949% %
3950% %
3951% %
3952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3953%
3954% DrawPolyline() draws a polyline using the current stroke, stroke width, and
3955% fill color or texture, using the specified array of coordinates.
3956%
3957% The format of the DrawPolyline method is:
3958%
3959% void DrawPolyline(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003960% const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003961%
3962% A description of each parameter follows:
3963%
3964% o wand: the drawing wand.
3965%
3966% o number_coordinates: number of coordinates
3967%
3968% o coordinates: coordinate array
3969%
3970*/
3971WandExport void DrawPolyline(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00003972 const size_t number_coordinates,const PointInfo *coordinates)
cristy3ed852e2009-09-05 21:47:34 +00003973{
3974 assert(wand != (DrawingWand *) NULL);
3975 assert(wand->signature == WandSignature);
3976 if (wand->debug != MagickFalse)
3977 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3978 MvgAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
3979}
3980
3981/*
3982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3983% %
3984% %
3985% %
3986% D r a w P o p C l i p P a t h %
3987% %
3988% %
3989% %
3990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3991%
3992% DrawPopClipPath() terminates a clip path definition.
3993%
3994% The format of the DrawPopClipPath method is:
3995%
3996% void DrawPopClipPath(DrawingWand *wand)
3997%
3998% A description of each parameter follows:
3999%
4000% o wand: the drawing wand.
4001%
4002*/
4003WandExport void DrawPopClipPath(DrawingWand *wand)
4004{
4005 assert(wand != (DrawingWand *) NULL);
4006 assert(wand->signature == WandSignature);
4007 if (wand->debug != MagickFalse)
4008 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4009 if (wand->indent_depth > 0)
4010 wand->indent_depth--;
4011 (void) MvgPrintf(wand,"pop clip-path\n");
4012}
4013
4014/*
4015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4016% %
4017% %
4018% %
4019% D r a w P o p D e f s %
4020% %
4021% %
4022% %
4023%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4024%
4025% DrawPopDefs() terminates a definition list.
4026%
4027% The format of the DrawPopDefs method is:
4028%
4029% void DrawPopDefs(DrawingWand *wand)
4030%
4031% A description of each parameter follows:
4032%
4033% o wand: the drawing wand.
4034%
4035*/
4036WandExport void DrawPopDefs(DrawingWand *wand)
4037{
4038 assert(wand != (DrawingWand *) NULL);
4039 assert(wand->signature == WandSignature);
4040 if (wand->debug != MagickFalse)
4041 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4042 if (wand->indent_depth > 0)
4043 wand->indent_depth--;
4044 (void) MvgPrintf(wand,"pop defs\n");
4045}
4046
4047/*
4048%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4049% %
4050% %
4051% %
4052% D r a w P o p P a t t e r n %
4053% %
4054% %
4055% %
4056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4057%
4058% DrawPopPattern() terminates a pattern definition.
4059%
4060% The format of the DrawPopPattern method is:
4061%
4062% MagickBooleanType DrawPopPattern(DrawingWand *wand)
4063%
4064% A description of each parameter follows:
4065%
4066% o wand: the drawing wand.
4067%
4068*/
4069WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4070{
4071 char
4072 geometry[MaxTextExtent],
4073 key[MaxTextExtent];
4074
4075 assert(wand != (DrawingWand *) NULL);
4076 assert(wand->signature == WandSignature);
4077 if (wand->debug != MagickFalse)
4078 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4079 if (wand->image == (Image *) NULL)
4080 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4081 if (wand->pattern_id == (const char *) NULL)
4082 {
4083 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4084 wand->name);
4085 return(MagickFalse);
4086 }
4087 (void) FormatMagickString(key,MaxTextExtent,"%s",wand->pattern_id);
4088 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
cristy6d8abba2010-06-03 01:10:47 +00004089 (void) FormatMagickString(geometry,MaxTextExtent,"%.20gx%.20g%+.20g%+.20g",
cristye8c25f92010-06-03 00:53:06 +00004090 (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
4091 (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
cristy3ed852e2009-09-05 21:47:34 +00004092 (void) SetImageArtifact(wand->image,key,geometry);
4093 wand->pattern_id=DestroyString(wand->pattern_id);
4094 wand->pattern_offset=0;
4095 wand->pattern_bounds.x=0;
4096 wand->pattern_bounds.y=0;
4097 wand->pattern_bounds.width=0;
4098 wand->pattern_bounds.height=0;
4099 wand->filter_off=MagickTrue;
4100 if (wand->indent_depth > 0)
4101 wand->indent_depth--;
4102 (void) MvgPrintf(wand,"pop pattern\n");
4103 return(MagickTrue);
4104}
4105
4106/*
4107%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4108% %
4109% %
4110% %
4111% D r a w P u s h C l i p P a t h %
4112% %
4113% %
4114% %
4115%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4116%
4117% DrawPushClipPath() starts a clip path definition which is comprized of any
4118% number of drawing commands and terminated by a DrawPopClipPath() command.
4119%
4120% The format of the DrawPushClipPath method is:
4121%
4122% void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4123%
4124% A description of each parameter follows:
4125%
4126% o wand: the drawing wand.
4127%
4128% o clip_mask_id: string identifier to associate with the clip path for
4129% later use.
4130%
4131*/
4132WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4133{
4134 assert(wand != (DrawingWand *) NULL);
4135 assert(wand->signature == WandSignature);
4136 if (wand->debug != MagickFalse)
4137 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4138 assert(clip_mask_id != (const char *) NULL);
4139 (void) MvgPrintf(wand,"push clip-path %s\n",clip_mask_id);
4140 wand->indent_depth++;
4141}
4142
4143/*
4144%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4145% %
4146% %
4147% %
4148% D r a w P u s h D e f s %
4149% %
4150% %
4151% %
4152%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4153%
4154% DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4155% command create named elements (e.g. clip-paths, textures, etc.) which
4156% may safely be processed earlier for the sake of efficiency.
4157%
4158% The format of the DrawPushDefs method is:
4159%
4160% void DrawPushDefs(DrawingWand *wand)
4161%
4162% A description of each parameter follows:
4163%
4164% o wand: the drawing wand.
4165%
4166*/
4167WandExport void DrawPushDefs(DrawingWand *wand)
4168{
4169 assert(wand != (DrawingWand *) NULL);
4170 assert(wand->signature == WandSignature);
4171 if (wand->debug != MagickFalse)
4172 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4173 (void) MvgPrintf(wand,"push defs\n");
4174 wand->indent_depth++;
4175}
4176
4177/*
4178%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4179% %
4180% %
4181% %
4182% D r a w P u s h P a t t e r n %
4183% %
4184% %
4185% %
4186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4187%
4188% DrawPushPattern() indicates that subsequent commands up to a
4189% DrawPopPattern() command comprise the definition of a named pattern.
4190% The pattern space is assigned top left corner coordinates, a width
4191% and height, and becomes its own drawing space. Anything which can
4192% be drawn may be used in a pattern definition.
4193% Named patterns may be used as stroke or brush definitions.
4194%
4195% The format of the DrawPushPattern method is:
4196%
4197% MagickBooleanType DrawPushPattern(DrawingWand *wand,
4198% const char *pattern_id,const double x,const double y,
4199% const double width,const double height)
4200%
4201% A description of each parameter follows:
4202%
4203% o wand: the drawing wand.
4204%
4205% o pattern_id: pattern identification for later reference
4206%
4207% o x: x ordinate of top left corner
4208%
4209% o y: y ordinate of top left corner
4210%
4211% o width: width of pattern space
4212%
4213% o height: height of pattern space
4214%
4215*/
4216WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4217 const char *pattern_id,const double x,const double y,const double width,
4218 const double height)
4219{
4220 assert(wand != (DrawingWand *) NULL);
4221 assert(wand->signature == WandSignature);
4222 if (wand->debug != MagickFalse)
4223 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4224 assert(pattern_id != (const char *) NULL);
4225 if (wand->pattern_id != NULL)
4226 {
4227 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4228 wand->pattern_id);
4229 return(MagickFalse);
4230 }
4231 wand->filter_off=MagickTrue;
cristye7f51092010-01-17 00:39:37 +00004232 (void) MvgPrintf(wand,"push pattern %s %g,%g %g,%g\n",pattern_id,
cristy8cd5b312010-01-07 01:10:24 +00004233 x,y,width,height);
cristy3ed852e2009-09-05 21:47:34 +00004234 wand->indent_depth++;
4235 wand->pattern_id=AcquireString(pattern_id);
cristybb503372010-05-27 20:51:26 +00004236 wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
4237 wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
4238 wand->pattern_bounds.width=(size_t) floor(width+0.5);
4239 wand->pattern_bounds.height=(size_t) floor(height+0.5);
cristy3ed852e2009-09-05 21:47:34 +00004240 wand->pattern_offset=wand->mvg_length;
4241 return(MagickTrue);
4242}
4243
4244/*
4245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4246% %
4247% %
4248% %
4249% D r a w R e c t a n g l e %
4250% %
4251% %
4252% %
4253%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4254%
4255% DrawRectangle() draws a rectangle given two coordinates and using the
4256% current stroke, stroke width, and fill settings.
4257%
4258% The format of the DrawRectangle method is:
4259%
4260% void DrawRectangle(DrawingWand *wand,const double x1,
4261% const double y1,const double x2,const double y2)
4262%
4263% A description of each parameter follows:
4264%
4265% o x1: x ordinate of first coordinate
4266%
4267% o y1: y ordinate of first coordinate
4268%
4269% o x2: x ordinate of second coordinate
4270%
4271% o y2: y ordinate of second coordinate
4272%
4273*/
4274WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4275 const double x2,const double y2)
4276{
4277 assert(wand != (DrawingWand *) NULL);
4278 assert(wand->signature == WandSignature);
4279 if (wand->debug != MagickFalse)
4280 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00004281 (void) MvgPrintf(wand,"rectangle %g,%g %g,%g\n",x1,y1,x2,y2);
cristy3ed852e2009-09-05 21:47:34 +00004282}
4283
4284/*
4285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4286% %
4287% %
4288% %
4289+ D r a w R e n d e r %
4290% %
4291% %
4292% %
4293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4294%
4295% DrawRender() renders all preceding drawing commands onto the image.
4296%
4297% The format of the DrawRender method is:
4298%
4299% MagickBooleanType DrawRender(DrawingWand *wand)
4300%
4301% A description of each parameter follows:
4302%
4303% o wand: the drawing wand.
4304%
4305*/
4306WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4307{
4308 MagickBooleanType
4309 status;
4310
4311 assert(wand != (const DrawingWand *) NULL);
4312 assert(wand->signature == WandSignature);
4313 if (wand->debug != MagickFalse)
4314 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4315 CurrentContext->primitive=wand->mvg;
4316 if (wand->debug != MagickFalse)
4317 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4318 if (wand->image == (Image *) NULL)
4319 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4320 status=DrawImage(wand->image,CurrentContext);
4321 InheritException(wand->exception,&wand->image->exception);
4322 CurrentContext->primitive=(char *) NULL;
4323 return(status);
4324}
4325
4326/*
4327%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4328% %
4329% %
4330% %
4331% D r a w R e s e t V e c t o r G r a p h i c s %
4332% %
4333% %
4334% %
4335%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4336%
4337% DrawResetVectorGraphics() resets the vector graphics associated with the
4338% specified wand.
4339%
4340% The format of the DrawResetVectorGraphics method is:
4341%
4342% void DrawResetVectorGraphics(DrawingWand *wand)
4343%
4344% A description of each parameter follows:
4345%
4346% o wand: the drawing wand.
4347%
4348*/
4349WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4350{
4351 assert(wand != (DrawingWand *) NULL);
4352 assert(wand->signature == WandSignature);
4353 if (wand->debug != MagickFalse)
4354 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4355 if (wand->mvg != (char *) NULL)
4356 wand->mvg=DestroyString(wand->mvg);
4357 wand->mvg_alloc=0;
4358 wand->mvg_length=0;
4359 wand->mvg_width=0;
4360}
4361
4362/*
4363%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4364% %
4365% %
4366% %
4367% D r a w R o t a t e %
4368% %
4369% %
4370% %
4371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4372%
4373% DrawRotate() applies the specified rotation to the current coordinate space.
4374%
4375% The format of the DrawRotate method is:
4376%
4377% void DrawRotate(DrawingWand *wand,const double degrees)
4378%
4379% A description of each parameter follows:
4380%
4381% o wand: the drawing wand.
4382%
4383% o degrees: degrees of rotation
4384%
4385*/
4386WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4387{
cristy3ed852e2009-09-05 21:47:34 +00004388 assert(wand != (DrawingWand *) NULL);
4389 assert(wand->signature == WandSignature);
4390 if (wand->debug != MagickFalse)
4391 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00004392 (void) MvgPrintf(wand,"rotate %g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00004393}
4394
4395/*
4396%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4397% %
4398% %
4399% %
4400% D r a w R o u n d R e c t a n g l e %
4401% %
4402% %
4403% %
4404%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4405%
4406% DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4407% x & y corner radiuses and using the current stroke, stroke width,
4408% and fill settings.
4409%
4410% The format of the DrawRoundRectangle method is:
4411%
4412% void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4413% double x2,double y2,double rx,double ry)
4414%
4415% A description of each parameter follows:
4416%
4417% o wand: the drawing wand.
4418%
4419% o x1: x ordinate of first coordinate
4420%
4421% o y1: y ordinate of first coordinate
4422%
4423% o x2: x ordinate of second coordinate
4424%
4425% o y2: y ordinate of second coordinate
4426%
4427% o rx: radius of corner in horizontal direction
4428%
4429% o ry: radius of corner in vertical direction
4430%
4431*/
4432WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4433 double x2,double y2,double rx,double ry)
4434{
4435 assert(wand != (DrawingWand *) NULL);
4436 assert(wand->signature == WandSignature);
4437 if (wand->debug != MagickFalse)
4438 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00004439 (void) MvgPrintf(wand,"roundrectangle %g,%g %g,%g %g,%g\n",
cristy8cd5b312010-01-07 01:10:24 +00004440 x1,y1,x2,y2,rx,ry);
cristy3ed852e2009-09-05 21:47:34 +00004441}
4442
4443/*
4444%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4445% %
4446% %
4447% %
4448% D r a w S c a l e %
4449% %
4450% %
4451% %
4452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4453%
4454% DrawScale() adjusts the scaling factor to apply in the horizontal and
4455% vertical directions to the current coordinate space.
4456%
4457% The format of the DrawScale method is:
4458%
4459% void DrawScale(DrawingWand *wand,const double x,const double y)
4460%
4461% A description of each parameter follows:
4462%
4463% o wand: the drawing wand.
4464%
4465% o x: horizontal scale factor
4466%
4467% o y: vertical scale factor
4468%
4469*/
4470WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4471{
cristy3ed852e2009-09-05 21:47:34 +00004472 assert(wand != (DrawingWand *) NULL);
4473 assert(wand->signature == WandSignature);
4474 if (wand->debug != MagickFalse)
4475 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00004476 (void) MvgPrintf(wand,"scale %g,%g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00004477}
4478
4479/*
4480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4481% %
4482% %
4483% %
4484% D r a w S e t B o r d e r C o l o r %
4485% %
4486% %
4487% %
4488%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4489%
4490% DrawSetBorderColor() sets the border color to be used for drawing bordered
4491% objects.
4492%
4493% The format of the DrawSetBorderColor method is:
4494%
4495% void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4496%
4497% A description of each parameter follows:
4498%
4499% o wand: the drawing wand.
4500%
4501% o border_wand: border wand.
4502%
4503*/
4504
4505static inline MagickBooleanType IsColorEqual(const PixelPacket *p,
4506 const PixelPacket *q)
4507{
cristy843c1722011-05-04 23:47:02 +00004508 if (GetRedPixelComponent(p) != GetRedPixelComponent(q))
cristy3ed852e2009-09-05 21:47:34 +00004509 return(MagickFalse);
cristy843c1722011-05-04 23:47:02 +00004510 if (GetGreenPixelComponent(p) != GetGreenPixelComponent(q))
cristy3ed852e2009-09-05 21:47:34 +00004511 return(MagickFalse);
cristy843c1722011-05-04 23:47:02 +00004512 if (GetBluePixelComponent(p) != GetBluePixelComponent(q))
cristy3ed852e2009-09-05 21:47:34 +00004513 return(MagickFalse);
cristy843c1722011-05-04 23:47:02 +00004514 if (GetOpacityPixelComponent(p) != GetOpacityPixelComponent(q))
cristy3ed852e2009-09-05 21:47:34 +00004515 return(MagickFalse);
4516 return(MagickTrue);
4517}
4518
4519WandExport void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4520{
4521 PixelPacket
4522 *current_border,
4523 border_color,
4524 new_border;
4525
4526 assert(wand != (DrawingWand *) NULL);
4527 assert(wand->signature == WandSignature);
4528 if (wand->debug != MagickFalse)
4529 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4530 assert(border_wand != (const PixelWand *) NULL);
4531 PixelGetQuantumColor(border_wand,&border_color);
4532 new_border=border_color;
4533 current_border=(&CurrentContext->border_color);
4534 if ((wand->filter_off != MagickFalse) ||
4535 (IsColorEqual(current_border,&new_border) == MagickFalse))
4536 {
4537 CurrentContext->border_color=new_border;
4538 (void) MvgPrintf(wand,"border-color '");
4539 MvgAppendColor(wand,&border_color);
4540 (void) MvgPrintf(wand,"'\n");
4541 }
4542}
4543
4544/*
4545%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4546% %
4547% %
4548% %
4549% D r a w S e t C l i p P a t h %
4550% %
4551% %
4552% %
4553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4554%
4555% DrawSetClipPath() associates a named clipping path with the image. Only
cristybb503372010-05-27 20:51:26 +00004556% the areas drawn on by the clipping path will be modified as ssize_t as it
cristy3ed852e2009-09-05 21:47:34 +00004557% remains in effect.
4558%
4559% The format of the DrawSetClipPath method is:
4560%
4561% MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4562% const char *clip_mask)
4563%
4564% A description of each parameter follows:
4565%
4566% o wand: the drawing wand.
4567%
4568% o clip_mask: name of clipping path to associate with image
4569%
4570*/
4571WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4572 const char *clip_mask)
4573{
4574 if (wand->debug != MagickFalse)
4575 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4576 assert(wand != (DrawingWand *) NULL);
4577 assert(wand->signature == WandSignature);
4578 assert(clip_mask != (const char *) NULL);
4579 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4580 (wand->filter_off != MagickFalse) ||
4581 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4582 {
4583 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4584#if DRAW_BINARY_IMPLEMENTATION
4585 if (wand->image == (Image *) NULL)
4586 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4587 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4588#endif
4589 (void) MvgPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4590 }
4591 return(MagickTrue);
4592}
4593
4594/*
4595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4596% %
4597% %
4598% %
4599% D r a w S e t C l i p R u l e %
4600% %
4601% %
4602% %
4603%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4604%
4605% DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4606%
4607% The format of the DrawSetClipRule method is:
4608%
4609% void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4610%
4611% A description of each parameter follows:
4612%
4613% o wand: the drawing wand.
4614%
4615% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4616%
4617*/
4618WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4619{
4620 assert(wand != (DrawingWand *) NULL);
4621 assert(wand->signature == WandSignature);
4622 if (wand->debug != MagickFalse)
4623 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4624 if ((wand->filter_off != MagickFalse) ||
4625 (CurrentContext->fill_rule != fill_rule))
4626 {
4627 CurrentContext->fill_rule=fill_rule;
cristy042ee782011-04-22 18:48:30 +00004628 (void) MvgPrintf(wand, "clip-rule '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004629 MagickFillRuleOptions,(ssize_t) fill_rule));
cristy3ed852e2009-09-05 21:47:34 +00004630 }
4631}
4632
4633/*
4634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4635% %
4636% %
4637% %
4638% D r a w S e t C l i p U n i t s %
4639% %
4640% %
4641% %
4642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4643%
4644% DrawSetClipUnits() sets the interpretation of clip path units.
4645%
4646% The format of the DrawSetClipUnits method is:
4647%
4648% void DrawSetClipUnits(DrawingWand *wand,
4649% const ClipPathUnits clip_units)
4650%
4651% A description of each parameter follows:
4652%
4653% o wand: the drawing wand.
4654%
4655% o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4656% ObjectBoundingBox)
4657%
4658*/
4659WandExport void DrawSetClipUnits(DrawingWand *wand,
4660 const ClipPathUnits clip_units)
4661{
4662 assert(wand != (DrawingWand *) NULL);
4663 assert(wand->signature == WandSignature);
4664 if (wand->debug != MagickFalse)
4665 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4666 if ((wand->filter_off != MagickFalse) ||
4667 (CurrentContext->clip_units != clip_units))
4668 {
4669 CurrentContext->clip_units=clip_units;
4670 if (clip_units == ObjectBoundingBox)
4671 {
4672 AffineMatrix
4673 affine;
4674
4675 GetAffineMatrix(&affine);
4676 affine.sx=CurrentContext->bounds.x2;
4677 affine.sy=CurrentContext->bounds.y2;
4678 affine.tx=CurrentContext->bounds.x1;
4679 affine.ty=CurrentContext->bounds.y1;
4680 AdjustAffine(wand,&affine);
4681 }
cristy042ee782011-04-22 18:48:30 +00004682 (void) MvgPrintf(wand, "clip-units '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004683 MagickClipPathOptions,(ssize_t) clip_units));
cristy3ed852e2009-09-05 21:47:34 +00004684 }
4685}
4686
4687/*
4688%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4689% %
4690% %
4691% %
4692% D r a w S e t F i l l C o l o r %
4693% %
4694% %
4695% %
4696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4697%
4698% DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4699%
4700% The format of the DrawSetFillColor method is:
4701%
4702% void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4703%
4704% A description of each parameter follows:
4705%
4706% o wand: the drawing wand.
4707%
4708% o fill_wand: fill wand.
4709%
4710*/
4711WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4712{
4713 PixelPacket
4714 *current_fill,
4715 fill_color,
4716 new_fill;
4717
4718 assert(wand != (DrawingWand *) NULL);
4719 assert(wand->signature == WandSignature);
4720 if (wand->debug != MagickFalse)
4721 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4722 assert(fill_wand != (const PixelWand *) NULL);
4723 PixelGetQuantumColor(fill_wand,&fill_color);
4724 new_fill=fill_color;
4725 current_fill=(&CurrentContext->fill);
4726 if ((wand->filter_off != MagickFalse) ||
4727 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4728 {
4729 CurrentContext->fill=new_fill;
4730 (void) MvgPrintf(wand,"fill '");
4731 MvgAppendColor(wand,&fill_color);
4732 (void) MvgPrintf(wand,"'\n");
4733 }
4734}
4735
4736/*
4737%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4738% %
4739% %
4740% %
4741% D r a w S e t F i l l O p a c i t y %
4742% %
4743% %
4744% %
4745%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4746%
4747% DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4748% color or fill texture. Fully opaque is 1.0.
4749%
4750% The format of the DrawSetFillOpacity method is:
4751%
4752% void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4753%
4754% A description of each parameter follows:
4755%
4756% o wand: the drawing wand.
4757%
4758% o fill_opacity: fill opacity
4759%
4760*/
4761WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4762{
4763 Quantum
4764 opacity;
4765
4766 assert(wand != (DrawingWand *) NULL);
4767 assert(wand->signature == WandSignature);
4768 if (wand->debug != MagickFalse)
4769 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyce70c172010-01-07 17:15:30 +00004770 opacity=ClampToQuantum((double) QuantumRange*(1.0-fill_opacity));
cristy3ed852e2009-09-05 21:47:34 +00004771 if ((wand->filter_off != MagickFalse) ||
4772 (CurrentContext->fill.opacity != opacity))
4773 {
4774 CurrentContext->fill.opacity=opacity;
cristye7f51092010-01-17 00:39:37 +00004775 (void) MvgPrintf(wand,"fill-opacity %g\n",fill_opacity);
cristy3ed852e2009-09-05 21:47:34 +00004776 }
4777}
4778
4779/*
4780%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4781% %
4782% %
4783% %
cristy56375382010-11-21 23:49:30 +00004784% D r a w S e t F o n t R e s o l u t i o n %
4785% %
4786% %
4787% %
4788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4789%
4790% DrawSetFontResolution() sets the image resolution.
4791%
4792% The format of the DrawSetFontResolution method is:
4793%
4794% DrawBooleanType DrawSetFontResolution(DrawingWand *wand,
4795% const double x_resolution,const doubtl y_resolution)
4796%
4797% A description of each parameter follows:
4798%
4799% o wand: the magick wand.
4800%
4801% o x_resolution: the image x resolution.
4802%
4803% o y_resolution: the image y resolution.
4804%
4805*/
4806WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
4807 const double x_resolution,const double y_resolution)
4808{
4809 char
4810 density[MaxTextExtent];
4811
4812 assert(wand != (DrawingWand *) NULL);
4813 assert(wand->signature == WandSignature);
4814 if (wand->debug != MagickFalse)
4815 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4816 (void) FormatMagickString(density,MaxTextExtent,"%gx%g",x_resolution,
4817 y_resolution);
4818 (void) CloneString(&CurrentContext->density,density);
4819 return(MagickTrue);
4820}
4821
4822/*
4823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4824% %
4825% %
4826% %
cristy3ed852e2009-09-05 21:47:34 +00004827% D r a w S e t O p a c i t y %
4828% %
4829% %
4830% %
4831%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4832%
4833% DrawSetOpacity() sets the opacity to use when drawing using the fill or
4834% stroke color or texture. Fully opaque is 1.0.
4835%
4836% The format of the DrawSetOpacity method is:
4837%
4838% void DrawSetOpacity(DrawingWand *wand,const double opacity)
4839%
4840% A description of each parameter follows:
4841%
4842% o wand: the drawing wand.
4843%
4844% o opacity: fill opacity
4845%
4846*/
4847WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4848{
4849 Quantum
4850 quantum_opacity;
4851
4852 assert(wand != (DrawingWand *) NULL);
4853 assert(wand->signature == WandSignature);
4854 if (wand->debug != MagickFalse)
4855 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyce70c172010-01-07 17:15:30 +00004856 quantum_opacity=ClampToQuantum((double) QuantumRange*(1.0-opacity));
cristy3ed852e2009-09-05 21:47:34 +00004857 if ((wand->filter_off != MagickFalse) ||
4858 (CurrentContext->opacity != quantum_opacity))
4859 {
cristycee97112010-05-28 00:44:52 +00004860 CurrentContext->opacity=(Quantum) opacity;
cristye7f51092010-01-17 00:39:37 +00004861 (void) MvgPrintf(wand,"opacity %g\n",opacity);
cristy3ed852e2009-09-05 21:47:34 +00004862 }
4863}
4864
4865/*
4866%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4867% %
4868% %
4869% %
4870% D r a w S e t F i l l P a t t e r n U R L %
4871% %
4872% %
4873% %
4874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4875%
4876% DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4877% objects. Only local URLs ("#identifier") are supported at this time. These
4878% local URLs are normally created by defining a named fill pattern with
4879% DrawPushPattern/DrawPopPattern.
4880%
4881% The format of the DrawSetFillPatternURL method is:
4882%
4883% MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4884% const char *fill_url)
4885%
4886% A description of each parameter follows:
4887%
4888% o wand: the drawing wand.
4889%
4890% o fill_url: URL to use to obtain fill pattern.
4891%
4892*/
4893WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4894 const char *fill_url)
4895{
4896 char
4897 pattern[MaxTextExtent],
4898 pattern_spec[MaxTextExtent];
4899
4900 assert(wand != (DrawingWand *) NULL);
4901 assert(wand->signature == WandSignature);
4902 if (wand->debug != MagickFalse)
4903 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4904 if (wand->image == (Image *) NULL)
4905 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4906 assert(fill_url != (const char *) NULL);
4907 if (*fill_url != '#')
4908 {
4909 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4910 return(MagickFalse);
4911 }
4912 (void) FormatMagickString(pattern,MaxTextExtent,"%s",fill_url+1);
4913 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4914 {
4915 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4916 return(MagickFalse);
4917 }
4918 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",fill_url);
4919#if DRAW_BINARY_IMPLEMENTATION
4920 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4921 &CurrentContext->fill_pattern);
4922#endif
4923 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4924 CurrentContext->fill.opacity=CurrentContext->opacity;
4925 (void) MvgPrintf(wand,"fill %s\n",pattern_spec);
4926 return(MagickTrue);
4927}
4928
4929/*
4930%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4931% %
4932% %
4933% %
4934% D r a w S e t F i l l R u l e %
4935% %
4936% %
4937% %
4938%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4939%
4940% DrawSetFillRule() sets the fill rule to use while drawing polygons.
4941%
4942% The format of the DrawSetFillRule method is:
4943%
4944% void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4945%
4946% A description of each parameter follows:
4947%
4948% o wand: the drawing wand.
4949%
4950% o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4951%
4952*/
4953WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4954{
4955 assert(wand != (DrawingWand *) NULL);
4956 assert(wand->signature == WandSignature);
4957 if (wand->debug != MagickFalse)
4958 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4959 if ((wand->filter_off != MagickFalse) ||
4960 (CurrentContext->fill_rule != fill_rule))
4961 {
4962 CurrentContext->fill_rule=fill_rule;
cristy042ee782011-04-22 18:48:30 +00004963 (void) MvgPrintf(wand, "fill-rule '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00004964 MagickFillRuleOptions,(ssize_t) fill_rule));
cristy3ed852e2009-09-05 21:47:34 +00004965 }
4966}
4967
4968/*
4969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4970% %
4971% %
4972% %
4973% D r a w S e t F o n t %
4974% %
4975% %
4976% %
4977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4978%
4979% DrawSetFont() sets the fully-sepecified font to use when annotating with
4980% text.
4981%
4982% The format of the DrawSetFont method is:
4983%
4984% MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4985%
4986% A description of each parameter follows:
4987%
4988% o wand: the drawing wand.
4989%
4990% o font_name: font name
4991%
4992*/
4993WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4994 const char *font_name)
4995{
4996 assert(wand != (DrawingWand *) NULL);
4997 assert(wand->signature == WandSignature);
4998 if (wand->debug != MagickFalse)
4999 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5000 assert(font_name != (const char *) NULL);
5001 if ((wand->filter_off != MagickFalse) ||
5002 (CurrentContext->font == (char *) NULL) ||
5003 (LocaleCompare(CurrentContext->font,font_name) != 0))
5004 {
5005 (void) CloneString(&CurrentContext->font,font_name);
5006 (void) MvgPrintf(wand,"font '%s'\n",font_name);
5007 }
5008 return(MagickTrue);
5009}
5010
5011/*
5012%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5013% %
5014% %
5015% %
5016% D r a w S e t F o n t F a m i l y %
5017% %
5018% %
5019% %
5020%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5021%
5022% DrawSetFontFamily() sets the font family to use when annotating with text.
5023%
5024% The format of the DrawSetFontFamily method is:
5025%
5026% MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5027% const char *font_family)
5028%
5029% A description of each parameter follows:
5030%
5031% o wand: the drawing wand.
5032%
5033% o font_family: font family
5034%
5035*/
5036WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5037 const char *font_family)
5038{
5039 assert(wand != (DrawingWand *) NULL);
5040 assert(wand->signature == WandSignature);
5041 if (wand->debug != MagickFalse)
5042 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5043 assert(font_family != (const char *) NULL);
5044 if ((wand->filter_off != MagickFalse) ||
5045 (CurrentContext->family == (const char *) NULL) ||
5046 (LocaleCompare(CurrentContext->family,font_family) != 0))
5047 {
5048 (void) CloneString(&CurrentContext->family,font_family);
5049 (void) MvgPrintf(wand,"font-family '%s'\n",font_family);
5050 }
5051 return(MagickTrue);
5052}
5053
5054/*
5055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5056% %
5057% %
5058% %
5059% D r a w S e t F o n t S i z e %
5060% %
5061% %
5062% %
5063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5064%
5065% DrawSetFontSize() sets the font pointsize to use when annotating with text.
5066%
5067% The format of the DrawSetFontSize method is:
5068%
5069% void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5070%
5071% A description of each parameter follows:
5072%
5073% o wand: the drawing wand.
5074%
5075% o pointsize: text pointsize
5076%
5077*/
5078WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5079{
5080 assert(wand != (DrawingWand *) NULL);
5081 assert(wand->signature == WandSignature);
5082 if (wand->debug != MagickFalse)
5083 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5084 if ((wand->filter_off != MagickFalse) ||
5085 (fabs(CurrentContext->pointsize-pointsize) > MagickEpsilon))
5086 {
5087 CurrentContext->pointsize=pointsize;
cristye7f51092010-01-17 00:39:37 +00005088 (void) MvgPrintf(wand,"font-size %g\n",pointsize);
cristy3ed852e2009-09-05 21:47:34 +00005089 }
5090}
5091
5092/*
5093%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5094% %
5095% %
5096% %
5097% D r a w S e t F o n t S t r e t c h %
5098% %
5099% %
5100% %
5101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5102%
5103% DrawSetFontStretch() sets the font stretch to use when annotating with text.
5104% The AnyStretch enumeration acts as a wild-card "don't care" option.
5105%
5106% The format of the DrawSetFontStretch method is:
5107%
5108% void DrawSetFontStretch(DrawingWand *wand,
5109% const StretchType font_stretch)
5110%
5111% A description of each parameter follows:
5112%
5113% o wand: the drawing wand.
5114%
5115% o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5116% CondensedStretch, SemiCondensedStretch,
5117% SemiExpandedStretch, ExpandedStretch,
5118% ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5119%
5120*/
5121WandExport void DrawSetFontStretch(DrawingWand *wand,
5122 const StretchType font_stretch)
5123{
5124 assert(wand != (DrawingWand *) NULL);
5125 assert(wand->signature == WandSignature);
5126 if (wand->debug != MagickFalse)
5127 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5128 if ((wand->filter_off != MagickFalse) ||
5129 (CurrentContext->stretch != font_stretch))
5130 {
5131 CurrentContext->stretch=font_stretch;
cristy042ee782011-04-22 18:48:30 +00005132 (void) MvgPrintf(wand, "font-stretch '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005133 MagickStretchOptions,(ssize_t) font_stretch));
cristy3ed852e2009-09-05 21:47:34 +00005134 }
5135}
5136
5137/*
5138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5139% %
5140% %
5141% %
5142% D r a w S e t F o n t S t y l e %
5143% %
5144% %
5145% %
5146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5147%
5148% DrawSetFontStyle() sets the font style to use when annotating with text.
5149% The AnyStyle enumeration acts as a wild-card "don't care" option.
5150%
5151% The format of the DrawSetFontStyle method is:
5152%
5153% void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5154%
5155% A description of each parameter follows:
5156%
5157% o wand: the drawing wand.
5158%
5159% o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5160%
5161*/
5162WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5163{
5164 assert(wand != (DrawingWand *) NULL);
5165 assert(wand->signature == WandSignature);
5166 if (wand->debug != MagickFalse)
5167 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5168 if ((wand->filter_off != MagickFalse) ||
5169 (CurrentContext->style != style))
5170 {
5171 CurrentContext->style=style;
cristy042ee782011-04-22 18:48:30 +00005172 (void) MvgPrintf(wand, "font-style '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005173 MagickStyleOptions,(ssize_t) style));
cristy3ed852e2009-09-05 21:47:34 +00005174 }
5175}
5176
5177/*
5178%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5179% %
5180% %
5181% %
5182% D r a w S e t F o n t W e i g h t %
5183% %
5184% %
5185% %
5186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5187%
5188% DrawSetFontWeight() sets the font weight to use when annotating with text.
5189%
5190% The format of the DrawSetFontWeight method is:
5191%
5192% void DrawSetFontWeight(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005193% const size_t font_weight)
cristy3ed852e2009-09-05 21:47:34 +00005194%
5195% A description of each parameter follows:
5196%
5197% o wand: the drawing wand.
5198%
5199% o font_weight: font weight (valid range 100-900)
5200%
5201*/
5202WandExport void DrawSetFontWeight(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005203 const size_t font_weight)
cristy3ed852e2009-09-05 21:47:34 +00005204{
5205 assert(wand != (DrawingWand *) NULL);
5206 assert(wand->signature == WandSignature);
5207 if (wand->debug != MagickFalse)
5208 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5209 if ((wand->filter_off != MagickFalse) ||
5210 (CurrentContext->weight != font_weight))
5211 {
5212 CurrentContext->weight=font_weight;
cristye8c25f92010-06-03 00:53:06 +00005213 (void) MvgPrintf(wand,"font-weight %.20g\n",(double) font_weight);
cristy3ed852e2009-09-05 21:47:34 +00005214 }
5215}
5216
5217/*
5218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5219% %
5220% %
5221% %
5222% D r a w S e t G r a v i t y %
5223% %
5224% %
5225% %
5226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5227%
5228% DrawSetGravity() sets the text placement gravity to use when annotating
5229% with text.
5230%
5231% The format of the DrawSetGravity method is:
5232%
5233% void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5234%
5235% A description of each parameter follows:
5236%
5237% o wand: the drawing wand.
5238%
5239% o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5240% NorthEastGravity, WestGravity, CenterGravity,
5241% EastGravity, SouthWestGravity, SouthGravity,
5242% SouthEastGravity)
5243%
5244*/
5245WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5246{
5247 assert(wand != (DrawingWand *) NULL);
5248 assert(wand->signature == WandSignature);
5249 if (wand->debug != MagickFalse)
5250 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5251 if ((wand->filter_off != MagickFalse) ||
5252 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5253 {
5254 CurrentContext->gravity=gravity;
cristy042ee782011-04-22 18:48:30 +00005255 (void) MvgPrintf(wand,"gravity '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005256 MagickGravityOptions,(ssize_t) gravity));
cristy3ed852e2009-09-05 21:47:34 +00005257 }
5258}
5259
5260/*
5261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5262% %
5263% %
5264% %
5265% D r a w S e t S t r o k e C o l o r %
5266% %
5267% %
5268% %
5269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5270%
5271% DrawSetStrokeColor() sets the color used for stroking object outlines.
5272%
5273% The format of the DrawSetStrokeColor method is:
5274%
5275% void DrawSetStrokeColor(DrawingWand *wand,
5276% const PixelWand *stroke_wand)
5277%
5278% A description of each parameter follows:
5279%
5280% o wand: the drawing wand.
5281%
5282% o stroke_wand: stroke wand.
5283%
5284*/
5285WandExport void DrawSetStrokeColor(DrawingWand *wand,
5286 const PixelWand *stroke_wand)
5287{
5288 PixelPacket
5289 *current_stroke,
5290 new_stroke,
5291 stroke_color;
5292
5293 assert(wand != (DrawingWand *) NULL);
5294 assert(wand->signature == WandSignature);
5295 if (wand->debug != MagickFalse)
5296 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5297 assert(stroke_wand != (const PixelWand *) NULL);
5298 PixelGetQuantumColor(stroke_wand,&stroke_color);
5299 new_stroke=stroke_color;
5300 current_stroke=(&CurrentContext->stroke);
5301 if ((wand->filter_off != MagickFalse) ||
5302 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5303 {
5304 CurrentContext->stroke=new_stroke;
5305 (void) MvgPrintf(wand,"stroke '");
5306 MvgAppendColor(wand,&stroke_color);
5307 (void) MvgPrintf(wand,"'\n");
5308 }
5309}
5310
5311/*
5312%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5313% %
5314% %
5315% %
5316% D r a w S e t S t r o k e P a t t e r n U R L %
5317% %
5318% %
5319% %
5320%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5321%
5322% DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5323%
5324% The format of the DrawSetStrokePatternURL method is:
5325%
5326% MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5327% const char *stroke_url)
5328%
5329% A description of each parameter follows:
5330%
5331% o wand: the drawing wand.
5332%
5333% o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5334%
5335*/
5336WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5337 const char *stroke_url)
5338{
5339 char
5340 pattern[MaxTextExtent],
5341 pattern_spec[MaxTextExtent];
5342
5343 assert(wand != (DrawingWand *) NULL);
5344 assert(wand->signature == WandSignature);
5345 if (wand->debug != MagickFalse)
5346 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5347 if (wand->image == (Image *) NULL)
5348 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5349 assert(stroke_url != NULL);
5350 if (stroke_url[0] != '#')
5351 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5352 (void) FormatMagickString(pattern,MaxTextExtent,"%s",stroke_url+1);
5353 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5354 {
5355 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5356 return(MagickFalse);
5357 }
5358 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",stroke_url);
5359#if DRAW_BINARY_IMPLEMENTATION
5360 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5361 &CurrentContext->stroke_pattern);
5362#endif
5363 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5364 CurrentContext->stroke.opacity=CurrentContext->opacity;
5365 (void) MvgPrintf(wand,"stroke %s\n",pattern_spec);
5366 return(MagickTrue);
5367}
5368
5369/*
5370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5371% %
5372% %
5373% %
5374% D r a w S e t S t r o k e A n t i a l i a s %
5375% %
5376% %
5377% %
5378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5379%
5380% DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5381% Stroked outlines are antialiased by default. When antialiasing is disabled
5382% stroked pixels are thresholded to determine if the stroke color or
5383% underlying canvas color should be used.
5384%
5385% The format of the DrawSetStrokeAntialias method is:
5386%
5387% void DrawSetStrokeAntialias(DrawingWand *wand,
5388% const MagickBooleanType stroke_antialias)
5389%
5390% A description of each parameter follows:
5391%
5392% o wand: the drawing wand.
5393%
5394% o stroke_antialias: set to false (zero) to disable antialiasing
5395%
5396*/
5397WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5398 const MagickBooleanType stroke_antialias)
5399{
5400 assert(wand != (DrawingWand *) NULL);
5401 assert(wand->signature == WandSignature);
5402 if (wand->debug != MagickFalse)
5403 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5404 if ((wand->filter_off != MagickFalse) ||
5405 (CurrentContext->stroke_antialias != stroke_antialias))
5406 {
5407 CurrentContext->stroke_antialias=stroke_antialias;
5408 (void) MvgPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5409 1 : 0);
5410 }
5411}
5412
5413/*
5414%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5415% %
5416% %
5417% %
5418% D r a w S e t S t r o k e D a s h A r r a y %
5419% %
5420% %
5421% %
5422%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5423%
5424% DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5425% stroke paths. The stroke dash array represents an array of numbers that
5426% specify the lengths of alternating dashes and gaps in pixels. If an odd
5427% number of values is provided, then the list of values is repeated to yield
5428% an even number of values. To remove an existing dash array, pass a zero
5429% number_elements argument and null dash_array. A typical stroke dash array
5430% might contain the members 5 3 2.
5431%
5432% The format of the DrawSetStrokeDashArray method is:
5433%
5434% MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005435% const size_t number_elements,const double *dash_array)
cristy3ed852e2009-09-05 21:47:34 +00005436%
5437% A description of each parameter follows:
5438%
5439% o wand: the drawing wand.
5440%
5441% o number_elements: number of elements in dash array
5442%
5443% o dash_array: dash array values
5444%
5445*/
5446WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005447 const size_t number_elements,const double *dash_array)
cristy3ed852e2009-09-05 21:47:34 +00005448{
5449 MagickBooleanType
5450 update;
5451
5452 register const double
5453 *p;
5454
5455 register double
5456 *q;
5457
cristybb503372010-05-27 20:51:26 +00005458 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005459 i;
5460
cristybb503372010-05-27 20:51:26 +00005461 size_t
cristy3ed852e2009-09-05 21:47:34 +00005462 n_new,
5463 n_old;
5464
5465 assert(wand != (DrawingWand *) NULL);
5466 assert(wand->signature == WandSignature);
5467 if (wand->debug != MagickFalse)
5468 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5469 n_new=number_elements;
5470 n_old=0;
5471 update=MagickFalse;
5472 q=CurrentContext->dash_pattern;
5473 if (q != (const double *) NULL)
5474 while (*q++ != 0.0)
5475 n_old++;
5476 if ((n_old == 0) && (n_new == 0))
5477 update=MagickFalse;
5478 else
5479 if (n_old != n_new)
5480 update=MagickTrue;
5481 else
5482 if ((CurrentContext->dash_pattern != (double *) NULL) &&
5483 (dash_array != (double *) NULL))
5484 {
5485 p=dash_array;
5486 q=CurrentContext->dash_pattern;
cristybb503372010-05-27 20:51:26 +00005487 for (i=0; i < (ssize_t) n_new; i++)
cristy3ed852e2009-09-05 21:47:34 +00005488 {
5489 if (fabs((*p)-(*q)) > MagickEpsilon)
5490 {
5491 update=MagickTrue;
5492 break;
5493 }
5494 p++;
5495 q++;
5496 }
5497 }
5498 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5499 {
5500 if (CurrentContext->dash_pattern != (double *) NULL)
5501 CurrentContext->dash_pattern=(double *)
5502 RelinquishMagickMemory(CurrentContext->dash_pattern);
5503 if (n_new != 0)
5504 {
5505 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5506 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5507 if (!CurrentContext->dash_pattern)
5508 {
5509 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5510 wand->name);
5511 return(MagickFalse);
5512 }
5513 q=CurrentContext->dash_pattern;
5514 p=dash_array;
cristybb503372010-05-27 20:51:26 +00005515 for (i=0; i < (ssize_t) n_new; i++)
cristy3ed852e2009-09-05 21:47:34 +00005516 *q++=(*p++);
5517 *q=0;
5518 }
5519 (void) MvgPrintf(wand,"stroke-dasharray ");
5520 if (n_new == 0)
5521 (void) MvgPrintf(wand,"none\n");
5522 else
5523 {
5524 p=dash_array;
cristye7f51092010-01-17 00:39:37 +00005525 (void) MvgPrintf(wand,"%g",*p++);
cristybb503372010-05-27 20:51:26 +00005526 for (i=1; i < (ssize_t) n_new; i++)
cristye7f51092010-01-17 00:39:37 +00005527 (void) MvgPrintf(wand,",%g",*p++);
cristy3ed852e2009-09-05 21:47:34 +00005528 (void) MvgPrintf(wand,"\n");
5529 }
5530 }
5531 return(MagickTrue);
5532}
5533
5534/*
5535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5536% %
5537% %
5538% %
5539% D r a w S e t S t r o k e D a s h O f f s e t %
5540% %
5541% %
5542% %
5543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5544%
5545% DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5546% start the dash.
5547%
5548% The format of the DrawSetStrokeDashOffset method is:
5549%
5550% void DrawSetStrokeDashOffset(DrawingWand *wand,
5551% const double dash_offset)
5552%
5553% A description of each parameter follows:
5554%
5555% o wand: the drawing wand.
5556%
5557% o dash_offset: dash offset
5558%
5559*/
5560WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5561 const double dash_offset)
5562{
5563 assert(wand != (DrawingWand *) NULL);
5564 assert(wand->signature == WandSignature);
5565 if (wand->debug != MagickFalse)
5566 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5567 if ((wand->filter_off != MagickFalse) ||
5568 (fabs(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
5569 {
5570 CurrentContext->dash_offset=dash_offset;
cristye7f51092010-01-17 00:39:37 +00005571 (void) MvgPrintf(wand,"stroke-dashoffset %g\n",dash_offset);
cristy3ed852e2009-09-05 21:47:34 +00005572 }
5573}
5574
5575/*
5576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5577% %
5578% %
5579% %
5580% D r a w S e t S t r o k e L i n e C a p %
5581% %
5582% %
5583% %
5584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5585%
5586% DrawSetStrokeLineCap() specifies the shape to be used at the end of
5587% open subpaths when they are stroked. Values of LineCap are
5588% UndefinedCap, ButtCap, RoundCap, and SquareCap.
5589%
5590% The format of the DrawSetStrokeLineCap method is:
5591%
5592% void DrawSetStrokeLineCap(DrawingWand *wand,
5593% const LineCap linecap)
5594%
5595% A description of each parameter follows:
5596%
5597% o wand: the drawing wand.
5598%
5599% o linecap: linecap style
5600%
5601*/
5602WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5603{
5604 assert(wand != (DrawingWand *) NULL);
5605 assert(wand->signature == WandSignature);
5606 if (wand->debug != MagickFalse)
5607 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5608 if ((wand->filter_off != MagickFalse) ||
5609 (CurrentContext->linecap != linecap))
5610 {
5611 CurrentContext->linecap=linecap;
cristy042ee782011-04-22 18:48:30 +00005612 (void) MvgPrintf(wand,"stroke-linecap '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005613 MagickLineCapOptions,(ssize_t) linecap));
cristy3ed852e2009-09-05 21:47:34 +00005614 }
5615}
5616
5617/*
5618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5619% %
5620% %
5621% %
5622% D r a w S e t S t r o k e L i n e J o i n %
5623% %
5624% %
5625% %
5626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5627%
5628% DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5629% paths (or other vector shapes) when they are stroked. Values of LineJoin are
5630% UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5631%
5632% The format of the DrawSetStrokeLineJoin method is:
5633%
5634% void DrawSetStrokeLineJoin(DrawingWand *wand,
5635% const LineJoin linejoin)
5636%
5637% A description of each parameter follows:
5638%
5639% o wand: the drawing wand.
5640%
5641% o linejoin: line join style
5642%
5643*/
5644WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5645{
5646 assert(wand != (DrawingWand *) NULL);
5647 assert(wand->signature == WandSignature);
5648 if (wand->debug != MagickFalse)
5649 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5650 if ((wand->filter_off != MagickFalse) ||
5651 (CurrentContext->linejoin != linejoin))
5652 {
5653 CurrentContext->linejoin=linejoin;
cristy042ee782011-04-22 18:48:30 +00005654 (void) MvgPrintf(wand, "stroke-linejoin '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005655 MagickLineJoinOptions,(ssize_t) linejoin));
cristy3ed852e2009-09-05 21:47:34 +00005656 }
5657}
5658
5659/*
5660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5661% %
5662% %
5663% %
5664% D r a w S e t S t r o k e M i t e r L i m i t %
5665% %
5666% %
5667% %
5668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5669%
5670% DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5671% segments meet at a sharp angle and miter joins have been specified for
5672% 'lineJoin', it is possible for the miter to extend far beyond the
5673% thickness of the line stroking the path. The miterLimit' imposes a
5674% limit on the ratio of the miter length to the 'lineWidth'.
5675%
5676% The format of the DrawSetStrokeMiterLimit method is:
5677%
5678% void DrawSetStrokeMiterLimit(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005679% const size_t miterlimit)
cristy3ed852e2009-09-05 21:47:34 +00005680%
5681% A description of each parameter follows:
5682%
5683% o wand: the drawing wand.
5684%
5685% o miterlimit: miter limit
5686%
5687*/
5688WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
cristybb503372010-05-27 20:51:26 +00005689 const size_t miterlimit)
cristy3ed852e2009-09-05 21:47:34 +00005690{
5691 assert(wand != (DrawingWand *) NULL);
5692 assert(wand->signature == WandSignature);
5693 if (wand->debug != MagickFalse)
5694 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5695 if (CurrentContext->miterlimit != miterlimit)
5696 {
5697 CurrentContext->miterlimit=miterlimit;
cristye8c25f92010-06-03 00:53:06 +00005698 (void) MvgPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit);
cristy3ed852e2009-09-05 21:47:34 +00005699 }
5700}
5701
5702/*
5703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5704% %
5705% %
5706% %
5707% D r a w S e t S t r o k e O p a c i t y %
5708% %
5709% %
5710% %
5711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5712%
5713% DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5714%
5715% The format of the DrawSetStrokeOpacity method is:
5716%
5717% void DrawSetStrokeOpacity(DrawingWand *wand,
5718% const double stroke_opacity)
5719%
5720% A description of each parameter follows:
5721%
5722% o wand: the drawing wand.
5723%
5724% o stroke_opacity: stroke opacity. The value 1.0 is opaque.
5725%
5726*/
5727WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5728 const double stroke_opacity)
5729{
5730 Quantum
5731 opacity;
5732
5733 assert(wand != (DrawingWand *) NULL);
5734 assert(wand->signature == WandSignature);
5735 if (wand->debug != MagickFalse)
5736 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristyce70c172010-01-07 17:15:30 +00005737 opacity=ClampToQuantum((double) QuantumRange*(1.0-stroke_opacity));
cristy3ed852e2009-09-05 21:47:34 +00005738 if ((wand->filter_off != MagickFalse) ||
5739 (CurrentContext->stroke.opacity != opacity))
5740 {
5741 CurrentContext->stroke.opacity=opacity;
cristye7f51092010-01-17 00:39:37 +00005742 (void) MvgPrintf(wand,"stroke-opacity %g\n",stroke_opacity);
cristy3ed852e2009-09-05 21:47:34 +00005743 }
5744}
5745
5746/*
5747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5748% %
5749% %
5750% %
5751% D r a w S e t S t r o k e W i d t h %
5752% %
5753% %
5754% %
5755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5756%
5757% DrawSetStrokeWidth() sets the width of the stroke used to draw object
5758% outlines.
5759%
5760% The format of the DrawSetStrokeWidth method is:
5761%
5762% void DrawSetStrokeWidth(DrawingWand *wand,
5763% const double stroke_width)
5764%
5765% A description of each parameter follows:
5766%
5767% o wand: the drawing wand.
5768%
5769% o stroke_width: stroke width
5770%
5771*/
5772WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5773{
5774 assert(wand != (DrawingWand *) NULL);
5775 assert(wand->signature == WandSignature);
5776 if (wand->debug != MagickFalse)
5777 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5778 if ((wand->filter_off != MagickFalse) ||
5779 (fabs(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
5780 {
5781 CurrentContext->stroke_width=stroke_width;
cristye7f51092010-01-17 00:39:37 +00005782 (void) MvgPrintf(wand,"stroke-width %g\n",stroke_width);
cristy3ed852e2009-09-05 21:47:34 +00005783 }
5784}
5785
5786/*
5787%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5788% %
5789% %
5790% %
5791% D r a w S e t T e x t A l i g n m e n t %
5792% %
5793% %
5794% %
5795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5796%
5797% DrawSetTextAlignment() specifies a text alignment to be applied when
5798% annotating with text.
5799%
5800% The format of the DrawSetTextAlignment method is:
5801%
5802% void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5803%
5804% A description of each parameter follows:
5805%
5806% o wand: the drawing wand.
5807%
5808% o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5809% CenterAlign, or RightAlign.
5810%
5811*/
5812WandExport void DrawSetTextAlignment(DrawingWand *wand,
5813 const AlignType alignment)
5814{
5815 assert(wand != (DrawingWand *) NULL);
5816 assert(wand->signature == WandSignature);
5817 if (wand->debug != MagickFalse)
5818 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5819 if ((wand->filter_off != MagickFalse) ||
5820 (CurrentContext->align != alignment))
5821 {
5822 CurrentContext->align=alignment;
cristy042ee782011-04-22 18:48:30 +00005823 (void) MvgPrintf(wand,"text-align '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005824 MagickAlignOptions,(ssize_t) alignment));
cristy3ed852e2009-09-05 21:47:34 +00005825 }
5826}
5827
5828/*
5829%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5830% %
5831% %
5832% %
5833% D r a w S e t T e x t A n t i a l i a s %
5834% %
5835% %
5836% %
5837%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5838%
5839% DrawSetTextAntialias() controls whether text is antialiased. Text is
5840% antialiased by default.
5841%
5842% The format of the DrawSetTextAntialias method is:
5843%
5844% void DrawSetTextAntialias(DrawingWand *wand,
5845% const MagickBooleanType text_antialias)
5846%
5847% A description of each parameter follows:
5848%
5849% o wand: the drawing wand.
5850%
5851% o text_antialias: antialias boolean. Set to false (0) to disable
5852% antialiasing.
5853%
5854*/
5855WandExport void DrawSetTextAntialias(DrawingWand *wand,
5856 const MagickBooleanType text_antialias)
5857{
5858 assert(wand != (DrawingWand *) NULL);
5859 assert(wand->signature == WandSignature);
5860 if (wand->debug != MagickFalse)
5861 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5862 if ((wand->filter_off != MagickFalse) ||
5863 (CurrentContext->text_antialias != text_antialias))
5864 {
5865 CurrentContext->text_antialias=text_antialias;
5866 (void) MvgPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5867 }
5868}
5869
5870/*
5871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5872% %
5873% %
5874% %
5875% D r a w S e t T e x t D e c o r a t i o n %
5876% %
5877% %
5878% %
5879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5880%
5881% DrawSetTextDecoration() specifies a decoration to be applied when
5882% annotating with text.
5883%
5884% The format of the DrawSetTextDecoration method is:
5885%
5886% void DrawSetTextDecoration(DrawingWand *wand,
5887% const DecorationType decoration)
5888%
5889% A description of each parameter follows:
5890%
5891% o wand: the drawing wand.
5892%
5893% o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5894% OverlineDecoration, or LineThroughDecoration
5895%
5896*/
5897WandExport void DrawSetTextDecoration(DrawingWand *wand,
5898 const DecorationType decoration)
5899{
5900 assert(wand != (DrawingWand *) NULL);
5901 assert(wand->signature == WandSignature);
5902 if (wand->debug != MagickFalse)
5903 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5904 if ((wand->filter_off != MagickFalse) ||
5905 (CurrentContext->decorate != decoration))
5906 {
5907 CurrentContext->decorate=decoration;
cristy042ee782011-04-22 18:48:30 +00005908 (void) MvgPrintf(wand,"decorate '%s'\n",CommandOptionToMnemonic(
cristybb503372010-05-27 20:51:26 +00005909 MagickDecorateOptions,(ssize_t) decoration));
cristy3ed852e2009-09-05 21:47:34 +00005910 }
5911}
5912
5913/*
5914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5915% %
5916% %
5917% %
5918% D r a w S e t T e x t E n c o d i n g %
5919% %
5920% %
5921% %
5922%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5923%
5924% DrawSetTextEncoding() specifies the code set to use for text
5925% annotations. The only character encoding which may be specified
5926% at this time is "UTF-8" for representing Unicode as a sequence of
5927% bytes. Specify an empty string to set text encoding to the system's
5928% default. Successful text annotation using Unicode may require fonts
5929% designed to support Unicode.
5930%
5931% The format of the DrawSetTextEncoding method is:
5932%
5933% void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5934%
5935% A description of each parameter follows:
5936%
5937% o wand: the drawing wand.
5938%
5939% o encoding: character string specifying text encoding
5940%
5941*/
5942WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5943{
5944 assert(wand != (DrawingWand *) NULL);
5945 assert(wand->signature == WandSignature);
5946 if (wand->debug != MagickFalse)
5947 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5948 assert(encoding != (char *) NULL);
5949 if ((wand->filter_off != MagickFalse) ||
5950 (CurrentContext->encoding == (char *) NULL) ||
5951 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
5952 {
5953 (void) CloneString(&CurrentContext->encoding,encoding);
5954 (void) MvgPrintf(wand,"encoding '%s'\n",encoding);
5955 }
5956}
5957
5958/*
5959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5960% %
5961% %
5962% %
5963% D r a w S e t T e x t K e r n i n g %
5964% %
5965% %
5966% %
5967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5968%
5969% DrawSetTextKerning() sets the spacing between characters in text.
5970%
5971% The format of the DrawSetTextKerning method is:
5972%
5973% void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5974%
5975% A description of each parameter follows:
5976%
5977% o wand: the drawing wand.
5978%
5979% o kerning: text kerning
5980%
5981*/
5982WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5983{
5984 assert(wand != (DrawingWand *) NULL);
5985 assert(wand->signature == WandSignature);
5986
5987 if (wand->debug != MagickFalse)
5988 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00005989 if ((wand->filter_off != MagickFalse) &&
cristy3ed852e2009-09-05 21:47:34 +00005990 (CurrentContext->kerning != kerning))
5991 {
5992 CurrentContext->kerning=kerning;
5993 (void) MvgPrintf(wand,"kerning %lf\n",kerning);
5994 }
5995}
5996
5997/*
5998%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5999% %
6000% %
6001% %
cristyb32b90a2009-09-07 21:45:48 +00006002% 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 %
6003% %
6004% %
6005% %
6006%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6007%
6008% DrawSetTextInterwordSpacing() sets the spacing between line in text.
6009%
6010% The format of the DrawSetInterwordSpacing method is:
6011%
6012% void DrawSetTextInterwordSpacing(DrawingWand *wand,
6013% const double interline_spacing)
6014%
6015% A description of each parameter follows:
6016%
6017% o wand: the drawing wand.
6018%
6019% o interline_spacing: text line spacing
6020%
6021*/
6022WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
6023 const double interline_spacing)
6024{
6025 assert(wand != (DrawingWand *) NULL);
6026 assert(wand->signature == WandSignature);
6027
6028 if (wand->debug != MagickFalse)
6029 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00006030 if ((wand->filter_off != MagickFalse) &&
cristyb32b90a2009-09-07 21:45:48 +00006031 (CurrentContext->interline_spacing != interline_spacing))
6032 {
6033 CurrentContext->interline_spacing=interline_spacing;
cristy738d3d32009-12-03 23:47:08 +00006034 (void) MvgPrintf(wand,"interline-spacing %lf\n",interline_spacing);
cristyb32b90a2009-09-07 21:45:48 +00006035 }
6036}
6037
6038/*
6039%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6040% %
6041% %
6042% %
cristy3ed852e2009-09-05 21:47:34 +00006043% 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 %
6044% %
6045% %
6046% %
6047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6048%
6049% DrawSetTextInterwordSpacing() sets the spacing between words in text.
6050%
6051% The format of the DrawSetInterwordSpacing method is:
6052%
6053% void DrawSetTextInterwordSpacing(DrawingWand *wand,
6054% const double interword_spacing)
6055%
6056% A description of each parameter follows:
6057%
6058% o wand: the drawing wand.
6059%
6060% o interword_spacing: text word spacing
6061%
6062*/
6063WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
6064 const double interword_spacing)
6065{
6066 assert(wand != (DrawingWand *) NULL);
6067 assert(wand->signature == WandSignature);
6068
6069 if (wand->debug != MagickFalse)
6070 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristy6a917d92009-10-06 19:23:54 +00006071 if ((wand->filter_off != MagickFalse) &&
cristy3ed852e2009-09-05 21:47:34 +00006072 (CurrentContext->interword_spacing != interword_spacing))
6073 {
6074 CurrentContext->interword_spacing=interword_spacing;
cristy738d3d32009-12-03 23:47:08 +00006075 (void) MvgPrintf(wand,"interword-spacing %lf\n",interword_spacing);
cristy3ed852e2009-09-05 21:47:34 +00006076 }
6077}
6078
6079/*
6080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6081% %
6082% %
6083% %
6084% D r a w S e t T e x t U n d e r C o l o r %
6085% %
6086% %
6087% %
6088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6089%
6090% DrawSetTextUnderColor() specifies the color of a background rectangle
6091% to place under text annotations.
6092%
6093% The format of the DrawSetTextUnderColor method is:
6094%
6095% void DrawSetTextUnderColor(DrawingWand *wand,
6096% const PixelWand *under_wand)
6097%
6098% A description of each parameter follows:
6099%
6100% o wand: the drawing wand.
6101%
6102% o under_wand: text under wand.
6103%
6104*/
6105WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6106 const PixelWand *under_wand)
6107{
6108 PixelPacket
6109 under_color;
6110
6111 assert(wand != (DrawingWand *) NULL);
6112 assert(wand->signature == WandSignature);
6113 if (wand->debug != MagickFalse)
6114 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6115 assert(under_wand != (const PixelWand *) NULL);
6116 PixelGetQuantumColor(under_wand,&under_color);
6117 if ((wand->filter_off != MagickFalse) ||
6118 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6119 {
6120 CurrentContext->undercolor=under_color;
6121 (void) MvgPrintf(wand,"text-undercolor '");
6122 MvgAppendColor(wand,&under_color);
6123 (void) MvgPrintf(wand,"'\n");
6124 }
6125}
6126
6127/*
6128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6129% %
6130% %
6131% %
6132% D r a w S e t V e c t o r G r a p h i c s %
6133% %
6134% %
6135% %
6136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6137%
6138% DrawSetVectorGraphics() sets the vector graphics associated with the
6139% specified wand. Use this method with DrawGetVectorGraphics() as a method
6140% to persist the vector graphics state.
6141%
6142% The format of the DrawSetVectorGraphics method is:
6143%
6144% MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6145% const char *xml)
6146%
6147% A description of each parameter follows:
6148%
6149% o wand: the drawing wand.
6150%
6151% o xml: the drawing wand XML.
6152%
6153*/
6154
6155static inline MagickBooleanType IsPoint(const char *point)
6156{
6157 char
6158 *p;
6159
cristycee97112010-05-28 00:44:52 +00006160 long
cristy3ed852e2009-09-05 21:47:34 +00006161 value;
6162
6163 value=strtol(point,&p,10);
cristyda16f162011-02-19 23:52:17 +00006164 (void) value;
cristy3ed852e2009-09-05 21:47:34 +00006165 return(p != point ? MagickTrue : MagickFalse);
6166}
6167
6168WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6169 const char *xml)
6170{
6171 const char
6172 *value;
6173
6174 XMLTreeInfo
6175 *child,
6176 *xml_info;
6177
6178 assert(wand != (DrawingWand *) NULL);
6179 assert(wand->signature == WandSignature);
6180 if (wand->debug != MagickFalse)
6181 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6182 CurrentContext=DestroyDrawInfo(CurrentContext);
6183 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6184 if (xml == (const char *) NULL)
6185 return(MagickFalse);
6186 xml_info=NewXMLTree(xml,wand->exception);
6187 if (xml_info == (XMLTreeInfo *) NULL)
6188 return(MagickFalse);
6189 child=GetXMLTreeChild(xml_info,"clip-path");
6190 if (child != (XMLTreeInfo *) NULL)
6191 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6192 child=GetXMLTreeChild(xml_info,"clip-units");
6193 if (child != (XMLTreeInfo *) NULL)
6194 {
6195 value=GetXMLTreeContent(child);
6196 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006197 CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006198 MagickClipPathOptions,MagickFalse,value);
6199 }
6200 child=GetXMLTreeChild(xml_info,"decorate");
6201 if (child != (XMLTreeInfo *) NULL)
6202 {
6203 value=GetXMLTreeContent(child);
6204 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006205 CurrentContext->decorate=(DecorationType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006206 MagickDecorateOptions,MagickFalse,value);
6207 }
6208 child=GetXMLTreeChild(xml_info,"encoding");
6209 if (child != (XMLTreeInfo *) NULL)
6210 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6211 child=GetXMLTreeChild(xml_info,"fill");
6212 if (child != (XMLTreeInfo *) NULL)
6213 {
6214 value=GetXMLTreeContent(child);
6215 if (value != (const char *) NULL)
6216 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6217 }
6218 child=GetXMLTreeChild(xml_info,"fill-opacity");
6219 if (child != (XMLTreeInfo *) NULL)
6220 {
6221 value=GetXMLTreeContent(child);
6222 if (value != (const char *) NULL)
cristyce70c172010-01-07 17:15:30 +00006223 CurrentContext->fill.opacity=ClampToQuantum((MagickRealType)
cristyf2f27272009-12-17 14:48:46 +00006224 QuantumRange*(1.0-StringToDouble(value)));
cristy3ed852e2009-09-05 21:47:34 +00006225 }
6226 child=GetXMLTreeChild(xml_info,"fill-rule");
6227 if (child != (XMLTreeInfo *) NULL)
6228 {
6229 value=GetXMLTreeContent(child);
6230 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006231 CurrentContext->fill_rule=(FillRule) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006232 MagickFillRuleOptions,MagickFalse,value);
6233 }
6234 child=GetXMLTreeChild(xml_info,"font");
6235 if (child != (XMLTreeInfo *) NULL)
6236 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6237 child=GetXMLTreeChild(xml_info,"font-family");
6238 if (child != (XMLTreeInfo *) NULL)
6239 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6240 child=GetXMLTreeChild(xml_info,"font-size");
6241 if (child != (XMLTreeInfo *) NULL)
6242 {
6243 value=GetXMLTreeContent(child);
6244 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006245 CurrentContext->pointsize=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006246 }
6247 child=GetXMLTreeChild(xml_info,"font-stretch");
6248 if (child != (XMLTreeInfo *) NULL)
6249 {
6250 value=GetXMLTreeContent(child);
6251 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006252 CurrentContext->stretch=(StretchType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006253 MagickStretchOptions,MagickFalse,value);
6254 }
6255 child=GetXMLTreeChild(xml_info,"font-style");
6256 if (child != (XMLTreeInfo *) NULL)
6257 {
6258 value=GetXMLTreeContent(child);
6259 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006260 CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
cristy3ed852e2009-09-05 21:47:34 +00006261 MagickFalse,value);
6262 }
6263 child=GetXMLTreeChild(xml_info,"font-weight");
6264 if (child != (XMLTreeInfo *) NULL)
6265 {
6266 value=GetXMLTreeContent(child);
6267 if (value != (const char *) NULL)
cristye27293e2009-12-18 02:53:20 +00006268 CurrentContext->weight=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006269 }
6270 child=GetXMLTreeChild(xml_info,"gravity");
6271 if (child != (XMLTreeInfo *) NULL)
6272 {
6273 value=GetXMLTreeContent(child);
6274 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006275 CurrentContext->gravity=(GravityType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006276 MagickGravityOptions,MagickFalse,value);
6277 }
6278 child=GetXMLTreeChild(xml_info,"stroke");
6279 if (child != (XMLTreeInfo *) NULL)
6280 {
6281 value=GetXMLTreeContent(child);
6282 if (value != (const char *) NULL)
6283 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6284 wand->exception);
6285 }
6286 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6287 if (child != (XMLTreeInfo *) NULL)
6288 {
6289 value=GetXMLTreeContent(child);
6290 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006291 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
cristy3ed852e2009-09-05 21:47:34 +00006292 MagickFalse;
6293 }
6294 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6295 if (child != (XMLTreeInfo *) NULL)
6296 {
6297 char
6298 token[MaxTextExtent];
6299
6300 const char
6301 *q;
6302
cristybb503372010-05-27 20:51:26 +00006303 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006304 x;
6305
cristy9d314ff2011-03-09 01:30:28 +00006306 ssize_t
6307 j;
6308
cristy3ed852e2009-09-05 21:47:34 +00006309 value=GetXMLTreeContent(child);
6310 if (value != (const char *) NULL)
6311 {
6312 if (CurrentContext->dash_pattern != (double *) NULL)
6313 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6314 CurrentContext->dash_pattern);
6315 q=(char *) value;
6316 if (IsPoint(q) != MagickFalse)
6317 {
6318 const char
6319 *p;
6320
6321 p=q;
6322 GetMagickToken(p,&p,token);
6323 if (*token == ',')
6324 GetMagickToken(p,&p,token);
6325 for (x=0; IsPoint(token) != MagickFalse; x++)
6326 {
6327 GetMagickToken(p,&p,token);
6328 if (*token == ',')
6329 GetMagickToken(p,&p,token);
6330 }
6331 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6332 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6333 if (CurrentContext->dash_pattern == (double *) NULL)
6334 ThrowWandFatalException(ResourceLimitFatalError,
6335 "MemoryAllocationFailed",wand->name);
6336 for (j=0; j < x; j++)
6337 {
6338 GetMagickToken(q,&q,token);
6339 if (*token == ',')
6340 GetMagickToken(q,&q,token);
cristyf2f27272009-12-17 14:48:46 +00006341 CurrentContext->dash_pattern[j]=StringToDouble(token);
cristy3ed852e2009-09-05 21:47:34 +00006342 }
6343 if ((x & 0x01) != 0)
6344 for ( ; j < (2*x); j++)
6345 CurrentContext->dash_pattern[j]=
6346 CurrentContext->dash_pattern[j-x];
6347 CurrentContext->dash_pattern[j]=0.0;
6348 }
6349 }
6350 }
6351 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6352 if (child != (XMLTreeInfo *) NULL)
6353 {
6354 value=GetXMLTreeContent(child);
6355 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006356 CurrentContext->dash_offset=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006357 }
6358 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6359 if (child != (XMLTreeInfo *) NULL)
6360 {
6361 value=GetXMLTreeContent(child);
6362 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006363 CurrentContext->linecap=(LineCap) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006364 MagickLineCapOptions,MagickFalse,value);
6365 }
6366 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6367 if (child != (XMLTreeInfo *) NULL)
6368 {
6369 value=GetXMLTreeContent(child);
6370 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006371 CurrentContext->linejoin=(LineJoin) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +00006372 MagickLineJoinOptions,MagickFalse,value);
6373 }
6374 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6375 if (child != (XMLTreeInfo *) NULL)
6376 {
6377 value=GetXMLTreeContent(child);
6378 if (value != (const char *) NULL)
cristye27293e2009-12-18 02:53:20 +00006379 CurrentContext->miterlimit=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006380 }
6381 child=GetXMLTreeChild(xml_info,"stroke-opacity");
6382 if (child != (XMLTreeInfo *) NULL)
6383 {
6384 value=GetXMLTreeContent(child);
6385 if (value != (const char *) NULL)
cristyce70c172010-01-07 17:15:30 +00006386 CurrentContext->stroke.opacity=ClampToQuantum((MagickRealType)
cristyf2f27272009-12-17 14:48:46 +00006387 QuantumRange*(1.0-StringToDouble(value)));
cristy3ed852e2009-09-05 21:47:34 +00006388 }
6389 child=GetXMLTreeChild(xml_info,"stroke-width");
6390 if (child != (XMLTreeInfo *) NULL)
6391 {
6392 value=GetXMLTreeContent(child);
6393 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006394 CurrentContext->stroke_width=StringToDouble(value);
cristy3ed852e2009-09-05 21:47:34 +00006395 }
6396 child=GetXMLTreeChild(xml_info,"text-align");
6397 if (child != (XMLTreeInfo *) NULL)
6398 {
6399 value=GetXMLTreeContent(child);
6400 if (value != (const char *) NULL)
cristy042ee782011-04-22 18:48:30 +00006401 CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
cristy3ed852e2009-09-05 21:47:34 +00006402 MagickFalse,value);
6403 }
6404 child=GetXMLTreeChild(xml_info,"text-antialias");
6405 if (child != (XMLTreeInfo *) NULL)
6406 {
6407 value=GetXMLTreeContent(child);
6408 if (value != (const char *) NULL)
cristyf2f27272009-12-17 14:48:46 +00006409 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
cristy3ed852e2009-09-05 21:47:34 +00006410 MagickFalse;
6411 }
6412 child=GetXMLTreeChild(xml_info,"text-undercolor");
6413 if (child != (XMLTreeInfo *) NULL)
6414 {
6415 value=GetXMLTreeContent(child);
6416 if (value != (const char *) NULL)
6417 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6418 wand->exception);
6419 }
6420 child=GetXMLTreeChild(xml_info,"vector-graphics");
6421 if (child != (XMLTreeInfo *) NULL)
6422 {
6423 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6424 wand->mvg_length=strlen(wand->mvg);
6425 wand->mvg_alloc=wand->mvg_length+1;
6426 }
6427 xml_info=DestroyXMLTree(xml_info);
6428 return(MagickTrue);
6429}
6430
6431/*
6432%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6433% %
6434% %
6435% %
6436% D r a w S k e w X %
6437% %
6438% %
6439% %
6440%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6441%
6442% DrawSkewX() skews the current coordinate system in the horizontal
6443% direction.
6444%
6445% The format of the DrawSkewX method is:
6446%
6447% void DrawSkewX(DrawingWand *wand,const double degrees)
6448%
6449% A description of each parameter follows:
6450%
6451% o wand: the drawing wand.
6452%
6453% o degrees: number of degrees to skew the coordinates
6454%
6455*/
6456WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6457{
cristy3ed852e2009-09-05 21:47:34 +00006458 assert(wand != (DrawingWand *) NULL);
6459 assert(wand->signature == WandSignature);
6460 if (wand->debug != MagickFalse)
6461 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00006462 (void) MvgPrintf(wand,"skewX %g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00006463}
6464
6465/*
6466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6467% %
6468% %
6469% %
6470% D r a w S k e w Y %
6471% %
6472% %
6473% %
6474%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6475%
6476% DrawSkewY() skews the current coordinate system in the vertical
6477% direction.
6478%
6479% The format of the DrawSkewY method is:
6480%
6481% void DrawSkewY(DrawingWand *wand,const double degrees)
6482%
6483% A description of each parameter follows:
6484%
6485% o wand: the drawing wand.
6486%
6487% o degrees: number of degrees to skew the coordinates
6488%
6489*/
6490WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6491{
cristy3ed852e2009-09-05 21:47:34 +00006492 assert(wand != (DrawingWand *) NULL);
6493 assert(wand->signature == WandSignature);
6494 if (wand->debug != MagickFalse)
6495 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00006496 (void) MvgPrintf(wand,"skewY %g\n",degrees);
cristy3ed852e2009-09-05 21:47:34 +00006497}
6498
6499/*
6500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6501% %
6502% %
6503% %
6504% D r a w T r a n s l a t e %
6505% %
6506% %
6507% %
6508%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6509%
6510% DrawTranslate() applies a translation to the current coordinate
6511% system which moves the coordinate system origin to the specified
6512% coordinate.
6513%
6514% The format of the DrawTranslate method is:
6515%
6516% void DrawTranslate(DrawingWand *wand,const double x,
6517% const double y)
6518%
6519% A description of each parameter follows:
6520%
6521% o wand: the drawing wand.
6522%
6523% o x: new x ordinate for coordinate system origin
6524%
6525% o y: new y ordinate for coordinate system origin
6526%
6527*/
6528WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6529{
cristy3ed852e2009-09-05 21:47:34 +00006530 assert(wand != (DrawingWand *) NULL);
6531 assert(wand->signature == WandSignature);
6532 if (wand->debug != MagickFalse)
6533 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye7f51092010-01-17 00:39:37 +00006534 (void) MvgPrintf(wand,"translate %g,%g\n",x,y);
cristy3ed852e2009-09-05 21:47:34 +00006535}
6536
6537/*
6538%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6539% %
6540% %
6541% %
6542% D r a w S e t V i e w b o x %
6543% %
6544% %
6545% %
6546%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6547%
6548% DrawSetViewbox() sets the overall canvas size to be recorded with the
6549% drawing vector data. Usually this will be specified using the same
6550% size as the canvas image. When the vector data is saved to SVG or MVG
6551% formats, the viewbox is use to specify the size of the canvas image that
6552% a viewer will render the vector data on.
6553%
6554% The format of the DrawSetViewbox method is:
6555%
cristybb503372010-05-27 20:51:26 +00006556% void DrawSetViewbox(DrawingWand *wand,size_t x1,
6557% size_t y1,size_t x2,size_t y2)
cristy3ed852e2009-09-05 21:47:34 +00006558%
6559% A description of each parameter follows:
6560%
6561% o wand: the drawing wand.
6562%
6563% o x1: left x ordinate
6564%
6565% o y1: top y ordinate
6566%
6567% o x2: right x ordinate
6568%
6569% o y2: bottom y ordinate
6570%
6571*/
cristy5ed838e2010-05-31 00:05:35 +00006572WandExport void DrawSetViewbox(DrawingWand *wand,ssize_t x1,ssize_t y1,
6573 ssize_t x2,ssize_t y2)
cristy3ed852e2009-09-05 21:47:34 +00006574{
6575 assert(wand != (DrawingWand *) NULL);
6576 assert(wand->signature == WandSignature);
6577 if (wand->debug != MagickFalse)
6578 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
cristye8c25f92010-06-03 00:53:06 +00006579 (void) MvgPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",(double) x1,
6580 (double) y1,(double) x2,(double) y2);
cristy3ed852e2009-09-05 21:47:34 +00006581}
6582
6583/*
6584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6585% %
6586% %
6587% %
6588% I s D r a w i n g W a n d %
6589% %
6590% %
6591% %
6592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6593%
6594% IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6595%
6596% The format of the IsDrawingWand method is:
6597%
6598% MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6599%
6600% A description of each parameter follows:
6601%
6602% o wand: the drawing wand.
6603%
6604*/
6605WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6606{
6607 if (wand == (const DrawingWand *) NULL)
6608 return(MagickFalse);
6609 if (wand->signature != WandSignature)
6610 return(MagickFalse);
6611 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6612 return(MagickFalse);
6613 return(MagickTrue);
6614}
6615
6616/*
6617%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6618% %
6619% %
6620% %
6621% N e w D r a w i n g W a n d %
6622% %
6623% %
6624% %
6625%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6626%
6627% NewDrawingWand() returns a drawing wand required for all other methods in
6628% the API.
6629%
6630% The format of the NewDrawingWand method is:
6631%
6632% DrawingWand NewDrawingWand(void)
6633%
6634*/
6635WandExport DrawingWand *NewDrawingWand(void)
6636{
6637 const char
6638 *quantum;
6639
6640 DrawingWand
6641 *wand;
6642
cristybb503372010-05-27 20:51:26 +00006643 size_t
cristy3ed852e2009-09-05 21:47:34 +00006644 depth;
6645
6646 quantum=GetMagickQuantumDepth(&depth);
6647 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6648 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
cristy73bd4a52010-10-05 11:24:23 +00006649 wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand));
cristy3ed852e2009-09-05 21:47:34 +00006650 if (wand == (DrawingWand *) NULL)
6651 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6652 GetExceptionMessage(errno));
6653 (void) ResetMagickMemory(wand,0,sizeof(*wand));
6654 wand->id=AcquireWandId();
cristye8c25f92010-06-03 00:53:06 +00006655 (void) FormatMagickString(wand->name,MaxTextExtent,"%s-%.20g",DrawingWandId,
6656 (double) wand->id);
cristy3ed852e2009-09-05 21:47:34 +00006657 if (wand->debug != MagickFalse)
6658 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6659 wand->mvg=(char *) NULL;
6660 wand->mvg_alloc=0;
6661 wand->mvg_length=0;
6662 wand->mvg_width=0;
6663 wand->pattern_id=(char *) NULL;
6664 wand->pattern_offset=0;
6665 wand->pattern_bounds.x=0;
6666 wand->pattern_bounds.y=0;
6667 wand->pattern_bounds.width=0;
6668 wand->pattern_bounds.height=0;
6669 wand->index=0;
cristy73bd4a52010-10-05 11:24:23 +00006670 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(
cristy3ed852e2009-09-05 21:47:34 +00006671 *wand->graphic_context));
6672 if (wand->graphic_context == (DrawInfo **) NULL)
6673 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6674 GetExceptionMessage(errno));
6675 wand->filter_off=MagickTrue;
6676 wand->indent_depth=0;
6677 wand->path_operation=PathDefaultOperation;
6678 wand->path_mode=DefaultPathMode;
6679 wand->image=AcquireImage((const ImageInfo *) NULL);
6680 wand->exception=AcquireExceptionInfo();
6681 wand->destroy=MagickTrue;
6682 wand->debug=IsEventLogging();
6683 wand->signature=WandSignature;
6684 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6685 return(wand);
6686}
6687
6688/*
6689%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6690% %
6691% %
6692% %
6693% P e e k D r a w i n g W a n d %
6694% %
6695% %
6696% %
6697%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6698%
6699% PeekDrawingWand() returns the current drawing wand.
6700%
6701% The format of the PeekDrawingWand method is:
6702%
6703% DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6704%
6705% A description of each parameter follows:
6706%
6707% o wand: the drawing wand.
6708%
6709*/
6710WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6711{
6712 DrawInfo
6713 *draw_info;
6714
6715 assert(wand != (const DrawingWand *) NULL);
6716 assert(wand->signature == WandSignature);
6717 if (wand->debug != MagickFalse)
6718 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6719 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6720 GetAffineMatrix(&draw_info->affine);
6721 (void) CloneString(&draw_info->primitive,wand->mvg);
6722 return(draw_info);
6723}
6724
6725/*
6726%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6727% %
6728% %
6729% %
6730% P o p D r a w i n g W a n d %
6731% %
6732% %
6733% %
6734%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6735%
6736% PopDrawingWand() destroys the current drawing wand and returns to the
6737% previously pushed drawing wand. Multiple drawing wands may exist. It is an
6738% error to attempt to pop more drawing wands than have been pushed, and it is
6739% proper form to pop all drawing wands which have been pushed.
6740%
6741% The format of the PopDrawingWand method is:
6742%
6743% MagickBooleanType PopDrawingWand(DrawingWand *wand)
6744%
6745% A description of each parameter follows:
6746%
6747% o wand: the drawing wand.
6748%
6749*/
6750WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6751{
6752 assert(wand != (DrawingWand *) NULL);
6753 assert(wand->signature == WandSignature);
6754 if (wand->debug != MagickFalse)
6755 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6756 if (wand->index == 0)
6757 {
6758 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6759 return(MagickFalse);
6760 }
6761 /*
6762 Destroy clip path if not same in preceding wand.
6763 */
6764#if DRAW_BINARY_IMPLEMENTATION
6765 if (wand->image == (Image *) NULL)
6766 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6767 if (CurrentContext->clip_mask != (char *) NULL)
6768 if (LocaleCompare(CurrentContext->clip_mask,
6769 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6770 (void) SetImageClipMask(wand->image,(Image *) NULL);
6771#endif
6772 CurrentContext=DestroyDrawInfo(CurrentContext);
6773 wand->index--;
6774 if (wand->indent_depth > 0)
6775 wand->indent_depth--;
6776 (void) MvgPrintf(wand,"pop graphic-context\n");
6777 return(MagickTrue);
6778}
6779
6780/*
6781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6782% %
6783% %
6784% %
6785% P u s h D r a w i n g W a n d %
6786% %
6787% %
6788% %
6789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6790%
6791% PushDrawingWand() clones the current drawing wand to create a new drawing
6792% wand. The original drawing wand(s) may be returned to by invoking
6793% PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6794% For every Pop there must have already been an equivalent Push.
6795%
6796% The format of the PushDrawingWand method is:
6797%
6798% MagickBooleanType PushDrawingWand(DrawingWand *wand)
6799%
6800% A description of each parameter follows:
6801%
6802% o wand: the drawing wand.
6803%
6804*/
6805WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6806{
6807 assert(wand != (DrawingWand *) NULL);
6808 assert(wand->signature == WandSignature);
6809 if (wand->debug != MagickFalse)
6810 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6811 wand->index++;
6812 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6813 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6814 if (wand->graphic_context == (DrawInfo **) NULL)
6815 {
6816 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6817 wand->name);
6818 return(MagickFalse);
6819 }
6820 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6821 wand->graphic_context[wand->index-1]);
6822 (void) MvgPrintf(wand,"push graphic-context\n");
6823 wand->indent_depth++;
6824 return(MagickTrue);
6825}