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