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 size_t,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 size_t,const PointInfo *);
210 void (*DrawPolyline)(DrawingWand *,const size_t,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 size_t);
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 size_t);
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 *,size_t,size_t,
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 size_t 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," %g,%g",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=affine->sx*current.sx+affine->ry*current.rx;
445 CurrentContext->affine.rx=affine->rx*current.sx+affine->sy*current.rx;
446 CurrentContext->affine.ry=affine->sx*current.ry+affine->ry*current.sy;
447 CurrentContext->affine.sy=affine->rx*current.ry+affine->sy*current.sy;
448 CurrentContext->affine.tx=affine->sx*current.tx+affine->ry*current.ty+
450 CurrentContext->affine.ty=affine->rx*current.tx+affine->sy*current.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 *) AcquireMagickMemory(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-%.20g",
566 (double) clone_wand->id);
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 <= (ssize_t) 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 %g,%g,%g,%g,%g,%g\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 %g,%g '%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 %g,%g %g,%g %g,%g\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 size_t 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 size_t 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 %g,%g %g,%g\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,"%.20g bytes",(double)
1037 (4L*blob_length/3L+4L));
1038 ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
1040 return(MagickFalse);
1042 mode=MagickOptionToMnemonic(MagickComposeOptions,(ssize_t) compose);
1043 media_type=MagickToMime(image->magick);
1044 (void) MvgPrintf(wand,"image %s %g,%g %g,%g 'data:%s;base64,\n",
1045 mode,x,y,width,height,media_type);
1047 for (i=(ssize_t) 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 %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
1104 MagickMethodOptions,(ssize_t) 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 %g,%g %g,%g %g,%g\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 R e s o l u t i o n %
1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1589 % DrawGetFontResolution() gets the image X and Y resolution.
1591 % The format of the DrawGetFontResolution method is:
1593 % DrawBooleanType DrawGetFontResolution(const DrawingWand *wand,
1594 % double *x,double *y)
1596 % A description of each parameter follows:
1598 % o wand: the magick wand.
1600 % o x: the x-resolution.
1602 % o y: the y-resolution.
1605 WandExport MagickBooleanType DrawGetFontResolution(const DrawingWand *wand,
1606 double *x,double *y)
1608 assert(wand != (DrawingWand *) NULL);
1609 assert(wand->signature == WandSignature);
1610 if (wand->debug != MagickFalse)
1611 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1614 if (CurrentContext->density != (char *) NULL)
1622 flags=ParseGeometry(CurrentContext->density,&geometry_info);
1623 *x=geometry_info.rho;
1624 *y=geometry_info.sigma;
1625 if ((flags & SigmaValue) == MagickFalse)
1632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1636 % D r a w G e t F o n t S i z e %
1640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1642 % DrawGetFontSize() returns the font pointsize used when annotating with text.
1644 % The format of the DrawGetFontSize method is:
1646 % double DrawGetFontSize(const DrawingWand *wand)
1648 % A description of each parameter follows:
1650 % o wand: the drawing wand.
1653 WandExport double DrawGetFontSize(const DrawingWand *wand)
1655 assert(wand != (const DrawingWand *) NULL);
1656 assert(wand->signature == WandSignature);
1657 if (wand->debug != MagickFalse)
1658 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1659 return(CurrentContext->pointsize);
1663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1667 % D r a w G e t F o n t S t r e t c h %
1671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673 % DrawGetFontStretch() returns the font stretch used when annotating with text.
1675 % The format of the DrawGetFontStretch method is:
1677 % StretchType DrawGetFontStretch(const DrawingWand *wand)
1679 % A description of each parameter follows:
1681 % o wand: the drawing wand.
1684 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1686 assert(wand != (const DrawingWand *) NULL);
1687 assert(wand->signature == WandSignature);
1688 if (wand->debug != MagickFalse)
1689 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1690 return(CurrentContext->stretch);
1694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1698 % D r a w G e t F o n t S t y l e %
1702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1704 % DrawGetFontStyle() returns the font style used when annotating with text.
1706 % The format of the DrawGetFontStyle method is:
1708 % StyleType DrawGetFontStyle(const DrawingWand *wand)
1710 % A description of each parameter follows:
1712 % o wand: the drawing wand.
1715 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1717 assert(wand != (const DrawingWand *) NULL);
1718 assert(wand->signature == WandSignature);
1719 if (wand->debug != MagickFalse)
1720 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1721 return(CurrentContext->style);
1725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1729 % D r a w G e t F o n t W e i g h t %
1733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1735 % DrawGetFontWeight() returns the font weight used when annotating with text.
1737 % The format of the DrawGetFontWeight method is:
1739 % size_t DrawGetFontWeight(const DrawingWand *wand)
1741 % A description of each parameter follows:
1743 % o wand: the drawing wand.
1746 WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
1748 assert(wand != (const DrawingWand *) NULL);
1749 assert(wand->signature == WandSignature);
1750 if (wand->debug != MagickFalse)
1751 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1752 return(CurrentContext->weight);
1756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1760 % D r a w G e t G r a v i t y %
1764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1766 % DrawGetGravity() returns the text placement gravity used when annotating
1769 % The format of the DrawGetGravity method is:
1771 % GravityType DrawGetGravity(const DrawingWand *wand)
1773 % A description of each parameter follows:
1775 % o wand: the drawing wand.
1778 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1780 assert(wand != (const DrawingWand *) NULL);
1781 assert(wand->signature == WandSignature);
1782 if (wand->debug != MagickFalse)
1783 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1784 return(CurrentContext->gravity);
1788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1792 % D r a w G e t O p a c i t y %
1796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1798 % DrawGetOpacity() returns the opacity used when drawing with the fill
1799 % or stroke color or texture. Fully opaque is 1.0.
1801 % The format of the DrawGetOpacity method is:
1803 % double DrawGetOpacity(const DrawingWand *wand)
1805 % A description of each parameter follows:
1807 % o wand: the drawing wand.
1810 WandExport double DrawGetOpacity(const DrawingWand *wand)
1815 assert(wand != (const DrawingWand *) NULL);
1816 assert(wand->signature == WandSignature);
1817 if (wand->debug != MagickFalse)
1818 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1819 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->opacity);
1824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828 % D r a w G e t S t r o k e A n t i a l i a s %
1832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1834 % DrawGetStrokeAntialias() returns the current stroke antialias setting.
1835 % Stroked outlines are antialiased by default. When antialiasing is disabled
1836 % stroked pixels are thresholded to determine if the stroke color or
1837 % underlying canvas color should be used.
1839 % The format of the DrawGetStrokeAntialias method is:
1841 % MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1843 % A description of each parameter follows:
1845 % o wand: the drawing wand.
1848 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1850 assert(wand != (const DrawingWand *) NULL);
1851 assert(wand->signature == WandSignature);
1852 if (wand->debug != MagickFalse)
1853 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1854 return(CurrentContext->stroke_antialias);
1858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1862 % D r a w G e t S t r o k e C o l o r %
1866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1868 % DrawGetStrokeColor() returns the color used for stroking object outlines.
1870 % The format of the DrawGetStrokeColor method is:
1872 % void DrawGetStrokeColor(const DrawingWand *wand,
1873 $ PixelWand *stroke_color)
1875 % A description of each parameter follows:
1877 % o wand: the drawing wand.
1879 % o stroke_color: Return the stroke color.
1882 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1883 PixelWand *stroke_color)
1885 assert(wand != (const DrawingWand *) NULL);
1886 assert(wand->signature == WandSignature);
1887 assert(stroke_color != (PixelWand *) NULL);
1888 if (wand->debug != MagickFalse)
1889 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1890 PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
1894 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1898 % D r a w G e t S t r o k e D a s h A r r a y %
1902 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1904 % DrawGetStrokeDashArray() returns an array representing the pattern of
1905 % dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
1906 % array must be freed once it is no longer required by the user.
1908 % The format of the DrawGetStrokeDashArray method is:
1910 % double *DrawGetStrokeDashArray(const DrawingWand *wand,
1911 % size_t *number_elements)
1913 % A description of each parameter follows:
1915 % o wand: the drawing wand.
1917 % o number_elements: address to place number of elements in dash array
1920 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
1921 size_t *number_elements)
1926 register const double
1938 assert(wand != (const DrawingWand *) NULL);
1939 assert(wand->signature == WandSignature);
1940 if (wand->debug != MagickFalse)
1941 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1942 assert(number_elements != (size_t *) NULL);
1944 p=CurrentContext->dash_pattern;
1945 if (p != (const double *) NULL)
1949 dash_array=(double *) NULL;
1952 dash_array=(double *) AcquireQuantumMemory((size_t) n,
1953 sizeof(*dash_array));
1954 p=CurrentContext->dash_pattern;
1956 for (i=0; i < (ssize_t) n; i++)
1963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1967 % D r a w G e t S t r o k e D a s h O f f s e t %
1971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1973 % DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1976 % The format of the DrawGetStrokeDashOffset method is:
1978 % double DrawGetStrokeDashOffset(const DrawingWand *wand)
1980 % A description of each parameter follows:
1982 % o wand: the drawing wand.
1985 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1987 assert(wand != (const DrawingWand *) NULL);
1988 assert(wand->signature == WandSignature);
1989 if (wand->debug != MagickFalse)
1990 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1991 return(CurrentContext->dash_offset);
1995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1999 % D r a w G e t S t r o k e L i n e C a p %
2003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005 % DrawGetStrokeLineCap() returns the shape to be used at the end of
2006 % open subpaths when they are stroked. Values of LineCap are
2007 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
2009 % The format of the DrawGetStrokeLineCap method is:
2011 % LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2013 % A description of each parameter follows:
2015 % o wand: the drawing wand.
2018 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
2020 assert(wand != (const DrawingWand *) NULL);
2021 assert(wand->signature == WandSignature);
2022 if (wand->debug != MagickFalse)
2023 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2024 return(CurrentContext->linecap);
2028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2032 % D r a w G e t S t r o k e L i n e J o i n %
2036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2038 % DrawGetStrokeLineJoin() returns the shape to be used at the
2039 % corners of paths (or other vector shapes) when they are
2040 % stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
2043 % The format of the DrawGetStrokeLineJoin method is:
2045 % LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2047 % A description of each parameter follows:
2049 % o wand: the drawing wand.
2052 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2054 assert(wand != (const DrawingWand *) NULL);
2055 assert(wand->signature == WandSignature);
2056 if (wand->debug != MagickFalse)
2057 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2058 return(CurrentContext->linejoin);
2062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2066 % D r a w G e t S t r o k e M i t e r L i m i t %
2070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2072 % DrawGetStrokeMiterLimit() returns the miter limit. When two line
2073 % segments meet at a sharp angle and miter joins have been specified for
2074 % 'lineJoin', it is possible for the miter to extend far beyond the
2075 % thickness of the line stroking the path. The miterLimit' imposes a
2076 % limit on the ratio of the miter length to the 'lineWidth'.
2078 % The format of the DrawGetStrokeMiterLimit method is:
2080 % size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2082 % A description of each parameter follows:
2084 % o wand: the drawing wand.
2087 WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2089 assert(wand != (const DrawingWand *) NULL);
2090 assert(wand->signature == WandSignature);
2091 if (wand->debug != MagickFalse)
2092 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2093 return CurrentContext->miterlimit;
2097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2101 % D r a w G e t S t r o k e O p a c i t y %
2105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2107 % DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
2109 % The format of the DrawGetStrokeOpacity method is:
2111 % double DrawGetStrokeOpacity(const DrawingWand *wand)
2113 % A description of each parameter follows:
2115 % o wand: the drawing wand.
2118 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2123 assert(wand != (const DrawingWand *) NULL);
2124 assert(wand->signature == WandSignature);
2125 if (wand->debug != MagickFalse)
2126 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2127 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity);
2132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2136 % D r a w G e t S t r o k e W i d t h %
2140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2142 % DrawGetStrokeWidth() returns the width of the stroke used to draw object
2145 % The format of the DrawGetStrokeWidth method is:
2147 % double DrawGetStrokeWidth(const DrawingWand *wand)
2149 % A description of each parameter follows:
2151 % o wand: the drawing wand.
2154 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2156 assert(wand != (const DrawingWand *) NULL);
2157 assert(wand->signature == WandSignature);
2158 if (wand->debug != MagickFalse)
2159 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2160 return(CurrentContext->stroke_width);
2164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2168 % D r a w G e t T e x t A l i g n m e n t %
2172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2174 % DrawGetTextAlignment() returns the alignment applied when annotating with
2177 % The format of the DrawGetTextAlignment method is:
2179 % AlignType DrawGetTextAlignment(DrawingWand *wand)
2181 % A description of each parameter follows:
2183 % o wand: the drawing wand.
2186 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2188 assert(wand != (const DrawingWand *) NULL);
2189 assert(wand->signature == WandSignature);
2190 if (wand->debug != MagickFalse)
2191 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2192 return(CurrentContext->align);
2196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2200 % D r a w G e t T e x t A n t i a l i a s %
2204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2206 % DrawGetTextAntialias() returns the current text antialias setting, which
2207 % determines whether text is antialiased. Text is antialiased by default.
2209 % The format of the DrawGetTextAntialias method is:
2211 % MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2213 % A description of each parameter follows:
2215 % o wand: the drawing wand.
2218 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2220 assert(wand != (const DrawingWand *) NULL);
2221 assert(wand->signature == WandSignature);
2222 if (wand->debug != MagickFalse)
2223 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2224 return(CurrentContext->text_antialias);
2228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2232 % D r a w G e t T e x t D e c o r a t i o n %
2236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238 % DrawGetTextDecoration() returns the decoration applied when annotating with
2241 % The format of the DrawGetTextDecoration method is:
2243 % DecorationType DrawGetTextDecoration(DrawingWand *wand)
2245 % A description of each parameter follows:
2247 % o wand: the drawing wand.
2250 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2252 assert(wand != (const DrawingWand *) NULL);
2253 assert(wand->signature == WandSignature);
2254 if (wand->debug != MagickFalse)
2255 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2256 return(CurrentContext->decorate);
2260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264 % D r a w G e t T e x t E n c o d i n g %
2268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2270 % DrawGetTextEncoding() returns a null-terminated string which specifies the
2271 % code set used for text annotations. The string must be freed by the user
2272 % once it is no longer required.
2274 % The format of the DrawGetTextEncoding method is:
2276 % char *DrawGetTextEncoding(const DrawingWand *wand)
2278 % A description of each parameter follows:
2280 % o wand: the drawing wand.
2283 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2285 assert(wand != (const DrawingWand *) NULL);
2286 assert(wand->signature == WandSignature);
2287 if (wand->debug != MagickFalse)
2288 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2289 if (CurrentContext->encoding != (char *) NULL)
2290 return((char *) AcquireString(CurrentContext->encoding));
2291 return((char *) NULL);
2295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2299 % D r a w G e t T e x t K e r n i n g %
2303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2305 % DrawGetTextKerning() gets the spacing between characters in text.
2307 % The format of the DrawSetFontKerning method is:
2309 % double DrawGetTextKerning(DrawingWand *wand)
2311 % A description of each parameter follows:
2313 % o wand: the drawing wand.
2316 WandExport double DrawGetTextKerning(DrawingWand *wand)
2318 assert(wand != (DrawingWand *) NULL);
2319 assert(wand->signature == WandSignature);
2321 if (wand->debug != MagickFalse)
2322 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2323 return(CurrentContext->kerning);
2327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2331 % 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 %
2335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337 % DrawGetTextInterwordSpacing() gets the spacing between lines in text.
2339 % The format of the DrawSetFontKerning method is:
2341 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2343 % A description of each parameter follows:
2345 % o wand: the drawing wand.
2348 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2350 assert(wand != (DrawingWand *) NULL);
2351 assert(wand->signature == WandSignature);
2352 if (wand->debug != MagickFalse)
2353 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2354 return(CurrentContext->interline_spacing);
2358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2362 % 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 %
2366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2368 % DrawGetTextInterwordSpacing() gets the spacing between words in text.
2370 % The format of the DrawSetFontKerning method is:
2372 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2374 % A description of each parameter follows:
2376 % o wand: the drawing wand.
2379 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2381 assert(wand != (DrawingWand *) NULL);
2382 assert(wand->signature == WandSignature);
2383 if (wand->debug != MagickFalse)
2384 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2385 return(CurrentContext->interword_spacing);
2389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2393 % D r a w G e t V e c t o r G r a p h i c s %
2397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2399 % DrawGetVectorGraphics() returns a null-terminated string which specifies the
2400 % vector graphics generated by any graphics calls made since the wand was
2401 % instantiated. The string must be freed by the user once it is no longer
2404 % The format of the DrawGetVectorGraphics method is:
2406 % char *DrawGetVectorGraphics(const DrawingWand *wand)
2408 % A description of each parameter follows:
2410 % o wand: the drawing wand.
2414 static inline void SetMagickPixelPacket(const Image *image,
2415 const PixelPacket *color,const IndexPacket *index,MagickPixelPacket *pixel)
2417 pixel->red=(MagickRealType) color->red;
2418 pixel->green=(MagickRealType) color->green;
2419 pixel->blue=(MagickRealType) color->blue;
2420 if (image->matte != MagickFalse)
2421 pixel->opacity=(MagickRealType) color->opacity;
2422 if (((image->colorspace == CMYKColorspace) ||
2423 (image->storage_class == PseudoClass)) &&
2424 (index != (const IndexPacket *) NULL))
2425 pixel->index=(MagickRealType) *index;
2428 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2431 value[MaxTextExtent],
2444 assert(wand != (const DrawingWand *) NULL);
2445 assert(wand->signature == WandSignature);
2446 if (wand->debug != MagickFalse)
2447 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2448 xml_info=NewXMLTreeTag("drawing-wand");
2449 if (xml_info == (XMLTreeInfo *) NULL)
2450 return(char *) NULL;
2451 GetMagickPixelPacket(wand->image,&pixel);
2452 child=AddChildToXMLTree(xml_info,"clip-path",0);
2453 if (child != (XMLTreeInfo *) NULL)
2454 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2455 child=AddChildToXMLTree(xml_info,"clip-units",0);
2456 if (child != (XMLTreeInfo *) NULL)
2458 (void) CopyMagickString(value,MagickOptionToMnemonic(
2459 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),MaxTextExtent);
2460 (void) SetXMLTreeContent(child,value);
2462 child=AddChildToXMLTree(xml_info,"decorate",0);
2463 if (child != (XMLTreeInfo *) NULL)
2465 (void) CopyMagickString(value,MagickOptionToMnemonic(
2466 MagickDecorateOptions,(ssize_t) CurrentContext->decorate),MaxTextExtent);
2467 (void) SetXMLTreeContent(child,value);
2469 child=AddChildToXMLTree(xml_info,"encoding",0);
2470 if (child != (XMLTreeInfo *) NULL)
2471 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2472 child=AddChildToXMLTree(xml_info,"fill",0);
2473 if (child != (XMLTreeInfo *) NULL)
2475 if (CurrentContext->fill.opacity != OpaqueOpacity)
2476 pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2477 MagickTrue : MagickFalse;
2478 SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2479 (const IndexPacket *) NULL,&pixel);
2480 GetColorTuple(&pixel,MagickTrue,value);
2481 (void) SetXMLTreeContent(child,value);
2483 child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2484 if (child != (XMLTreeInfo *) NULL)
2486 (void) FormatMagickString(value,MaxTextExtent,"%g",
2487 (double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity));
2488 (void) SetXMLTreeContent(child,value);
2490 child=AddChildToXMLTree(xml_info,"fill-rule",0);
2491 if (child != (XMLTreeInfo *) NULL)
2493 (void) CopyMagickString(value,MagickOptionToMnemonic(
2494 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),MaxTextExtent);
2495 (void) SetXMLTreeContent(child,value);
2497 child=AddChildToXMLTree(xml_info,"font",0);
2498 if (child != (XMLTreeInfo *) NULL)
2499 (void) SetXMLTreeContent(child,CurrentContext->font);
2500 child=AddChildToXMLTree(xml_info,"font-family",0);
2501 if (child != (XMLTreeInfo *) NULL)
2502 (void) SetXMLTreeContent(child,CurrentContext->family);
2503 child=AddChildToXMLTree(xml_info,"font-size",0);
2504 if (child != (XMLTreeInfo *) NULL)
2506 (void) FormatMagickString(value,MaxTextExtent,"%g",
2507 CurrentContext->pointsize);
2508 (void) SetXMLTreeContent(child,value);
2510 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2511 if (child != (XMLTreeInfo *) NULL)
2513 (void) CopyMagickString(value,MagickOptionToMnemonic(
2514 MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
2515 (void) SetXMLTreeContent(child,value);
2517 child=AddChildToXMLTree(xml_info,"font-style",0);
2518 if (child != (XMLTreeInfo *) NULL)
2520 (void) CopyMagickString(value,MagickOptionToMnemonic(
2521 MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
2522 (void) SetXMLTreeContent(child,value);
2524 child=AddChildToXMLTree(xml_info,"font-weight",0);
2525 if (child != (XMLTreeInfo *) NULL)
2527 (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
2528 CurrentContext->weight);
2529 (void) SetXMLTreeContent(child,value);
2531 child=AddChildToXMLTree(xml_info,"gravity",0);
2532 if (child != (XMLTreeInfo *) NULL)
2534 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickGravityOptions,
2535 (ssize_t) CurrentContext->gravity),MaxTextExtent);
2536 (void) SetXMLTreeContent(child,value);
2538 child=AddChildToXMLTree(xml_info,"stroke",0);
2539 if (child != (XMLTreeInfo *) NULL)
2541 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2542 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2543 MagickTrue : MagickFalse;
2544 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2545 (const IndexPacket *) NULL,&pixel);
2546 GetColorTuple(&pixel,MagickTrue,value);
2547 (void) SetXMLTreeContent(child,value);
2549 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2550 if (child != (XMLTreeInfo *) NULL)
2552 (void) FormatMagickString(value,MaxTextExtent,"%d",
2553 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2554 (void) SetXMLTreeContent(child,value);
2556 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2557 if ((child != (XMLTreeInfo *) NULL) &&
2558 (CurrentContext->dash_pattern != (double *) NULL))
2563 dash_pattern=AcquireString((char *) NULL);
2564 for (i=0; CurrentContext->dash_pattern[i] != 0.0; i++)
2567 (void) ConcatenateString(&dash_pattern,",");
2568 (void) FormatMagickString(value,MaxTextExtent,"%g",
2569 CurrentContext->dash_pattern[i]);
2570 (void) ConcatenateString(&dash_pattern,value);
2572 (void) SetXMLTreeContent(child,dash_pattern);
2573 dash_pattern=DestroyString(dash_pattern);
2575 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2576 if (child != (XMLTreeInfo *) NULL)
2578 (void) FormatMagickString(value,MaxTextExtent,"%g",
2579 CurrentContext->dash_offset);
2580 (void) SetXMLTreeContent(child,value);
2582 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2583 if (child != (XMLTreeInfo *) NULL)
2585 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickLineCapOptions,
2586 (ssize_t) CurrentContext->linecap),MaxTextExtent);
2587 (void) SetXMLTreeContent(child,value);
2589 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2590 if (child != (XMLTreeInfo *) NULL)
2592 (void) CopyMagickString(value,MagickOptionToMnemonic(
2593 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2595 (void) SetXMLTreeContent(child,value);
2597 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2598 if (child != (XMLTreeInfo *) NULL)
2600 (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
2601 CurrentContext->miterlimit);
2602 (void) SetXMLTreeContent(child,value);
2604 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2605 if (child != (XMLTreeInfo *) NULL)
2607 (void) FormatMagickString(value,MaxTextExtent,"%g",
2608 (double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity));
2609 (void) SetXMLTreeContent(child,value);
2611 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2612 if (child != (XMLTreeInfo *) NULL)
2614 (void) FormatMagickString(value,MaxTextExtent,"%g",
2615 CurrentContext->stroke_width);
2616 (void) SetXMLTreeContent(child,value);
2618 child=AddChildToXMLTree(xml_info,"text-align",0);
2619 if (child != (XMLTreeInfo *) NULL)
2621 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickAlignOptions,
2622 (ssize_t) CurrentContext->align),MaxTextExtent);
2623 (void) SetXMLTreeContent(child,value);
2625 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2626 if (child != (XMLTreeInfo *) NULL)
2628 (void) FormatMagickString(value,MaxTextExtent,"%d",
2629 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2630 (void) SetXMLTreeContent(child,value);
2632 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2633 if (child != (XMLTreeInfo *) NULL)
2635 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2636 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2637 MagickTrue : MagickFalse;
2638 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2639 (const IndexPacket *) NULL,&pixel);
2640 GetColorTuple(&pixel,MagickTrue,value);
2641 (void) SetXMLTreeContent(child,value);
2643 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2644 if (child != (XMLTreeInfo *) NULL)
2645 (void) SetXMLTreeContent(child,wand->mvg);
2646 xml=XMLTreeInfoToXML(xml_info);
2647 xml_info=DestroyXMLTree(xml_info);
2652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2656 % D r a w G e t T e x t U n d e r C o l o r %
2660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2662 % DrawGetTextUnderColor() returns the color of a background rectangle
2663 % to place under text annotations.
2665 % The format of the DrawGetTextUnderColor method is:
2667 % void DrawGetTextUnderColor(const DrawingWand *wand,
2668 % PixelWand *under_color)
2670 % A description of each parameter follows:
2672 % o wand: the drawing wand.
2674 % o under_color: Return the under color.
2677 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2678 PixelWand *under_color)
2680 assert(wand != (const DrawingWand *) NULL);
2681 assert(wand->signature == WandSignature);
2682 assert(under_color != (PixelWand *) NULL);
2683 if (wand->debug != MagickFalse)
2684 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2685 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2699 % DrawLine() draws a line on the image using the current stroke color,
2700 % stroke opacity, and stroke width.
2702 % The format of the DrawLine method is:
2704 % void DrawLine(DrawingWand *wand,const double sx,const double sy,
2705 % const double ex,const double ey)
2707 % A description of each parameter follows:
2709 % o wand: the drawing wand.
2711 % o sx: starting x ordinate
2713 % o sy: starting y ordinate
2715 % o ex: ending x ordinate
2717 % o ey: ending y ordinate
2720 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2721 const double ex,const double ey)
2723 assert(wand != (DrawingWand *) NULL);
2724 assert(wand->signature == WandSignature);
2725 if (wand->debug != MagickFalse)
2726 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2727 (void) MvgPrintf(wand,"line %g,%g %g,%g\n",sx,sy,ex,ey);
2731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2735 % D r a w M a t t e %
2739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2741 % DrawMatte() paints on the image's opacity channel in order to set effected
2742 % pixels to transparent.
2743 % to influence the opacity of pixels. The available paint
2746 % PointMethod: Select the target pixel
2747 % ReplaceMethod: Select any pixel that matches the target pixel.
2748 % FloodfillMethod: Select the target pixel and matching neighbors.
2749 % FillToBorderMethod: Select the target pixel and neighbors not matching
2751 % ResetMethod: Select all pixels.
2753 % The format of the DrawMatte method is:
2755 % void DrawMatte(DrawingWand *wand,const double x,const double y,
2756 % const PaintMethod paint_method)
2758 % A description of each parameter follows:
2760 % o wand: the drawing wand.
2766 % o paint_method: paint method.
2769 WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2770 const PaintMethod paint_method)
2772 assert(wand != (DrawingWand *) NULL);
2773 assert(wand->signature == WandSignature);
2774 if (wand->debug != MagickFalse)
2775 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2776 (void) MvgPrintf(wand,"matte %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
2777 MagickMethodOptions,(ssize_t) paint_method));
2781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2785 % D r a w P a t h C l o s e %
2789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2791 % DrawPathClose() adds a path element to the current path which closes the
2792 % current subpath by drawing a straight line from the current point to the
2793 % current subpath's most recent starting point (usually, the most recent
2796 % The format of the DrawPathClose method is:
2798 % void DrawPathClose(DrawingWand *wand)
2800 % A description of each parameter follows:
2802 % o wand: the drawing wand.
2805 WandExport void DrawPathClose(DrawingWand *wand)
2807 assert(wand != (DrawingWand *) NULL);
2808 assert(wand->signature == WandSignature);
2809 if (wand->debug != MagickFalse)
2810 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2811 (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2820 % D r a w P a t h C u r v e T o A b s o l u t e %
2824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2826 % DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2827 % point to (x,y) using (x1,y1) as the control point at the beginning of
2828 % the curve and (x2,y2) as the control point at the end of the curve using
2829 % absolute coordinates. At the end of the command, the new current point
2830 % becomes the final (x,y) coordinate pair used in the polybezier.
2832 % The format of the DrawPathCurveToAbsolute method is:
2834 % void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2835 % const double y1,const double x2,const double y2,const double x,
2838 % A description of each parameter follows:
2840 % o wand: the drawing wand.
2842 % o x1: x ordinate of control point for curve beginning
2844 % o y1: y ordinate of control point for curve beginning
2846 % o x2: x ordinate of control point for curve ending
2848 % o y2: y ordinate of control point for curve ending
2850 % o x: x ordinate of the end of the curve
2852 % o y: y ordinate of the end of the curve
2856 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2857 const double x1,const double y1,const double x2,const double y2,
2858 const double x,const double y)
2860 assert(wand != (DrawingWand *) NULL);
2861 assert(wand->signature == WandSignature);
2862 if (wand->debug != MagickFalse)
2863 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2864 if ((wand->path_operation != PathCurveToOperation) ||
2865 (wand->path_mode != mode))
2867 wand->path_operation=PathCurveToOperation;
2868 wand->path_mode=mode;
2869 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g %g,%g",
2870 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2873 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g %g,%g",x1,y1,
2877 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2878 const double y1,const double x2,const double y2,const double x,const double y)
2880 assert(wand != (DrawingWand *) NULL);
2881 assert(wand->signature == WandSignature);
2882 if (wand->debug != MagickFalse)
2883 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2884 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2892 % D r a w P a t h C u r v e T o R e l a t i v e %
2896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2898 % DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2899 % point to (x,y) using (x1,y1) as the control point at the beginning of
2900 % the curve and (x2,y2) as the control point at the end of the curve using
2901 % relative coordinates. At the end of the command, the new current point
2902 % becomes the final (x,y) coordinate pair used in the polybezier.
2904 % The format of the DrawPathCurveToRelative method is:
2906 % void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2907 % const double y1,const double x2,const double y2,const double x,
2910 % A description of each parameter follows:
2912 % o wand: the drawing wand.
2914 % o x1: x ordinate of control point for curve beginning
2916 % o y1: y ordinate of control point for curve beginning
2918 % o x2: x ordinate of control point for curve ending
2920 % o y2: y ordinate of control point for curve ending
2922 % o x: x ordinate of the end of the curve
2924 % o y: y ordinate of the end of the curve
2927 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2928 const double y1,const double x2,const double y2,const double x,const double y)
2930 assert(wand != (DrawingWand *) NULL);
2931 assert(wand->signature == WandSignature);
2932 if (wand->debug != MagickFalse)
2933 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2934 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2942 % D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r A b s o l u t e %
2946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2948 % DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2949 % from the current point to (x,y) using (x1,y1) as the control point using
2950 % absolute coordinates. At the end of the command, the new current point
2951 % becomes the final (x,y) coordinate pair used in the polybezier.
2953 % The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2955 % void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2956 % const double x1,const double y1,onst double x,const double y)
2958 % A description of each parameter follows:
2960 % o wand: the drawing wand.
2962 % o x1: x ordinate of the control point
2964 % o y1: y ordinate of the control point
2966 % o x: x ordinate of final point
2968 % o y: y ordinate of final point
2972 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2973 const PathMode mode,const double x1,double y1,const double x,const double y)
2975 assert(wand != (DrawingWand *) NULL);
2976 assert(wand->signature == WandSignature);
2977 if (wand->debug != MagickFalse)
2978 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2979 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2980 (wand->path_mode != mode))
2982 wand->path_operation=PathCurveToQuadraticBezierOperation;
2983 wand->path_mode=mode;
2984 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g",
2985 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
2988 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x1,y1,x,y);
2991 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2992 const double x1,const double y1,const double x,const double y)
2994 assert(wand != (DrawingWand *) NULL);
2995 assert(wand->signature == WandSignature);
2996 if (wand->debug != MagickFalse)
2997 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2998 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
3002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3006 % D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r R e l a t i v e
3010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3012 % DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
3013 % from the current point to (x,y) using (x1,y1) as the control point using
3014 % relative coordinates. At the end of the command, the new current point
3015 % becomes the final (x,y) coordinate pair used in the polybezier.
3017 % The format of the DrawPathCurveToQuadraticBezierRelative method is:
3019 % void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3020 % const double x1,const double y1,const double x,const double y)
3022 % A description of each parameter follows:
3024 % o wand: the drawing wand.
3026 % o x1: x ordinate of the control point
3028 % o y1: y ordinate of the control point
3030 % o x: x ordinate of final point
3032 % o y: y ordinate of final point
3035 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
3036 const double x1,const double y1,const double x,const double y)
3038 assert(wand != (DrawingWand *) NULL);
3039 assert(wand->signature == WandSignature);
3040 if (wand->debug != MagickFalse)
3041 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3042 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
3046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3050 % D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h %
3054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3056 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3057 % Bezier curve (using absolute coordinates) from the current point to
3058 % (x,y). The control point is assumed to be the reflection of the
3059 % control point on the previous command relative to the current
3060 % point. (If there is no previous command or if the previous command was
3061 % not a DrawPathCurveToQuadraticBezierAbsolute,
3062 % DrawPathCurveToQuadraticBezierRelative,
3063 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3064 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3065 % is coincident with the current point.). At the end of the command, the
3066 % new current point becomes the final (x,y) coordinate pair used in the
3069 % The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3071 % void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3072 % DrawingWand *wand,const double x,const double y)
3074 % A description of each parameter follows:
3076 % o wand: the drawing wand.
3078 % o x: x ordinate of final point
3080 % o y: y ordinate of final point
3084 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3085 const PathMode mode,const double x,const double y)
3087 assert(wand != (DrawingWand *) NULL);
3088 assert(wand->signature == WandSignature);
3089 if (wand->debug != MagickFalse)
3090 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3091 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3092 (wand->path_mode != mode))
3094 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3095 wand->path_mode=mode;
3096 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3100 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3103 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3104 const double x,const double y)
3106 assert(wand != (DrawingWand *) NULL);
3107 assert(wand->signature == WandSignature);
3108 if (wand->debug != MagickFalse)
3109 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3110 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3118 % D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h %
3122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3124 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3125 % curve (using relative coordinates) from the current point to (x,y). The
3126 % control point is assumed to be the reflection of the control point on the
3127 % previous command relative to the current point. (If there is no previous
3128 % command or if the previous command was not a
3129 % DrawPathCurveToQuadraticBezierAbsolute,
3130 % DrawPathCurveToQuadraticBezierRelative,
3131 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3132 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3133 % coincident with the current point.). At the end of the command, the new
3134 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3136 % The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3138 % void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3139 % const double x,const double y)
3141 % A description of each parameter follows:
3143 % o wand: the drawing wand.
3145 % o x: x ordinate of final point
3147 % o y: y ordinate of final point
3150 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3151 const double x,const double y)
3153 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3161 % D r a w P a t h C u r v e T o S m o o t h A b s o l u t e %
3165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3167 % DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3168 % current point to (x,y) using absolute coordinates. The first control
3169 % point is assumed to be the reflection of the second control point on
3170 % the previous command relative to the current point. (If there is no
3171 % previous command or if the previous command was not an
3172 % DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3173 % DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3174 % the first control point is coincident with the current point.) (x2,y2)
3175 % is the second control point (i.e., the control point at the end of the
3176 % curve). At the end of the command, the new current point becomes the
3177 % final (x,y) coordinate pair used in the polybezier.
3179 % The format of the DrawPathCurveToSmoothAbsolute method is:
3181 % void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3182 % const double x2const double y2,const double x,const double y)
3184 % A description of each parameter follows:
3186 % o wand: the drawing wand.
3188 % o x2: x ordinate of second control point
3190 % o y2: y ordinate of second control point
3192 % o x: x ordinate of termination point
3194 % o y: y ordinate of termination point
3198 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3199 const double x2,const double y2,const double x,const double y)
3201 assert(wand != (DrawingWand *) NULL);
3202 assert(wand->signature == WandSignature);
3203 if (wand->debug != MagickFalse)
3204 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3205 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3206 (wand->path_mode != mode))
3208 wand->path_operation=PathCurveToSmoothOperation;
3209 wand->path_mode=mode;
3210 (void) MvgAutoWrapPrintf(wand,"%c%g,%g %g,%g",
3211 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
3214 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x2,y2,x,y);
3217 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3218 const double y2,const double x,const double y)
3220 assert(wand != (DrawingWand *) NULL);
3221 assert(wand->signature == WandSignature);
3222 if (wand->debug != MagickFalse)
3223 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3224 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3232 % D r a w P a t h C u r v e T o S m o o t h R e l a t i v e %
3236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3238 % DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3239 % point to (x,y) using relative coordinates. The first control point is
3240 % assumed to be the reflection of the second control point on the previous
3241 % command relative to the current point. (If there is no previous command or
3242 % if the previous command was not an DrawPathCurveToAbsolute,
3243 % DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3244 % DrawPathCurveToSmoothRelative, assume the first control point is coincident
3245 % with the current point.) (x2,y2) is the second control point (i.e., the
3246 % control point at the end of the curve). At the end of the command, the new
3247 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3249 % The format of the DrawPathCurveToSmoothRelative method is:
3251 % void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3252 % const double x2,const double y2,const double x,const double y)
3254 % A description of each parameter follows:
3256 % o wand: the drawing wand.
3258 % o x2: x ordinate of second control point
3260 % o y2: y ordinate of second control point
3262 % o x: x ordinate of termination point
3264 % o y: y ordinate of termination point
3267 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3268 const double y2,const double x,const double y)
3270 assert(wand != (DrawingWand *) NULL);
3271 assert(wand->signature == WandSignature);
3272 if (wand->debug != MagickFalse)
3273 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3274 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3282 % D r a w P a t h E l l i p t i c A r c A b s o l u t e %
3286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3288 % DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3289 % to (x, y) using absolute coordinates. The size and orientation of the
3290 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3291 % indicates how the ellipse as a whole is rotated relative to the current
3292 % coordinate system. The center (cx, cy) of the ellipse is calculated
3293 % automagically to satisfy the constraints imposed by the other parameters.
3294 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3295 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3296 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3297 % clock-wise rotation.
3299 % The format of the DrawPathEllipticArcAbsolute method is:
3301 % void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3302 % const double rx,const double ry,const double x_axis_rotation,
3303 % const MagickBooleanType large_arc_flag,
3304 % const MagickBooleanType sweep_flag,const double x,const double y)
3306 % A description of each parameter follows:
3308 % o wand: the drawing wand.
3314 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3315 % relative to the current coordinate system
3317 % o large_arc_flag: If non-zero (true) then draw the larger of the
3320 % o sweep_flag: If non-zero (true) then draw the arc matching a
3321 % clock-wise rotation
3326 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3327 const double rx,const double ry,const double x_axis_rotation,
3328 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3329 const double x,const double y)
3331 assert(wand != (DrawingWand *) NULL);
3332 assert(wand->signature == WandSignature);
3333 if (wand->debug != MagickFalse)
3334 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3335 if ((wand->path_operation != PathEllipticArcOperation) ||
3336 (wand->path_mode != mode))
3338 wand->path_operation=PathEllipticArcOperation;
3339 wand->path_mode=mode;
3340 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g %u %u %g,%g",
3341 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3342 large_arc_flag,sweep_flag,x,y);
3345 (void) MvgAutoWrapPrintf(wand," %g,%g %g %u %u %g,%g",rx,ry,
3346 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3349 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3350 const double ry,const double x_axis_rotation,
3351 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3352 const double x,const double y)
3354 assert(wand != (DrawingWand *) NULL);
3355 assert(wand->signature == WandSignature);
3356 if (wand->debug != MagickFalse)
3357 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3358 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3359 large_arc_flag,sweep_flag,x,y);
3363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3367 % D r a w P a t h E l l i p t i c A r c R e l a t i v e %
3371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3373 % DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3374 % to (x, y) using relative coordinates. The size and orientation of the
3375 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3376 % indicates how the ellipse as a whole is rotated relative to the current
3377 % coordinate system. The center (cx, cy) of the ellipse is calculated
3378 % automagically to satisfy the constraints imposed by the other parameters.
3379 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3380 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3381 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3382 % clock-wise rotation.
3384 % The format of the DrawPathEllipticArcRelative method is:
3386 % void DrawPathEllipticArcRelative(DrawingWand *wand,
3387 % const double rx,const double ry,const double x_axis_rotation,
3388 % const MagickBooleanType large_arc_flag,
3389 % const MagickBooleanType sweep_flag,const double x,const double y)
3391 % A description of each parameter follows:
3393 % o wand: the drawing wand.
3399 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3400 % relative to the current coordinate system
3402 % o large_arc_flag: If non-zero (true) then draw the larger of the
3405 % o sweep_flag: If non-zero (true) then draw the arc matching a
3406 % clock-wise rotation
3409 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3410 const double ry,const double x_axis_rotation,
3411 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3412 const double x,const double y)
3414 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3415 large_arc_flag,sweep_flag,x,y);
3419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3423 % D r a w P a t h F i n i s h %
3427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3429 % DrawPathFinish() terminates the current path.
3431 % The format of the DrawPathFinish method is:
3433 % void DrawPathFinish(DrawingWand *wand)
3435 % A description of each parameter follows:
3437 % o wand: the drawing wand.
3440 WandExport void DrawPathFinish(DrawingWand *wand)
3442 assert(wand != (DrawingWand *) NULL);
3443 assert(wand->signature == WandSignature);
3444 if (wand->debug != MagickFalse)
3445 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3446 (void) MvgPrintf(wand,"'\n");
3447 wand->path_operation=PathDefaultOperation;
3448 wand->path_mode=DefaultPathMode;
3452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3456 % D r a w P a t h L i n e T o A b s o l u t e %
3460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3462 % DrawPathLineToAbsolute() draws a line path from the current point to the
3463 % given coordinate using absolute coordinates. The coordinate then becomes
3464 % the new current point.
3466 % The format of the DrawPathLineToAbsolute method is:
3468 % void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3471 % A description of each parameter follows:
3473 % o wand: the drawing wand.
3475 % o x: target x ordinate
3477 % o y: target y ordinate
3480 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3481 const double x,const double y)
3483 assert(wand != (DrawingWand *) NULL);
3484 assert(wand->signature == WandSignature);
3485 if (wand->debug != MagickFalse)
3486 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3487 if ((wand->path_operation != PathLineToOperation) ||
3488 (wand->path_mode != mode))
3490 wand->path_operation=PathLineToOperation;
3491 wand->path_mode=mode;
3492 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3496 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3499 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3502 assert(wand != (DrawingWand *) NULL);
3503 assert(wand->signature == WandSignature);
3504 if (wand->debug != MagickFalse)
3505 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3506 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3514 % D r a w P a t h L i n e T o R e l a t i v e %
3518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3520 % DrawPathLineToRelative() draws a line path from the current point to the
3521 % given coordinate using relative coordinates. The coordinate then becomes
3522 % the new current point.
3524 % The format of the DrawPathLineToRelative method is:
3526 % void DrawPathLineToRelative(DrawingWand *wand,const double x,
3529 % A description of each parameter follows:
3531 % o wand: the drawing wand.
3533 % o x: target x ordinate
3535 % o y: target y ordinate
3538 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3541 assert(wand != (DrawingWand *) NULL);
3542 assert(wand->signature == WandSignature);
3543 if (wand->debug != MagickFalse)
3544 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3545 DrawPathLineTo(wand,RelativePathMode,x,y);
3549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3553 % D r a w P a t h L i n e T o H o r i z o n t a l A b s o l u t e %
3557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3559 % DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3560 % current point to the target point using absolute coordinates. The target
3561 % point then becomes the new current point.
3563 % The format of the DrawPathLineToHorizontalAbsolute method is:
3565 % void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3566 % const PathMode mode,const double x)
3568 % A description of each parameter follows:
3570 % o wand: the drawing wand.
3572 % o x: target x ordinate
3576 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3579 assert(wand != (DrawingWand *) NULL);
3580 assert(wand->signature == WandSignature);
3581 if (wand->debug != MagickFalse)
3582 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3583 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3584 (wand->path_mode != mode))
3586 wand->path_operation=PathLineToHorizontalOperation;
3587 wand->path_mode=mode;
3588 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3592 (void) MvgAutoWrapPrintf(wand," %g",x);
3595 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3598 assert(wand != (DrawingWand *) NULL);
3599 assert(wand->signature == WandSignature);
3600 if (wand->debug != MagickFalse)
3601 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3602 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3610 % D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e %
3614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3616 % DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3617 % current point to the target point using relative coordinates. The target
3618 % point then becomes the new current point.
3620 % The format of the DrawPathLineToHorizontalRelative method is:
3622 % void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3625 % A description of each parameter follows:
3627 % o wand: the drawing wand.
3629 % o x: target x ordinate
3632 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3635 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3643 % D r a w P a t h L i n e T o V e r t i c a l A b s o l u t e %
3647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3649 % DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3650 % current point to the target point using absolute coordinates. The target
3651 % point then becomes the new current point.
3653 % The format of the DrawPathLineToVerticalAbsolute method is:
3655 % void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3658 % A description of each parameter follows:
3660 % o wand: the drawing wand.
3662 % o y: target y ordinate
3666 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3669 assert(wand != (DrawingWand *) NULL);
3670 assert(wand->signature == WandSignature);
3671 if (wand->debug != MagickFalse)
3672 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3673 if ((wand->path_operation != PathLineToVerticalOperation) ||
3674 (wand->path_mode != mode))
3676 wand->path_operation=PathLineToVerticalOperation;
3677 wand->path_mode=mode;
3678 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3682 (void) MvgAutoWrapPrintf(wand," %g",y);
3685 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3687 assert(wand != (DrawingWand *) NULL);
3688 assert(wand->signature == WandSignature);
3689 if (wand->debug != MagickFalse)
3690 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3691 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3699 % D r a w P a t h L i n e T o V e r t i c a l R e l a t i v e %
3703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3705 % DrawPathLineToVerticalRelative() draws a vertical line path from the
3706 % current point to the target point using relative coordinates. The target
3707 % point then becomes the new current point.
3709 % The format of the DrawPathLineToVerticalRelative method is:
3711 % void DrawPathLineToVerticalRelative(DrawingWand *wand,
3714 % A description of each parameter follows:
3716 % o wand: the drawing wand.
3718 % o y: target y ordinate
3721 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3723 assert(wand != (DrawingWand *) NULL);
3724 assert(wand->signature == WandSignature);
3725 if (wand->debug != MagickFalse)
3726 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3727 DrawPathLineToVertical(wand,RelativePathMode,y);
3730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3734 % D r a w P a t h M o v e T o A b s o l u t e %
3738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3740 % DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3741 % using absolute coordinates. The current point then becomes the
3742 % specified coordinate.
3744 % The format of the DrawPathMoveToAbsolute method is:
3746 % void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3749 % A description of each parameter follows:
3751 % o wand: the drawing wand.
3753 % o x: target x ordinate
3755 % o y: target y ordinate
3759 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3762 assert(wand != (DrawingWand *) NULL);
3763 assert(wand->signature == WandSignature);
3764 if (wand->debug != MagickFalse)
3765 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3766 if ((wand->path_operation != PathMoveToOperation) ||
3767 (wand->path_mode != mode))
3769 wand->path_operation=PathMoveToOperation;
3770 wand->path_mode=mode;
3771 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3775 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3778 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3781 assert(wand != (DrawingWand *) NULL);
3782 assert(wand->signature == WandSignature);
3783 if (wand->debug != MagickFalse)
3784 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3785 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3793 % D r a w P a t h M o v e T o R e l a t i v e %
3797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3799 % DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3800 % relative coordinates. The current point then becomes the specified
3803 % The format of the DrawPathMoveToRelative method is:
3805 % void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3808 % A description of each parameter follows:
3810 % o wand: the drawing wand.
3812 % o x: target x ordinate
3814 % o y: target y ordinate
3817 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3820 assert(wand != (DrawingWand *) NULL);
3821 assert(wand->signature == WandSignature);
3822 if (wand->debug != MagickFalse)
3823 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3824 DrawPathMoveTo(wand,RelativePathMode,x,y);
3828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3832 % D r a w P a t h S t a r t %
3836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3838 % DrawPathStart() declares the start of a path drawing list which is terminated
3839 % by a matching DrawPathFinish() command. All other DrawPath commands must
3840 % be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3841 % is because path drawing commands are subordinate commands and they do not
3842 % function by themselves.
3844 % The format of the DrawPathStart method is:
3846 % void DrawPathStart(DrawingWand *wand)
3848 % A description of each parameter follows:
3850 % o wand: the drawing wand.
3853 WandExport void DrawPathStart(DrawingWand *wand)
3855 assert(wand != (DrawingWand *) NULL);
3856 assert(wand->signature == WandSignature);
3857 if (wand->debug != MagickFalse)
3858 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3859 (void) MvgPrintf(wand,"path '");
3860 wand->path_operation=PathDefaultOperation;
3861 wand->path_mode=DefaultPathMode;
3865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3869 % D r a w P o i n t %
3873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3875 % DrawPoint() draws a point using the current fill color.
3877 % The format of the DrawPoint method is:
3879 % void DrawPoint(DrawingWand *wand,const double x,const double y)
3881 % A description of each parameter follows:
3883 % o wand: the drawing wand.
3885 % o x: target x coordinate
3887 % o y: target y coordinate
3890 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3892 assert(wand != (DrawingWand *) NULL);
3893 assert(wand->signature == WandSignature);
3894 if (wand->debug != MagickFalse)
3895 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3896 (void) MvgPrintf(wand,"point %g,%g\n",x,y);
3900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3904 % D r a w P o l y g o n %
3908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3910 % DrawPolygon() draws a polygon using the current stroke, stroke width, and
3911 % fill color or texture, using the specified array of coordinates.
3913 % The format of the DrawPolygon method is:
3915 % void DrawPolygon(DrawingWand *wand,
3916 % const size_t number_coordinates,const PointInfo *coordinates)
3918 % A description of each parameter follows:
3920 % o wand: the drawing wand.
3922 % o number_coordinates: number of coordinates
3924 % o coordinates: coordinate array
3927 WandExport void DrawPolygon(DrawingWand *wand,
3928 const size_t number_coordinates,const PointInfo *coordinates)
3930 assert(wand != (DrawingWand *) NULL);
3931 assert(wand->signature == WandSignature);
3932 if (wand->debug != MagickFalse)
3933 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3934 MvgAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3942 % D r a w P o l y l i n e %
3946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3948 % DrawPolyline() draws a polyline using the current stroke, stroke width, and
3949 % fill color or texture, using the specified array of coordinates.
3951 % The format of the DrawPolyline method is:
3953 % void DrawPolyline(DrawingWand *wand,
3954 % const size_t number_coordinates,const PointInfo *coordinates)
3956 % A description of each parameter follows:
3958 % o wand: the drawing wand.
3960 % o number_coordinates: number of coordinates
3962 % o coordinates: coordinate array
3965 WandExport void DrawPolyline(DrawingWand *wand,
3966 const size_t number_coordinates,const PointInfo *coordinates)
3968 assert(wand != (DrawingWand *) NULL);
3969 assert(wand->signature == WandSignature);
3970 if (wand->debug != MagickFalse)
3971 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3972 MvgAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
3976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3980 % D r a w P o p C l i p P a t h %
3984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3986 % DrawPopClipPath() terminates a clip path definition.
3988 % The format of the DrawPopClipPath method is:
3990 % void DrawPopClipPath(DrawingWand *wand)
3992 % A description of each parameter follows:
3994 % o wand: the drawing wand.
3997 WandExport void DrawPopClipPath(DrawingWand *wand)
3999 assert(wand != (DrawingWand *) NULL);
4000 assert(wand->signature == WandSignature);
4001 if (wand->debug != MagickFalse)
4002 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4003 if (wand->indent_depth > 0)
4004 wand->indent_depth--;
4005 (void) MvgPrintf(wand,"pop clip-path\n");
4009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4013 % D r a w P o p D e f s %
4017 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4019 % DrawPopDefs() terminates a definition list.
4021 % The format of the DrawPopDefs method is:
4023 % void DrawPopDefs(DrawingWand *wand)
4025 % A description of each parameter follows:
4027 % o wand: the drawing wand.
4030 WandExport void DrawPopDefs(DrawingWand *wand)
4032 assert(wand != (DrawingWand *) NULL);
4033 assert(wand->signature == WandSignature);
4034 if (wand->debug != MagickFalse)
4035 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4036 if (wand->indent_depth > 0)
4037 wand->indent_depth--;
4038 (void) MvgPrintf(wand,"pop defs\n");
4042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4046 % D r a w P o p P a t t e r n %
4050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4052 % DrawPopPattern() terminates a pattern definition.
4054 % The format of the DrawPopPattern method is:
4056 % MagickBooleanType DrawPopPattern(DrawingWand *wand)
4058 % A description of each parameter follows:
4060 % o wand: the drawing wand.
4063 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4066 geometry[MaxTextExtent],
4069 assert(wand != (DrawingWand *) NULL);
4070 assert(wand->signature == WandSignature);
4071 if (wand->debug != MagickFalse)
4072 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4073 if (wand->image == (Image *) NULL)
4074 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4075 if (wand->pattern_id == (const char *) NULL)
4077 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4079 return(MagickFalse);
4081 (void) FormatMagickString(key,MaxTextExtent,"%s",wand->pattern_id);
4082 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4083 (void) FormatMagickString(geometry,MaxTextExtent,"%.20gx%.20g%+.20g%+.20g",
4084 (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
4085 (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
4086 (void) SetImageArtifact(wand->image,key,geometry);
4087 wand->pattern_id=DestroyString(wand->pattern_id);
4088 wand->pattern_offset=0;
4089 wand->pattern_bounds.x=0;
4090 wand->pattern_bounds.y=0;
4091 wand->pattern_bounds.width=0;
4092 wand->pattern_bounds.height=0;
4093 wand->filter_off=MagickTrue;
4094 if (wand->indent_depth > 0)
4095 wand->indent_depth--;
4096 (void) MvgPrintf(wand,"pop pattern\n");
4101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4105 % D r a w P u s h C l i p P a t h %
4109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4111 % DrawPushClipPath() starts a clip path definition which is comprized of any
4112 % number of drawing commands and terminated by a DrawPopClipPath() command.
4114 % The format of the DrawPushClipPath method is:
4116 % void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4118 % A description of each parameter follows:
4120 % o wand: the drawing wand.
4122 % o clip_mask_id: string identifier to associate with the clip path for
4126 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4128 assert(wand != (DrawingWand *) NULL);
4129 assert(wand->signature == WandSignature);
4130 if (wand->debug != MagickFalse)
4131 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4132 assert(clip_mask_id != (const char *) NULL);
4133 (void) MvgPrintf(wand,"push clip-path %s\n",clip_mask_id);
4134 wand->indent_depth++;
4138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4142 % D r a w P u s h D e f s %
4146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4148 % DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4149 % command create named elements (e.g. clip-paths, textures, etc.) which
4150 % may safely be processed earlier for the sake of efficiency.
4152 % The format of the DrawPushDefs method is:
4154 % void DrawPushDefs(DrawingWand *wand)
4156 % A description of each parameter follows:
4158 % o wand: the drawing wand.
4161 WandExport void DrawPushDefs(DrawingWand *wand)
4163 assert(wand != (DrawingWand *) NULL);
4164 assert(wand->signature == WandSignature);
4165 if (wand->debug != MagickFalse)
4166 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4167 (void) MvgPrintf(wand,"push defs\n");
4168 wand->indent_depth++;
4172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4176 % D r a w P u s h P a t t e r n %
4180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4182 % DrawPushPattern() indicates that subsequent commands up to a
4183 % DrawPopPattern() command comprise the definition of a named pattern.
4184 % The pattern space is assigned top left corner coordinates, a width
4185 % and height, and becomes its own drawing space. Anything which can
4186 % be drawn may be used in a pattern definition.
4187 % Named patterns may be used as stroke or brush definitions.
4189 % The format of the DrawPushPattern method is:
4191 % MagickBooleanType DrawPushPattern(DrawingWand *wand,
4192 % const char *pattern_id,const double x,const double y,
4193 % const double width,const double height)
4195 % A description of each parameter follows:
4197 % o wand: the drawing wand.
4199 % o pattern_id: pattern identification for later reference
4201 % o x: x ordinate of top left corner
4203 % o y: y ordinate of top left corner
4205 % o width: width of pattern space
4207 % o height: height of pattern space
4210 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4211 const char *pattern_id,const double x,const double y,const double width,
4212 const double height)
4214 assert(wand != (DrawingWand *) NULL);
4215 assert(wand->signature == WandSignature);
4216 if (wand->debug != MagickFalse)
4217 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4218 assert(pattern_id != (const char *) NULL);
4219 if (wand->pattern_id != NULL)
4221 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4223 return(MagickFalse);
4225 wand->filter_off=MagickTrue;
4226 (void) MvgPrintf(wand,"push pattern %s %g,%g %g,%g\n",pattern_id,
4228 wand->indent_depth++;
4229 wand->pattern_id=AcquireString(pattern_id);
4230 wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
4231 wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
4232 wand->pattern_bounds.width=(size_t) floor(width+0.5);
4233 wand->pattern_bounds.height=(size_t) floor(height+0.5);
4234 wand->pattern_offset=wand->mvg_length;
4239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4243 % D r a w R e c t a n g l e %
4247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4249 % DrawRectangle() draws a rectangle given two coordinates and using the
4250 % current stroke, stroke width, and fill settings.
4252 % The format of the DrawRectangle method is:
4254 % void DrawRectangle(DrawingWand *wand,const double x1,
4255 % const double y1,const double x2,const double y2)
4257 % A description of each parameter follows:
4259 % o x1: x ordinate of first coordinate
4261 % o y1: y ordinate of first coordinate
4263 % o x2: x ordinate of second coordinate
4265 % o y2: y ordinate of second coordinate
4268 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4269 const double x2,const double y2)
4271 assert(wand != (DrawingWand *) NULL);
4272 assert(wand->signature == WandSignature);
4273 if (wand->debug != MagickFalse)
4274 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4275 (void) MvgPrintf(wand,"rectangle %g,%g %g,%g\n",x1,y1,x2,y2);
4279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4283 + D r a w R e n d e r %
4287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4289 % DrawRender() renders all preceding drawing commands onto the image.
4291 % The format of the DrawRender method is:
4293 % MagickBooleanType DrawRender(DrawingWand *wand)
4295 % A description of each parameter follows:
4297 % o wand: the drawing wand.
4300 WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4305 assert(wand != (const DrawingWand *) NULL);
4306 assert(wand->signature == WandSignature);
4307 if (wand->debug != MagickFalse)
4308 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4309 CurrentContext->primitive=wand->mvg;
4310 if (wand->debug != MagickFalse)
4311 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4312 if (wand->image == (Image *) NULL)
4313 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4314 status=DrawImage(wand->image,CurrentContext);
4315 InheritException(wand->exception,&wand->image->exception);
4316 CurrentContext->primitive=(char *) NULL;
4321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4325 % D r a w R e s e t V e c t o r G r a p h i c s %
4329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4331 % DrawResetVectorGraphics() resets the vector graphics associated with the
4334 % The format of the DrawResetVectorGraphics method is:
4336 % void DrawResetVectorGraphics(DrawingWand *wand)
4338 % A description of each parameter follows:
4340 % o wand: the drawing wand.
4343 WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4345 assert(wand != (DrawingWand *) NULL);
4346 assert(wand->signature == WandSignature);
4347 if (wand->debug != MagickFalse)
4348 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4349 if (wand->mvg != (char *) NULL)
4350 wand->mvg=DestroyString(wand->mvg);
4357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4361 % D r a w R o t a t e %
4365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367 % DrawRotate() applies the specified rotation to the current coordinate space.
4369 % The format of the DrawRotate method is:
4371 % void DrawRotate(DrawingWand *wand,const double degrees)
4373 % A description of each parameter follows:
4375 % o wand: the drawing wand.
4377 % o degrees: degrees of rotation
4380 WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4382 assert(wand != (DrawingWand *) NULL);
4383 assert(wand->signature == WandSignature);
4384 if (wand->debug != MagickFalse)
4385 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4386 (void) MvgPrintf(wand,"rotate %g\n",degrees);
4390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4394 % D r a w R o u n d R e c t a n g l e %
4398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4400 % DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4401 % x & y corner radiuses and using the current stroke, stroke width,
4402 % and fill settings.
4404 % The format of the DrawRoundRectangle method is:
4406 % void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4407 % double x2,double y2,double rx,double ry)
4409 % A description of each parameter follows:
4411 % o wand: the drawing wand.
4413 % o x1: x ordinate of first coordinate
4415 % o y1: y ordinate of first coordinate
4417 % o x2: x ordinate of second coordinate
4419 % o y2: y ordinate of second coordinate
4421 % o rx: radius of corner in horizontal direction
4423 % o ry: radius of corner in vertical direction
4426 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4427 double x2,double y2,double rx,double ry)
4429 assert(wand != (DrawingWand *) NULL);
4430 assert(wand->signature == WandSignature);
4431 if (wand->debug != MagickFalse)
4432 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4433 (void) MvgPrintf(wand,"roundrectangle %g,%g %g,%g %g,%g\n",
4438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4442 % D r a w S c a l e %
4446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4448 % DrawScale() adjusts the scaling factor to apply in the horizontal and
4449 % vertical directions to the current coordinate space.
4451 % The format of the DrawScale method is:
4453 % void DrawScale(DrawingWand *wand,const double x,const double y)
4455 % A description of each parameter follows:
4457 % o wand: the drawing wand.
4459 % o x: horizontal scale factor
4461 % o y: vertical scale factor
4464 WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4466 assert(wand != (DrawingWand *) NULL);
4467 assert(wand->signature == WandSignature);
4468 if (wand->debug != MagickFalse)
4469 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4470 (void) MvgPrintf(wand,"scale %g,%g\n",x,y);
4474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4478 % D r a w S e t B o r d e r C o l o r %
4482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4484 % DrawSetBorderColor() sets the border color to be used for drawing bordered
4487 % The format of the DrawSetBorderColor method is:
4489 % void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4491 % A description of each parameter follows:
4493 % o wand: the drawing wand.
4495 % o border_wand: border wand.
4499 static inline MagickBooleanType IsColorEqual(const PixelPacket *p,
4500 const PixelPacket *q)
4502 if (p->red != q->red)
4503 return(MagickFalse);
4504 if (p->green != q->green)
4505 return(MagickFalse);
4506 if (p->blue != q->blue)
4507 return(MagickFalse);
4508 if (p->opacity != q->opacity)
4509 return(MagickFalse);
4513 WandExport void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4520 assert(wand != (DrawingWand *) NULL);
4521 assert(wand->signature == WandSignature);
4522 if (wand->debug != MagickFalse)
4523 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4524 assert(border_wand != (const PixelWand *) NULL);
4525 PixelGetQuantumColor(border_wand,&border_color);
4526 new_border=border_color;
4527 current_border=(&CurrentContext->border_color);
4528 if ((wand->filter_off != MagickFalse) ||
4529 (IsColorEqual(current_border,&new_border) == MagickFalse))
4531 CurrentContext->border_color=new_border;
4532 (void) MvgPrintf(wand,"border-color '");
4533 MvgAppendColor(wand,&border_color);
4534 (void) MvgPrintf(wand,"'\n");
4539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4543 % D r a w S e t C l i p P a t h %
4547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4549 % DrawSetClipPath() associates a named clipping path with the image. Only
4550 % the areas drawn on by the clipping path will be modified as ssize_t as it
4551 % remains in effect.
4553 % The format of the DrawSetClipPath method is:
4555 % MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4556 % const char *clip_mask)
4558 % A description of each parameter follows:
4560 % o wand: the drawing wand.
4562 % o clip_mask: name of clipping path to associate with image
4565 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4566 const char *clip_mask)
4568 if (wand->debug != MagickFalse)
4569 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4570 assert(wand != (DrawingWand *) NULL);
4571 assert(wand->signature == WandSignature);
4572 assert(clip_mask != (const char *) NULL);
4573 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4574 (wand->filter_off != MagickFalse) ||
4575 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4577 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4578 #if DRAW_BINARY_IMPLEMENTATION
4579 if (wand->image == (Image *) NULL)
4580 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4581 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4583 (void) MvgPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4593 % D r a w S e t C l i p R u l e %
4597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4599 % DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4601 % The format of the DrawSetClipRule method is:
4603 % void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4605 % A description of each parameter follows:
4607 % o wand: the drawing wand.
4609 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4612 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4614 assert(wand != (DrawingWand *) NULL);
4615 assert(wand->signature == WandSignature);
4616 if (wand->debug != MagickFalse)
4617 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4618 if ((wand->filter_off != MagickFalse) ||
4619 (CurrentContext->fill_rule != fill_rule))
4621 CurrentContext->fill_rule=fill_rule;
4622 (void) MvgPrintf(wand, "clip-rule '%s'\n",MagickOptionToMnemonic(
4623 MagickFillRuleOptions,(ssize_t) fill_rule));
4628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4632 % D r a w S e t C l i p U n i t s %
4636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4638 % DrawSetClipUnits() sets the interpretation of clip path units.
4640 % The format of the DrawSetClipUnits method is:
4642 % void DrawSetClipUnits(DrawingWand *wand,
4643 % const ClipPathUnits clip_units)
4645 % A description of each parameter follows:
4647 % o wand: the drawing wand.
4649 % o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4650 % ObjectBoundingBox)
4653 WandExport void DrawSetClipUnits(DrawingWand *wand,
4654 const ClipPathUnits clip_units)
4656 assert(wand != (DrawingWand *) NULL);
4657 assert(wand->signature == WandSignature);
4658 if (wand->debug != MagickFalse)
4659 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4660 if ((wand->filter_off != MagickFalse) ||
4661 (CurrentContext->clip_units != clip_units))
4663 CurrentContext->clip_units=clip_units;
4664 if (clip_units == ObjectBoundingBox)
4669 GetAffineMatrix(&affine);
4670 affine.sx=CurrentContext->bounds.x2;
4671 affine.sy=CurrentContext->bounds.y2;
4672 affine.tx=CurrentContext->bounds.x1;
4673 affine.ty=CurrentContext->bounds.y1;
4674 AdjustAffine(wand,&affine);
4676 (void) MvgPrintf(wand, "clip-units '%s'\n",MagickOptionToMnemonic(
4677 MagickClipPathOptions,(ssize_t) clip_units));
4682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4686 % D r a w S e t F i l l C o l o r %
4690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4692 % DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4694 % The format of the DrawSetFillColor method is:
4696 % void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4698 % A description of each parameter follows:
4700 % o wand: the drawing wand.
4702 % o fill_wand: fill wand.
4705 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4712 assert(wand != (DrawingWand *) NULL);
4713 assert(wand->signature == WandSignature);
4714 if (wand->debug != MagickFalse)
4715 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4716 assert(fill_wand != (const PixelWand *) NULL);
4717 PixelGetQuantumColor(fill_wand,&fill_color);
4718 new_fill=fill_color;
4719 current_fill=(&CurrentContext->fill);
4720 if ((wand->filter_off != MagickFalse) ||
4721 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4723 CurrentContext->fill=new_fill;
4724 (void) MvgPrintf(wand,"fill '");
4725 MvgAppendColor(wand,&fill_color);
4726 (void) MvgPrintf(wand,"'\n");
4731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4735 % D r a w S e t F i l l O p a c i t y %
4739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4741 % DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4742 % color or fill texture. Fully opaque is 1.0.
4744 % The format of the DrawSetFillOpacity method is:
4746 % void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4748 % A description of each parameter follows:
4750 % o wand: the drawing wand.
4752 % o fill_opacity: fill opacity
4755 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4760 assert(wand != (DrawingWand *) NULL);
4761 assert(wand->signature == WandSignature);
4762 if (wand->debug != MagickFalse)
4763 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4764 opacity=ClampToQuantum((double) QuantumRange*(1.0-fill_opacity));
4765 if ((wand->filter_off != MagickFalse) ||
4766 (CurrentContext->fill.opacity != opacity))
4768 CurrentContext->fill.opacity=opacity;
4769 (void) MvgPrintf(wand,"fill-opacity %g\n",fill_opacity);
4774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4778 % D r a w S e t F o n t R e s o l u t i o n %
4782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4784 % DrawSetFontResolution() sets the image resolution.
4786 % The format of the DrawSetFontResolution method is:
4788 % DrawBooleanType DrawSetFontResolution(DrawingWand *wand,
4789 % const double x_resolution,const doubtl y_resolution)
4791 % A description of each parameter follows:
4793 % o wand: the magick wand.
4795 % o x_resolution: the image x resolution.
4797 % o y_resolution: the image y resolution.
4800 WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand,
4801 const double x_resolution,const double y_resolution)
4804 density[MaxTextExtent];
4806 assert(wand != (DrawingWand *) NULL);
4807 assert(wand->signature == WandSignature);
4808 if (wand->debug != MagickFalse)
4809 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4810 (void) FormatMagickString(density,MaxTextExtent,"%gx%g",x_resolution,
4812 (void) CloneString(&CurrentContext->density,density);
4817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4821 % D r a w S e t O p a c i t y %
4825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4827 % DrawSetOpacity() sets the opacity to use when drawing using the fill or
4828 % stroke color or texture. Fully opaque is 1.0.
4830 % The format of the DrawSetOpacity method is:
4832 % void DrawSetOpacity(DrawingWand *wand,const double opacity)
4834 % A description of each parameter follows:
4836 % o wand: the drawing wand.
4838 % o opacity: fill opacity
4841 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4846 assert(wand != (DrawingWand *) NULL);
4847 assert(wand->signature == WandSignature);
4848 if (wand->debug != MagickFalse)
4849 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4850 quantum_opacity=ClampToQuantum((double) QuantumRange*(1.0-opacity));
4851 if ((wand->filter_off != MagickFalse) ||
4852 (CurrentContext->opacity != quantum_opacity))
4854 CurrentContext->opacity=(Quantum) opacity;
4855 (void) MvgPrintf(wand,"opacity %g\n",opacity);
4860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4864 % D r a w S e t F i l l P a t t e r n U R L %
4868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4870 % DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4871 % objects. Only local URLs ("#identifier") are supported at this time. These
4872 % local URLs are normally created by defining a named fill pattern with
4873 % DrawPushPattern/DrawPopPattern.
4875 % The format of the DrawSetFillPatternURL method is:
4877 % MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4878 % const char *fill_url)
4880 % A description of each parameter follows:
4882 % o wand: the drawing wand.
4884 % o fill_url: URL to use to obtain fill pattern.
4887 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4888 const char *fill_url)
4891 pattern[MaxTextExtent],
4892 pattern_spec[MaxTextExtent];
4894 assert(wand != (DrawingWand *) NULL);
4895 assert(wand->signature == WandSignature);
4896 if (wand->debug != MagickFalse)
4897 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4898 if (wand->image == (Image *) NULL)
4899 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4900 assert(fill_url != (const char *) NULL);
4901 if (*fill_url != '#')
4903 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4904 return(MagickFalse);
4906 (void) FormatMagickString(pattern,MaxTextExtent,"%s",fill_url+1);
4907 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4909 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4910 return(MagickFalse);
4912 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",fill_url);
4913 #if DRAW_BINARY_IMPLEMENTATION
4914 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4915 &CurrentContext->fill_pattern);
4917 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4918 CurrentContext->fill.opacity=CurrentContext->opacity;
4919 (void) MvgPrintf(wand,"fill %s\n",pattern_spec);
4924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4928 % D r a w S e t F i l l R u l e %
4932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4934 % DrawSetFillRule() sets the fill rule to use while drawing polygons.
4936 % The format of the DrawSetFillRule method is:
4938 % void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4940 % A description of each parameter follows:
4942 % o wand: the drawing wand.
4944 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4947 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4949 assert(wand != (DrawingWand *) NULL);
4950 assert(wand->signature == WandSignature);
4951 if (wand->debug != MagickFalse)
4952 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4953 if ((wand->filter_off != MagickFalse) ||
4954 (CurrentContext->fill_rule != fill_rule))
4956 CurrentContext->fill_rule=fill_rule;
4957 (void) MvgPrintf(wand, "fill-rule '%s'\n",MagickOptionToMnemonic(
4958 MagickFillRuleOptions,(ssize_t) fill_rule));
4963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4967 % D r a w S e t F o n t %
4971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4973 % DrawSetFont() sets the fully-sepecified font to use when annotating with
4976 % The format of the DrawSetFont method is:
4978 % MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4980 % A description of each parameter follows:
4982 % o wand: the drawing wand.
4984 % o font_name: font name
4987 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4988 const char *font_name)
4990 assert(wand != (DrawingWand *) NULL);
4991 assert(wand->signature == WandSignature);
4992 if (wand->debug != MagickFalse)
4993 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4994 assert(font_name != (const char *) NULL);
4995 if ((wand->filter_off != MagickFalse) ||
4996 (CurrentContext->font == (char *) NULL) ||
4997 (LocaleCompare(CurrentContext->font,font_name) != 0))
4999 (void) CloneString(&CurrentContext->font,font_name);
5000 (void) MvgPrintf(wand,"font '%s'\n",font_name);
5006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5010 % D r a w S e t F o n t F a m i l y %
5014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5016 % DrawSetFontFamily() sets the font family to use when annotating with text.
5018 % The format of the DrawSetFontFamily method is:
5020 % MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5021 % const char *font_family)
5023 % A description of each parameter follows:
5025 % o wand: the drawing wand.
5027 % o font_family: font family
5030 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
5031 const char *font_family)
5033 assert(wand != (DrawingWand *) NULL);
5034 assert(wand->signature == WandSignature);
5035 if (wand->debug != MagickFalse)
5036 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5037 assert(font_family != (const char *) NULL);
5038 if ((wand->filter_off != MagickFalse) ||
5039 (CurrentContext->family == (const char *) NULL) ||
5040 (LocaleCompare(CurrentContext->family,font_family) != 0))
5042 (void) CloneString(&CurrentContext->family,font_family);
5043 (void) MvgPrintf(wand,"font-family '%s'\n",font_family);
5049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5053 % D r a w S e t F o n t S i z e %
5057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5059 % DrawSetFontSize() sets the font pointsize to use when annotating with text.
5061 % The format of the DrawSetFontSize method is:
5063 % void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5065 % A description of each parameter follows:
5067 % o wand: the drawing wand.
5069 % o pointsize: text pointsize
5072 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
5074 assert(wand != (DrawingWand *) NULL);
5075 assert(wand->signature == WandSignature);
5076 if (wand->debug != MagickFalse)
5077 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5078 if ((wand->filter_off != MagickFalse) ||
5079 (fabs(CurrentContext->pointsize-pointsize) > MagickEpsilon))
5081 CurrentContext->pointsize=pointsize;
5082 (void) MvgPrintf(wand,"font-size %g\n",pointsize);
5087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5091 % D r a w S e t F o n t S t r e t c h %
5095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5097 % DrawSetFontStretch() sets the font stretch to use when annotating with text.
5098 % The AnyStretch enumeration acts as a wild-card "don't care" option.
5100 % The format of the DrawSetFontStretch method is:
5102 % void DrawSetFontStretch(DrawingWand *wand,
5103 % const StretchType font_stretch)
5105 % A description of each parameter follows:
5107 % o wand: the drawing wand.
5109 % o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5110 % CondensedStretch, SemiCondensedStretch,
5111 % SemiExpandedStretch, ExpandedStretch,
5112 % ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5115 WandExport void DrawSetFontStretch(DrawingWand *wand,
5116 const StretchType font_stretch)
5118 assert(wand != (DrawingWand *) NULL);
5119 assert(wand->signature == WandSignature);
5120 if (wand->debug != MagickFalse)
5121 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5122 if ((wand->filter_off != MagickFalse) ||
5123 (CurrentContext->stretch != font_stretch))
5125 CurrentContext->stretch=font_stretch;
5126 (void) MvgPrintf(wand, "font-stretch '%s'\n",MagickOptionToMnemonic(
5127 MagickStretchOptions,(ssize_t) font_stretch));
5132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5136 % D r a w S e t F o n t S t y l e %
5140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5142 % DrawSetFontStyle() sets the font style to use when annotating with text.
5143 % The AnyStyle enumeration acts as a wild-card "don't care" option.
5145 % The format of the DrawSetFontStyle method is:
5147 % void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5149 % A description of each parameter follows:
5151 % o wand: the drawing wand.
5153 % o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5156 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5158 assert(wand != (DrawingWand *) NULL);
5159 assert(wand->signature == WandSignature);
5160 if (wand->debug != MagickFalse)
5161 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5162 if ((wand->filter_off != MagickFalse) ||
5163 (CurrentContext->style != style))
5165 CurrentContext->style=style;
5166 (void) MvgPrintf(wand, "font-style '%s'\n",MagickOptionToMnemonic(
5167 MagickStyleOptions,(ssize_t) style));
5172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5176 % D r a w S e t F o n t W e i g h t %
5180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5182 % DrawSetFontWeight() sets the font weight to use when annotating with text.
5184 % The format of the DrawSetFontWeight method is:
5186 % void DrawSetFontWeight(DrawingWand *wand,
5187 % const size_t font_weight)
5189 % A description of each parameter follows:
5191 % o wand: the drawing wand.
5193 % o font_weight: font weight (valid range 100-900)
5196 WandExport void DrawSetFontWeight(DrawingWand *wand,
5197 const size_t font_weight)
5199 assert(wand != (DrawingWand *) NULL);
5200 assert(wand->signature == WandSignature);
5201 if (wand->debug != MagickFalse)
5202 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5203 if ((wand->filter_off != MagickFalse) ||
5204 (CurrentContext->weight != font_weight))
5206 CurrentContext->weight=font_weight;
5207 (void) MvgPrintf(wand,"font-weight %.20g\n",(double) font_weight);
5212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5216 % D r a w S e t G r a v i t y %
5220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5222 % DrawSetGravity() sets the text placement gravity to use when annotating
5225 % The format of the DrawSetGravity method is:
5227 % void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5229 % A description of each parameter follows:
5231 % o wand: the drawing wand.
5233 % o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5234 % NorthEastGravity, WestGravity, CenterGravity,
5235 % EastGravity, SouthWestGravity, SouthGravity,
5239 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5241 assert(wand != (DrawingWand *) NULL);
5242 assert(wand->signature == WandSignature);
5243 if (wand->debug != MagickFalse)
5244 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5245 if ((wand->filter_off != MagickFalse) ||
5246 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5248 CurrentContext->gravity=gravity;
5249 (void) MvgPrintf(wand,"gravity '%s'\n",MagickOptionToMnemonic(
5250 MagickGravityOptions,(ssize_t) gravity));
5255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5259 % D r a w S e t S t r o k e C o l o r %
5263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5265 % DrawSetStrokeColor() sets the color used for stroking object outlines.
5267 % The format of the DrawSetStrokeColor method is:
5269 % void DrawSetStrokeColor(DrawingWand *wand,
5270 % const PixelWand *stroke_wand)
5272 % A description of each parameter follows:
5274 % o wand: the drawing wand.
5276 % o stroke_wand: stroke wand.
5279 WandExport void DrawSetStrokeColor(DrawingWand *wand,
5280 const PixelWand *stroke_wand)
5287 assert(wand != (DrawingWand *) NULL);
5288 assert(wand->signature == WandSignature);
5289 if (wand->debug != MagickFalse)
5290 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5291 assert(stroke_wand != (const PixelWand *) NULL);
5292 PixelGetQuantumColor(stroke_wand,&stroke_color);
5293 new_stroke=stroke_color;
5294 current_stroke=(&CurrentContext->stroke);
5295 if ((wand->filter_off != MagickFalse) ||
5296 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5298 CurrentContext->stroke=new_stroke;
5299 (void) MvgPrintf(wand,"stroke '");
5300 MvgAppendColor(wand,&stroke_color);
5301 (void) MvgPrintf(wand,"'\n");
5306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5310 % D r a w S e t S t r o k e P a t t e r n U R L %
5314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5316 % DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5318 % The format of the DrawSetStrokePatternURL method is:
5320 % MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5321 % const char *stroke_url)
5323 % A description of each parameter follows:
5325 % o wand: the drawing wand.
5327 % o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5330 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5331 const char *stroke_url)
5334 pattern[MaxTextExtent],
5335 pattern_spec[MaxTextExtent];
5337 assert(wand != (DrawingWand *) NULL);
5338 assert(wand->signature == WandSignature);
5339 if (wand->debug != MagickFalse)
5340 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5341 if (wand->image == (Image *) NULL)
5342 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5343 assert(stroke_url != NULL);
5344 if (stroke_url[0] != '#')
5345 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5346 (void) FormatMagickString(pattern,MaxTextExtent,"%s",stroke_url+1);
5347 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5349 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5350 return(MagickFalse);
5352 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",stroke_url);
5353 #if DRAW_BINARY_IMPLEMENTATION
5354 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5355 &CurrentContext->stroke_pattern);
5357 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5358 CurrentContext->stroke.opacity=CurrentContext->opacity;
5359 (void) MvgPrintf(wand,"stroke %s\n",pattern_spec);
5364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5368 % D r a w S e t S t r o k e A n t i a l i a s %
5372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5374 % DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5375 % Stroked outlines are antialiased by default. When antialiasing is disabled
5376 % stroked pixels are thresholded to determine if the stroke color or
5377 % underlying canvas color should be used.
5379 % The format of the DrawSetStrokeAntialias method is:
5381 % void DrawSetStrokeAntialias(DrawingWand *wand,
5382 % const MagickBooleanType stroke_antialias)
5384 % A description of each parameter follows:
5386 % o wand: the drawing wand.
5388 % o stroke_antialias: set to false (zero) to disable antialiasing
5391 WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5392 const MagickBooleanType stroke_antialias)
5394 assert(wand != (DrawingWand *) NULL);
5395 assert(wand->signature == WandSignature);
5396 if (wand->debug != MagickFalse)
5397 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5398 if ((wand->filter_off != MagickFalse) ||
5399 (CurrentContext->stroke_antialias != stroke_antialias))
5401 CurrentContext->stroke_antialias=stroke_antialias;
5402 (void) MvgPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5412 % D r a w S e t S t r o k e D a s h A r r a y %
5416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5418 % DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5419 % stroke paths. The stroke dash array represents an array of numbers that
5420 % specify the lengths of alternating dashes and gaps in pixels. If an odd
5421 % number of values is provided, then the list of values is repeated to yield
5422 % an even number of values. To remove an existing dash array, pass a zero
5423 % number_elements argument and null dash_array. A typical stroke dash array
5424 % might contain the members 5 3 2.
5426 % The format of the DrawSetStrokeDashArray method is:
5428 % MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5429 % const size_t number_elements,const double *dash_array)
5431 % A description of each parameter follows:
5433 % o wand: the drawing wand.
5435 % o number_elements: number of elements in dash array
5437 % o dash_array: dash array values
5440 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5441 const size_t number_elements,const double *dash_array)
5446 register const double
5459 assert(wand != (DrawingWand *) NULL);
5460 assert(wand->signature == WandSignature);
5461 if (wand->debug != MagickFalse)
5462 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5463 n_new=number_elements;
5466 q=CurrentContext->dash_pattern;
5467 if (q != (const double *) NULL)
5470 if ((n_old == 0) && (n_new == 0))
5476 if ((CurrentContext->dash_pattern != (double *) NULL) &&
5477 (dash_array != (double *) NULL))
5480 q=CurrentContext->dash_pattern;
5481 for (i=0; i < (ssize_t) n_new; i++)
5483 if (fabs((*p)-(*q)) > MagickEpsilon)
5492 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5494 if (CurrentContext->dash_pattern != (double *) NULL)
5495 CurrentContext->dash_pattern=(double *)
5496 RelinquishMagickMemory(CurrentContext->dash_pattern);
5499 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5500 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5501 if (!CurrentContext->dash_pattern)
5503 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5505 return(MagickFalse);
5507 q=CurrentContext->dash_pattern;
5509 for (i=0; i < (ssize_t) n_new; i++)
5513 (void) MvgPrintf(wand,"stroke-dasharray ");
5515 (void) MvgPrintf(wand,"none\n");
5519 (void) MvgPrintf(wand,"%g",*p++);
5520 for (i=1; i < (ssize_t) n_new; i++)
5521 (void) MvgPrintf(wand,",%g",*p++);
5522 (void) MvgPrintf(wand,"\n");
5529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5533 % D r a w S e t S t r o k e D a s h O f f s e t %
5537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5539 % DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5542 % The format of the DrawSetStrokeDashOffset method is:
5544 % void DrawSetStrokeDashOffset(DrawingWand *wand,
5545 % const double dash_offset)
5547 % A description of each parameter follows:
5549 % o wand: the drawing wand.
5551 % o dash_offset: dash offset
5554 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5555 const double dash_offset)
5557 assert(wand != (DrawingWand *) NULL);
5558 assert(wand->signature == WandSignature);
5559 if (wand->debug != MagickFalse)
5560 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5561 if ((wand->filter_off != MagickFalse) ||
5562 (fabs(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
5564 CurrentContext->dash_offset=dash_offset;
5565 (void) MvgPrintf(wand,"stroke-dashoffset %g\n",dash_offset);
5570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5574 % D r a w S e t S t r o k e L i n e C a p %
5578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5580 % DrawSetStrokeLineCap() specifies the shape to be used at the end of
5581 % open subpaths when they are stroked. Values of LineCap are
5582 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
5584 % The format of the DrawSetStrokeLineCap method is:
5586 % void DrawSetStrokeLineCap(DrawingWand *wand,
5587 % const LineCap linecap)
5589 % A description of each parameter follows:
5591 % o wand: the drawing wand.
5593 % o linecap: linecap style
5596 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5598 assert(wand != (DrawingWand *) NULL);
5599 assert(wand->signature == WandSignature);
5600 if (wand->debug != MagickFalse)
5601 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5602 if ((wand->filter_off != MagickFalse) ||
5603 (CurrentContext->linecap != linecap))
5605 CurrentContext->linecap=linecap;
5606 (void) MvgPrintf(wand,"stroke-linecap '%s'\n",MagickOptionToMnemonic(
5607 MagickLineCapOptions,(ssize_t) linecap));
5612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5616 % D r a w S e t S t r o k e L i n e J o i n %
5620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5622 % DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5623 % paths (or other vector shapes) when they are stroked. Values of LineJoin are
5624 % UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5626 % The format of the DrawSetStrokeLineJoin method is:
5628 % void DrawSetStrokeLineJoin(DrawingWand *wand,
5629 % const LineJoin linejoin)
5631 % A description of each parameter follows:
5633 % o wand: the drawing wand.
5635 % o linejoin: line join style
5638 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5640 assert(wand != (DrawingWand *) NULL);
5641 assert(wand->signature == WandSignature);
5642 if (wand->debug != MagickFalse)
5643 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5644 if ((wand->filter_off != MagickFalse) ||
5645 (CurrentContext->linejoin != linejoin))
5647 CurrentContext->linejoin=linejoin;
5648 (void) MvgPrintf(wand, "stroke-linejoin '%s'\n",MagickOptionToMnemonic(
5649 MagickLineJoinOptions,(ssize_t) linejoin));
5654 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5658 % D r a w S e t S t r o k e M i t e r L i m i t %
5662 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5664 % DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5665 % segments meet at a sharp angle and miter joins have been specified for
5666 % 'lineJoin', it is possible for the miter to extend far beyond the
5667 % thickness of the line stroking the path. The miterLimit' imposes a
5668 % limit on the ratio of the miter length to the 'lineWidth'.
5670 % The format of the DrawSetStrokeMiterLimit method is:
5672 % void DrawSetStrokeMiterLimit(DrawingWand *wand,
5673 % const size_t miterlimit)
5675 % A description of each parameter follows:
5677 % o wand: the drawing wand.
5679 % o miterlimit: miter limit
5682 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
5683 const size_t miterlimit)
5685 assert(wand != (DrawingWand *) NULL);
5686 assert(wand->signature == WandSignature);
5687 if (wand->debug != MagickFalse)
5688 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5689 if (CurrentContext->miterlimit != miterlimit)
5691 CurrentContext->miterlimit=miterlimit;
5692 (void) MvgPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit);
5697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5701 % D r a w S e t S t r o k e O p a c i t y %
5705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5707 % DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5709 % The format of the DrawSetStrokeOpacity method is:
5711 % void DrawSetStrokeOpacity(DrawingWand *wand,
5712 % const double stroke_opacity)
5714 % A description of each parameter follows:
5716 % o wand: the drawing wand.
5718 % o stroke_opacity: stroke opacity. The value 1.0 is opaque.
5721 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5722 const double stroke_opacity)
5727 assert(wand != (DrawingWand *) NULL);
5728 assert(wand->signature == WandSignature);
5729 if (wand->debug != MagickFalse)
5730 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5731 opacity=ClampToQuantum((double) QuantumRange*(1.0-stroke_opacity));
5732 if ((wand->filter_off != MagickFalse) ||
5733 (CurrentContext->stroke.opacity != opacity))
5735 CurrentContext->stroke.opacity=opacity;
5736 (void) MvgPrintf(wand,"stroke-opacity %g\n",stroke_opacity);
5741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5745 % D r a w S e t S t r o k e W i d t h %
5749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5751 % DrawSetStrokeWidth() sets the width of the stroke used to draw object
5754 % The format of the DrawSetStrokeWidth method is:
5756 % void DrawSetStrokeWidth(DrawingWand *wand,
5757 % const double stroke_width)
5759 % A description of each parameter follows:
5761 % o wand: the drawing wand.
5763 % o stroke_width: stroke width
5766 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5768 assert(wand != (DrawingWand *) NULL);
5769 assert(wand->signature == WandSignature);
5770 if (wand->debug != MagickFalse)
5771 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5772 if ((wand->filter_off != MagickFalse) ||
5773 (fabs(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
5775 CurrentContext->stroke_width=stroke_width;
5776 (void) MvgPrintf(wand,"stroke-width %g\n",stroke_width);
5781 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5785 % D r a w S e t T e x t A l i g n m e n t %
5789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5791 % DrawSetTextAlignment() specifies a text alignment to be applied when
5792 % annotating with text.
5794 % The format of the DrawSetTextAlignment method is:
5796 % void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5798 % A description of each parameter follows:
5800 % o wand: the drawing wand.
5802 % o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5803 % CenterAlign, or RightAlign.
5806 WandExport void DrawSetTextAlignment(DrawingWand *wand,
5807 const AlignType alignment)
5809 assert(wand != (DrawingWand *) NULL);
5810 assert(wand->signature == WandSignature);
5811 if (wand->debug != MagickFalse)
5812 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5813 if ((wand->filter_off != MagickFalse) ||
5814 (CurrentContext->align != alignment))
5816 CurrentContext->align=alignment;
5817 (void) MvgPrintf(wand,"text-align '%s'\n",MagickOptionToMnemonic(
5818 MagickAlignOptions,(ssize_t) alignment));
5823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5827 % D r a w S e t T e x t A n t i a l i a s %
5831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5833 % DrawSetTextAntialias() controls whether text is antialiased. Text is
5834 % antialiased by default.
5836 % The format of the DrawSetTextAntialias method is:
5838 % void DrawSetTextAntialias(DrawingWand *wand,
5839 % const MagickBooleanType text_antialias)
5841 % A description of each parameter follows:
5843 % o wand: the drawing wand.
5845 % o text_antialias: antialias boolean. Set to false (0) to disable
5849 WandExport void DrawSetTextAntialias(DrawingWand *wand,
5850 const MagickBooleanType text_antialias)
5852 assert(wand != (DrawingWand *) NULL);
5853 assert(wand->signature == WandSignature);
5854 if (wand->debug != MagickFalse)
5855 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5856 if ((wand->filter_off != MagickFalse) ||
5857 (CurrentContext->text_antialias != text_antialias))
5859 CurrentContext->text_antialias=text_antialias;
5860 (void) MvgPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5869 % D r a w S e t T e x t D e c o r a t i o n %
5873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5875 % DrawSetTextDecoration() specifies a decoration to be applied when
5876 % annotating with text.
5878 % The format of the DrawSetTextDecoration method is:
5880 % void DrawSetTextDecoration(DrawingWand *wand,
5881 % const DecorationType decoration)
5883 % A description of each parameter follows:
5885 % o wand: the drawing wand.
5887 % o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5888 % OverlineDecoration, or LineThroughDecoration
5891 WandExport void DrawSetTextDecoration(DrawingWand *wand,
5892 const DecorationType decoration)
5894 assert(wand != (DrawingWand *) NULL);
5895 assert(wand->signature == WandSignature);
5896 if (wand->debug != MagickFalse)
5897 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5898 if ((wand->filter_off != MagickFalse) ||
5899 (CurrentContext->decorate != decoration))
5901 CurrentContext->decorate=decoration;
5902 (void) MvgPrintf(wand,"decorate '%s'\n",MagickOptionToMnemonic(
5903 MagickDecorateOptions,(ssize_t) decoration));
5908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5912 % D r a w S e t T e x t E n c o d i n g %
5916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5918 % DrawSetTextEncoding() specifies the code set to use for text
5919 % annotations. The only character encoding which may be specified
5920 % at this time is "UTF-8" for representing Unicode as a sequence of
5921 % bytes. Specify an empty string to set text encoding to the system's
5922 % default. Successful text annotation using Unicode may require fonts
5923 % designed to support Unicode.
5925 % The format of the DrawSetTextEncoding method is:
5927 % void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5929 % A description of each parameter follows:
5931 % o wand: the drawing wand.
5933 % o encoding: character string specifying text encoding
5936 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5938 assert(wand != (DrawingWand *) NULL);
5939 assert(wand->signature == WandSignature);
5940 if (wand->debug != MagickFalse)
5941 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5942 assert(encoding != (char *) NULL);
5943 if ((wand->filter_off != MagickFalse) ||
5944 (CurrentContext->encoding == (char *) NULL) ||
5945 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
5947 (void) CloneString(&CurrentContext->encoding,encoding);
5948 (void) MvgPrintf(wand,"encoding '%s'\n",encoding);
5953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5957 % D r a w S e t T e x t K e r n i n g %
5961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5963 % DrawSetTextKerning() sets the spacing between characters in text.
5965 % The format of the DrawSetTextKerning method is:
5967 % void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5969 % A description of each parameter follows:
5971 % o wand: the drawing wand.
5973 % o kerning: text kerning
5976 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5978 assert(wand != (DrawingWand *) NULL);
5979 assert(wand->signature == WandSignature);
5981 if (wand->debug != MagickFalse)
5982 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5983 if ((wand->filter_off != MagickFalse) &&
5984 (CurrentContext->kerning != kerning))
5986 CurrentContext->kerning=kerning;
5987 (void) MvgPrintf(wand,"kerning %lf\n",kerning);
5992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5996 % 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 %
6000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6002 % DrawSetTextInterwordSpacing() sets the spacing between line in text.
6004 % The format of the DrawSetInterwordSpacing method is:
6006 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
6007 % const double interline_spacing)
6009 % A description of each parameter follows:
6011 % o wand: the drawing wand.
6013 % o interline_spacing: text line spacing
6016 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
6017 const double interline_spacing)
6019 assert(wand != (DrawingWand *) NULL);
6020 assert(wand->signature == WandSignature);
6022 if (wand->debug != MagickFalse)
6023 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6024 if ((wand->filter_off != MagickFalse) &&
6025 (CurrentContext->interline_spacing != interline_spacing))
6027 CurrentContext->interline_spacing=interline_spacing;
6028 (void) MvgPrintf(wand,"interline-spacing %lf\n",interline_spacing);
6033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6037 % 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 %
6041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6043 % DrawSetTextInterwordSpacing() sets the spacing between words in text.
6045 % The format of the DrawSetInterwordSpacing method is:
6047 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
6048 % const double interword_spacing)
6050 % A description of each parameter follows:
6052 % o wand: the drawing wand.
6054 % o interword_spacing: text word spacing
6057 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
6058 const double interword_spacing)
6060 assert(wand != (DrawingWand *) NULL);
6061 assert(wand->signature == WandSignature);
6063 if (wand->debug != MagickFalse)
6064 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6065 if ((wand->filter_off != MagickFalse) &&
6066 (CurrentContext->interword_spacing != interword_spacing))
6068 CurrentContext->interword_spacing=interword_spacing;
6069 (void) MvgPrintf(wand,"interword-spacing %lf\n",interword_spacing);
6074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6078 % D r a w S e t T e x t U n d e r C o l o r %
6082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6084 % DrawSetTextUnderColor() specifies the color of a background rectangle
6085 % to place under text annotations.
6087 % The format of the DrawSetTextUnderColor method is:
6089 % void DrawSetTextUnderColor(DrawingWand *wand,
6090 % const PixelWand *under_wand)
6092 % A description of each parameter follows:
6094 % o wand: the drawing wand.
6096 % o under_wand: text under wand.
6099 WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6100 const PixelWand *under_wand)
6105 assert(wand != (DrawingWand *) NULL);
6106 assert(wand->signature == WandSignature);
6107 if (wand->debug != MagickFalse)
6108 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6109 assert(under_wand != (const PixelWand *) NULL);
6110 PixelGetQuantumColor(under_wand,&under_color);
6111 if ((wand->filter_off != MagickFalse) ||
6112 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6114 CurrentContext->undercolor=under_color;
6115 (void) MvgPrintf(wand,"text-undercolor '");
6116 MvgAppendColor(wand,&under_color);
6117 (void) MvgPrintf(wand,"'\n");
6122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6126 % D r a w S e t V e c t o r G r a p h i c s %
6130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6132 % DrawSetVectorGraphics() sets the vector graphics associated with the
6133 % specified wand. Use this method with DrawGetVectorGraphics() as a method
6134 % to persist the vector graphics state.
6136 % The format of the DrawSetVectorGraphics method is:
6138 % MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6141 % A description of each parameter follows:
6143 % o wand: the drawing wand.
6145 % o xml: the drawing wand XML.
6149 static inline MagickBooleanType IsPoint(const char *point)
6157 value=strtol(point,&p,10);
6158 return(p != point ? MagickTrue : MagickFalse);
6161 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6171 assert(wand != (DrawingWand *) NULL);
6172 assert(wand->signature == WandSignature);
6173 if (wand->debug != MagickFalse)
6174 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6175 CurrentContext=DestroyDrawInfo(CurrentContext);
6176 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6177 if (xml == (const char *) NULL)
6178 return(MagickFalse);
6179 xml_info=NewXMLTree(xml,wand->exception);
6180 if (xml_info == (XMLTreeInfo *) NULL)
6181 return(MagickFalse);
6182 child=GetXMLTreeChild(xml_info,"clip-path");
6183 if (child != (XMLTreeInfo *) NULL)
6184 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6185 child=GetXMLTreeChild(xml_info,"clip-units");
6186 if (child != (XMLTreeInfo *) NULL)
6188 value=GetXMLTreeContent(child);
6189 if (value != (const char *) NULL)
6190 CurrentContext->clip_units=(ClipPathUnits) ParseMagickOption(
6191 MagickClipPathOptions,MagickFalse,value);
6193 child=GetXMLTreeChild(xml_info,"decorate");
6194 if (child != (XMLTreeInfo *) NULL)
6196 value=GetXMLTreeContent(child);
6197 if (value != (const char *) NULL)
6198 CurrentContext->decorate=(DecorationType) ParseMagickOption(
6199 MagickDecorateOptions,MagickFalse,value);
6201 child=GetXMLTreeChild(xml_info,"encoding");
6202 if (child != (XMLTreeInfo *) NULL)
6203 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6204 child=GetXMLTreeChild(xml_info,"fill");
6205 if (child != (XMLTreeInfo *) NULL)
6207 value=GetXMLTreeContent(child);
6208 if (value != (const char *) NULL)
6209 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6211 child=GetXMLTreeChild(xml_info,"fill-opacity");
6212 if (child != (XMLTreeInfo *) NULL)
6214 value=GetXMLTreeContent(child);
6215 if (value != (const char *) NULL)
6216 CurrentContext->fill.opacity=ClampToQuantum((MagickRealType)
6217 QuantumRange*(1.0-StringToDouble(value)));
6219 child=GetXMLTreeChild(xml_info,"fill-rule");
6220 if (child != (XMLTreeInfo *) NULL)
6222 value=GetXMLTreeContent(child);
6223 if (value != (const char *) NULL)
6224 CurrentContext->fill_rule=(FillRule) ParseMagickOption(
6225 MagickFillRuleOptions,MagickFalse,value);
6227 child=GetXMLTreeChild(xml_info,"font");
6228 if (child != (XMLTreeInfo *) NULL)
6229 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6230 child=GetXMLTreeChild(xml_info,"font-family");
6231 if (child != (XMLTreeInfo *) NULL)
6232 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6233 child=GetXMLTreeChild(xml_info,"font-size");
6234 if (child != (XMLTreeInfo *) NULL)
6236 value=GetXMLTreeContent(child);
6237 if (value != (const char *) NULL)
6238 CurrentContext->pointsize=StringToDouble(value);
6240 child=GetXMLTreeChild(xml_info,"font-stretch");
6241 if (child != (XMLTreeInfo *) NULL)
6243 value=GetXMLTreeContent(child);
6244 if (value != (const char *) NULL)
6245 CurrentContext->stretch=(StretchType) ParseMagickOption(
6246 MagickStretchOptions,MagickFalse,value);
6248 child=GetXMLTreeChild(xml_info,"font-style");
6249 if (child != (XMLTreeInfo *) NULL)
6251 value=GetXMLTreeContent(child);
6252 if (value != (const char *) NULL)
6253 CurrentContext->style=(StyleType) ParseMagickOption(MagickStyleOptions,
6256 child=GetXMLTreeChild(xml_info,"font-weight");
6257 if (child != (XMLTreeInfo *) NULL)
6259 value=GetXMLTreeContent(child);
6260 if (value != (const char *) NULL)
6261 CurrentContext->weight=StringToUnsignedLong(value);
6263 child=GetXMLTreeChild(xml_info,"gravity");
6264 if (child != (XMLTreeInfo *) NULL)
6266 value=GetXMLTreeContent(child);
6267 if (value != (const char *) NULL)
6268 CurrentContext->gravity=(GravityType) ParseMagickOption(
6269 MagickGravityOptions,MagickFalse,value);
6271 child=GetXMLTreeChild(xml_info,"stroke");
6272 if (child != (XMLTreeInfo *) NULL)
6274 value=GetXMLTreeContent(child);
6275 if (value != (const char *) NULL)
6276 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6279 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6280 if (child != (XMLTreeInfo *) NULL)
6282 value=GetXMLTreeContent(child);
6283 if (value != (const char *) NULL)
6284 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6287 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6288 if (child != (XMLTreeInfo *) NULL)
6291 token[MaxTextExtent];
6302 value=GetXMLTreeContent(child);
6303 if (value != (const char *) NULL)
6305 if (CurrentContext->dash_pattern != (double *) NULL)
6306 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6307 CurrentContext->dash_pattern);
6309 if (IsPoint(q) != MagickFalse)
6315 GetMagickToken(p,&p,token);
6317 GetMagickToken(p,&p,token);
6318 for (x=0; IsPoint(token) != MagickFalse; x++)
6320 GetMagickToken(p,&p,token);
6322 GetMagickToken(p,&p,token);
6324 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6325 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6326 if (CurrentContext->dash_pattern == (double *) NULL)
6327 ThrowWandFatalException(ResourceLimitFatalError,
6328 "MemoryAllocationFailed",wand->name);
6329 for (j=0; j < x; j++)
6331 GetMagickToken(q,&q,token);
6333 GetMagickToken(q,&q,token);
6334 CurrentContext->dash_pattern[j]=StringToDouble(token);
6336 if ((x & 0x01) != 0)
6337 for ( ; j < (2*x); j++)
6338 CurrentContext->dash_pattern[j]=
6339 CurrentContext->dash_pattern[j-x];
6340 CurrentContext->dash_pattern[j]=0.0;
6344 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6345 if (child != (XMLTreeInfo *) NULL)
6347 value=GetXMLTreeContent(child);
6348 if (value != (const char *) NULL)
6349 CurrentContext->dash_offset=StringToDouble(value);
6351 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6352 if (child != (XMLTreeInfo *) NULL)
6354 value=GetXMLTreeContent(child);
6355 if (value != (const char *) NULL)
6356 CurrentContext->linecap=(LineCap) ParseMagickOption(
6357 MagickLineCapOptions,MagickFalse,value);
6359 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6360 if (child != (XMLTreeInfo *) NULL)
6362 value=GetXMLTreeContent(child);
6363 if (value != (const char *) NULL)
6364 CurrentContext->linejoin=(LineJoin) ParseMagickOption(
6365 MagickLineJoinOptions,MagickFalse,value);
6367 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6368 if (child != (XMLTreeInfo *) NULL)
6370 value=GetXMLTreeContent(child);
6371 if (value != (const char *) NULL)
6372 CurrentContext->miterlimit=StringToUnsignedLong(value);
6374 child=GetXMLTreeChild(xml_info,"stroke-opacity");
6375 if (child != (XMLTreeInfo *) NULL)
6377 value=GetXMLTreeContent(child);
6378 if (value != (const char *) NULL)
6379 CurrentContext->stroke.opacity=ClampToQuantum((MagickRealType)
6380 QuantumRange*(1.0-StringToDouble(value)));
6382 child=GetXMLTreeChild(xml_info,"stroke-width");
6383 if (child != (XMLTreeInfo *) NULL)
6385 value=GetXMLTreeContent(child);
6386 if (value != (const char *) NULL)
6387 CurrentContext->stroke_width=StringToDouble(value);
6389 child=GetXMLTreeChild(xml_info,"text-align");
6390 if (child != (XMLTreeInfo *) NULL)
6392 value=GetXMLTreeContent(child);
6393 if (value != (const char *) NULL)
6394 CurrentContext->align=(AlignType) ParseMagickOption(MagickAlignOptions,
6397 child=GetXMLTreeChild(xml_info,"text-antialias");
6398 if (child != (XMLTreeInfo *) NULL)
6400 value=GetXMLTreeContent(child);
6401 if (value != (const char *) NULL)
6402 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6405 child=GetXMLTreeChild(xml_info,"text-undercolor");
6406 if (child != (XMLTreeInfo *) NULL)
6408 value=GetXMLTreeContent(child);
6409 if (value != (const char *) NULL)
6410 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6413 child=GetXMLTreeChild(xml_info,"vector-graphics");
6414 if (child != (XMLTreeInfo *) NULL)
6416 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6417 wand->mvg_length=strlen(wand->mvg);
6418 wand->mvg_alloc=wand->mvg_length+1;
6420 xml_info=DestroyXMLTree(xml_info);
6425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6429 % D r a w S k e w X %
6433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6435 % DrawSkewX() skews the current coordinate system in the horizontal
6438 % The format of the DrawSkewX method is:
6440 % void DrawSkewX(DrawingWand *wand,const double degrees)
6442 % A description of each parameter follows:
6444 % o wand: the drawing wand.
6446 % o degrees: number of degrees to skew the coordinates
6449 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6451 assert(wand != (DrawingWand *) NULL);
6452 assert(wand->signature == WandSignature);
6453 if (wand->debug != MagickFalse)
6454 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6455 (void) MvgPrintf(wand,"skewX %g\n",degrees);
6459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6463 % D r a w S k e w Y %
6467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6469 % DrawSkewY() skews the current coordinate system in the vertical
6472 % The format of the DrawSkewY method is:
6474 % void DrawSkewY(DrawingWand *wand,const double degrees)
6476 % A description of each parameter follows:
6478 % o wand: the drawing wand.
6480 % o degrees: number of degrees to skew the coordinates
6483 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6485 assert(wand != (DrawingWand *) NULL);
6486 assert(wand->signature == WandSignature);
6487 if (wand->debug != MagickFalse)
6488 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6489 (void) MvgPrintf(wand,"skewY %g\n",degrees);
6493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6497 % D r a w T r a n s l a t e %
6501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6503 % DrawTranslate() applies a translation to the current coordinate
6504 % system which moves the coordinate system origin to the specified
6507 % The format of the DrawTranslate method is:
6509 % void DrawTranslate(DrawingWand *wand,const double x,
6512 % A description of each parameter follows:
6514 % o wand: the drawing wand.
6516 % o x: new x ordinate for coordinate system origin
6518 % o y: new y ordinate for coordinate system origin
6521 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6523 assert(wand != (DrawingWand *) NULL);
6524 assert(wand->signature == WandSignature);
6525 if (wand->debug != MagickFalse)
6526 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6527 (void) MvgPrintf(wand,"translate %g,%g\n",x,y);
6531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6535 % D r a w S e t V i e w b o x %
6539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6541 % DrawSetViewbox() sets the overall canvas size to be recorded with the
6542 % drawing vector data. Usually this will be specified using the same
6543 % size as the canvas image. When the vector data is saved to SVG or MVG
6544 % formats, the viewbox is use to specify the size of the canvas image that
6545 % a viewer will render the vector data on.
6547 % The format of the DrawSetViewbox method is:
6549 % void DrawSetViewbox(DrawingWand *wand,size_t x1,
6550 % size_t y1,size_t x2,size_t y2)
6552 % A description of each parameter follows:
6554 % o wand: the drawing wand.
6556 % o x1: left x ordinate
6558 % o y1: top y ordinate
6560 % o x2: right x ordinate
6562 % o y2: bottom y ordinate
6565 WandExport void DrawSetViewbox(DrawingWand *wand,ssize_t x1,ssize_t y1,
6566 ssize_t x2,ssize_t y2)
6568 assert(wand != (DrawingWand *) NULL);
6569 assert(wand->signature == WandSignature);
6570 if (wand->debug != MagickFalse)
6571 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6572 (void) MvgPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",(double) x1,
6573 (double) y1,(double) x2,(double) y2);
6577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6581 % I s D r a w i n g W a n d %
6585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6587 % IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6589 % The format of the IsDrawingWand method is:
6591 % MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6593 % A description of each parameter follows:
6595 % o wand: the drawing wand.
6598 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6600 if (wand == (const DrawingWand *) NULL)
6601 return(MagickFalse);
6602 if (wand->signature != WandSignature)
6603 return(MagickFalse);
6604 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6605 return(MagickFalse);
6610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6614 % N e w D r a w i n g W a n d %
6618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6620 % NewDrawingWand() returns a drawing wand required for all other methods in
6623 % The format of the NewDrawingWand method is:
6625 % DrawingWand NewDrawingWand(void)
6628 WandExport DrawingWand *NewDrawingWand(void)
6639 quantum=GetMagickQuantumDepth(&depth);
6640 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6641 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
6642 wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand));
6643 if (wand == (DrawingWand *) NULL)
6644 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6645 GetExceptionMessage(errno));
6646 (void) ResetMagickMemory(wand,0,sizeof(*wand));
6647 wand->id=AcquireWandId();
6648 (void) FormatMagickString(wand->name,MaxTextExtent,"%s-%.20g",DrawingWandId,
6650 if (wand->debug != MagickFalse)
6651 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6652 wand->mvg=(char *) NULL;
6656 wand->pattern_id=(char *) NULL;
6657 wand->pattern_offset=0;
6658 wand->pattern_bounds.x=0;
6659 wand->pattern_bounds.y=0;
6660 wand->pattern_bounds.width=0;
6661 wand->pattern_bounds.height=0;
6663 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(
6664 *wand->graphic_context));
6665 if (wand->graphic_context == (DrawInfo **) NULL)
6666 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6667 GetExceptionMessage(errno));
6668 wand->filter_off=MagickTrue;
6669 wand->indent_depth=0;
6670 wand->path_operation=PathDefaultOperation;
6671 wand->path_mode=DefaultPathMode;
6672 wand->image=AcquireImage((const ImageInfo *) NULL);
6673 wand->exception=AcquireExceptionInfo();
6674 wand->destroy=MagickTrue;
6675 wand->debug=IsEventLogging();
6676 wand->signature=WandSignature;
6677 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6686 % P e e k D r a w i n g W a n d %
6690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6692 % PeekDrawingWand() returns the current drawing wand.
6694 % The format of the PeekDrawingWand method is:
6696 % DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6698 % A description of each parameter follows:
6700 % o wand: the drawing wand.
6703 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6708 assert(wand != (const DrawingWand *) NULL);
6709 assert(wand->signature == WandSignature);
6710 if (wand->debug != MagickFalse)
6711 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6712 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6713 GetAffineMatrix(&draw_info->affine);
6714 (void) CloneString(&draw_info->primitive,wand->mvg);
6719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6723 % P o p D r a w i n g W a n d %
6727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6729 % PopDrawingWand() destroys the current drawing wand and returns to the
6730 % previously pushed drawing wand. Multiple drawing wands may exist. It is an
6731 % error to attempt to pop more drawing wands than have been pushed, and it is
6732 % proper form to pop all drawing wands which have been pushed.
6734 % The format of the PopDrawingWand method is:
6736 % MagickBooleanType PopDrawingWand(DrawingWand *wand)
6738 % A description of each parameter follows:
6740 % o wand: the drawing wand.
6743 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6745 assert(wand != (DrawingWand *) NULL);
6746 assert(wand->signature == WandSignature);
6747 if (wand->debug != MagickFalse)
6748 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6749 if (wand->index == 0)
6751 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6752 return(MagickFalse);
6755 Destroy clip path if not same in preceding wand.
6757 #if DRAW_BINARY_IMPLEMENTATION
6758 if (wand->image == (Image *) NULL)
6759 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6760 if (CurrentContext->clip_mask != (char *) NULL)
6761 if (LocaleCompare(CurrentContext->clip_mask,
6762 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6763 (void) SetImageClipMask(wand->image,(Image *) NULL);
6765 CurrentContext=DestroyDrawInfo(CurrentContext);
6767 if (wand->indent_depth > 0)
6768 wand->indent_depth--;
6769 (void) MvgPrintf(wand,"pop graphic-context\n");
6774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6778 % P u s h D r a w i n g W a n d %
6782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6784 % PushDrawingWand() clones the current drawing wand to create a new drawing
6785 % wand. The original drawing wand(s) may be returned to by invoking
6786 % PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6787 % For every Pop there must have already been an equivalent Push.
6789 % The format of the PushDrawingWand method is:
6791 % MagickBooleanType PushDrawingWand(DrawingWand *wand)
6793 % A description of each parameter follows:
6795 % o wand: the drawing wand.
6798 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6800 assert(wand != (DrawingWand *) NULL);
6801 assert(wand->signature == WandSignature);
6802 if (wand->debug != MagickFalse)
6803 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6805 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6806 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6807 if (wand->graphic_context == (DrawInfo **) NULL)
6809 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6811 return(MagickFalse);
6813 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6814 wand->graphic_context[wand->index-1]);
6815 (void) MvgPrintf(wand,"push graphic-context\n");
6816 wand->indent_depth++;