2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
14 % W W W AAAAA N N N D D %
15 % WW WW A A N NN D D %
19 % MagickWand Image Vector Drawing Methods %
26 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
27 % dedicated to making software imaging solutions freely available. %
29 % You may not use this file except in compliance with the License. You may %
30 % obtain a copy of the License at %
32 % http://www.imagemagick.org/script/license.php %
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. %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 #include "wand/studio.h"
50 #include "wand/MagickWand.h"
51 #include "wand/magick-wand-private.h"
52 #include "wand/wand.h"
53 #include "magick/string-private.h"
58 #define DRAW_BINARY_IMPLEMENTATION 0
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);
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)+ */
98 /* Support structures */
105 /* MVG output string and housekeeping */
110 mvg_alloc, /* total allocated memory */
111 mvg_length; /* total MVG length */
114 mvg_width; /* current line width */
116 /* Pattern support */
128 index; /* array index */
134 filter_off; /* true if not filtering attributes */
136 /* Pretty-printing depth */
138 indent_depth; /* number of left-hand pad characters */
140 /* Path operation support */
155 /* Vector table for invoking subordinate renderers */
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);
163 void (*DrawBezier)(DrawingWand *,const unsigned long,const PointInfo *);
164 void (*DrawCircle)(DrawingWand *,const double,const double,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,
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,
195 void (*DrawPathEllipticArcRelative)(DrawingWand *,const double,const double,
196 const double,const MagickBooleanType,const MagickBooleanType,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);
209 void (*DrawPolygon)(DrawingWand *,const unsigned long,const PointInfo *);
210 void (*DrawPolyline)(DrawingWand *,const unsigned long,const PointInfo *);
211 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,
220 void (*DrawRoundRectangle)(DrawingWand *,double,double,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);
239 void (*DrawSetFontWeight)(DrawingWand *,const unsigned long);
240 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);
251 void (*DrawSetStrokeMiterLimit)(DrawingWand *,const unsigned long);
252 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);
258 void (*DrawSetViewbox)(DrawingWand *,unsigned long,unsigned long,
259 unsigned long,unsigned long);
260 void (*PeekDrawingWand)(DrawingWand *);
261 MagickBooleanType (*PopDrawingWand)(DrawingWand *);
262 MagickBooleanType (*PushDrawingWand)(DrawingWand *);
266 Forward declarations.
269 MvgPrintf(DrawingWand *,const char *,...) wand_attribute((format
271 MvgAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format
275 MvgAppendColor(DrawingWand *,const PixelPacket *);
278 "Printf" for MVG commands
280 static int MvgPrintf(DrawingWand *wand,const char *format,...)
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)
292 wand->mvg=(char *) AcquireQuantumMemory(alloc_size,sizeof(*wand->mvg));
293 if (wand->mvg == (char *) NULL)
295 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
299 wand->mvg_alloc=alloc_size;
302 if (wand->mvg_alloc < (wand->mvg_length+10*MaxTextExtent))
307 realloc_size=wand->mvg_alloc+alloc_size;
308 wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,realloc_size,
310 if (wand->mvg == (char *) NULL)
312 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
316 wand->mvg_alloc=realloc_size;
325 while (wand->mvg_width < wand->indent_depth)
327 wand->mvg[wand->mvg_length]=' ';
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);
337 formatted_length=vsprintf(wand->mvg+wand->mvg_length,
341 if (formatted_length < 0)
342 ThrowDrawException(DrawError,"UnableToPrint",format)
345 wand->mvg_length+=formatted_length;
346 wand->mvg_width+=formatted_length;
348 wand->mvg[wand->mvg_length]='\0';
349 if ((wand->mvg_length > 1) &&
350 (wand->mvg[wand->mvg_length-1] == '\n'))
352 assert((wand->mvg_length+1) < wand->mvg_alloc);
353 return formatted_length;
357 static int MvgAutoWrapPrintf(DrawingWand *wand,const char *format,...)
360 buffer[MaxTextExtent];
368 va_start(argp,format);
369 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
370 formatted_length=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
372 formatted_length=vsprintf(buffer,format,argp);
375 *(buffer+sizeof(buffer)-1)='\0';
376 if (formatted_length < 0)
377 ThrowDrawException(DrawError,"UnableToPrint",format)
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);
385 return(formatted_length);
388 static void MvgAppendColor(DrawingWand *wand,const PixelPacket *color)
390 if ((color->red == 0) && (color->green == 0) && (color->blue == 0) &&
391 (color->opacity == (Quantum) TransparentOpacity))
392 (void) MvgPrintf(wand,"none");
396 tuple[MaxTextExtent];
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);
413 static void MvgAppendPointsCommand(DrawingWand *wand,const char *command,
414 const unsigned long number_coordinates,const PointInfo *coordinates)
422 (void) MvgPrintf(wand,"%s",command);
423 for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
425 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g",coordinate->x,coordinate->y);
428 (void) MvgPrintf(wand, "\n");
431 static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine)
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))
443 current=CurrentContext->affine;
444 CurrentContext->affine.sx=current.sx*affine->sx+current.ry*affine->rx;
445 CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
446 CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
447 CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
448 CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+
450 CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
460 % C l e a r D r a w i n g W a n d %
464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
466 % ClearDrawingWand() clear resources associated with the drawing wand.
468 % The format of the ClearDrawingWand method is:
470 % DrawingWand *ClearDrawingWand(DrawingWand *wand)
472 % A description of each parameter follows:
474 % o wand: the drawing wand. to destroy
477 WandExport void ClearDrawingWand(DrawingWand *wand)
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);
494 wand->image=(Image *) NULL;
495 wand->mvg=(char *) NULL;
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;
506 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
507 sizeof(*wand->graphic_context));
508 if (wand->graphic_context == (DrawInfo **) NULL)
510 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
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();
526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530 % C l o n e D r a w i n g W a n d %
534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536 % CloneDrawingWand() makes an exact copy of the specified wand.
538 % The format of the CloneDrawingWand method is:
540 % DrawingWand *CloneDrawingWand(const DrawingWand *wand)
542 % A description of each parameter follows:
544 % o wand: the magick wand.
547 WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
555 assert(wand != (DrawingWand *) NULL);
556 assert(wand->signature == WandSignature);
557 if (wand->debug != MagickFalse)
558 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
559 clone_wand=(DrawingWand *) AcquireAlignedMemory(1,sizeof(*clone_wand));
560 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();
565 (void) FormatMagickString(clone_wand->name,MaxTextExtent,"DrawingWand-%lu",
567 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));
582 for (i=0; i <= (long) wand->index; i++)
583 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;
602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606 % D e s t r o y D r a w i n g W a n d %
610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
616 % The format of the DestroyDrawingWand method is:
618 % DrawingWand *DestroyDrawingWand(DrawingWand *wand)
620 % A description of each parameter follows:
622 % o wand: the drawing wand. to destroy
625 WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
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);
650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654 % D r a w A f f i n e %
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
664 % The format of the DrawAffine method is:
666 % void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
668 % A description of each parameter follows:
670 % o wand: Drawing wand
672 % o affine: Affine matrix parameters
675 WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
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);
683 (void) MvgPrintf(wand,"affine %.15g,%.15g,%.15g,%.15g,%.15g,%.15g\n",
684 affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692 + D r a w A l l o c a t e W a n d %
696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
698 % DrawAllocateWand() allocates an initial drawing wand which is an opaque
699 % handle required by the remaining drawing methods.
701 % The format of the DrawAllocateWand method is:
703 % DrawingWand DrawAllocateWand(const DrawInfo *draw_info,Image *image)
705 % A description of each parameter follows:
707 % o draw_info: Initial drawing defaults. Set to NULL to use defaults.
709 % o image: the image to draw on.
712 WandExport DrawingWand *DrawAllocateWand(const DrawInfo *draw_info,Image *image)
717 wand=NewDrawingWand();
718 if (draw_info != (const DrawInfo *) NULL)
720 CurrentContext=DestroyDrawInfo(CurrentContext);
721 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
723 if (image != (Image *) NULL)
725 wand->image=DestroyImage(wand->image);
726 wand->destroy=MagickFalse;
733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
737 % D r a w A n n o t a t i o n %
741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743 % DrawAnnotation() draws text on the image.
745 % The format of the DrawAnnotation method is:
747 % void DrawAnnotation(DrawingWand *wand,const double x,
748 % const double y,const unsigned char *text)
750 % A description of each parameter follows:
752 % o wand: the drawing wand.
754 % o x: x ordinate to left of text
756 % o y: y ordinate to text baseline
758 % o text: text to draw
761 WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y,
762 const unsigned char *text)
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,'\'');
773 (void) MvgPrintf(wand,"text %.15g,%.15g '%s'\n",x,y,escaped_text);
774 escaped_text=DestroyString(escaped_text);
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
788 % DrawArc() draws an arc falling within a specified bounding rectangle on the
791 % The format of the DrawArc method is:
793 % void DrawArc(DrawingWand *wand,const double sx,const double sy,
794 % const double ex,const double ey,const double sd,const double ed)
796 % A description of each parameter follows:
798 % o wand: the drawing wand.
800 % o sx: starting x ordinate of bounding rectangle
802 % o sy: starting y ordinate of bounding rectangle
804 % o ex: ending x ordinate of bounding rectangle
806 % o ey: ending y ordinate of bounding rectangle
808 % o sd: starting degrees of rotation
810 % o ed: ending degrees of rotation
813 WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy,
814 const double ex,const double ey,const double sd,const double ed)
816 assert(wand != (DrawingWand *) NULL);
817 assert(wand->signature == WandSignature);
818 if (wand->debug != MagickFalse)
819 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
820 (void) MvgPrintf(wand,"arc %.15g,%.15g %.15g,%.15g %.15g,%.15g\n",sx,sy,ex,
825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829 % D r a w B e z i e r %
833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835 % DrawBezier() draws a bezier curve through a set of points on the image.
837 % The format of the DrawBezier method is:
839 % void DrawBezier(DrawingWand *wand,
840 % const unsigned long number_coordinates,const PointInfo *coordinates)
842 % A description of each parameter follows:
844 % o wand: the drawing wand.
846 % o number_coordinates: number of coordinates
848 % o coordinates: coordinates
851 WandExport void DrawBezier(DrawingWand *wand,
852 const unsigned long number_coordinates,const PointInfo *coordinates)
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);
863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
867 % D r a w C i r c l e %
871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
873 % DrawCircle() draws a circle on the image.
875 % The format of the DrawCircle method is:
877 % void DrawCircle(DrawingWand *wand,const double ox,
878 % const double oy,const double px, const double py)
880 % A description of each parameter follows:
882 % o wand: the drawing wand.
884 % o ox: origin x ordinate
886 % o oy: origin y ordinate
888 % o px: perimeter x ordinate
890 % o py: perimeter y ordinate
893 WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
894 const double px,const double py)
896 assert(wand != (DrawingWand *) NULL);
897 assert(wand->signature == WandSignature);
898 if (wand->debug != MagickFalse)
899 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
900 (void) MvgPrintf(wand,"circle %.15g,%.15g %.15g,%.15g\n",ox,oy,px,py);
904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 % D r a w C l e a r E x c e p t i o n %
912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
914 % DrawClearException() clear any exceptions associated with the wand.
916 % The format of the DrawClearException method is:
918 % MagickBooleanType DrawClearException(DrawWand *wand)
920 % A description of each parameter follows:
922 % o wand: the drawing wand.
925 WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
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);
936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
940 % D r a w C o m p o s i t e %
944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946 % DrawComposite() composites an image onto the current image, using the
947 % specified composition operator, specified position, and at the specified
950 % The format of the DrawComposite method is:
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)
957 % A description of each parameter follows:
959 % o wand: the drawing wand.
961 % o compose: composition operator
963 % o x: x ordinate of top left corner
965 % o y: y ordinate of top left corner
967 % o width: Width to resize image to prior to compositing. Specify zero to
968 % use existing width.
970 % o height: Height to resize image to prior to compositing. Specify zero
971 % to use existing height.
973 % o magick_wand: Image to composite is obtained from this wand.
976 WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
977 const CompositeOperator compose,const double x,const double y,
978 const double width,const double height,MagickWand *magick_wand)
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);
1022 blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
1024 image_info=DestroyImageInfo(image_info);
1025 clone_image=DestroyImageList(clone_image);
1026 if (blob == (void *) NULL)
1027 return(MagickFalse);
1029 base64=Base64Encode(blob,blob_length,&encoded_length);
1030 blob=(unsigned char *) RelinquishMagickMemory(blob);
1031 if (base64 == (char *) NULL)
1034 buffer[MaxTextExtent];
1036 (void) FormatMagickString(buffer,MaxTextExtent,"%ld bytes",
1037 (4L*blob_length/3L+4L));
1038 ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
1040 return(MagickFalse);
1042 mode=MagickOptionToMnemonic(MagickComposeOptions,(long) compose);
1043 media_type=MagickToMime(image->magick);
1044 (void) MvgPrintf(wand,"image %s %.15g,%.15g %.15g,%.15g 'data:%s;base64,\n",
1045 mode,x,y,width,height,media_type);
1047 for (i=(long) encoded_length; i > 0; i-=76)
1049 (void) MvgPrintf(wand,"%.76s",p);
1052 (void) MvgPrintf(wand,"\n");
1054 (void) MvgPrintf(wand,"'\n");
1055 media_type=DestroyString(media_type);
1056 base64=DestroyString(base64);
1061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065 % D r a w C o l o r %
1069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 % DrawColor() draws color on image using the current fill color, starting at
1072 % specified position, and using specified paint method. The available paint
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.
1080 % The format of the DrawColor method is:
1082 % void DrawColor(DrawingWand *wand,const double x,const double y,
1083 % const PaintMethod paint_method)
1085 % A description of each parameter follows:
1087 % o wand: the drawing wand.
1093 % o paint_method: paint method.
1096 WandExport void DrawColor(DrawingWand *wand,const double x,const double y,
1097 const PaintMethod paint_method)
1099 assert(wand != (DrawingWand *) NULL);
1100 assert(wand->signature == WandSignature);
1101 if (wand->debug != MagickFalse)
1102 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1103 (void) MvgPrintf(wand,"color %.15g,%.15g '%s'\n",x,y,MagickOptionToMnemonic(
1104 MagickMethodOptions,(long) paint_method));
1108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1112 % D r a w C o m m e n t %
1116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118 % DrawComment() adds a comment to a vector output stream.
1120 % The format of the DrawComment method is:
1122 % void DrawComment(DrawingWand *wand,const char *comment)
1124 % A description of each parameter follows:
1126 % o wand: the drawing wand.
1128 % o comment: comment text
1131 WandExport void DrawComment(DrawingWand *wand,const char *comment)
1133 (void) MvgPrintf(wand,"#%s\n",comment);
1137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1141 % D r a w E l l i p s e %
1145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147 % DrawEllipse() draws an ellipse on the image.
1149 % The format of the DrawEllipse method is:
1151 % void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1152 % const double rx,const double ry,const double start,const double end)
1154 % A description of each parameter follows:
1156 % o wand: the drawing wand.
1158 % o ox: origin x ordinate
1160 % o oy: origin y ordinate
1166 % o start: starting rotation in degrees
1168 % o end: ending rotation in degrees
1171 WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1172 const double rx,const double ry,const double start,const double end)
1174 assert(wand != (DrawingWand *) NULL);
1175 assert(wand->signature == WandSignature);
1176 if (wand->debug != MagickFalse)
1177 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1178 (void) MvgPrintf(wand,"ellipse %.15g,%.15g %.15g,%.15g %.15g,%.15g\n",ox,oy,
1183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1187 % D r a w G e t B o r d e r C o l o r %
1191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 % DrawGetBorderColor() returns the border color used for drawing bordered
1196 % The format of the DrawGetBorderColor method is:
1198 % void DrawGetBorderColor(const DrawingWand *wand,
1199 % PixelWand *border_color)
1201 % A description of each parameter follows:
1203 % o wand: the drawing wand.
1205 % o border_color: Return the border color.
1208 WandExport void DrawGetBorderColor(const DrawingWand *wand,
1209 PixelWand *border_color)
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);
1220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1224 % D r a w G e t C l i p P a t h %
1228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1230 % DrawGetClipPath() obtains the current clipping path ID. The value returned
1231 % must be deallocated by the user when it is no longer needed.
1233 % The format of the DrawGetClipPath method is:
1235 % char *DrawGetClipPath(const DrawingWand *wand)
1237 % A description of each parameter follows:
1239 % o wand: the drawing wand.
1242 WandExport char *DrawGetClipPath(const DrawingWand *wand)
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);
1254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1258 % D r a w G e t C l i p R u l e %
1262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264 % DrawGetClipRule() returns the current polygon fill rule to be used by the
1267 % The format of the DrawGetClipRule method is:
1269 % FillRule DrawGetClipRule(const DrawingWand *wand)
1271 % A description of each parameter follows:
1273 % o wand: the drawing wand.
1276 WandExport FillRule DrawGetClipRule(const DrawingWand *wand)
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);
1286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290 % D r a w G e t C l i p U n i t s %
1294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296 % DrawGetClipUnits() returns the interpretation of clip path units.
1298 % The format of the DrawGetClipUnits method is:
1300 % ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1302 % A description of each parameter follows:
1304 % o wand: the drawing wand.
1307 WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
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);
1317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1321 % D r a w G e t E x c e p t i o n %
1325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1327 % DrawGetException() returns the severity, reason, and description of any
1328 % error that occurs when using other methods in this API.
1330 % The format of the DrawGetException method is:
1332 % char *DrawGetException(const DrawWand *wand,
1333 % ExceptionType *severity)
1335 % A description of each parameter follows:
1337 % o wand: the drawing wand.
1339 % o severity: the severity of the error is returned here.
1342 WandExport char *DrawGetException(const DrawingWand *wand,
1343 ExceptionType *severity)
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",
1360 if (wand->exception->reason != (char *) NULL)
1361 (void) CopyMagickString(description,GetLocaleExceptionMessage(
1362 wand->exception->severity,wand->exception->reason),
1364 if (wand->exception->description != (char *) NULL)
1366 (void) ConcatenateMagickString(description," (",MaxTextExtent);
1367 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
1368 wand->exception->severity,wand->exception->description),
1370 (void) ConcatenateMagickString(description,")",MaxTextExtent);
1372 return(description);
1376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1380 % P i x e l G e t E x c e p t i o n T y p e %
1384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1386 % DrawGetExceptionType() the exception type associated with the wand. If
1387 % no exception has occurred, UndefinedExceptionType is returned.
1389 % The format of the DrawGetExceptionType method is:
1391 % ExceptionType DrawGetExceptionType(const DrawWand *wand)
1393 % A description of each parameter follows:
1395 % o wand: the magick wand.
1398 WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand)
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);
1408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1412 % D r a w G e t F i l l C o l o r %
1416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1418 % DrawGetFillColor() returns the fill color used for drawing filled objects.
1420 % The format of the DrawGetFillColor method is:
1422 % void DrawGetFillColor(const DrawingWand *wand,
1423 % PixelWand *fill_color)
1425 % A description of each parameter follows:
1427 % o wand: the drawing wand.
1429 % o fill_color: Return the fill color.
1432 WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color)
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);
1443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1447 % D r a w G e t F i l l O p a c i t y %
1451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453 % DrawGetFillOpacity() returns the opacity used when drawing using the fill
1454 % color or fill texture. Fully opaque is 1.0.
1456 % The format of the DrawGetFillOpacity method is:
1458 % double DrawGetFillOpacity(const DrawingWand *wand)
1460 % A description of each parameter follows:
1462 % o wand: the drawing wand.
1465 WandExport double DrawGetFillOpacity(const DrawingWand *wand)
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);
1479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1483 % D r a w G e t F i l l R u l e %
1487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1489 % DrawGetFillRule() returns the fill rule used while drawing polygons.
1491 % The format of the DrawGetFillRule method is:
1493 % FillRule DrawGetFillRule(const DrawingWand *wand)
1495 % A description of each parameter follows:
1497 % o wand: the drawing wand.
1500 WandExport FillRule DrawGetFillRule(const DrawingWand *wand)
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);
1510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1514 % D r a w G e t F o n t %
1518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
1522 % when no longer needed.
1524 % The format of the DrawGetFont method is:
1526 % char *DrawGetFont(const DrawingWand *wand)
1528 % A description of each parameter follows:
1530 % o wand: the drawing wand.
1533 WandExport char *DrawGetFont(const DrawingWand *wand)
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);
1545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1549 % D r a w G e t F o n t F a m i l y %
1553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1555 % DrawGetFontFamily() returns the font family to use when annotating with text.
1556 % The value returned must be freed by the user when it is no longer needed.
1558 % The format of the DrawGetFontFamily method is:
1560 % char *DrawGetFontFamily(const DrawingWand *wand)
1562 % A description of each parameter follows:
1564 % o wand: the drawing wand.
1567 WandExport char *DrawGetFontFamily(const DrawingWand *wand)
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);
1579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1583 % D r a w G e t F o n t S i z e %
1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1589 % DrawGetFontSize() returns the font pointsize used when annotating with text.
1591 % The format of the DrawGetFontSize method is:
1593 % double DrawGetFontSize(const DrawingWand *wand)
1595 % A description of each parameter follows:
1597 % o wand: the drawing wand.
1600 WandExport double DrawGetFontSize(const DrawingWand *wand)
1602 assert(wand != (const DrawingWand *) NULL);
1603 assert(wand->signature == WandSignature);
1604 if (wand->debug != MagickFalse)
1605 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1606 return(CurrentContext->pointsize);
1610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1614 % D r a w G e t F o n t S t r e t c h %
1618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1620 % DrawGetFontStretch() returns the font stretch used when annotating with text.
1622 % The format of the DrawGetFontStretch method is:
1624 % StretchType DrawGetFontStretch(const DrawingWand *wand)
1626 % A description of each parameter follows:
1628 % o wand: the drawing wand.
1631 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1633 assert(wand != (const DrawingWand *) NULL);
1634 assert(wand->signature == WandSignature);
1635 if (wand->debug != MagickFalse)
1636 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1637 return(CurrentContext->stretch);
1641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1645 % D r a w G e t F o n t S t y l e %
1649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1651 % DrawGetFontStyle() returns the font style used when annotating with text.
1653 % The format of the DrawGetFontStyle method is:
1655 % StyleType DrawGetFontStyle(const DrawingWand *wand)
1657 % A description of each parameter follows:
1659 % o wand: the drawing wand.
1662 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1664 assert(wand != (const DrawingWand *) NULL);
1665 assert(wand->signature == WandSignature);
1666 if (wand->debug != MagickFalse)
1667 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1668 return(CurrentContext->style);
1672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1676 % D r a w G e t F o n t W e i g h t %
1680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1682 % DrawGetFontWeight() returns the font weight used when annotating with text.
1684 % The format of the DrawGetFontWeight method is:
1686 % unsigned long DrawGetFontWeight(const DrawingWand *wand)
1688 % A description of each parameter follows:
1690 % o wand: the drawing wand.
1693 WandExport unsigned long DrawGetFontWeight(const DrawingWand *wand)
1695 assert(wand != (const DrawingWand *) NULL);
1696 assert(wand->signature == WandSignature);
1697 if (wand->debug != MagickFalse)
1698 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1699 return(CurrentContext->weight);
1703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1707 % D r a w G e t G r a v i t y %
1711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1713 % DrawGetGravity() returns the text placement gravity used when annotating
1716 % The format of the DrawGetGravity method is:
1718 % GravityType DrawGetGravity(const DrawingWand *wand)
1720 % A description of each parameter follows:
1722 % o wand: the drawing wand.
1725 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1727 assert(wand != (const DrawingWand *) NULL);
1728 assert(wand->signature == WandSignature);
1729 if (wand->debug != MagickFalse)
1730 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1731 return(CurrentContext->gravity);
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1739 % D r a w G e t O p a c i t y %
1743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 % DrawGetOpacity() returns the opacity used when drawing with the fill
1746 % or stroke color or texture. Fully opaque is 1.0.
1748 % The format of the DrawGetOpacity method is:
1750 % double DrawGetOpacity(const DrawingWand *wand)
1752 % A description of each parameter follows:
1754 % o wand: the drawing wand.
1757 WandExport double DrawGetOpacity(const DrawingWand *wand)
1762 assert(wand != (const DrawingWand *) NULL);
1763 assert(wand->signature == WandSignature);
1764 if (wand->debug != MagickFalse)
1765 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1766 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->opacity);
1771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1775 % D r a w G e t S t r o k e A n t i a l i a s %
1779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1781 % DrawGetStrokeAntialias() returns the current stroke antialias setting.
1782 % Stroked outlines are antialiased by default. When antialiasing is disabled
1783 % stroked pixels are thresholded to determine if the stroke color or
1784 % underlying canvas color should be used.
1786 % The format of the DrawGetStrokeAntialias method is:
1788 % MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1790 % A description of each parameter follows:
1792 % o wand: the drawing wand.
1795 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1797 assert(wand != (const DrawingWand *) NULL);
1798 assert(wand->signature == WandSignature);
1799 if (wand->debug != MagickFalse)
1800 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1801 return(CurrentContext->stroke_antialias);
1805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1809 % D r a w G e t S t r o k e C o l o r %
1813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1815 % DrawGetStrokeColor() returns the color used for stroking object outlines.
1817 % The format of the DrawGetStrokeColor method is:
1819 % void DrawGetStrokeColor(const DrawingWand *wand,
1820 $ PixelWand *stroke_color)
1822 % A description of each parameter follows:
1824 % o wand: the drawing wand.
1826 % o stroke_color: Return the stroke color.
1829 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1830 PixelWand *stroke_color)
1832 assert(wand != (const DrawingWand *) NULL);
1833 assert(wand->signature == WandSignature);
1834 assert(stroke_color != (PixelWand *) NULL);
1835 if (wand->debug != MagickFalse)
1836 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1837 PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
1841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1845 % D r a w G e t S t r o k e D a s h A r r a y %
1849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1851 % DrawGetStrokeDashArray() returns an array representing the pattern of
1852 % dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
1853 % array must be freed once it is no longer required by the user.
1855 % The format of the DrawGetStrokeDashArray method is:
1857 % double *DrawGetStrokeDashArray(const DrawingWand *wand,
1858 % unsigned long *number_elements)
1860 % A description of each parameter follows:
1862 % o wand: the drawing wand.
1864 % o number_elements: address to place number of elements in dash array
1867 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
1868 unsigned long *number_elements)
1873 register const double
1885 assert(wand != (const DrawingWand *) NULL);
1886 assert(wand->signature == WandSignature);
1887 if (wand->debug != MagickFalse)
1888 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1889 assert(number_elements != (unsigned long *) NULL);
1891 p=CurrentContext->dash_pattern;
1892 if (p != (const double *) NULL)
1896 dash_array=(double *) NULL;
1899 dash_array=(double *) AcquireQuantumMemory((size_t) n,
1900 sizeof(*dash_array));
1901 p=CurrentContext->dash_pattern;
1903 for (i=0; i < (long) n; i++)
1910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1914 % D r a w G e t S t r o k e D a s h O f f s e t %
1918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1920 % DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1923 % The format of the DrawGetStrokeDashOffset method is:
1925 % double DrawGetStrokeDashOffset(const DrawingWand *wand)
1927 % A description of each parameter follows:
1929 % o wand: the drawing wand.
1932 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1934 assert(wand != (const DrawingWand *) NULL);
1935 assert(wand->signature == WandSignature);
1936 if (wand->debug != MagickFalse)
1937 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1938 return(CurrentContext->dash_offset);
1942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1946 % D r a w G e t S t r o k e L i n e C a p %
1950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1952 % DrawGetStrokeLineCap() returns the shape to be used at the end of
1953 % open subpaths when they are stroked. Values of LineCap are
1954 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
1956 % The format of the DrawGetStrokeLineCap method is:
1958 % LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1960 % A description of each parameter follows:
1962 % o wand: the drawing wand.
1965 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1967 assert(wand != (const DrawingWand *) NULL);
1968 assert(wand->signature == WandSignature);
1969 if (wand->debug != MagickFalse)
1970 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1971 return(CurrentContext->linecap);
1975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1979 % D r a w G e t S t r o k e L i n e J o i n %
1983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1985 % DrawGetStrokeLineJoin() returns the shape to be used at the
1986 % corners of paths (or other vector shapes) when they are
1987 % stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
1990 % The format of the DrawGetStrokeLineJoin method is:
1992 % LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
1994 % A description of each parameter follows:
1996 % o wand: the drawing wand.
1999 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2001 assert(wand != (const DrawingWand *) NULL);
2002 assert(wand->signature == WandSignature);
2003 if (wand->debug != MagickFalse)
2004 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2005 return(CurrentContext->linejoin);
2009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2013 % D r a w G e t S t r o k e M i t e r L i m i t %
2017 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2019 % DrawGetStrokeMiterLimit() returns the miter limit. When two line
2020 % segments meet at a sharp angle and miter joins have been specified for
2021 % 'lineJoin', it is possible for the miter to extend far beyond the
2022 % thickness of the line stroking the path. The miterLimit' imposes a
2023 % limit on the ratio of the miter length to the 'lineWidth'.
2025 % The format of the DrawGetStrokeMiterLimit method is:
2027 % unsigned long DrawGetStrokeMiterLimit(const DrawingWand *wand)
2029 % A description of each parameter follows:
2031 % o wand: the drawing wand.
2034 WandExport unsigned long DrawGetStrokeMiterLimit(const DrawingWand *wand)
2036 assert(wand != (const DrawingWand *) NULL);
2037 assert(wand->signature == WandSignature);
2038 if (wand->debug != MagickFalse)
2039 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2040 return CurrentContext->miterlimit;
2044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2048 % D r a w G e t S t r o k e O p a c i t y %
2052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2054 % DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
2056 % The format of the DrawGetStrokeOpacity method is:
2058 % double DrawGetStrokeOpacity(const DrawingWand *wand)
2060 % A description of each parameter follows:
2062 % o wand: the drawing wand.
2065 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2070 assert(wand != (const DrawingWand *) NULL);
2071 assert(wand->signature == WandSignature);
2072 if (wand->debug != MagickFalse)
2073 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2074 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity);
2079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2083 % D r a w G e t S t r o k e W i d t h %
2087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2089 % DrawGetStrokeWidth() returns the width of the stroke used to draw object
2092 % The format of the DrawGetStrokeWidth method is:
2094 % double DrawGetStrokeWidth(const DrawingWand *wand)
2096 % A description of each parameter follows:
2098 % o wand: the drawing wand.
2101 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2103 assert(wand != (const DrawingWand *) NULL);
2104 assert(wand->signature == WandSignature);
2105 if (wand->debug != MagickFalse)
2106 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2107 return(CurrentContext->stroke_width);
2111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2115 % D r a w G e t T e x t A l i g n m e n t %
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2121 % DrawGetTextAlignment() returns the alignment applied when annotating with
2124 % The format of the DrawGetTextAlignment method is:
2126 % AlignType DrawGetTextAlignment(DrawingWand *wand)
2128 % A description of each parameter follows:
2130 % o wand: the drawing wand.
2133 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2135 assert(wand != (const DrawingWand *) NULL);
2136 assert(wand->signature == WandSignature);
2137 if (wand->debug != MagickFalse)
2138 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2139 return(CurrentContext->align);
2143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2147 % D r a w G e t T e x t A n t i a l i a s %
2151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2153 % DrawGetTextAntialias() returns the current text antialias setting, which
2154 % determines whether text is antialiased. Text is antialiased by default.
2156 % The format of the DrawGetTextAntialias method is:
2158 % MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2160 % A description of each parameter follows:
2162 % o wand: the drawing wand.
2165 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2167 assert(wand != (const DrawingWand *) NULL);
2168 assert(wand->signature == WandSignature);
2169 if (wand->debug != MagickFalse)
2170 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2171 return(CurrentContext->text_antialias);
2175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2179 % D r a w G e t T e x t D e c o r a t i o n %
2183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2185 % DrawGetTextDecoration() returns the decoration applied when annotating with
2188 % The format of the DrawGetTextDecoration method is:
2190 % DecorationType DrawGetTextDecoration(DrawingWand *wand)
2192 % A description of each parameter follows:
2194 % o wand: the drawing wand.
2197 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2199 assert(wand != (const DrawingWand *) NULL);
2200 assert(wand->signature == WandSignature);
2201 if (wand->debug != MagickFalse)
2202 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2203 return(CurrentContext->decorate);
2207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2211 % D r a w G e t T e x t E n c o d i n g %
2215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2217 % DrawGetTextEncoding() returns a null-terminated string which specifies the
2218 % code set used for text annotations. The string must be freed by the user
2219 % once it is no longer required.
2221 % The format of the DrawGetTextEncoding method is:
2223 % char *DrawGetTextEncoding(const DrawingWand *wand)
2225 % A description of each parameter follows:
2227 % o wand: the drawing wand.
2230 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2232 assert(wand != (const DrawingWand *) NULL);
2233 assert(wand->signature == WandSignature);
2234 if (wand->debug != MagickFalse)
2235 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2236 if (CurrentContext->encoding != (char *) NULL)
2237 return((char *) AcquireString(CurrentContext->encoding));
2238 return((char *) NULL);
2242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2246 % D r a w G e t T e x t K e r n i n g %
2250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2252 % DrawGetTextKerning() gets the spacing between characters in text.
2254 % The format of the DrawSetFontKerning method is:
2256 % double DrawGetTextKerning(DrawingWand *wand)
2258 % A description of each parameter follows:
2260 % o wand: the drawing wand.
2263 WandExport double DrawGetTextKerning(DrawingWand *wand)
2265 assert(wand != (DrawingWand *) NULL);
2266 assert(wand->signature == WandSignature);
2268 if (wand->debug != MagickFalse)
2269 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2270 return(CurrentContext->kerning);
2274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2278 % 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 %
2282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2284 % DrawGetTextInterwordSpacing() gets the spacing between lines in text.
2286 % The format of the DrawSetFontKerning method is:
2288 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2290 % A description of each parameter follows:
2292 % o wand: the drawing wand.
2295 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2297 assert(wand != (DrawingWand *) NULL);
2298 assert(wand->signature == WandSignature);
2299 if (wand->debug != MagickFalse)
2300 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2301 return(CurrentContext->interline_spacing);
2305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2309 % 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 %
2313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2315 % DrawGetTextInterwordSpacing() gets the spacing between words in text.
2317 % The format of the DrawSetFontKerning method is:
2319 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2321 % A description of each parameter follows:
2323 % o wand: the drawing wand.
2326 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2328 assert(wand != (DrawingWand *) NULL);
2329 assert(wand->signature == WandSignature);
2330 if (wand->debug != MagickFalse)
2331 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2332 return(CurrentContext->interword_spacing);
2336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2340 % D r a w G e t V e c t o r G r a p h i c s %
2344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2346 % DrawGetVectorGraphics() returns a null-terminated string which specifies the
2347 % vector graphics generated by any graphics calls made since the wand was
2348 % instantiated. The string must be freed by the user once it is no longer
2351 % The format of the DrawGetVectorGraphics method is:
2353 % char *DrawGetVectorGraphics(const DrawingWand *wand)
2355 % A description of each parameter follows:
2357 % o wand: the drawing wand.
2361 static inline void SetMagickPixelPacket(const Image *image,
2362 const PixelPacket *color,const IndexPacket *index,MagickPixelPacket *pixel)
2364 pixel->red=(MagickRealType) color->red;
2365 pixel->green=(MagickRealType) color->green;
2366 pixel->blue=(MagickRealType) color->blue;
2367 if (image->matte != MagickFalse)
2368 pixel->opacity=(MagickRealType) color->opacity;
2369 if (((image->colorspace == CMYKColorspace) ||
2370 (image->storage_class == PseudoClass)) &&
2371 (index != (const IndexPacket *) NULL))
2372 pixel->index=(MagickRealType) *index;
2375 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2378 value[MaxTextExtent],
2391 assert(wand != (const DrawingWand *) NULL);
2392 assert(wand->signature == WandSignature);
2393 if (wand->debug != MagickFalse)
2394 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2395 xml_info=NewXMLTreeTag("drawing-wand");
2396 if (xml_info == (XMLTreeInfo *) NULL)
2397 return(char *) NULL;
2398 GetMagickPixelPacket(wand->image,&pixel);
2399 child=AddChildToXMLTree(xml_info,"clip-path",0);
2400 if (child != (XMLTreeInfo *) NULL)
2401 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2402 child=AddChildToXMLTree(xml_info,"clip-units",0);
2403 if (child != (XMLTreeInfo *) NULL)
2405 (void) CopyMagickString(value,MagickOptionToMnemonic(
2406 MagickClipPathOptions,(long) CurrentContext->clip_units),MaxTextExtent);
2407 (void) SetXMLTreeContent(child,value);
2409 child=AddChildToXMLTree(xml_info,"decorate",0);
2410 if (child != (XMLTreeInfo *) NULL)
2412 (void) CopyMagickString(value,MagickOptionToMnemonic(
2413 MagickDecorateOptions,(long) CurrentContext->decorate),MaxTextExtent);
2414 (void) SetXMLTreeContent(child,value);
2416 child=AddChildToXMLTree(xml_info,"encoding",0);
2417 if (child != (XMLTreeInfo *) NULL)
2418 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2419 child=AddChildToXMLTree(xml_info,"fill",0);
2420 if (child != (XMLTreeInfo *) NULL)
2422 if (CurrentContext->fill.opacity != OpaqueOpacity)
2423 pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2424 MagickTrue : MagickFalse;
2425 SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2426 (const IndexPacket *) NULL,&pixel);
2427 GetColorTuple(&pixel,MagickTrue,value);
2428 (void) SetXMLTreeContent(child,value);
2430 child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2431 if (child != (XMLTreeInfo *) NULL)
2433 (void) FormatMagickString(value,MaxTextExtent,"%.15g",
2434 (double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity));
2435 (void) SetXMLTreeContent(child,value);
2437 child=AddChildToXMLTree(xml_info,"fill-rule",0);
2438 if (child != (XMLTreeInfo *) NULL)
2440 (void) CopyMagickString(value,MagickOptionToMnemonic(
2441 MagickFillRuleOptions,(long) CurrentContext->fill_rule),MaxTextExtent);
2442 (void) SetXMLTreeContent(child,value);
2444 child=AddChildToXMLTree(xml_info,"font",0);
2445 if (child != (XMLTreeInfo *) NULL)
2446 (void) SetXMLTreeContent(child,CurrentContext->font);
2447 child=AddChildToXMLTree(xml_info,"font-family",0);
2448 if (child != (XMLTreeInfo *) NULL)
2449 (void) SetXMLTreeContent(child,CurrentContext->family);
2450 child=AddChildToXMLTree(xml_info,"font-size",0);
2451 if (child != (XMLTreeInfo *) NULL)
2453 (void) FormatMagickString(value,MaxTextExtent,"%.15g",
2454 CurrentContext->pointsize);
2455 (void) SetXMLTreeContent(child,value);
2457 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2458 if (child != (XMLTreeInfo *) NULL)
2460 (void) CopyMagickString(value,MagickOptionToMnemonic(
2461 MagickStretchOptions,(long) CurrentContext->stretch),MaxTextExtent);
2462 (void) SetXMLTreeContent(child,value);
2464 child=AddChildToXMLTree(xml_info,"font-style",0);
2465 if (child != (XMLTreeInfo *) NULL)
2467 (void) CopyMagickString(value,MagickOptionToMnemonic(
2468 MagickStyleOptions,(long) CurrentContext->style),MaxTextExtent);
2469 (void) SetXMLTreeContent(child,value);
2471 child=AddChildToXMLTree(xml_info,"font-weight",0);
2472 if (child != (XMLTreeInfo *) NULL)
2474 (void) FormatMagickString(value,MaxTextExtent,"%lu",
2475 CurrentContext->weight);
2476 (void) SetXMLTreeContent(child,value);
2478 child=AddChildToXMLTree(xml_info,"gravity",0);
2479 if (child != (XMLTreeInfo *) NULL)
2481 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickGravityOptions,
2482 (long) CurrentContext->gravity),MaxTextExtent);
2483 (void) SetXMLTreeContent(child,value);
2485 child=AddChildToXMLTree(xml_info,"stroke",0);
2486 if (child != (XMLTreeInfo *) NULL)
2488 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2489 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2490 MagickTrue : MagickFalse;
2491 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2492 (const IndexPacket *) NULL,&pixel);
2493 GetColorTuple(&pixel,MagickTrue,value);
2494 (void) SetXMLTreeContent(child,value);
2496 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2497 if (child != (XMLTreeInfo *) NULL)
2499 (void) FormatMagickString(value,MaxTextExtent,"%d",
2500 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2501 (void) SetXMLTreeContent(child,value);
2503 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2504 if ((child != (XMLTreeInfo *) NULL) &&
2505 (CurrentContext->dash_pattern != (double *) NULL))
2510 dash_pattern=AcquireString((char *) NULL);
2511 for (i=0; CurrentContext->dash_pattern[i] != 0.0; i++)
2514 (void) ConcatenateString(&dash_pattern,",");
2515 (void) FormatMagickString(value,MaxTextExtent,"%.15g",
2516 CurrentContext->dash_pattern[i]);
2517 (void) ConcatenateString(&dash_pattern,value);
2519 (void) SetXMLTreeContent(child,dash_pattern);
2520 dash_pattern=DestroyString(dash_pattern);
2522 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2523 if (child != (XMLTreeInfo *) NULL)
2525 (void) FormatMagickString(value,MaxTextExtent,"%.15g",
2526 CurrentContext->dash_offset);
2527 (void) SetXMLTreeContent(child,value);
2529 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2530 if (child != (XMLTreeInfo *) NULL)
2532 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickLineCapOptions,
2533 (long) CurrentContext->linecap),MaxTextExtent);
2534 (void) SetXMLTreeContent(child,value);
2536 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2537 if (child != (XMLTreeInfo *) NULL)
2539 (void) CopyMagickString(value,MagickOptionToMnemonic(
2540 MagickLineJoinOptions,(long) CurrentContext->linejoin),MaxTextExtent);
2541 (void) SetXMLTreeContent(child,value);
2543 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2544 if (child != (XMLTreeInfo *) NULL)
2546 (void) FormatMagickString(value,MaxTextExtent,"%lu",
2547 CurrentContext->miterlimit);
2548 (void) SetXMLTreeContent(child,value);
2550 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2551 if (child != (XMLTreeInfo *) NULL)
2553 (void) FormatMagickString(value,MaxTextExtent,"%.15g",
2554 (double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity));
2555 (void) SetXMLTreeContent(child,value);
2557 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2558 if (child != (XMLTreeInfo *) NULL)
2560 (void) FormatMagickString(value,MaxTextExtent,"%.15g",
2561 CurrentContext->stroke_width);
2562 (void) SetXMLTreeContent(child,value);
2564 child=AddChildToXMLTree(xml_info,"text-align",0);
2565 if (child != (XMLTreeInfo *) NULL)
2567 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickAlignOptions,
2568 (long) CurrentContext->align),MaxTextExtent);
2569 (void) SetXMLTreeContent(child,value);
2571 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2572 if (child != (XMLTreeInfo *) NULL)
2574 (void) FormatMagickString(value,MaxTextExtent,"%d",
2575 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2576 (void) SetXMLTreeContent(child,value);
2578 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2579 if (child != (XMLTreeInfo *) NULL)
2581 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2582 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2583 MagickTrue : MagickFalse;
2584 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2585 (const IndexPacket *) NULL,&pixel);
2586 GetColorTuple(&pixel,MagickTrue,value);
2587 (void) SetXMLTreeContent(child,value);
2589 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2590 if (child != (XMLTreeInfo *) NULL)
2591 (void) SetXMLTreeContent(child,wand->mvg);
2592 xml=XMLTreeInfoToXML(xml_info);
2593 xml_info=DestroyXMLTree(xml_info);
2598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2602 % D r a w G e t T e x t U n d e r C o l o r %
2606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2608 % DrawGetTextUnderColor() returns the color of a background rectangle
2609 % to place under text annotations.
2611 % The format of the DrawGetTextUnderColor method is:
2613 % void DrawGetTextUnderColor(const DrawingWand *wand,
2614 % PixelWand *under_color)
2616 % A description of each parameter follows:
2618 % o wand: the drawing wand.
2620 % o under_color: Return the under color.
2623 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2624 PixelWand *under_color)
2626 assert(wand != (const DrawingWand *) NULL);
2627 assert(wand->signature == WandSignature);
2628 assert(under_color != (PixelWand *) NULL);
2629 if (wand->debug != MagickFalse)
2630 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2631 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2645 % DrawLine() draws a line on the image using the current stroke color,
2646 % stroke opacity, and stroke width.
2648 % The format of the DrawLine method is:
2650 % void DrawLine(DrawingWand *wand,const double sx,const double sy,
2651 % const double ex,const double ey)
2653 % A description of each parameter follows:
2655 % o wand: the drawing wand.
2657 % o sx: starting x ordinate
2659 % o sy: starting y ordinate
2661 % o ex: ending x ordinate
2663 % o ey: ending y ordinate
2666 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2667 const double ex,const double ey)
2669 assert(wand != (DrawingWand *) NULL);
2670 assert(wand->signature == WandSignature);
2671 if (wand->debug != MagickFalse)
2672 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2673 (void) MvgPrintf(wand,"line %.15g,%.15g %.15g,%.15g\n",sx,sy,ex,ey);
2677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2681 % D r a w M a t t e %
2685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2687 % DrawMatte() paints on the image's opacity channel in order to set effected
2688 % pixels to transparent.
2689 % to influence the opacity of pixels. The available paint
2692 % PointMethod: Select the target pixel
2693 % ReplaceMethod: Select any pixel that matches the target pixel.
2694 % FloodfillMethod: Select the target pixel and matching neighbors.
2695 % FillToBorderMethod: Select the target pixel and neighbors not matching
2697 % ResetMethod: Select all pixels.
2699 % The format of the DrawMatte method is:
2701 % void DrawMatte(DrawingWand *wand,const double x,const double y,
2702 % const PaintMethod paint_method)
2704 % A description of each parameter follows:
2706 % o wand: the drawing wand.
2712 % o paint_method: paint method.
2715 WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2716 const PaintMethod paint_method)
2718 assert(wand != (DrawingWand *) NULL);
2719 assert(wand->signature == WandSignature);
2720 if (wand->debug != MagickFalse)
2721 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2722 (void) MvgPrintf(wand,"matte %.15g,%.15g '%s'\n",x,y,MagickOptionToMnemonic(
2723 MagickMethodOptions,(long) paint_method));
2727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2731 % D r a w P a t h C l o s e %
2735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2737 % DrawPathClose() adds a path element to the current path which closes the
2738 % current subpath by drawing a straight line from the current point to the
2739 % current subpath's most recent starting point (usually, the most recent
2742 % The format of the DrawPathClose method is:
2744 % void DrawPathClose(DrawingWand *wand)
2746 % A description of each parameter follows:
2748 % o wand: the drawing wand.
2751 WandExport void DrawPathClose(DrawingWand *wand)
2753 assert(wand != (DrawingWand *) NULL);
2754 assert(wand->signature == WandSignature);
2755 if (wand->debug != MagickFalse)
2756 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2757 (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2766 % D r a w P a t h C u r v e T o A b s o l u t e %
2770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2772 % DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2773 % point to (x,y) using (x1,y1) as the control point at the beginning of
2774 % the curve and (x2,y2) as the control point at the end of the curve using
2775 % absolute coordinates. At the end of the command, the new current point
2776 % becomes the final (x,y) coordinate pair used in the polybezier.
2778 % The format of the DrawPathCurveToAbsolute method is:
2780 % void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2781 % const double y1,const double x2,const double y2,const double x,
2784 % A description of each parameter follows:
2786 % o wand: the drawing wand.
2788 % o x1: x ordinate of control point for curve beginning
2790 % o y1: y ordinate of control point for curve beginning
2792 % o x2: x ordinate of control point for curve ending
2794 % o y2: y ordinate of control point for curve ending
2796 % o x: x ordinate of the end of the curve
2798 % o y: y ordinate of the end of the curve
2802 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2803 const double x1,const double y1,const double x2,const double y2,
2804 const double x,const double y)
2806 assert(wand != (DrawingWand *) NULL);
2807 assert(wand->signature == WandSignature);
2808 if (wand->debug != MagickFalse)
2809 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2810 if ((wand->path_operation != PathCurveToOperation) ||
2811 (wand->path_mode != mode))
2813 wand->path_operation=PathCurveToOperation;
2814 wand->path_mode=mode;
2815 (void) MvgAutoWrapPrintf(wand, "%c%.15g,%.15g %.15g,%.15g %.15g,%.15g",
2816 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2819 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g %.15g,%.15g %.15g,%.15g",x1,y1,
2823 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2824 const double y1,const double x2,const double y2,const double x,const double y)
2826 assert(wand != (DrawingWand *) NULL);
2827 assert(wand->signature == WandSignature);
2828 if (wand->debug != MagickFalse)
2829 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2830 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2838 % D r a w P a t h C u r v e T o R e l a t i v e %
2842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2844 % DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2845 % point to (x,y) using (x1,y1) as the control point at the beginning of
2846 % the curve and (x2,y2) as the control point at the end of the curve using
2847 % relative coordinates. At the end of the command, the new current point
2848 % becomes the final (x,y) coordinate pair used in the polybezier.
2850 % The format of the DrawPathCurveToRelative method is:
2852 % void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2853 % const double y1,const double x2,const double y2,const double x,
2856 % A description of each parameter follows:
2858 % o wand: the drawing wand.
2860 % o x1: x ordinate of control point for curve beginning
2862 % o y1: y ordinate of control point for curve beginning
2864 % o x2: x ordinate of control point for curve ending
2866 % o y2: y ordinate of control point for curve ending
2868 % o x: x ordinate of the end of the curve
2870 % o y: y ordinate of the end of the curve
2873 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2874 const double y1,const double x2,const double y2,const double x,const double y)
2876 assert(wand != (DrawingWand *) NULL);
2877 assert(wand->signature == WandSignature);
2878 if (wand->debug != MagickFalse)
2879 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2880 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2888 % 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 %
2892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2894 % DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2895 % from the current point to (x,y) using (x1,y1) as the control point using
2896 % absolute coordinates. At the end of the command, the new current point
2897 % becomes the final (x,y) coordinate pair used in the polybezier.
2899 % The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2901 % void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2902 % const double x1,const double y1,onst double x,const double y)
2904 % A description of each parameter follows:
2906 % o wand: the drawing wand.
2908 % o x1: x ordinate of the control point
2910 % o y1: y ordinate of the control point
2912 % o x: x ordinate of final point
2914 % o y: y ordinate of final point
2918 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2919 const PathMode mode,const double x1,double y1,const double x,const double y)
2921 assert(wand != (DrawingWand *) NULL);
2922 assert(wand->signature == WandSignature);
2923 if (wand->debug != MagickFalse)
2924 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2925 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2926 (wand->path_mode != mode))
2928 wand->path_operation=PathCurveToQuadraticBezierOperation;
2929 wand->path_mode=mode;
2930 (void) MvgAutoWrapPrintf(wand, "%c%.15g,%.15g %.15g,%.15g",
2931 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
2934 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g %.15g,%.15g",x1,y1,x,y);
2937 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2938 const double x1,const double y1,const double x,const double y)
2940 assert(wand != (DrawingWand *) NULL);
2941 assert(wand->signature == WandSignature);
2942 if (wand->debug != MagickFalse)
2943 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2944 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
2948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2952 % 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
2956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2958 % DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
2959 % from the current point to (x,y) using (x1,y1) as the control point using
2960 % relative coordinates. At the end of the command, the new current point
2961 % becomes the final (x,y) coordinate pair used in the polybezier.
2963 % The format of the DrawPathCurveToQuadraticBezierRelative method is:
2965 % void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2966 % const double x1,const double y1,const double x,const double y)
2968 % A description of each parameter follows:
2970 % o wand: the drawing wand.
2972 % o x1: x ordinate of the control point
2974 % o y1: y ordinate of the control point
2976 % o x: x ordinate of final point
2978 % o y: y ordinate of final point
2981 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2982 const double x1,const double y1,const double x,const double y)
2984 assert(wand != (DrawingWand *) NULL);
2985 assert(wand->signature == WandSignature);
2986 if (wand->debug != MagickFalse)
2987 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2988 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
2992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2996 % 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 %
3000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3002 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3003 % Bezier curve (using absolute coordinates) from the current point to
3004 % (x,y). The control point is assumed to be the reflection of the
3005 % control point on the previous command relative to the current
3006 % point. (If there is no previous command or if the previous command was
3007 % not a DrawPathCurveToQuadraticBezierAbsolute,
3008 % DrawPathCurveToQuadraticBezierRelative,
3009 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3010 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3011 % is coincident with the current point.). At the end of the command, the
3012 % new current point becomes the final (x,y) coordinate pair used in the
3015 % The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3017 % void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3018 % DrawingWand *wand,const double x,const double y)
3020 % A description of each parameter follows:
3022 % o wand: the drawing wand.
3024 % o x: x ordinate of final point
3026 % o y: y ordinate of final point
3030 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3031 const PathMode mode,const double x,const double y)
3033 assert(wand != (DrawingWand *) NULL);
3034 assert(wand->signature == WandSignature);
3035 if (wand->debug != MagickFalse)
3036 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3037 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3038 (wand->path_mode != mode))
3040 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3041 wand->path_mode=mode;
3042 (void) MvgAutoWrapPrintf(wand,"%c%.15g,%.15g",mode == AbsolutePathMode ?
3046 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g",x,y);
3049 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3050 const double x,const double y)
3052 assert(wand != (DrawingWand *) NULL);
3053 assert(wand->signature == WandSignature);
3054 if (wand->debug != MagickFalse)
3055 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3056 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3064 % 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 %
3068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3070 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3071 % curve (using relative coordinates) from the current point to (x,y). The
3072 % control point is assumed to be the reflection of the control point on the
3073 % previous command relative to the current point. (If there is no previous
3074 % command or if the previous command was not a
3075 % DrawPathCurveToQuadraticBezierAbsolute,
3076 % DrawPathCurveToQuadraticBezierRelative,
3077 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3078 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3079 % coincident with the current point.). At the end of the command, the new
3080 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3082 % The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3084 % void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3085 % const double x,const double y)
3087 % A description of each parameter follows:
3089 % o wand: the drawing wand.
3091 % o x: x ordinate of final point
3093 % o y: y ordinate of final point
3096 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3097 const double x,const double y)
3099 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3107 % 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 %
3111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3113 % DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3114 % current point to (x,y) using absolute coordinates. The first control
3115 % point is assumed to be the reflection of the second control point on
3116 % the previous command relative to the current point. (If there is no
3117 % previous command or if the previous command was not an
3118 % DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3119 % DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3120 % the first control point is coincident with the current point.) (x2,y2)
3121 % is the second control point (i.e., the control point at the end of the
3122 % curve). At the end of the command, the new current point becomes the
3123 % final (x,y) coordinate pair used in the polybezier.
3125 % The format of the DrawPathCurveToSmoothAbsolute method is:
3127 % void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3128 % const double x2const double y2,const double x,const double y)
3130 % A description of each parameter follows:
3132 % o wand: the drawing wand.
3134 % o x2: x ordinate of second control point
3136 % o y2: y ordinate of second control point
3138 % o x: x ordinate of termination point
3140 % o y: y ordinate of termination point
3144 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3145 const double x2,const double y2,const double x,const double y)
3147 assert(wand != (DrawingWand *) NULL);
3148 assert(wand->signature == WandSignature);
3149 if (wand->debug != MagickFalse)
3150 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3151 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3152 (wand->path_mode != mode))
3154 wand->path_operation=PathCurveToSmoothOperation;
3155 wand->path_mode=mode;
3156 (void) MvgAutoWrapPrintf(wand,"%c%.15g,%.15g %.15g,%.15g",
3157 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
3160 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g %.15g,%.15g",x2,y2,x,y);
3163 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3164 const double y2,const double x,const double y)
3166 assert(wand != (DrawingWand *) NULL);
3167 assert(wand->signature == WandSignature);
3168 if (wand->debug != MagickFalse)
3169 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3170 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3178 % 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 %
3182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3184 % DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3185 % point to (x,y) using relative coordinates. The first control point is
3186 % assumed to be the reflection of the second control point on the previous
3187 % command relative to the current point. (If there is no previous command or
3188 % if the previous command was not an DrawPathCurveToAbsolute,
3189 % DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3190 % DrawPathCurveToSmoothRelative, assume the first control point is coincident
3191 % with the current point.) (x2,y2) is the second control point (i.e., the
3192 % control point at the end of the curve). At the end of the command, the new
3193 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3195 % The format of the DrawPathCurveToSmoothRelative method is:
3197 % void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3198 % const double x2,const double y2,const double x,const double y)
3200 % A description of each parameter follows:
3202 % o wand: the drawing wand.
3204 % o x2: x ordinate of second control point
3206 % o y2: y ordinate of second control point
3208 % o x: x ordinate of termination point
3210 % o y: y ordinate of termination point
3213 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3214 const double y2,const double x,const double y)
3216 assert(wand != (DrawingWand *) NULL);
3217 assert(wand->signature == WandSignature);
3218 if (wand->debug != MagickFalse)
3219 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3220 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3228 % 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 %
3232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3234 % DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3235 % to (x, y) using absolute coordinates. The size and orientation of the
3236 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3237 % indicates how the ellipse as a whole is rotated relative to the current
3238 % coordinate system. The center (cx, cy) of the ellipse is calculated
3239 % automagically to satisfy the constraints imposed by the other parameters.
3240 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3241 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3242 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3243 % clock-wise rotation.
3245 % The format of the DrawPathEllipticArcAbsolute method is:
3247 % void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3248 % const double rx,const double ry,const double x_axis_rotation,
3249 % const MagickBooleanType large_arc_flag,
3250 % const MagickBooleanType sweep_flag,const double x,const double y)
3252 % A description of each parameter follows:
3254 % o wand: the drawing wand.
3260 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3261 % relative to the current coordinate system
3263 % o large_arc_flag: If non-zero (true) then draw the larger of the
3266 % o sweep_flag: If non-zero (true) then draw the arc matching a
3267 % clock-wise rotation
3272 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3273 const double rx,const double ry,const double x_axis_rotation,
3274 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3275 const double x,const double y)
3277 assert(wand != (DrawingWand *) NULL);
3278 assert(wand->signature == WandSignature);
3279 if (wand->debug != MagickFalse)
3280 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3281 if ((wand->path_operation != PathEllipticArcOperation) ||
3282 (wand->path_mode != mode))
3284 wand->path_operation=PathEllipticArcOperation;
3285 wand->path_mode=mode;
3286 (void) MvgAutoWrapPrintf(wand, "%c%.15g,%.15g %.15g %u %u %.15g,%.15g",
3287 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3288 large_arc_flag,sweep_flag,x,y);
3291 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g %.15g %u %u %.15g,%.15g",rx,ry,
3292 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3295 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3296 const double ry,const double x_axis_rotation,
3297 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3298 const double x,const double y)
3300 assert(wand != (DrawingWand *) NULL);
3301 assert(wand->signature == WandSignature);
3302 if (wand->debug != MagickFalse)
3303 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3304 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3305 large_arc_flag,sweep_flag,x,y);
3309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3313 % 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 %
3317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3319 % DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3320 % to (x, y) using relative coordinates. The size and orientation of the
3321 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3322 % indicates how the ellipse as a whole is rotated relative to the current
3323 % coordinate system. The center (cx, cy) of the ellipse is calculated
3324 % automagically to satisfy the constraints imposed by the other parameters.
3325 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3326 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3327 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3328 % clock-wise rotation.
3330 % The format of the DrawPathEllipticArcRelative method is:
3332 % void DrawPathEllipticArcRelative(DrawingWand *wand,
3333 % const double rx,const double ry,const double x_axis_rotation,
3334 % const MagickBooleanType large_arc_flag,
3335 % const MagickBooleanType sweep_flag,const double x,const double y)
3337 % A description of each parameter follows:
3339 % o wand: the drawing wand.
3345 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3346 % relative to the current coordinate system
3348 % o large_arc_flag: If non-zero (true) then draw the larger of the
3351 % o sweep_flag: If non-zero (true) then draw the arc matching a
3352 % clock-wise rotation
3355 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3356 const double ry,const double x_axis_rotation,
3357 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3358 const double x,const double y)
3360 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3361 large_arc_flag,sweep_flag,x,y);
3365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3369 % D r a w P a t h F i n i s h %
3373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3375 % DrawPathFinish() terminates the current path.
3377 % The format of the DrawPathFinish method is:
3379 % void DrawPathFinish(DrawingWand *wand)
3381 % A description of each parameter follows:
3383 % o wand: the drawing wand.
3386 WandExport void DrawPathFinish(DrawingWand *wand)
3388 assert(wand != (DrawingWand *) NULL);
3389 assert(wand->signature == WandSignature);
3390 if (wand->debug != MagickFalse)
3391 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3392 (void) MvgPrintf(wand,"'\n");
3393 wand->path_operation=PathDefaultOperation;
3394 wand->path_mode=DefaultPathMode;
3398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3402 % D r a w P a t h L i n e T o A b s o l u t e %
3406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3408 % DrawPathLineToAbsolute() draws a line path from the current point to the
3409 % given coordinate using absolute coordinates. The coordinate then becomes
3410 % the new current point.
3412 % The format of the DrawPathLineToAbsolute method is:
3414 % void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3417 % A description of each parameter follows:
3419 % o wand: the drawing wand.
3421 % o x: target x ordinate
3423 % o y: target y ordinate
3426 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3427 const double x,const double y)
3429 assert(wand != (DrawingWand *) NULL);
3430 assert(wand->signature == WandSignature);
3431 if (wand->debug != MagickFalse)
3432 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3433 if ((wand->path_operation != PathLineToOperation) ||
3434 (wand->path_mode != mode))
3436 wand->path_operation=PathLineToOperation;
3437 wand->path_mode=mode;
3438 (void) MvgAutoWrapPrintf(wand,"%c%.15g,%.15g",mode == AbsolutePathMode ?
3442 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g",x,y);
3445 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3448 assert(wand != (DrawingWand *) NULL);
3449 assert(wand->signature == WandSignature);
3450 if (wand->debug != MagickFalse)
3451 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3452 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3460 % D r a w P a t h L i n e T o R e l a t i v e %
3464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3466 % DrawPathLineToRelative() draws a line path from the current point to the
3467 % given coordinate using relative coordinates. The coordinate then becomes
3468 % the new current point.
3470 % The format of the DrawPathLineToRelative method is:
3472 % void DrawPathLineToRelative(DrawingWand *wand,const double x,
3475 % A description of each parameter follows:
3477 % o wand: the drawing wand.
3479 % o x: target x ordinate
3481 % o y: target y ordinate
3484 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3487 assert(wand != (DrawingWand *) NULL);
3488 assert(wand->signature == WandSignature);
3489 if (wand->debug != MagickFalse)
3490 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3491 DrawPathLineTo(wand,RelativePathMode,x,y);
3495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3499 % 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 %
3503 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3505 % DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3506 % current point to the target point using absolute coordinates. The target
3507 % point then becomes the new current point.
3509 % The format of the DrawPathLineToHorizontalAbsolute method is:
3511 % void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3512 % const PathMode mode,const double x)
3514 % A description of each parameter follows:
3516 % o wand: the drawing wand.
3518 % o x: target x ordinate
3522 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3525 assert(wand != (DrawingWand *) NULL);
3526 assert(wand->signature == WandSignature);
3527 if (wand->debug != MagickFalse)
3528 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3529 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3530 (wand->path_mode != mode))
3532 wand->path_operation=PathLineToHorizontalOperation;
3533 wand->path_mode=mode;
3534 (void) MvgAutoWrapPrintf(wand,"%c%.15g",mode == AbsolutePathMode ?
3538 (void) MvgAutoWrapPrintf(wand," %.15g",x);
3541 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3544 assert(wand != (DrawingWand *) NULL);
3545 assert(wand->signature == WandSignature);
3546 if (wand->debug != MagickFalse)
3547 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3548 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3552 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3556 % 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 %
3560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3562 % DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3563 % current point to the target point using relative coordinates. The target
3564 % point then becomes the new current point.
3566 % The format of the DrawPathLineToHorizontalRelative method is:
3568 % void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3571 % A description of each parameter follows:
3573 % o wand: the drawing wand.
3575 % o x: target x ordinate
3578 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3581 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3589 % 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 %
3593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3595 % DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3596 % current point to the target point using absolute coordinates. The target
3597 % point then becomes the new current point.
3599 % The format of the DrawPathLineToVerticalAbsolute method is:
3601 % void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3604 % A description of each parameter follows:
3606 % o wand: the drawing wand.
3608 % o y: target y ordinate
3612 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3615 assert(wand != (DrawingWand *) NULL);
3616 assert(wand->signature == WandSignature);
3617 if (wand->debug != MagickFalse)
3618 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3619 if ((wand->path_operation != PathLineToVerticalOperation) ||
3620 (wand->path_mode != mode))
3622 wand->path_operation=PathLineToVerticalOperation;
3623 wand->path_mode=mode;
3624 (void) MvgAutoWrapPrintf(wand,"%c%.15g",mode == AbsolutePathMode ?
3628 (void) MvgAutoWrapPrintf(wand," %.15g",y);
3631 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3633 assert(wand != (DrawingWand *) NULL);
3634 assert(wand->signature == WandSignature);
3635 if (wand->debug != MagickFalse)
3636 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3637 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3645 % 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 %
3649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3651 % DrawPathLineToVerticalRelative() draws a vertical line path from the
3652 % current point to the target point using relative coordinates. The target
3653 % point then becomes the new current point.
3655 % The format of the DrawPathLineToVerticalRelative method is:
3657 % void DrawPathLineToVerticalRelative(DrawingWand *wand,
3660 % A description of each parameter follows:
3662 % o wand: the drawing wand.
3664 % o y: target y ordinate
3667 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3669 assert(wand != (DrawingWand *) NULL);
3670 assert(wand->signature == WandSignature);
3671 if (wand->debug != MagickFalse)
3672 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3673 DrawPathLineToVertical(wand,RelativePathMode,y);
3676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3680 % D r a w P a t h M o v e T o A b s o l u t e %
3684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3686 % DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3687 % using absolute coordinates. The current point then becomes the
3688 % specified coordinate.
3690 % The format of the DrawPathMoveToAbsolute method is:
3692 % void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3695 % A description of each parameter follows:
3697 % o wand: the drawing wand.
3699 % o x: target x ordinate
3701 % o y: target y ordinate
3705 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3708 assert(wand != (DrawingWand *) NULL);
3709 assert(wand->signature == WandSignature);
3710 if (wand->debug != MagickFalse)
3711 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3712 if ((wand->path_operation != PathMoveToOperation) ||
3713 (wand->path_mode != mode))
3715 wand->path_operation=PathMoveToOperation;
3716 wand->path_mode=mode;
3717 (void) MvgAutoWrapPrintf(wand,"%c%.15g,%.15g",mode == AbsolutePathMode ?
3721 (void) MvgAutoWrapPrintf(wand," %.15g,%.15g",x,y);
3724 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3727 assert(wand != (DrawingWand *) NULL);
3728 assert(wand->signature == WandSignature);
3729 if (wand->debug != MagickFalse)
3730 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3731 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3739 % D r a w P a t h M o v e T o R e l a t i v e %
3743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3745 % DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3746 % relative coordinates. The current point then becomes the specified
3749 % The format of the DrawPathMoveToRelative method is:
3751 % void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3754 % A description of each parameter follows:
3756 % o wand: the drawing wand.
3758 % o x: target x ordinate
3760 % o y: target y ordinate
3763 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3766 assert(wand != (DrawingWand *) NULL);
3767 assert(wand->signature == WandSignature);
3768 if (wand->debug != MagickFalse)
3769 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3770 DrawPathMoveTo(wand,RelativePathMode,x,y);
3774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3778 % D r a w P a t h S t a r t %
3782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3784 % DrawPathStart() declares the start of a path drawing list which is terminated
3785 % by a matching DrawPathFinish() command. All other DrawPath commands must
3786 % be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3787 % is because path drawing commands are subordinate commands and they do not
3788 % function by themselves.
3790 % The format of the DrawPathStart method is:
3792 % void DrawPathStart(DrawingWand *wand)
3794 % A description of each parameter follows:
3796 % o wand: the drawing wand.
3799 WandExport void DrawPathStart(DrawingWand *wand)
3801 assert(wand != (DrawingWand *) NULL);
3802 assert(wand->signature == WandSignature);
3803 if (wand->debug != MagickFalse)
3804 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3805 (void) MvgPrintf(wand,"path '");
3806 wand->path_operation=PathDefaultOperation;
3807 wand->path_mode=DefaultPathMode;
3811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3815 % D r a w P o i n t %
3819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3821 % DrawPoint() draws a point using the current fill color.
3823 % The format of the DrawPoint method is:
3825 % void DrawPoint(DrawingWand *wand,const double x,const double y)
3827 % A description of each parameter follows:
3829 % o wand: the drawing wand.
3831 % o x: target x coordinate
3833 % o y: target y coordinate
3836 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3838 assert(wand != (DrawingWand *) NULL);
3839 assert(wand->signature == WandSignature);
3840 if (wand->debug != MagickFalse)
3841 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3842 (void) MvgPrintf(wand,"point %.15g,%.15g\n",x,y);
3846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3850 % D r a w P o l y g o n %
3854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3856 % DrawPolygon() draws a polygon using the current stroke, stroke width, and
3857 % fill color or texture, using the specified array of coordinates.
3859 % The format of the DrawPolygon method is:
3861 % void DrawPolygon(DrawingWand *wand,
3862 % const unsigned long number_coordinates,const PointInfo *coordinates)
3864 % A description of each parameter follows:
3866 % o wand: the drawing wand.
3868 % o number_coordinates: number of coordinates
3870 % o coordinates: coordinate array
3873 WandExport void DrawPolygon(DrawingWand *wand,
3874 const unsigned long number_coordinates,const PointInfo *coordinates)
3876 assert(wand != (DrawingWand *) NULL);
3877 assert(wand->signature == WandSignature);
3878 if (wand->debug != MagickFalse)
3879 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3880 MvgAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3888 % D r a w P o l y l i n e %
3892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3894 % DrawPolyline() draws a polyline using the current stroke, stroke width, and
3895 % fill color or texture, using the specified array of coordinates.
3897 % The format of the DrawPolyline method is:
3899 % void DrawPolyline(DrawingWand *wand,
3900 % const unsigned long number_coordinates,const PointInfo *coordinates)
3902 % A description of each parameter follows:
3904 % o wand: the drawing wand.
3906 % o number_coordinates: number of coordinates
3908 % o coordinates: coordinate array
3911 WandExport void DrawPolyline(DrawingWand *wand,
3912 const unsigned long number_coordinates,const PointInfo *coordinates)
3914 assert(wand != (DrawingWand *) NULL);
3915 assert(wand->signature == WandSignature);
3916 if (wand->debug != MagickFalse)
3917 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3918 MvgAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
3922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3926 % D r a w P o p C l i p P a t h %
3930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3932 % DrawPopClipPath() terminates a clip path definition.
3934 % The format of the DrawPopClipPath method is:
3936 % void DrawPopClipPath(DrawingWand *wand)
3938 % A description of each parameter follows:
3940 % o wand: the drawing wand.
3943 WandExport void DrawPopClipPath(DrawingWand *wand)
3945 assert(wand != (DrawingWand *) NULL);
3946 assert(wand->signature == WandSignature);
3947 if (wand->debug != MagickFalse)
3948 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3949 if (wand->indent_depth > 0)
3950 wand->indent_depth--;
3951 (void) MvgPrintf(wand,"pop clip-path\n");
3955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3959 % D r a w P o p D e f s %
3963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3965 % DrawPopDefs() terminates a definition list.
3967 % The format of the DrawPopDefs method is:
3969 % void DrawPopDefs(DrawingWand *wand)
3971 % A description of each parameter follows:
3973 % o wand: the drawing wand.
3976 WandExport void DrawPopDefs(DrawingWand *wand)
3978 assert(wand != (DrawingWand *) NULL);
3979 assert(wand->signature == WandSignature);
3980 if (wand->debug != MagickFalse)
3981 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3982 if (wand->indent_depth > 0)
3983 wand->indent_depth--;
3984 (void) MvgPrintf(wand,"pop defs\n");
3988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3992 % D r a w P o p P a t t e r n %
3996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3998 % DrawPopPattern() terminates a pattern definition.
4000 % The format of the DrawPopPattern method is:
4002 % MagickBooleanType DrawPopPattern(DrawingWand *wand)
4004 % A description of each parameter follows:
4006 % o wand: the drawing wand.
4009 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4012 geometry[MaxTextExtent],
4015 assert(wand != (DrawingWand *) NULL);
4016 assert(wand->signature == WandSignature);
4017 if (wand->debug != MagickFalse)
4018 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4019 if (wand->image == (Image *) NULL)
4020 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4021 if (wand->pattern_id == (const char *) NULL)
4023 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4025 return(MagickFalse);
4027 (void) FormatMagickString(key,MaxTextExtent,"%s",wand->pattern_id);
4028 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4029 (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
4030 wand->pattern_bounds.width,wand->pattern_bounds.height,
4031 wand->pattern_bounds.x,wand->pattern_bounds.y);
4032 (void) SetImageArtifact(wand->image,key,geometry);
4033 wand->pattern_id=DestroyString(wand->pattern_id);
4034 wand->pattern_offset=0;
4035 wand->pattern_bounds.x=0;
4036 wand->pattern_bounds.y=0;
4037 wand->pattern_bounds.width=0;
4038 wand->pattern_bounds.height=0;
4039 wand->filter_off=MagickTrue;
4040 if (wand->indent_depth > 0)
4041 wand->indent_depth--;
4042 (void) MvgPrintf(wand,"pop pattern\n");
4047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4051 % D r a w P u s h C l i p P a t h %
4055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4057 % DrawPushClipPath() starts a clip path definition which is comprized of any
4058 % number of drawing commands and terminated by a DrawPopClipPath() command.
4060 % The format of the DrawPushClipPath method is:
4062 % void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4064 % A description of each parameter follows:
4066 % o wand: the drawing wand.
4068 % o clip_mask_id: string identifier to associate with the clip path for
4072 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4074 assert(wand != (DrawingWand *) NULL);
4075 assert(wand->signature == WandSignature);
4076 if (wand->debug != MagickFalse)
4077 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4078 assert(clip_mask_id != (const char *) NULL);
4079 (void) MvgPrintf(wand,"push clip-path %s\n",clip_mask_id);
4080 wand->indent_depth++;
4084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4088 % D r a w P u s h D e f s %
4092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4094 % DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4095 % command create named elements (e.g. clip-paths, textures, etc.) which
4096 % may safely be processed earlier for the sake of efficiency.
4098 % The format of the DrawPushDefs method is:
4100 % void DrawPushDefs(DrawingWand *wand)
4102 % A description of each parameter follows:
4104 % o wand: the drawing wand.
4107 WandExport void DrawPushDefs(DrawingWand *wand)
4109 assert(wand != (DrawingWand *) NULL);
4110 assert(wand->signature == WandSignature);
4111 if (wand->debug != MagickFalse)
4112 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4113 (void) MvgPrintf(wand,"push defs\n");
4114 wand->indent_depth++;
4118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4122 % D r a w P u s h P a t t e r n %
4126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4128 % DrawPushPattern() indicates that subsequent commands up to a
4129 % DrawPopPattern() command comprise the definition of a named pattern.
4130 % The pattern space is assigned top left corner coordinates, a width
4131 % and height, and becomes its own drawing space. Anything which can
4132 % be drawn may be used in a pattern definition.
4133 % Named patterns may be used as stroke or brush definitions.
4135 % The format of the DrawPushPattern method is:
4137 % MagickBooleanType DrawPushPattern(DrawingWand *wand,
4138 % const char *pattern_id,const double x,const double y,
4139 % const double width,const double height)
4141 % A description of each parameter follows:
4143 % o wand: the drawing wand.
4145 % o pattern_id: pattern identification for later reference
4147 % o x: x ordinate of top left corner
4149 % o y: y ordinate of top left corner
4151 % o width: width of pattern space
4153 % o height: height of pattern space
4156 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4157 const char *pattern_id,const double x,const double y,const double width,
4158 const double height)
4160 assert(wand != (DrawingWand *) NULL);
4161 assert(wand->signature == WandSignature);
4162 if (wand->debug != MagickFalse)
4163 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4164 assert(pattern_id != (const char *) NULL);
4165 if (wand->pattern_id != NULL)
4167 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4169 return(MagickFalse);
4171 wand->filter_off=MagickTrue;
4172 (void) MvgPrintf(wand,"push pattern %s %.15g,%.15g %.15g,%.15g\n",pattern_id,
4174 wand->indent_depth++;
4175 wand->pattern_id=AcquireString(pattern_id);
4176 wand->pattern_bounds.x=(long) ceil(x-0.5);
4177 wand->pattern_bounds.y=(long) ceil(y-0.5);
4178 wand->pattern_bounds.width=(unsigned long) (width+0.5);
4179 wand->pattern_bounds.height=(unsigned long) (height+0.5);
4180 wand->pattern_offset=wand->mvg_length;
4185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4189 % D r a w R e c t a n g l e %
4193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4195 % DrawRectangle() draws a rectangle given two coordinates and using the
4196 % current stroke, stroke width, and fill settings.
4198 % The format of the DrawRectangle method is:
4200 % void DrawRectangle(DrawingWand *wand,const double x1,
4201 % const double y1,const double x2,const double y2)
4203 % A description of each parameter follows:
4205 % o x1: x ordinate of first coordinate
4207 % o y1: y ordinate of first coordinate
4209 % o x2: x ordinate of second coordinate
4211 % o y2: y ordinate of second coordinate
4214 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4215 const double x2,const double y2)
4217 assert(wand != (DrawingWand *) NULL);
4218 assert(wand->signature == WandSignature);
4219 if (wand->debug != MagickFalse)
4220 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4221 (void) MvgPrintf(wand,"rectangle %.15g,%.15g %.15g,%.15g\n",x1,y1,x2,y2);
4225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4229 + D r a w R e n d e r %
4233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4235 % DrawRender() renders all preceding drawing commands onto the image.
4237 % The format of the DrawRender method is:
4239 % MagickBooleanType DrawRender(DrawingWand *wand)
4241 % A description of each parameter follows:
4243 % o wand: the drawing wand.
4246 WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4251 assert(wand != (const DrawingWand *) NULL);
4252 assert(wand->signature == WandSignature);
4253 if (wand->debug != MagickFalse)
4254 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4255 CurrentContext->primitive=wand->mvg;
4256 if (wand->debug != MagickFalse)
4257 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4258 if (wand->image == (Image *) NULL)
4259 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4260 status=DrawImage(wand->image,CurrentContext);
4261 InheritException(wand->exception,&wand->image->exception);
4262 CurrentContext->primitive=(char *) NULL;
4267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4271 % D r a w R e s e t V e c t o r G r a p h i c s %
4275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4277 % DrawResetVectorGraphics() resets the vector graphics associated with the
4280 % The format of the DrawResetVectorGraphics method is:
4282 % void DrawResetVectorGraphics(DrawingWand *wand)
4284 % A description of each parameter follows:
4286 % o wand: the drawing wand.
4289 WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4291 assert(wand != (DrawingWand *) NULL);
4292 assert(wand->signature == WandSignature);
4293 if (wand->debug != MagickFalse)
4294 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4295 if (wand->mvg != (char *) NULL)
4296 wand->mvg=DestroyString(wand->mvg);
4303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4307 % D r a w R o t a t e %
4311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4313 % DrawRotate() applies the specified rotation to the current coordinate space.
4315 % The format of the DrawRotate method is:
4317 % void DrawRotate(DrawingWand *wand,const double degrees)
4319 % A description of each parameter follows:
4321 % o wand: the drawing wand.
4323 % o degrees: degrees of rotation
4326 WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4331 assert(wand != (DrawingWand *) NULL);
4332 assert(wand->signature == WandSignature);
4333 if (wand->debug != MagickFalse)
4334 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4335 GetAffineMatrix(&affine);
4336 affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
4337 affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
4338 affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
4339 affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
4340 AdjustAffine(wand,&affine);
4341 (void) MvgPrintf(wand,"rotate %.15g\n",degrees);
4345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4349 % D r a w R o u n d R e c t a n g l e %
4353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4355 % DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4356 % x & y corner radiuses and using the current stroke, stroke width,
4357 % and fill settings.
4359 % The format of the DrawRoundRectangle method is:
4361 % void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4362 % double x2,double y2,double rx,double ry)
4364 % A description of each parameter follows:
4366 % o wand: the drawing wand.
4368 % o x1: x ordinate of first coordinate
4370 % o y1: y ordinate of first coordinate
4372 % o x2: x ordinate of second coordinate
4374 % o y2: y ordinate of second coordinate
4376 % o rx: radius of corner in horizontal direction
4378 % o ry: radius of corner in vertical direction
4381 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4382 double x2,double y2,double rx,double ry)
4384 assert(wand != (DrawingWand *) NULL);
4385 assert(wand->signature == WandSignature);
4386 if (wand->debug != MagickFalse)
4387 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4388 (void) MvgPrintf(wand,"roundrectangle %.15g,%.15g %.15g,%.15g %.15g,%.15g\n",
4393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4397 % D r a w S c a l e %
4401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4403 % DrawScale() adjusts the scaling factor to apply in the horizontal and
4404 % vertical directions to the current coordinate space.
4406 % The format of the DrawScale method is:
4408 % void DrawScale(DrawingWand *wand,const double x,const double y)
4410 % A description of each parameter follows:
4412 % o wand: the drawing wand.
4414 % o x: horizontal scale factor
4416 % o y: vertical scale factor
4419 WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4424 assert(wand != (DrawingWand *) NULL);
4425 assert(wand->signature == WandSignature);
4426 if (wand->debug != MagickFalse)
4427 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4428 GetAffineMatrix(&affine);
4431 AdjustAffine(wand,&affine);
4432 (void) MvgPrintf(wand,"scale %.15g,%.15g\n",x,y);
4436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4440 % D r a w S e t B o r d e r C o l o r %
4444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4446 % DrawSetBorderColor() sets the border color to be used for drawing bordered
4449 % The format of the DrawSetBorderColor method is:
4451 % void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4453 % A description of each parameter follows:
4455 % o wand: the drawing wand.
4457 % o border_wand: border wand.
4461 static inline MagickBooleanType IsColorEqual(const PixelPacket *p,
4462 const PixelPacket *q)
4464 if (p->red != q->red)
4465 return(MagickFalse);
4466 if (p->green != q->green)
4467 return(MagickFalse);
4468 if (p->blue != q->blue)
4469 return(MagickFalse);
4470 if (p->opacity != q->opacity)
4471 return(MagickFalse);
4475 WandExport void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4482 assert(wand != (DrawingWand *) NULL);
4483 assert(wand->signature == WandSignature);
4484 if (wand->debug != MagickFalse)
4485 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4486 assert(border_wand != (const PixelWand *) NULL);
4487 PixelGetQuantumColor(border_wand,&border_color);
4488 new_border=border_color;
4489 current_border=(&CurrentContext->border_color);
4490 if ((wand->filter_off != MagickFalse) ||
4491 (IsColorEqual(current_border,&new_border) == MagickFalse))
4493 CurrentContext->border_color=new_border;
4494 (void) MvgPrintf(wand,"border-color '");
4495 MvgAppendColor(wand,&border_color);
4496 (void) MvgPrintf(wand,"'\n");
4501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4505 % D r a w S e t C l i p P a t h %
4509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4511 % DrawSetClipPath() associates a named clipping path with the image. Only
4512 % the areas drawn on by the clipping path will be modified as long as it
4513 % remains in effect.
4515 % The format of the DrawSetClipPath method is:
4517 % MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4518 % const char *clip_mask)
4520 % A description of each parameter follows:
4522 % o wand: the drawing wand.
4524 % o clip_mask: name of clipping path to associate with image
4527 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4528 const char *clip_mask)
4530 if (wand->debug != MagickFalse)
4531 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4532 assert(wand != (DrawingWand *) NULL);
4533 assert(wand->signature == WandSignature);
4534 assert(clip_mask != (const char *) NULL);
4535 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4536 (wand->filter_off != MagickFalse) ||
4537 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4539 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4540 #if DRAW_BINARY_IMPLEMENTATION
4541 if (wand->image == (Image *) NULL)
4542 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4543 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4545 (void) MvgPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4555 % D r a w S e t C l i p R u l e %
4559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4561 % DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4563 % The format of the DrawSetClipRule method is:
4565 % void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4567 % A description of each parameter follows:
4569 % o wand: the drawing wand.
4571 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4574 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4576 assert(wand != (DrawingWand *) NULL);
4577 assert(wand->signature == WandSignature);
4578 if (wand->debug != MagickFalse)
4579 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4580 if ((wand->filter_off != MagickFalse) ||
4581 (CurrentContext->fill_rule != fill_rule))
4583 CurrentContext->fill_rule=fill_rule;
4584 (void) MvgPrintf(wand, "clip-rule '%s'\n",MagickOptionToMnemonic(
4585 MagickFillRuleOptions,(long) fill_rule));
4590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4594 % D r a w S e t C l i p U n i t s %
4598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4600 % DrawSetClipUnits() sets the interpretation of clip path units.
4602 % The format of the DrawSetClipUnits method is:
4604 % void DrawSetClipUnits(DrawingWand *wand,
4605 % const ClipPathUnits clip_units)
4607 % A description of each parameter follows:
4609 % o wand: the drawing wand.
4611 % o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4612 % ObjectBoundingBox)
4615 WandExport void DrawSetClipUnits(DrawingWand *wand,
4616 const ClipPathUnits clip_units)
4618 assert(wand != (DrawingWand *) NULL);
4619 assert(wand->signature == WandSignature);
4620 if (wand->debug != MagickFalse)
4621 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4622 if ((wand->filter_off != MagickFalse) ||
4623 (CurrentContext->clip_units != clip_units))
4625 CurrentContext->clip_units=clip_units;
4626 if (clip_units == ObjectBoundingBox)
4631 GetAffineMatrix(&affine);
4632 affine.sx=CurrentContext->bounds.x2;
4633 affine.sy=CurrentContext->bounds.y2;
4634 affine.tx=CurrentContext->bounds.x1;
4635 affine.ty=CurrentContext->bounds.y1;
4636 AdjustAffine(wand,&affine);
4638 (void) MvgPrintf(wand, "clip-units '%s'\n",MagickOptionToMnemonic(
4639 MagickClipPathOptions,(long) clip_units));
4644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4648 % D r a w S e t F i l l C o l o r %
4652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4654 % DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4656 % The format of the DrawSetFillColor method is:
4658 % void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4660 % A description of each parameter follows:
4662 % o wand: the drawing wand.
4664 % o fill_wand: fill wand.
4667 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4674 assert(wand != (DrawingWand *) NULL);
4675 assert(wand->signature == WandSignature);
4676 if (wand->debug != MagickFalse)
4677 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4678 assert(fill_wand != (const PixelWand *) NULL);
4679 PixelGetQuantumColor(fill_wand,&fill_color);
4680 new_fill=fill_color;
4681 current_fill=(&CurrentContext->fill);
4682 if ((wand->filter_off != MagickFalse) ||
4683 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4685 CurrentContext->fill=new_fill;
4686 (void) MvgPrintf(wand,"fill '");
4687 MvgAppendColor(wand,&fill_color);
4688 (void) MvgPrintf(wand,"'\n");
4693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4697 % D r a w S e t F i l l O p a c i t y %
4701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4703 % DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4704 % color or fill texture. Fully opaque is 1.0.
4706 % The format of the DrawSetFillOpacity method is:
4708 % void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4710 % A description of each parameter follows:
4712 % o wand: the drawing wand.
4714 % o fill_opacity: fill opacity
4717 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4722 assert(wand != (DrawingWand *) NULL);
4723 assert(wand->signature == WandSignature);
4724 if (wand->debug != MagickFalse)
4725 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4726 opacity=RoundToQuantum((double) QuantumRange*(1.0-fill_opacity));
4727 if ((wand->filter_off != MagickFalse) ||
4728 (CurrentContext->fill.opacity != opacity))
4730 CurrentContext->fill.opacity=opacity;
4731 (void) MvgPrintf(wand,"fill-opacity %.15g\n",fill_opacity);
4736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4740 % D r a w S e t O p a c i t y %
4744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4746 % DrawSetOpacity() sets the opacity to use when drawing using the fill or
4747 % stroke color or texture. Fully opaque is 1.0.
4749 % The format of the DrawSetOpacity method is:
4751 % void DrawSetOpacity(DrawingWand *wand,const double opacity)
4753 % A description of each parameter follows:
4755 % o wand: the drawing wand.
4757 % o opacity: fill opacity
4760 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4765 assert(wand != (DrawingWand *) NULL);
4766 assert(wand->signature == WandSignature);
4767 if (wand->debug != MagickFalse)
4768 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4769 quantum_opacity=RoundToQuantum((double) QuantumRange*(1.0-opacity));
4770 if ((wand->filter_off != MagickFalse) ||
4771 (CurrentContext->opacity != quantum_opacity))
4773 CurrentContext->opacity=opacity;
4774 (void) MvgPrintf(wand,"opacity %.15g\n",opacity);
4779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4783 % D r a w S e t F i l l P a t t e r n U R L %
4787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4789 % DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4790 % objects. Only local URLs ("#identifier") are supported at this time. These
4791 % local URLs are normally created by defining a named fill pattern with
4792 % DrawPushPattern/DrawPopPattern.
4794 % The format of the DrawSetFillPatternURL method is:
4796 % MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4797 % const char *fill_url)
4799 % A description of each parameter follows:
4801 % o wand: the drawing wand.
4803 % o fill_url: URL to use to obtain fill pattern.
4806 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4807 const char *fill_url)
4810 pattern[MaxTextExtent],
4811 pattern_spec[MaxTextExtent];
4813 assert(wand != (DrawingWand *) NULL);
4814 assert(wand->signature == WandSignature);
4815 if (wand->debug != MagickFalse)
4816 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4817 if (wand->image == (Image *) NULL)
4818 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4819 assert(fill_url != (const char *) NULL);
4820 if (*fill_url != '#')
4822 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4823 return(MagickFalse);
4825 (void) FormatMagickString(pattern,MaxTextExtent,"%s",fill_url+1);
4826 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4828 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4829 return(MagickFalse);
4831 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",fill_url);
4832 #if DRAW_BINARY_IMPLEMENTATION
4833 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4834 &CurrentContext->fill_pattern);
4836 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4837 CurrentContext->fill.opacity=CurrentContext->opacity;
4838 (void) MvgPrintf(wand,"fill %s\n",pattern_spec);
4843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4847 % D r a w S e t F i l l R u l e %
4851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4853 % DrawSetFillRule() sets the fill rule to use while drawing polygons.
4855 % The format of the DrawSetFillRule method is:
4857 % void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4859 % A description of each parameter follows:
4861 % o wand: the drawing wand.
4863 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4866 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4868 assert(wand != (DrawingWand *) NULL);
4869 assert(wand->signature == WandSignature);
4870 if (wand->debug != MagickFalse)
4871 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4872 if ((wand->filter_off != MagickFalse) ||
4873 (CurrentContext->fill_rule != fill_rule))
4875 CurrentContext->fill_rule=fill_rule;
4876 (void) MvgPrintf(wand, "fill-rule '%s'\n",MagickOptionToMnemonic(
4877 MagickFillRuleOptions,(long) fill_rule));
4882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4886 % D r a w S e t F o n t %
4890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4892 % DrawSetFont() sets the fully-sepecified font to use when annotating with
4895 % The format of the DrawSetFont method is:
4897 % MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4899 % A description of each parameter follows:
4901 % o wand: the drawing wand.
4903 % o font_name: font name
4906 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4907 const char *font_name)
4909 assert(wand != (DrawingWand *) NULL);
4910 assert(wand->signature == WandSignature);
4911 if (wand->debug != MagickFalse)
4912 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4913 assert(font_name != (const char *) NULL);
4914 if ((wand->filter_off != MagickFalse) ||
4915 (CurrentContext->font == (char *) NULL) ||
4916 (LocaleCompare(CurrentContext->font,font_name) != 0))
4918 (void) CloneString(&CurrentContext->font,font_name);
4919 (void) MvgPrintf(wand,"font '%s'\n",font_name);
4925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4929 % D r a w S e t F o n t F a m i l y %
4933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4935 % DrawSetFontFamily() sets the font family to use when annotating with text.
4937 % The format of the DrawSetFontFamily method is:
4939 % MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4940 % const char *font_family)
4942 % A description of each parameter follows:
4944 % o wand: the drawing wand.
4946 % o font_family: font family
4949 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4950 const char *font_family)
4952 assert(wand != (DrawingWand *) NULL);
4953 assert(wand->signature == WandSignature);
4954 if (wand->debug != MagickFalse)
4955 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4956 assert(font_family != (const char *) NULL);
4957 if ((wand->filter_off != MagickFalse) ||
4958 (CurrentContext->family == (const char *) NULL) ||
4959 (LocaleCompare(CurrentContext->family,font_family) != 0))
4961 (void) CloneString(&CurrentContext->family,font_family);
4962 (void) MvgPrintf(wand,"font-family '%s'\n",font_family);
4968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4972 % D r a w S e t F o n t S i z e %
4976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4978 % DrawSetFontSize() sets the font pointsize to use when annotating with text.
4980 % The format of the DrawSetFontSize method is:
4982 % void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4984 % A description of each parameter follows:
4986 % o wand: the drawing wand.
4988 % o pointsize: text pointsize
4991 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4993 assert(wand != (DrawingWand *) NULL);
4994 assert(wand->signature == WandSignature);
4995 if (wand->debug != MagickFalse)
4996 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4997 if ((wand->filter_off != MagickFalse) ||
4998 (fabs(CurrentContext->pointsize-pointsize) > MagickEpsilon))
5000 CurrentContext->pointsize=pointsize;
5001 (void) MvgPrintf(wand,"font-size %.15g\n",pointsize);
5006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5010 % D r a w S e t F o n t S t r e t c h %
5014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5016 % DrawSetFontStretch() sets the font stretch to use when annotating with text.
5017 % The AnyStretch enumeration acts as a wild-card "don't care" option.
5019 % The format of the DrawSetFontStretch method is:
5021 % void DrawSetFontStretch(DrawingWand *wand,
5022 % const StretchType font_stretch)
5024 % A description of each parameter follows:
5026 % o wand: the drawing wand.
5028 % o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5029 % CondensedStretch, SemiCondensedStretch,
5030 % SemiExpandedStretch, ExpandedStretch,
5031 % ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5034 WandExport void DrawSetFontStretch(DrawingWand *wand,
5035 const StretchType font_stretch)
5037 assert(wand != (DrawingWand *) NULL);
5038 assert(wand->signature == WandSignature);
5039 if (wand->debug != MagickFalse)
5040 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5041 if ((wand->filter_off != MagickFalse) ||
5042 (CurrentContext->stretch != font_stretch))
5044 CurrentContext->stretch=font_stretch;
5045 (void) MvgPrintf(wand, "font-stretch '%s'\n",MagickOptionToMnemonic(
5046 MagickStretchOptions,(long) font_stretch));
5051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5055 % D r a w S e t F o n t S t y l e %
5059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5061 % DrawSetFontStyle() sets the font style to use when annotating with text.
5062 % The AnyStyle enumeration acts as a wild-card "don't care" option.
5064 % The format of the DrawSetFontStyle method is:
5066 % void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5068 % A description of each parameter follows:
5070 % o wand: the drawing wand.
5072 % o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5075 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5077 assert(wand != (DrawingWand *) NULL);
5078 assert(wand->signature == WandSignature);
5079 if (wand->debug != MagickFalse)
5080 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5081 if ((wand->filter_off != MagickFalse) ||
5082 (CurrentContext->style != style))
5084 CurrentContext->style=style;
5085 (void) MvgPrintf(wand, "font-style '%s'\n",MagickOptionToMnemonic(
5086 MagickStyleOptions,(long) style));
5091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5095 % D r a w S e t F o n t W e i g h t %
5099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5101 % DrawSetFontWeight() sets the font weight to use when annotating with text.
5103 % The format of the DrawSetFontWeight method is:
5105 % void DrawSetFontWeight(DrawingWand *wand,
5106 % const unsigned long font_weight)
5108 % A description of each parameter follows:
5110 % o wand: the drawing wand.
5112 % o font_weight: font weight (valid range 100-900)
5115 WandExport void DrawSetFontWeight(DrawingWand *wand,
5116 const unsigned long font_weight)
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->weight != font_weight))
5125 CurrentContext->weight=font_weight;
5126 (void) MvgPrintf(wand,"font-weight %lu\n",font_weight);
5131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5135 % D r a w S e t G r a v i t y %
5139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5141 % DrawSetGravity() sets the text placement gravity to use when annotating
5144 % The format of the DrawSetGravity method is:
5146 % void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5148 % A description of each parameter follows:
5150 % o wand: the drawing wand.
5152 % o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5153 % NorthEastGravity, WestGravity, CenterGravity,
5154 % EastGravity, SouthWestGravity, SouthGravity,
5158 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5160 assert(wand != (DrawingWand *) NULL);
5161 assert(wand->signature == WandSignature);
5162 if (wand->debug != MagickFalse)
5163 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5164 if ((wand->filter_off != MagickFalse) ||
5165 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5167 CurrentContext->gravity=gravity;
5168 (void) MvgPrintf(wand,"gravity '%s'\n",MagickOptionToMnemonic(
5169 MagickGravityOptions,(long) gravity));
5174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5178 % D r a w S e t S t r o k e C o l o r %
5182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5184 % DrawSetStrokeColor() sets the color used for stroking object outlines.
5186 % The format of the DrawSetStrokeColor method is:
5188 % void DrawSetStrokeColor(DrawingWand *wand,
5189 % const PixelWand *stroke_wand)
5191 % A description of each parameter follows:
5193 % o wand: the drawing wand.
5195 % o stroke_wand: stroke wand.
5198 WandExport void DrawSetStrokeColor(DrawingWand *wand,
5199 const PixelWand *stroke_wand)
5206 assert(wand != (DrawingWand *) NULL);
5207 assert(wand->signature == WandSignature);
5208 if (wand->debug != MagickFalse)
5209 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5210 assert(stroke_wand != (const PixelWand *) NULL);
5211 PixelGetQuantumColor(stroke_wand,&stroke_color);
5212 new_stroke=stroke_color;
5213 current_stroke=(&CurrentContext->stroke);
5214 if ((wand->filter_off != MagickFalse) ||
5215 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5217 CurrentContext->stroke=new_stroke;
5218 (void) MvgPrintf(wand,"stroke '");
5219 MvgAppendColor(wand,&stroke_color);
5220 (void) MvgPrintf(wand,"'\n");
5225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5229 % D r a w S e t S t r o k e P a t t e r n U R L %
5233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5235 % DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5237 % The format of the DrawSetStrokePatternURL method is:
5239 % MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5240 % const char *stroke_url)
5242 % A description of each parameter follows:
5244 % o wand: the drawing wand.
5246 % o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5249 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5250 const char *stroke_url)
5253 pattern[MaxTextExtent],
5254 pattern_spec[MaxTextExtent];
5256 assert(wand != (DrawingWand *) NULL);
5257 assert(wand->signature == WandSignature);
5258 if (wand->debug != MagickFalse)
5259 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5260 if (wand->image == (Image *) NULL)
5261 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5262 assert(stroke_url != NULL);
5263 if (stroke_url[0] != '#')
5264 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5265 (void) FormatMagickString(pattern,MaxTextExtent,"%s",stroke_url+1);
5266 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5268 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5269 return(MagickFalse);
5271 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",stroke_url);
5272 #if DRAW_BINARY_IMPLEMENTATION
5273 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5274 &CurrentContext->stroke_pattern);
5276 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5277 CurrentContext->stroke.opacity=CurrentContext->opacity;
5278 (void) MvgPrintf(wand,"stroke %s\n",pattern_spec);
5283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5287 % D r a w S e t S t r o k e A n t i a l i a s %
5291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5293 % DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5294 % Stroked outlines are antialiased by default. When antialiasing is disabled
5295 % stroked pixels are thresholded to determine if the stroke color or
5296 % underlying canvas color should be used.
5298 % The format of the DrawSetStrokeAntialias method is:
5300 % void DrawSetStrokeAntialias(DrawingWand *wand,
5301 % const MagickBooleanType stroke_antialias)
5303 % A description of each parameter follows:
5305 % o wand: the drawing wand.
5307 % o stroke_antialias: set to false (zero) to disable antialiasing
5310 WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5311 const MagickBooleanType stroke_antialias)
5313 assert(wand != (DrawingWand *) NULL);
5314 assert(wand->signature == WandSignature);
5315 if (wand->debug != MagickFalse)
5316 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5317 if ((wand->filter_off != MagickFalse) ||
5318 (CurrentContext->stroke_antialias != stroke_antialias))
5320 CurrentContext->stroke_antialias=stroke_antialias;
5321 (void) MvgPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5331 % D r a w S e t S t r o k e D a s h A r r a y %
5335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5337 % DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5338 % stroke paths. The stroke dash array represents an array of numbers that
5339 % specify the lengths of alternating dashes and gaps in pixels. If an odd
5340 % number of values is provided, then the list of values is repeated to yield
5341 % an even number of values. To remove an existing dash array, pass a zero
5342 % number_elements argument and null dash_array. A typical stroke dash array
5343 % might contain the members 5 3 2.
5345 % The format of the DrawSetStrokeDashArray method is:
5347 % MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5348 % const unsigned long number_elements,const double *dash_array)
5350 % A description of each parameter follows:
5352 % o wand: the drawing wand.
5354 % o number_elements: number of elements in dash array
5356 % o dash_array: dash array values
5359 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5360 const unsigned long number_elements,const double *dash_array)
5365 register const double
5378 assert(wand != (DrawingWand *) NULL);
5379 assert(wand->signature == WandSignature);
5380 if (wand->debug != MagickFalse)
5381 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5382 n_new=number_elements;
5385 q=CurrentContext->dash_pattern;
5386 if (q != (const double *) NULL)
5389 if ((n_old == 0) && (n_new == 0))
5395 if ((CurrentContext->dash_pattern != (double *) NULL) &&
5396 (dash_array != (double *) NULL))
5399 q=CurrentContext->dash_pattern;
5400 for (i=0; i < (long) n_new; i++)
5402 if (fabs((*p)-(*q)) > MagickEpsilon)
5411 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5413 if (CurrentContext->dash_pattern != (double *) NULL)
5414 CurrentContext->dash_pattern=(double *)
5415 RelinquishMagickMemory(CurrentContext->dash_pattern);
5418 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5419 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5420 if (!CurrentContext->dash_pattern)
5422 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5424 return(MagickFalse);
5426 q=CurrentContext->dash_pattern;
5428 for (i=0; i < (long) n_new; i++)
5432 (void) MvgPrintf(wand,"stroke-dasharray ");
5434 (void) MvgPrintf(wand,"none\n");
5438 (void) MvgPrintf(wand,"%.15g",*p++);
5439 for (i=1; i < (long) n_new; i++)
5440 (void) MvgPrintf(wand,",%.15g",*p++);
5441 (void) MvgPrintf(wand,"\n");
5448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5452 % D r a w S e t S t r o k e D a s h O f f s e t %
5456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5458 % DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5461 % The format of the DrawSetStrokeDashOffset method is:
5463 % void DrawSetStrokeDashOffset(DrawingWand *wand,
5464 % const double dash_offset)
5466 % A description of each parameter follows:
5468 % o wand: the drawing wand.
5470 % o dash_offset: dash offset
5473 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5474 const double dash_offset)
5476 assert(wand != (DrawingWand *) NULL);
5477 assert(wand->signature == WandSignature);
5478 if (wand->debug != MagickFalse)
5479 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5480 if ((wand->filter_off != MagickFalse) ||
5481 (fabs(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
5483 CurrentContext->dash_offset=dash_offset;
5484 (void) MvgPrintf(wand,"stroke-dashoffset %.15g\n",dash_offset);
5489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5493 % D r a w S e t S t r o k e L i n e C a p %
5497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5499 % DrawSetStrokeLineCap() specifies the shape to be used at the end of
5500 % open subpaths when they are stroked. Values of LineCap are
5501 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
5503 % The format of the DrawSetStrokeLineCap method is:
5505 % void DrawSetStrokeLineCap(DrawingWand *wand,
5506 % const LineCap linecap)
5508 % A description of each parameter follows:
5510 % o wand: the drawing wand.
5512 % o linecap: linecap style
5515 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5517 assert(wand != (DrawingWand *) NULL);
5518 assert(wand->signature == WandSignature);
5519 if (wand->debug != MagickFalse)
5520 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5521 if ((wand->filter_off != MagickFalse) ||
5522 (CurrentContext->linecap != linecap))
5524 CurrentContext->linecap=linecap;
5525 (void) MvgPrintf(wand,"stroke-linecap '%s'\n",MagickOptionToMnemonic(
5526 MagickLineCapOptions,(long) linecap));
5531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5535 % D r a w S e t S t r o k e L i n e J o i n %
5539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5541 % DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5542 % paths (or other vector shapes) when they are stroked. Values of LineJoin are
5543 % UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5545 % The format of the DrawSetStrokeLineJoin method is:
5547 % void DrawSetStrokeLineJoin(DrawingWand *wand,
5548 % const LineJoin linejoin)
5550 % A description of each parameter follows:
5552 % o wand: the drawing wand.
5554 % o linejoin: line join style
5557 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5559 assert(wand != (DrawingWand *) NULL);
5560 assert(wand->signature == WandSignature);
5561 if (wand->debug != MagickFalse)
5562 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5563 if ((wand->filter_off != MagickFalse) ||
5564 (CurrentContext->linejoin != linejoin))
5566 CurrentContext->linejoin=linejoin;
5567 (void) MvgPrintf(wand, "stroke-linejoin '%s'\n",MagickOptionToMnemonic(
5568 MagickLineJoinOptions,(long) linejoin));
5573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5577 % D r a w S e t S t r o k e M i t e r L i m i t %
5581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5583 % DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5584 % segments meet at a sharp angle and miter joins have been specified for
5585 % 'lineJoin', it is possible for the miter to extend far beyond the
5586 % thickness of the line stroking the path. The miterLimit' imposes a
5587 % limit on the ratio of the miter length to the 'lineWidth'.
5589 % The format of the DrawSetStrokeMiterLimit method is:
5591 % void DrawSetStrokeMiterLimit(DrawingWand *wand,
5592 % const unsigned long miterlimit)
5594 % A description of each parameter follows:
5596 % o wand: the drawing wand.
5598 % o miterlimit: miter limit
5601 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
5602 const unsigned long miterlimit)
5604 assert(wand != (DrawingWand *) NULL);
5605 assert(wand->signature == WandSignature);
5606 if (wand->debug != MagickFalse)
5607 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5608 if (CurrentContext->miterlimit != miterlimit)
5610 CurrentContext->miterlimit=miterlimit;
5611 (void) MvgPrintf(wand,"stroke-miterlimit %lu\n",miterlimit);
5616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5620 % D r a w S e t S t r o k e O p a c i t y %
5624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5626 % DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5628 % The format of the DrawSetStrokeOpacity method is:
5630 % void DrawSetStrokeOpacity(DrawingWand *wand,
5631 % const double stroke_opacity)
5633 % A description of each parameter follows:
5635 % o wand: the drawing wand.
5637 % o stroke_opacity: stroke opacity. The value 1.0 is opaque.
5640 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5641 const double stroke_opacity)
5646 assert(wand != (DrawingWand *) NULL);
5647 assert(wand->signature == WandSignature);
5648 if (wand->debug != MagickFalse)
5649 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5650 opacity=RoundToQuantum((double) QuantumRange*(1.0-stroke_opacity));
5651 if ((wand->filter_off != MagickFalse) ||
5652 (CurrentContext->stroke.opacity != opacity))
5654 CurrentContext->stroke.opacity=opacity;
5655 (void) MvgPrintf(wand,"stroke-opacity %.15g\n",stroke_opacity);
5660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5664 % D r a w S e t S t r o k e W i d t h %
5668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5670 % DrawSetStrokeWidth() sets the width of the stroke used to draw object
5673 % The format of the DrawSetStrokeWidth method is:
5675 % void DrawSetStrokeWidth(DrawingWand *wand,
5676 % const double stroke_width)
5678 % A description of each parameter follows:
5680 % o wand: the drawing wand.
5682 % o stroke_width: stroke width
5685 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5687 assert(wand != (DrawingWand *) NULL);
5688 assert(wand->signature == WandSignature);
5689 if (wand->debug != MagickFalse)
5690 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5691 if ((wand->filter_off != MagickFalse) ||
5692 (fabs(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
5694 CurrentContext->stroke_width=stroke_width;
5695 (void) MvgPrintf(wand,"stroke-width %.15g\n",stroke_width);
5700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5704 % D r a w S e t T e x t A l i g n m e n t %
5708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5710 % DrawSetTextAlignment() specifies a text alignment to be applied when
5711 % annotating with text.
5713 % The format of the DrawSetTextAlignment method is:
5715 % void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5717 % A description of each parameter follows:
5719 % o wand: the drawing wand.
5721 % o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5722 % CenterAlign, or RightAlign.
5725 WandExport void DrawSetTextAlignment(DrawingWand *wand,
5726 const AlignType alignment)
5728 assert(wand != (DrawingWand *) NULL);
5729 assert(wand->signature == WandSignature);
5730 if (wand->debug != MagickFalse)
5731 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5732 if ((wand->filter_off != MagickFalse) ||
5733 (CurrentContext->align != alignment))
5735 CurrentContext->align=alignment;
5736 (void) MvgPrintf(wand,"text-align '%s'\n",MagickOptionToMnemonic(
5737 MagickAlignOptions,(long) alignment));
5742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5746 % D r a w S e t T e x t A n t i a l i a s %
5750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5752 % DrawSetTextAntialias() controls whether text is antialiased. Text is
5753 % antialiased by default.
5755 % The format of the DrawSetTextAntialias method is:
5757 % void DrawSetTextAntialias(DrawingWand *wand,
5758 % const MagickBooleanType text_antialias)
5760 % A description of each parameter follows:
5762 % o wand: the drawing wand.
5764 % o text_antialias: antialias boolean. Set to false (0) to disable
5768 WandExport void DrawSetTextAntialias(DrawingWand *wand,
5769 const MagickBooleanType text_antialias)
5771 assert(wand != (DrawingWand *) NULL);
5772 assert(wand->signature == WandSignature);
5773 if (wand->debug != MagickFalse)
5774 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5775 if ((wand->filter_off != MagickFalse) ||
5776 (CurrentContext->text_antialias != text_antialias))
5778 CurrentContext->text_antialias=text_antialias;
5779 (void) MvgPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5788 % D r a w S e t T e x t D e c o r a t i o n %
5792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5794 % DrawSetTextDecoration() specifies a decoration to be applied when
5795 % annotating with text.
5797 % The format of the DrawSetTextDecoration method is:
5799 % void DrawSetTextDecoration(DrawingWand *wand,
5800 % const DecorationType decoration)
5802 % A description of each parameter follows:
5804 % o wand: the drawing wand.
5806 % o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5807 % OverlineDecoration, or LineThroughDecoration
5810 WandExport void DrawSetTextDecoration(DrawingWand *wand,
5811 const DecorationType decoration)
5813 assert(wand != (DrawingWand *) NULL);
5814 assert(wand->signature == WandSignature);
5815 if (wand->debug != MagickFalse)
5816 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5817 if ((wand->filter_off != MagickFalse) ||
5818 (CurrentContext->decorate != decoration))
5820 CurrentContext->decorate=decoration;
5821 (void) MvgPrintf(wand,"decorate '%s'\n",MagickOptionToMnemonic(
5822 MagickDecorateOptions,(long) decoration));
5827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5831 % D r a w S e t T e x t E n c o d i n g %
5835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5837 % DrawSetTextEncoding() specifies the code set to use for text
5838 % annotations. The only character encoding which may be specified
5839 % at this time is "UTF-8" for representing Unicode as a sequence of
5840 % bytes. Specify an empty string to set text encoding to the system's
5841 % default. Successful text annotation using Unicode may require fonts
5842 % designed to support Unicode.
5844 % The format of the DrawSetTextEncoding method is:
5846 % void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5848 % A description of each parameter follows:
5850 % o wand: the drawing wand.
5852 % o encoding: character string specifying text encoding
5855 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5857 assert(wand != (DrawingWand *) NULL);
5858 assert(wand->signature == WandSignature);
5859 if (wand->debug != MagickFalse)
5860 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5861 assert(encoding != (char *) NULL);
5862 if ((wand->filter_off != MagickFalse) ||
5863 (CurrentContext->encoding == (char *) NULL) ||
5864 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
5866 (void) CloneString(&CurrentContext->encoding,encoding);
5867 (void) MvgPrintf(wand,"encoding '%s'\n",encoding);
5872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5876 % D r a w S e t T e x t K e r n i n g %
5880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5882 % DrawSetTextKerning() sets the spacing between characters in text.
5884 % The format of the DrawSetTextKerning method is:
5886 % void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5888 % A description of each parameter follows:
5890 % o wand: the drawing wand.
5892 % o kerning: text kerning
5895 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5897 assert(wand != (DrawingWand *) NULL);
5898 assert(wand->signature == WandSignature);
5900 if (wand->debug != MagickFalse)
5901 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5902 if ((wand->filter_off != MagickFalse) &&
5903 (CurrentContext->kerning != kerning))
5905 CurrentContext->kerning=kerning;
5906 (void) MvgPrintf(wand,"kerning %lf\n",kerning);
5911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5915 % 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 %
5919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5921 % DrawSetTextInterwordSpacing() sets the spacing between line in text.
5923 % The format of the DrawSetInterwordSpacing method is:
5925 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
5926 % const double interline_spacing)
5928 % A description of each parameter follows:
5930 % o wand: the drawing wand.
5932 % o interline_spacing: text line spacing
5935 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
5936 const double interline_spacing)
5938 assert(wand != (DrawingWand *) NULL);
5939 assert(wand->signature == WandSignature);
5941 if (wand->debug != MagickFalse)
5942 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5943 if ((wand->filter_off != MagickFalse) &&
5944 (CurrentContext->interline_spacing != interline_spacing))
5946 CurrentContext->interline_spacing=interline_spacing;
5947 (void) MvgPrintf(wand,"interline-spacing %lf\n",interline_spacing);
5952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5956 % 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 %
5960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5962 % DrawSetTextInterwordSpacing() sets the spacing between words in text.
5964 % The format of the DrawSetInterwordSpacing method is:
5966 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
5967 % const double interword_spacing)
5969 % A description of each parameter follows:
5971 % o wand: the drawing wand.
5973 % o interword_spacing: text word spacing
5976 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
5977 const double interword_spacing)
5979 assert(wand != (DrawingWand *) NULL);
5980 assert(wand->signature == WandSignature);
5982 if (wand->debug != MagickFalse)
5983 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5984 if ((wand->filter_off != MagickFalse) &&
5985 (CurrentContext->interword_spacing != interword_spacing))
5987 CurrentContext->interword_spacing=interword_spacing;
5988 (void) MvgPrintf(wand,"interword-spacing %lf\n",interword_spacing);
5993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5997 % D r a w S e t T e x t U n d e r C o l o r %
6001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6003 % DrawSetTextUnderColor() specifies the color of a background rectangle
6004 % to place under text annotations.
6006 % The format of the DrawSetTextUnderColor method is:
6008 % void DrawSetTextUnderColor(DrawingWand *wand,
6009 % const PixelWand *under_wand)
6011 % A description of each parameter follows:
6013 % o wand: the drawing wand.
6015 % o under_wand: text under wand.
6018 WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6019 const PixelWand *under_wand)
6024 assert(wand != (DrawingWand *) NULL);
6025 assert(wand->signature == WandSignature);
6026 if (wand->debug != MagickFalse)
6027 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6028 assert(under_wand != (const PixelWand *) NULL);
6029 PixelGetQuantumColor(under_wand,&under_color);
6030 if ((wand->filter_off != MagickFalse) ||
6031 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6033 CurrentContext->undercolor=under_color;
6034 (void) MvgPrintf(wand,"text-undercolor '");
6035 MvgAppendColor(wand,&under_color);
6036 (void) MvgPrintf(wand,"'\n");
6041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6045 % D r a w S e t V e c t o r G r a p h i c s %
6049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6051 % DrawSetVectorGraphics() sets the vector graphics associated with the
6052 % specified wand. Use this method with DrawGetVectorGraphics() as a method
6053 % to persist the vector graphics state.
6055 % The format of the DrawSetVectorGraphics method is:
6057 % MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6060 % A description of each parameter follows:
6062 % o wand: the drawing wand.
6064 % o xml: the drawing wand XML.
6068 static inline MagickBooleanType IsPoint(const char *point)
6076 value=strtol(point,&p,10);
6077 return(p != point ? MagickTrue : MagickFalse);
6080 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6090 assert(wand != (DrawingWand *) NULL);
6091 assert(wand->signature == WandSignature);
6092 if (wand->debug != MagickFalse)
6093 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6094 CurrentContext=DestroyDrawInfo(CurrentContext);
6095 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6096 if (xml == (const char *) NULL)
6097 return(MagickFalse);
6098 xml_info=NewXMLTree(xml,wand->exception);
6099 if (xml_info == (XMLTreeInfo *) NULL)
6100 return(MagickFalse);
6101 child=GetXMLTreeChild(xml_info,"clip-path");
6102 if (child != (XMLTreeInfo *) NULL)
6103 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6104 child=GetXMLTreeChild(xml_info,"clip-units");
6105 if (child != (XMLTreeInfo *) NULL)
6107 value=GetXMLTreeContent(child);
6108 if (value != (const char *) NULL)
6109 CurrentContext->clip_units=(ClipPathUnits) ParseMagickOption(
6110 MagickClipPathOptions,MagickFalse,value);
6112 child=GetXMLTreeChild(xml_info,"decorate");
6113 if (child != (XMLTreeInfo *) NULL)
6115 value=GetXMLTreeContent(child);
6116 if (value != (const char *) NULL)
6117 CurrentContext->decorate=(DecorationType) ParseMagickOption(
6118 MagickDecorateOptions,MagickFalse,value);
6120 child=GetXMLTreeChild(xml_info,"encoding");
6121 if (child != (XMLTreeInfo *) NULL)
6122 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6123 child=GetXMLTreeChild(xml_info,"fill");
6124 if (child != (XMLTreeInfo *) NULL)
6126 value=GetXMLTreeContent(child);
6127 if (value != (const char *) NULL)
6128 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6130 child=GetXMLTreeChild(xml_info,"fill-opacity");
6131 if (child != (XMLTreeInfo *) NULL)
6133 value=GetXMLTreeContent(child);
6134 if (value != (const char *) NULL)
6135 CurrentContext->fill.opacity=RoundToQuantum((MagickRealType)
6136 QuantumRange*(1.0-StringToDouble(value)));
6138 child=GetXMLTreeChild(xml_info,"fill-rule");
6139 if (child != (XMLTreeInfo *) NULL)
6141 value=GetXMLTreeContent(child);
6142 if (value != (const char *) NULL)
6143 CurrentContext->fill_rule=(FillRule) ParseMagickOption(
6144 MagickFillRuleOptions,MagickFalse,value);
6146 child=GetXMLTreeChild(xml_info,"font");
6147 if (child != (XMLTreeInfo *) NULL)
6148 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6149 child=GetXMLTreeChild(xml_info,"font-family");
6150 if (child != (XMLTreeInfo *) NULL)
6151 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6152 child=GetXMLTreeChild(xml_info,"font-size");
6153 if (child != (XMLTreeInfo *) NULL)
6155 value=GetXMLTreeContent(child);
6156 if (value != (const char *) NULL)
6157 CurrentContext->pointsize=StringToDouble(value);
6159 child=GetXMLTreeChild(xml_info,"font-stretch");
6160 if (child != (XMLTreeInfo *) NULL)
6162 value=GetXMLTreeContent(child);
6163 if (value != (const char *) NULL)
6164 CurrentContext->stretch=(StretchType) ParseMagickOption(
6165 MagickStretchOptions,MagickFalse,value);
6167 child=GetXMLTreeChild(xml_info,"font-style");
6168 if (child != (XMLTreeInfo *) NULL)
6170 value=GetXMLTreeContent(child);
6171 if (value != (const char *) NULL)
6172 CurrentContext->style=(StyleType) ParseMagickOption(MagickStyleOptions,
6175 child=GetXMLTreeChild(xml_info,"font-weight");
6176 if (child != (XMLTreeInfo *) NULL)
6178 value=GetXMLTreeContent(child);
6179 if (value != (const char *) NULL)
6180 CurrentContext->weight=StringToUnsignedLong(value);
6182 child=GetXMLTreeChild(xml_info,"gravity");
6183 if (child != (XMLTreeInfo *) NULL)
6185 value=GetXMLTreeContent(child);
6186 if (value != (const char *) NULL)
6187 CurrentContext->gravity=(GravityType) ParseMagickOption(
6188 MagickGravityOptions,MagickFalse,value);
6190 child=GetXMLTreeChild(xml_info,"stroke");
6191 if (child != (XMLTreeInfo *) NULL)
6193 value=GetXMLTreeContent(child);
6194 if (value != (const char *) NULL)
6195 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6198 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6199 if (child != (XMLTreeInfo *) NULL)
6201 value=GetXMLTreeContent(child);
6202 if (value != (const char *) NULL)
6203 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6206 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6207 if (child != (XMLTreeInfo *) NULL)
6210 token[MaxTextExtent];
6221 value=GetXMLTreeContent(child);
6222 if (value != (const char *) NULL)
6224 if (CurrentContext->dash_pattern != (double *) NULL)
6225 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6226 CurrentContext->dash_pattern);
6228 if (IsPoint(q) != MagickFalse)
6234 GetMagickToken(p,&p,token);
6236 GetMagickToken(p,&p,token);
6237 for (x=0; IsPoint(token) != MagickFalse; x++)
6239 GetMagickToken(p,&p,token);
6241 GetMagickToken(p,&p,token);
6243 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6244 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6245 if (CurrentContext->dash_pattern == (double *) NULL)
6246 ThrowWandFatalException(ResourceLimitFatalError,
6247 "MemoryAllocationFailed",wand->name);
6248 for (j=0; j < x; j++)
6250 GetMagickToken(q,&q,token);
6252 GetMagickToken(q,&q,token);
6253 CurrentContext->dash_pattern[j]=StringToDouble(token);
6255 if ((x & 0x01) != 0)
6256 for ( ; j < (2*x); j++)
6257 CurrentContext->dash_pattern[j]=
6258 CurrentContext->dash_pattern[j-x];
6259 CurrentContext->dash_pattern[j]=0.0;
6263 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6264 if (child != (XMLTreeInfo *) NULL)
6266 value=GetXMLTreeContent(child);
6267 if (value != (const char *) NULL)
6268 CurrentContext->dash_offset=StringToDouble(value);
6270 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6271 if (child != (XMLTreeInfo *) NULL)
6273 value=GetXMLTreeContent(child);
6274 if (value != (const char *) NULL)
6275 CurrentContext->linecap=(LineCap) ParseMagickOption(
6276 MagickLineCapOptions,MagickFalse,value);
6278 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6279 if (child != (XMLTreeInfo *) NULL)
6281 value=GetXMLTreeContent(child);
6282 if (value != (const char *) NULL)
6283 CurrentContext->linejoin=(LineJoin) ParseMagickOption(
6284 MagickLineJoinOptions,MagickFalse,value);
6286 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6287 if (child != (XMLTreeInfo *) NULL)
6289 value=GetXMLTreeContent(child);
6290 if (value != (const char *) NULL)
6291 CurrentContext->miterlimit=StringToUnsignedLong(value);
6293 child=GetXMLTreeChild(xml_info,"stroke-opacity");
6294 if (child != (XMLTreeInfo *) NULL)
6296 value=GetXMLTreeContent(child);
6297 if (value != (const char *) NULL)
6298 CurrentContext->stroke.opacity=RoundToQuantum((MagickRealType)
6299 QuantumRange*(1.0-StringToDouble(value)));
6301 child=GetXMLTreeChild(xml_info,"stroke-width");
6302 if (child != (XMLTreeInfo *) NULL)
6304 value=GetXMLTreeContent(child);
6305 if (value != (const char *) NULL)
6306 CurrentContext->stroke_width=StringToDouble(value);
6308 child=GetXMLTreeChild(xml_info,"text-align");
6309 if (child != (XMLTreeInfo *) NULL)
6311 value=GetXMLTreeContent(child);
6312 if (value != (const char *) NULL)
6313 CurrentContext->align=(AlignType) ParseMagickOption(MagickAlignOptions,
6316 child=GetXMLTreeChild(xml_info,"text-antialias");
6317 if (child != (XMLTreeInfo *) NULL)
6319 value=GetXMLTreeContent(child);
6320 if (value != (const char *) NULL)
6321 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6324 child=GetXMLTreeChild(xml_info,"text-undercolor");
6325 if (child != (XMLTreeInfo *) NULL)
6327 value=GetXMLTreeContent(child);
6328 if (value != (const char *) NULL)
6329 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6332 child=GetXMLTreeChild(xml_info,"vector-graphics");
6333 if (child != (XMLTreeInfo *) NULL)
6335 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6336 wand->mvg_length=strlen(wand->mvg);
6337 wand->mvg_alloc=wand->mvg_length+1;
6339 xml_info=DestroyXMLTree(xml_info);
6344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6348 % D r a w S k e w X %
6352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6354 % DrawSkewX() skews the current coordinate system in the horizontal
6357 % The format of the DrawSkewX method is:
6359 % void DrawSkewX(DrawingWand *wand,const double degrees)
6361 % A description of each parameter follows:
6363 % o wand: the drawing wand.
6365 % o degrees: number of degrees to skew the coordinates
6368 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6373 assert(wand != (DrawingWand *) NULL);
6374 assert(wand->signature == WandSignature);
6375 if (wand->debug != MagickFalse)
6376 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6377 GetAffineMatrix(&affine);
6378 affine.ry=tan(DegreesToRadians(fmod(degrees,360.0)));
6379 AdjustAffine(wand,&affine);
6380 (void) MvgPrintf(wand,"skewX %.15g\n",degrees);
6384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6388 % D r a w S k e w Y %
6392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6394 % DrawSkewY() skews the current coordinate system in the vertical
6397 % The format of the DrawSkewY method is:
6399 % void DrawSkewY(DrawingWand *wand,const double degrees)
6401 % A description of each parameter follows:
6403 % o wand: the drawing wand.
6405 % o degrees: number of degrees to skew the coordinates
6408 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6413 assert(wand != (DrawingWand *) NULL);
6414 assert(wand->signature == WandSignature);
6415 if (wand->debug != MagickFalse)
6416 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6417 GetAffineMatrix(&affine);
6418 affine.rx=tan(DegreesToRadians(fmod(degrees,360.0)));
6419 DrawAffine(wand,&affine);
6420 (void) MvgPrintf(wand,"skewY %.15g\n",degrees);
6424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6428 % D r a w T r a n s l a t e %
6432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6434 % DrawTranslate() applies a translation to the current coordinate
6435 % system which moves the coordinate system origin to the specified
6438 % The format of the DrawTranslate method is:
6440 % void DrawTranslate(DrawingWand *wand,const double x,
6443 % A description of each parameter follows:
6445 % o wand: the drawing wand.
6447 % o x: new x ordinate for coordinate system origin
6449 % o y: new y ordinate for coordinate system origin
6452 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6457 assert(wand != (DrawingWand *) NULL);
6458 assert(wand->signature == WandSignature);
6459 if (wand->debug != MagickFalse)
6460 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6461 GetAffineMatrix(&affine);
6464 AdjustAffine(wand,&affine);
6465 (void) MvgPrintf(wand,"translate %.15g,%.15g\n",x,y);
6469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6473 % D r a w S e t V i e w b o x %
6477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6479 % DrawSetViewbox() sets the overall canvas size to be recorded with the
6480 % drawing vector data. Usually this will be specified using the same
6481 % size as the canvas image. When the vector data is saved to SVG or MVG
6482 % formats, the viewbox is use to specify the size of the canvas image that
6483 % a viewer will render the vector data on.
6485 % The format of the DrawSetViewbox method is:
6487 % void DrawSetViewbox(DrawingWand *wand,unsigned long x1,
6488 % unsigned long y1,unsigned long x2,unsigned long y2)
6490 % A description of each parameter follows:
6492 % o wand: the drawing wand.
6494 % o x1: left x ordinate
6496 % o y1: top y ordinate
6498 % o x2: right x ordinate
6500 % o y2: bottom y ordinate
6503 WandExport void DrawSetViewbox(DrawingWand *wand,unsigned long x1,
6504 unsigned long y1,unsigned long x2,unsigned long y2)
6506 assert(wand != (DrawingWand *) NULL);
6507 assert(wand->signature == WandSignature);
6508 if (wand->debug != MagickFalse)
6509 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6510 (void) MvgPrintf(wand,"viewbox %lu %lu %lu %lu\n",x1,y1,x2,y2);
6514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6518 % I s D r a w i n g W a n d %
6522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6524 % IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6526 % The format of the IsDrawingWand method is:
6528 % MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6530 % A description of each parameter follows:
6532 % o wand: the drawing wand.
6535 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6537 if (wand == (const DrawingWand *) NULL)
6538 return(MagickFalse);
6539 if (wand->signature != WandSignature)
6540 return(MagickFalse);
6541 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6542 return(MagickFalse);
6547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6551 % N e w D r a w i n g W a n d %
6555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6557 % NewDrawingWand() returns a drawing wand required for all other methods in
6560 % The format of the NewDrawingWand method is:
6562 % DrawingWand NewDrawingWand(void)
6565 WandExport DrawingWand *NewDrawingWand(void)
6576 quantum=GetMagickQuantumDepth(&depth);
6577 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6578 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
6579 wand=(DrawingWand *) AcquireAlignedMemory(1,sizeof(*wand));
6580 if (wand == (DrawingWand *) NULL)
6581 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6582 GetExceptionMessage(errno));
6583 (void) ResetMagickMemory(wand,0,sizeof(*wand));
6584 wand->id=AcquireWandId();
6585 (void) FormatMagickString(wand->name,MaxTextExtent,"%s-%lu",DrawingWandId,
6587 if (wand->debug != MagickFalse)
6588 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6589 wand->mvg=(char *) NULL;
6593 wand->pattern_id=(char *) NULL;
6594 wand->pattern_offset=0;
6595 wand->pattern_bounds.x=0;
6596 wand->pattern_bounds.y=0;
6597 wand->pattern_bounds.width=0;
6598 wand->pattern_bounds.height=0;
6600 wand->graphic_context=(DrawInfo **) AcquireAlignedMemory(1,sizeof(
6601 *wand->graphic_context));
6602 if (wand->graphic_context == (DrawInfo **) NULL)
6603 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6604 GetExceptionMessage(errno));
6605 wand->filter_off=MagickTrue;
6606 wand->indent_depth=0;
6607 wand->path_operation=PathDefaultOperation;
6608 wand->path_mode=DefaultPathMode;
6609 wand->image=AcquireImage((const ImageInfo *) NULL);
6610 wand->exception=AcquireExceptionInfo();
6611 wand->destroy=MagickTrue;
6612 wand->debug=IsEventLogging();
6613 wand->signature=WandSignature;
6614 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6623 % P e e k D r a w i n g W a n d %
6627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6629 % PeekDrawingWand() returns the current drawing wand.
6631 % The format of the PeekDrawingWand method is:
6633 % DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6635 % A description of each parameter follows:
6637 % o wand: the drawing wand.
6640 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6645 assert(wand != (const DrawingWand *) NULL);
6646 assert(wand->signature == WandSignature);
6647 if (wand->debug != MagickFalse)
6648 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6649 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6650 GetAffineMatrix(&draw_info->affine);
6651 (void) CloneString(&draw_info->primitive,wand->mvg);
6656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6660 % P o p D r a w i n g W a n d %
6664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6666 % PopDrawingWand() destroys the current drawing wand and returns to the
6667 % previously pushed drawing wand. Multiple drawing wands may exist. It is an
6668 % error to attempt to pop more drawing wands than have been pushed, and it is
6669 % proper form to pop all drawing wands which have been pushed.
6671 % The format of the PopDrawingWand method is:
6673 % MagickBooleanType PopDrawingWand(DrawingWand *wand)
6675 % A description of each parameter follows:
6677 % o wand: the drawing wand.
6680 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6682 assert(wand != (DrawingWand *) NULL);
6683 assert(wand->signature == WandSignature);
6684 if (wand->debug != MagickFalse)
6685 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6686 if (wand->index == 0)
6688 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6689 return(MagickFalse);
6692 Destroy clip path if not same in preceding wand.
6694 #if DRAW_BINARY_IMPLEMENTATION
6695 if (wand->image == (Image *) NULL)
6696 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6697 if (CurrentContext->clip_mask != (char *) NULL)
6698 if (LocaleCompare(CurrentContext->clip_mask,
6699 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6700 (void) SetImageClipMask(wand->image,(Image *) NULL);
6702 CurrentContext=DestroyDrawInfo(CurrentContext);
6704 if (wand->indent_depth > 0)
6705 wand->indent_depth--;
6706 (void) MvgPrintf(wand,"pop graphic-context\n");
6711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6715 % P u s h D r a w i n g W a n d %
6719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6721 % PushDrawingWand() clones the current drawing wand to create a new drawing
6722 % wand. The original drawing wand(s) may be returned to by invoking
6723 % PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6724 % For every Pop there must have already been an equivalent Push.
6726 % The format of the PushDrawingWand method is:
6728 % MagickBooleanType PushDrawingWand(DrawingWand *wand)
6730 % A description of each parameter follows:
6732 % o wand: the drawing wand.
6735 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6737 assert(wand != (DrawingWand *) NULL);
6738 assert(wand->signature == WandSignature);
6739 if (wand->debug != MagickFalse)
6740 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6742 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6743 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6744 if (wand->graphic_context == (DrawInfo **) NULL)
6746 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6748 return(MagickFalse);
6750 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6751 wand->graphic_context[wand->index-1]);
6752 (void) MvgPrintf(wand,"push graphic-context\n");
6753 wand->indent_depth++;