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 S i z e %
1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1589 % DrawGetFontSize() returns the font pointsize used when annotating with text.
1591 % The format of the DrawGetFontSize method is:
1593 % double DrawGetFontSize(const DrawingWand *wand)
1595 % A description of each parameter follows:
1597 % o wand: the drawing wand.
1600 WandExport double DrawGetFontSize(const DrawingWand *wand)
1602 assert(wand != (const DrawingWand *) NULL);
1603 assert(wand->signature == WandSignature);
1604 if (wand->debug != MagickFalse)
1605 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1606 return(CurrentContext->pointsize);
1610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1614 % D r a w G e t F o n t S t r e t c h %
1618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1620 % DrawGetFontStretch() returns the font stretch used when annotating with text.
1622 % The format of the DrawGetFontStretch method is:
1624 % StretchType DrawGetFontStretch(const DrawingWand *wand)
1626 % A description of each parameter follows:
1628 % o wand: the drawing wand.
1631 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1633 assert(wand != (const DrawingWand *) NULL);
1634 assert(wand->signature == WandSignature);
1635 if (wand->debug != MagickFalse)
1636 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1637 return(CurrentContext->stretch);
1641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1645 % D r a w G e t F o n t S t y l e %
1649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1651 % DrawGetFontStyle() returns the font style used when annotating with text.
1653 % The format of the DrawGetFontStyle method is:
1655 % StyleType DrawGetFontStyle(const DrawingWand *wand)
1657 % A description of each parameter follows:
1659 % o wand: the drawing wand.
1662 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1664 assert(wand != (const DrawingWand *) NULL);
1665 assert(wand->signature == WandSignature);
1666 if (wand->debug != MagickFalse)
1667 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1668 return(CurrentContext->style);
1672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1676 % D r a w G e t F o n t W e i g h t %
1680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1682 % DrawGetFontWeight() returns the font weight used when annotating with text.
1684 % The format of the DrawGetFontWeight method is:
1686 % size_t DrawGetFontWeight(const DrawingWand *wand)
1688 % A description of each parameter follows:
1690 % o wand: the drawing wand.
1693 WandExport size_t DrawGetFontWeight(const DrawingWand *wand)
1695 assert(wand != (const DrawingWand *) NULL);
1696 assert(wand->signature == WandSignature);
1697 if (wand->debug != MagickFalse)
1698 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1699 return(CurrentContext->weight);
1703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1707 % D r a w G e t G r a v i t y %
1711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1713 % DrawGetGravity() returns the text placement gravity used when annotating
1716 % The format of the DrawGetGravity method is:
1718 % GravityType DrawGetGravity(const DrawingWand *wand)
1720 % A description of each parameter follows:
1722 % o wand: the drawing wand.
1725 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1727 assert(wand != (const DrawingWand *) NULL);
1728 assert(wand->signature == WandSignature);
1729 if (wand->debug != MagickFalse)
1730 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1731 return(CurrentContext->gravity);
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1739 % D r a w G e t O p a c i t y %
1743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 % DrawGetOpacity() returns the opacity used when drawing with the fill
1746 % or stroke color or texture. Fully opaque is 1.0.
1748 % The format of the DrawGetOpacity method is:
1750 % double DrawGetOpacity(const DrawingWand *wand)
1752 % A description of each parameter follows:
1754 % o wand: the drawing wand.
1757 WandExport double DrawGetOpacity(const DrawingWand *wand)
1762 assert(wand != (const DrawingWand *) NULL);
1763 assert(wand->signature == WandSignature);
1764 if (wand->debug != MagickFalse)
1765 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1766 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->opacity);
1771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1775 % D r a w G e t S t r o k e A n t i a l i a s %
1779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1781 % DrawGetStrokeAntialias() returns the current stroke antialias setting.
1782 % Stroked outlines are antialiased by default. When antialiasing is disabled
1783 % stroked pixels are thresholded to determine if the stroke color or
1784 % underlying canvas color should be used.
1786 % The format of the DrawGetStrokeAntialias method is:
1788 % MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1790 % A description of each parameter follows:
1792 % o wand: the drawing wand.
1795 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1797 assert(wand != (const DrawingWand *) NULL);
1798 assert(wand->signature == WandSignature);
1799 if (wand->debug != MagickFalse)
1800 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1801 return(CurrentContext->stroke_antialias);
1805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1809 % D r a w G e t S t r o k e C o l o r %
1813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1815 % DrawGetStrokeColor() returns the color used for stroking object outlines.
1817 % The format of the DrawGetStrokeColor method is:
1819 % void DrawGetStrokeColor(const DrawingWand *wand,
1820 $ PixelWand *stroke_color)
1822 % A description of each parameter follows:
1824 % o wand: the drawing wand.
1826 % o stroke_color: Return the stroke color.
1829 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1830 PixelWand *stroke_color)
1832 assert(wand != (const DrawingWand *) NULL);
1833 assert(wand->signature == WandSignature);
1834 assert(stroke_color != (PixelWand *) NULL);
1835 if (wand->debug != MagickFalse)
1836 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1837 PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
1841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1845 % D r a w G e t S t r o k e D a s h A r r a y %
1849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1851 % DrawGetStrokeDashArray() returns an array representing the pattern of
1852 % dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
1853 % array must be freed once it is no longer required by the user.
1855 % The format of the DrawGetStrokeDashArray method is:
1857 % double *DrawGetStrokeDashArray(const DrawingWand *wand,
1858 % size_t *number_elements)
1860 % A description of each parameter follows:
1862 % o wand: the drawing wand.
1864 % o number_elements: address to place number of elements in dash array
1867 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
1868 size_t *number_elements)
1873 register const double
1885 assert(wand != (const DrawingWand *) NULL);
1886 assert(wand->signature == WandSignature);
1887 if (wand->debug != MagickFalse)
1888 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1889 assert(number_elements != (size_t *) NULL);
1891 p=CurrentContext->dash_pattern;
1892 if (p != (const double *) NULL)
1896 dash_array=(double *) NULL;
1899 dash_array=(double *) AcquireQuantumMemory((size_t) n,
1900 sizeof(*dash_array));
1901 p=CurrentContext->dash_pattern;
1903 for (i=0; i < (ssize_t) n; i++)
1910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1914 % D r a w G e t S t r o k e D a s h O f f s e t %
1918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1920 % DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1923 % The format of the DrawGetStrokeDashOffset method is:
1925 % double DrawGetStrokeDashOffset(const DrawingWand *wand)
1927 % A description of each parameter follows:
1929 % o wand: the drawing wand.
1932 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1934 assert(wand != (const DrawingWand *) NULL);
1935 assert(wand->signature == WandSignature);
1936 if (wand->debug != MagickFalse)
1937 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1938 return(CurrentContext->dash_offset);
1942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1946 % D r a w G e t S t r o k e L i n e C a p %
1950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1952 % DrawGetStrokeLineCap() returns the shape to be used at the end of
1953 % open subpaths when they are stroked. Values of LineCap are
1954 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
1956 % The format of the DrawGetStrokeLineCap method is:
1958 % LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1960 % A description of each parameter follows:
1962 % o wand: the drawing wand.
1965 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1967 assert(wand != (const DrawingWand *) NULL);
1968 assert(wand->signature == WandSignature);
1969 if (wand->debug != MagickFalse)
1970 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1971 return(CurrentContext->linecap);
1975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1979 % D r a w G e t S t r o k e L i n e J o i n %
1983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1985 % DrawGetStrokeLineJoin() returns the shape to be used at the
1986 % corners of paths (or other vector shapes) when they are
1987 % stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
1990 % The format of the DrawGetStrokeLineJoin method is:
1992 % LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
1994 % A description of each parameter follows:
1996 % o wand: the drawing wand.
1999 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
2001 assert(wand != (const DrawingWand *) NULL);
2002 assert(wand->signature == WandSignature);
2003 if (wand->debug != MagickFalse)
2004 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2005 return(CurrentContext->linejoin);
2009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2013 % D r a w G e t S t r o k e M i t e r L i m i t %
2017 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2019 % DrawGetStrokeMiterLimit() returns the miter limit. When two line
2020 % segments meet at a sharp angle and miter joins have been specified for
2021 % 'lineJoin', it is possible for the miter to extend far beyond the
2022 % thickness of the line stroking the path. The miterLimit' imposes a
2023 % limit on the ratio of the miter length to the 'lineWidth'.
2025 % The format of the DrawGetStrokeMiterLimit method is:
2027 % size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2029 % A description of each parameter follows:
2031 % o wand: the drawing wand.
2034 WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand)
2036 assert(wand != (const DrawingWand *) NULL);
2037 assert(wand->signature == WandSignature);
2038 if (wand->debug != MagickFalse)
2039 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2040 return CurrentContext->miterlimit;
2044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2048 % D r a w G e t S t r o k e O p a c i t y %
2052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2054 % DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
2056 % The format of the DrawGetStrokeOpacity method is:
2058 % double DrawGetStrokeOpacity(const DrawingWand *wand)
2060 % A description of each parameter follows:
2062 % o wand: the drawing wand.
2065 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2070 assert(wand != (const DrawingWand *) NULL);
2071 assert(wand->signature == WandSignature);
2072 if (wand->debug != MagickFalse)
2073 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2074 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity);
2079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2083 % D r a w G e t S t r o k e W i d t h %
2087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2089 % DrawGetStrokeWidth() returns the width of the stroke used to draw object
2092 % The format of the DrawGetStrokeWidth method is:
2094 % double DrawGetStrokeWidth(const DrawingWand *wand)
2096 % A description of each parameter follows:
2098 % o wand: the drawing wand.
2101 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2103 assert(wand != (const DrawingWand *) NULL);
2104 assert(wand->signature == WandSignature);
2105 if (wand->debug != MagickFalse)
2106 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2107 return(CurrentContext->stroke_width);
2111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2115 % D r a w G e t T e x t A l i g n m e n t %
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2121 % DrawGetTextAlignment() returns the alignment applied when annotating with
2124 % The format of the DrawGetTextAlignment method is:
2126 % AlignType DrawGetTextAlignment(DrawingWand *wand)
2128 % A description of each parameter follows:
2130 % o wand: the drawing wand.
2133 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2135 assert(wand != (const DrawingWand *) NULL);
2136 assert(wand->signature == WandSignature);
2137 if (wand->debug != MagickFalse)
2138 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2139 return(CurrentContext->align);
2143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2147 % D r a w G e t T e x t A n t i a l i a s %
2151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2153 % DrawGetTextAntialias() returns the current text antialias setting, which
2154 % determines whether text is antialiased. Text is antialiased by default.
2156 % The format of the DrawGetTextAntialias method is:
2158 % MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2160 % A description of each parameter follows:
2162 % o wand: the drawing wand.
2165 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2167 assert(wand != (const DrawingWand *) NULL);
2168 assert(wand->signature == WandSignature);
2169 if (wand->debug != MagickFalse)
2170 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2171 return(CurrentContext->text_antialias);
2175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2179 % D r a w G e t T e x t D e c o r a t i o n %
2183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2185 % DrawGetTextDecoration() returns the decoration applied when annotating with
2188 % The format of the DrawGetTextDecoration method is:
2190 % DecorationType DrawGetTextDecoration(DrawingWand *wand)
2192 % A description of each parameter follows:
2194 % o wand: the drawing wand.
2197 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2199 assert(wand != (const DrawingWand *) NULL);
2200 assert(wand->signature == WandSignature);
2201 if (wand->debug != MagickFalse)
2202 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2203 return(CurrentContext->decorate);
2207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2211 % D r a w G e t T e x t E n c o d i n g %
2215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2217 % DrawGetTextEncoding() returns a null-terminated string which specifies the
2218 % code set used for text annotations. The string must be freed by the user
2219 % once it is no longer required.
2221 % The format of the DrawGetTextEncoding method is:
2223 % char *DrawGetTextEncoding(const DrawingWand *wand)
2225 % A description of each parameter follows:
2227 % o wand: the drawing wand.
2230 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2232 assert(wand != (const DrawingWand *) NULL);
2233 assert(wand->signature == WandSignature);
2234 if (wand->debug != MagickFalse)
2235 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2236 if (CurrentContext->encoding != (char *) NULL)
2237 return((char *) AcquireString(CurrentContext->encoding));
2238 return((char *) NULL);
2242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2246 % D r a w G e t T e x t K e r n i n g %
2250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2252 % DrawGetTextKerning() gets the spacing between characters in text.
2254 % The format of the DrawSetFontKerning method is:
2256 % double DrawGetTextKerning(DrawingWand *wand)
2258 % A description of each parameter follows:
2260 % o wand: the drawing wand.
2263 WandExport double DrawGetTextKerning(DrawingWand *wand)
2265 assert(wand != (DrawingWand *) NULL);
2266 assert(wand->signature == WandSignature);
2268 if (wand->debug != MagickFalse)
2269 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2270 return(CurrentContext->kerning);
2274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2278 % D r a w G e t T e x t I n t e r L i n e S p a c i n g %
2282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2284 % DrawGetTextInterwordSpacing() gets the spacing between lines in text.
2286 % The format of the DrawSetFontKerning method is:
2288 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2290 % A description of each parameter follows:
2292 % o wand: the drawing wand.
2295 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2297 assert(wand != (DrawingWand *) NULL);
2298 assert(wand->signature == WandSignature);
2299 if (wand->debug != MagickFalse)
2300 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2301 return(CurrentContext->interline_spacing);
2305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2309 % D r a w G e t T e x t I n t e r w o r d S p a c i n g %
2313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2315 % DrawGetTextInterwordSpacing() gets the spacing between words in text.
2317 % The format of the DrawSetFontKerning method is:
2319 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2321 % A description of each parameter follows:
2323 % o wand: the drawing wand.
2326 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2328 assert(wand != (DrawingWand *) NULL);
2329 assert(wand->signature == WandSignature);
2330 if (wand->debug != MagickFalse)
2331 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2332 return(CurrentContext->interword_spacing);
2336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2340 % D r a w G e t V e c t o r G r a p h i c s %
2344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2346 % DrawGetVectorGraphics() returns a null-terminated string which specifies the
2347 % vector graphics generated by any graphics calls made since the wand was
2348 % instantiated. The string must be freed by the user once it is no longer
2351 % The format of the DrawGetVectorGraphics method is:
2353 % char *DrawGetVectorGraphics(const DrawingWand *wand)
2355 % A description of each parameter follows:
2357 % o wand: the drawing wand.
2361 static inline void SetMagickPixelPacket(const Image *image,
2362 const PixelPacket *color,const IndexPacket *index,MagickPixelPacket *pixel)
2364 pixel->red=(MagickRealType) color->red;
2365 pixel->green=(MagickRealType) color->green;
2366 pixel->blue=(MagickRealType) color->blue;
2367 if (image->matte != MagickFalse)
2368 pixel->opacity=(MagickRealType) color->opacity;
2369 if (((image->colorspace == CMYKColorspace) ||
2370 (image->storage_class == PseudoClass)) &&
2371 (index != (const IndexPacket *) NULL))
2372 pixel->index=(MagickRealType) *index;
2375 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2378 value[MaxTextExtent],
2391 assert(wand != (const DrawingWand *) NULL);
2392 assert(wand->signature == WandSignature);
2393 if (wand->debug != MagickFalse)
2394 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2395 xml_info=NewXMLTreeTag("drawing-wand");
2396 if (xml_info == (XMLTreeInfo *) NULL)
2397 return(char *) NULL;
2398 GetMagickPixelPacket(wand->image,&pixel);
2399 child=AddChildToXMLTree(xml_info,"clip-path",0);
2400 if (child != (XMLTreeInfo *) NULL)
2401 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2402 child=AddChildToXMLTree(xml_info,"clip-units",0);
2403 if (child != (XMLTreeInfo *) NULL)
2405 (void) CopyMagickString(value,MagickOptionToMnemonic(
2406 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),MaxTextExtent);
2407 (void) SetXMLTreeContent(child,value);
2409 child=AddChildToXMLTree(xml_info,"decorate",0);
2410 if (child != (XMLTreeInfo *) NULL)
2412 (void) CopyMagickString(value,MagickOptionToMnemonic(
2413 MagickDecorateOptions,(ssize_t) CurrentContext->decorate),MaxTextExtent);
2414 (void) SetXMLTreeContent(child,value);
2416 child=AddChildToXMLTree(xml_info,"encoding",0);
2417 if (child != (XMLTreeInfo *) NULL)
2418 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2419 child=AddChildToXMLTree(xml_info,"fill",0);
2420 if (child != (XMLTreeInfo *) NULL)
2422 if (CurrentContext->fill.opacity != OpaqueOpacity)
2423 pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2424 MagickTrue : MagickFalse;
2425 SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2426 (const IndexPacket *) NULL,&pixel);
2427 GetColorTuple(&pixel,MagickTrue,value);
2428 (void) SetXMLTreeContent(child,value);
2430 child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2431 if (child != (XMLTreeInfo *) NULL)
2433 (void) FormatMagickString(value,MaxTextExtent,"%g",
2434 (double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity));
2435 (void) SetXMLTreeContent(child,value);
2437 child=AddChildToXMLTree(xml_info,"fill-rule",0);
2438 if (child != (XMLTreeInfo *) NULL)
2440 (void) CopyMagickString(value,MagickOptionToMnemonic(
2441 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),MaxTextExtent);
2442 (void) SetXMLTreeContent(child,value);
2444 child=AddChildToXMLTree(xml_info,"font",0);
2445 if (child != (XMLTreeInfo *) NULL)
2446 (void) SetXMLTreeContent(child,CurrentContext->font);
2447 child=AddChildToXMLTree(xml_info,"font-family",0);
2448 if (child != (XMLTreeInfo *) NULL)
2449 (void) SetXMLTreeContent(child,CurrentContext->family);
2450 child=AddChildToXMLTree(xml_info,"font-size",0);
2451 if (child != (XMLTreeInfo *) NULL)
2453 (void) FormatMagickString(value,MaxTextExtent,"%g",
2454 CurrentContext->pointsize);
2455 (void) SetXMLTreeContent(child,value);
2457 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2458 if (child != (XMLTreeInfo *) NULL)
2460 (void) CopyMagickString(value,MagickOptionToMnemonic(
2461 MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
2462 (void) SetXMLTreeContent(child,value);
2464 child=AddChildToXMLTree(xml_info,"font-style",0);
2465 if (child != (XMLTreeInfo *) NULL)
2467 (void) CopyMagickString(value,MagickOptionToMnemonic(
2468 MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
2469 (void) SetXMLTreeContent(child,value);
2471 child=AddChildToXMLTree(xml_info,"font-weight",0);
2472 if (child != (XMLTreeInfo *) NULL)
2474 (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
2475 CurrentContext->weight);
2476 (void) SetXMLTreeContent(child,value);
2478 child=AddChildToXMLTree(xml_info,"gravity",0);
2479 if (child != (XMLTreeInfo *) NULL)
2481 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickGravityOptions,
2482 (ssize_t) CurrentContext->gravity),MaxTextExtent);
2483 (void) SetXMLTreeContent(child,value);
2485 child=AddChildToXMLTree(xml_info,"stroke",0);
2486 if (child != (XMLTreeInfo *) NULL)
2488 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2489 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2490 MagickTrue : MagickFalse;
2491 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2492 (const IndexPacket *) NULL,&pixel);
2493 GetColorTuple(&pixel,MagickTrue,value);
2494 (void) SetXMLTreeContent(child,value);
2496 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2497 if (child != (XMLTreeInfo *) NULL)
2499 (void) FormatMagickString(value,MaxTextExtent,"%d",
2500 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2501 (void) SetXMLTreeContent(child,value);
2503 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2504 if ((child != (XMLTreeInfo *) NULL) &&
2505 (CurrentContext->dash_pattern != (double *) NULL))
2510 dash_pattern=AcquireString((char *) NULL);
2511 for (i=0; CurrentContext->dash_pattern[i] != 0.0; i++)
2514 (void) ConcatenateString(&dash_pattern,",");
2515 (void) FormatMagickString(value,MaxTextExtent,"%g",
2516 CurrentContext->dash_pattern[i]);
2517 (void) ConcatenateString(&dash_pattern,value);
2519 (void) SetXMLTreeContent(child,dash_pattern);
2520 dash_pattern=DestroyString(dash_pattern);
2522 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2523 if (child != (XMLTreeInfo *) NULL)
2525 (void) FormatMagickString(value,MaxTextExtent,"%g",
2526 CurrentContext->dash_offset);
2527 (void) SetXMLTreeContent(child,value);
2529 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2530 if (child != (XMLTreeInfo *) NULL)
2532 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickLineCapOptions,
2533 (ssize_t) CurrentContext->linecap),MaxTextExtent);
2534 (void) SetXMLTreeContent(child,value);
2536 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2537 if (child != (XMLTreeInfo *) NULL)
2539 (void) CopyMagickString(value,MagickOptionToMnemonic(
2540 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2542 (void) SetXMLTreeContent(child,value);
2544 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2545 if (child != (XMLTreeInfo *) NULL)
2547 (void) FormatMagickString(value,MaxTextExtent,"%.20g",(double)
2548 CurrentContext->miterlimit);
2549 (void) SetXMLTreeContent(child,value);
2551 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2552 if (child != (XMLTreeInfo *) NULL)
2554 (void) FormatMagickString(value,MaxTextExtent,"%g",
2555 (double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity));
2556 (void) SetXMLTreeContent(child,value);
2558 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2559 if (child != (XMLTreeInfo *) NULL)
2561 (void) FormatMagickString(value,MaxTextExtent,"%g",
2562 CurrentContext->stroke_width);
2563 (void) SetXMLTreeContent(child,value);
2565 child=AddChildToXMLTree(xml_info,"text-align",0);
2566 if (child != (XMLTreeInfo *) NULL)
2568 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickAlignOptions,
2569 (ssize_t) CurrentContext->align),MaxTextExtent);
2570 (void) SetXMLTreeContent(child,value);
2572 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2573 if (child != (XMLTreeInfo *) NULL)
2575 (void) FormatMagickString(value,MaxTextExtent,"%d",
2576 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2577 (void) SetXMLTreeContent(child,value);
2579 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2580 if (child != (XMLTreeInfo *) NULL)
2582 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2583 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2584 MagickTrue : MagickFalse;
2585 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2586 (const IndexPacket *) NULL,&pixel);
2587 GetColorTuple(&pixel,MagickTrue,value);
2588 (void) SetXMLTreeContent(child,value);
2590 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2591 if (child != (XMLTreeInfo *) NULL)
2592 (void) SetXMLTreeContent(child,wand->mvg);
2593 xml=XMLTreeInfoToXML(xml_info);
2594 xml_info=DestroyXMLTree(xml_info);
2599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2603 % D r a w G e t T e x t U n d e r C o l o r %
2607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2609 % DrawGetTextUnderColor() returns the color of a background rectangle
2610 % to place under text annotations.
2612 % The format of the DrawGetTextUnderColor method is:
2614 % void DrawGetTextUnderColor(const DrawingWand *wand,
2615 % PixelWand *under_color)
2617 % A description of each parameter follows:
2619 % o wand: the drawing wand.
2621 % o under_color: Return the under color.
2624 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2625 PixelWand *under_color)
2627 assert(wand != (const DrawingWand *) NULL);
2628 assert(wand->signature == WandSignature);
2629 assert(under_color != (PixelWand *) NULL);
2630 if (wand->debug != MagickFalse)
2631 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2632 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2646 % DrawLine() draws a line on the image using the current stroke color,
2647 % stroke opacity, and stroke width.
2649 % The format of the DrawLine method is:
2651 % void DrawLine(DrawingWand *wand,const double sx,const double sy,
2652 % const double ex,const double ey)
2654 % A description of each parameter follows:
2656 % o wand: the drawing wand.
2658 % o sx: starting x ordinate
2660 % o sy: starting y ordinate
2662 % o ex: ending x ordinate
2664 % o ey: ending y ordinate
2667 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2668 const double ex,const double ey)
2670 assert(wand != (DrawingWand *) NULL);
2671 assert(wand->signature == WandSignature);
2672 if (wand->debug != MagickFalse)
2673 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2674 (void) MvgPrintf(wand,"line %g,%g %g,%g\n",sx,sy,ex,ey);
2678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2682 % D r a w M a t t e %
2686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2688 % DrawMatte() paints on the image's opacity channel in order to set effected
2689 % pixels to transparent.
2690 % to influence the opacity of pixels. The available paint
2693 % PointMethod: Select the target pixel
2694 % ReplaceMethod: Select any pixel that matches the target pixel.
2695 % FloodfillMethod: Select the target pixel and matching neighbors.
2696 % FillToBorderMethod: Select the target pixel and neighbors not matching
2698 % ResetMethod: Select all pixels.
2700 % The format of the DrawMatte method is:
2702 % void DrawMatte(DrawingWand *wand,const double x,const double y,
2703 % const PaintMethod paint_method)
2705 % A description of each parameter follows:
2707 % o wand: the drawing wand.
2713 % o paint_method: paint method.
2716 WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2717 const PaintMethod paint_method)
2719 assert(wand != (DrawingWand *) NULL);
2720 assert(wand->signature == WandSignature);
2721 if (wand->debug != MagickFalse)
2722 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2723 (void) MvgPrintf(wand,"matte %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
2724 MagickMethodOptions,(ssize_t) paint_method));
2728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2732 % D r a w P a t h C l o s e %
2736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2738 % DrawPathClose() adds a path element to the current path which closes the
2739 % current subpath by drawing a straight line from the current point to the
2740 % current subpath's most recent starting point (usually, the most recent
2743 % The format of the DrawPathClose method is:
2745 % void DrawPathClose(DrawingWand *wand)
2747 % A description of each parameter follows:
2749 % o wand: the drawing wand.
2752 WandExport void DrawPathClose(DrawingWand *wand)
2754 assert(wand != (DrawingWand *) NULL);
2755 assert(wand->signature == WandSignature);
2756 if (wand->debug != MagickFalse)
2757 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2758 (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2767 % D r a w P a t h C u r v e T o A b s o l u t e %
2771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2773 % DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2774 % point to (x,y) using (x1,y1) as the control point at the beginning of
2775 % the curve and (x2,y2) as the control point at the end of the curve using
2776 % absolute coordinates. At the end of the command, the new current point
2777 % becomes the final (x,y) coordinate pair used in the polybezier.
2779 % The format of the DrawPathCurveToAbsolute method is:
2781 % void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2782 % const double y1,const double x2,const double y2,const double x,
2785 % A description of each parameter follows:
2787 % o wand: the drawing wand.
2789 % o x1: x ordinate of control point for curve beginning
2791 % o y1: y ordinate of control point for curve beginning
2793 % o x2: x ordinate of control point for curve ending
2795 % o y2: y ordinate of control point for curve ending
2797 % o x: x ordinate of the end of the curve
2799 % o y: y ordinate of the end of the curve
2803 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2804 const double x1,const double y1,const double x2,const double y2,
2805 const double x,const double y)
2807 assert(wand != (DrawingWand *) NULL);
2808 assert(wand->signature == WandSignature);
2809 if (wand->debug != MagickFalse)
2810 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2811 if ((wand->path_operation != PathCurveToOperation) ||
2812 (wand->path_mode != mode))
2814 wand->path_operation=PathCurveToOperation;
2815 wand->path_mode=mode;
2816 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g %g,%g",
2817 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2820 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g %g,%g",x1,y1,
2824 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2825 const double y1,const double x2,const double y2,const double x,const double y)
2827 assert(wand != (DrawingWand *) NULL);
2828 assert(wand->signature == WandSignature);
2829 if (wand->debug != MagickFalse)
2830 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2831 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2839 % D r a w P a t h C u r v e T o R e l a t i v e %
2843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2845 % DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2846 % point to (x,y) using (x1,y1) as the control point at the beginning of
2847 % the curve and (x2,y2) as the control point at the end of the curve using
2848 % relative coordinates. At the end of the command, the new current point
2849 % becomes the final (x,y) coordinate pair used in the polybezier.
2851 % The format of the DrawPathCurveToRelative method is:
2853 % void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2854 % const double y1,const double x2,const double y2,const double x,
2857 % A description of each parameter follows:
2859 % o wand: the drawing wand.
2861 % o x1: x ordinate of control point for curve beginning
2863 % o y1: y ordinate of control point for curve beginning
2865 % o x2: x ordinate of control point for curve ending
2867 % o y2: y ordinate of control point for curve ending
2869 % o x: x ordinate of the end of the curve
2871 % o y: y ordinate of the end of the curve
2874 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2875 const double y1,const double x2,const double y2,const double x,const double y)
2877 assert(wand != (DrawingWand *) NULL);
2878 assert(wand->signature == WandSignature);
2879 if (wand->debug != MagickFalse)
2880 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2881 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2889 % 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 %
2893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2895 % DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2896 % from the current point to (x,y) using (x1,y1) as the control point using
2897 % absolute coordinates. At the end of the command, the new current point
2898 % becomes the final (x,y) coordinate pair used in the polybezier.
2900 % The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2902 % void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2903 % const double x1,const double y1,onst double x,const double y)
2905 % A description of each parameter follows:
2907 % o wand: the drawing wand.
2909 % o x1: x ordinate of the control point
2911 % o y1: y ordinate of the control point
2913 % o x: x ordinate of final point
2915 % o y: y ordinate of final point
2919 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2920 const PathMode mode,const double x1,double y1,const double x,const double y)
2922 assert(wand != (DrawingWand *) NULL);
2923 assert(wand->signature == WandSignature);
2924 if (wand->debug != MagickFalse)
2925 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2926 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2927 (wand->path_mode != mode))
2929 wand->path_operation=PathCurveToQuadraticBezierOperation;
2930 wand->path_mode=mode;
2931 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g",
2932 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y);
2935 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x1,y1,x,y);
2938 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2939 const double x1,const double y1,const double x,const double y)
2941 assert(wand != (DrawingWand *) NULL);
2942 assert(wand->signature == WandSignature);
2943 if (wand->debug != MagickFalse)
2944 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2945 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
2949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2953 % 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
2957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2959 % DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
2960 % from the current point to (x,y) using (x1,y1) as the control point using
2961 % relative coordinates. At the end of the command, the new current point
2962 % becomes the final (x,y) coordinate pair used in the polybezier.
2964 % The format of the DrawPathCurveToQuadraticBezierRelative method is:
2966 % void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2967 % const double x1,const double y1,const double x,const double y)
2969 % A description of each parameter follows:
2971 % o wand: the drawing wand.
2973 % o x1: x ordinate of the control point
2975 % o y1: y ordinate of the control point
2977 % o x: x ordinate of final point
2979 % o y: y ordinate of final point
2982 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2983 const double x1,const double y1,const double x,const double y)
2985 assert(wand != (DrawingWand *) NULL);
2986 assert(wand->signature == WandSignature);
2987 if (wand->debug != MagickFalse)
2988 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2989 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
2993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2997 % 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 %
3001 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3003 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3004 % Bezier curve (using absolute coordinates) from the current point to
3005 % (x,y). The control point is assumed to be the reflection of the
3006 % control point on the previous command relative to the current
3007 % point. (If there is no previous command or if the previous command was
3008 % not a DrawPathCurveToQuadraticBezierAbsolute,
3009 % DrawPathCurveToQuadraticBezierRelative,
3010 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3011 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3012 % is coincident with the current point.). At the end of the command, the
3013 % new current point becomes the final (x,y) coordinate pair used in the
3016 % The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3018 % void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3019 % DrawingWand *wand,const double x,const double y)
3021 % A description of each parameter follows:
3023 % o wand: the drawing wand.
3025 % o x: x ordinate of final point
3027 % o y: y ordinate of final point
3031 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3032 const PathMode mode,const double x,const double y)
3034 assert(wand != (DrawingWand *) NULL);
3035 assert(wand->signature == WandSignature);
3036 if (wand->debug != MagickFalse)
3037 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3038 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3039 (wand->path_mode != mode))
3041 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3042 wand->path_mode=mode;
3043 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3047 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3050 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3051 const double x,const double y)
3053 assert(wand != (DrawingWand *) NULL);
3054 assert(wand->signature == WandSignature);
3055 if (wand->debug != MagickFalse)
3056 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3057 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3065 % 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 %
3069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3071 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3072 % curve (using relative coordinates) from the current point to (x,y). The
3073 % control point is assumed to be the reflection of the control point on the
3074 % previous command relative to the current point. (If there is no previous
3075 % command or if the previous command was not a
3076 % DrawPathCurveToQuadraticBezierAbsolute,
3077 % DrawPathCurveToQuadraticBezierRelative,
3078 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3079 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3080 % coincident with the current point.). At the end of the command, the new
3081 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3083 % The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3085 % void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3086 % const double x,const double y)
3088 % A description of each parameter follows:
3090 % o wand: the drawing wand.
3092 % o x: x ordinate of final point
3094 % o y: y ordinate of final point
3097 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3098 const double x,const double y)
3100 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3108 % 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 %
3112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3114 % DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3115 % current point to (x,y) using absolute coordinates. The first control
3116 % point is assumed to be the reflection of the second control point on
3117 % the previous command relative to the current point. (If there is no
3118 % previous command or if the previous command was not an
3119 % DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3120 % DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3121 % the first control point is coincident with the current point.) (x2,y2)
3122 % is the second control point (i.e., the control point at the end of the
3123 % curve). At the end of the command, the new current point becomes the
3124 % final (x,y) coordinate pair used in the polybezier.
3126 % The format of the DrawPathCurveToSmoothAbsolute method is:
3128 % void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3129 % const double x2const double y2,const double x,const double y)
3131 % A description of each parameter follows:
3133 % o wand: the drawing wand.
3135 % o x2: x ordinate of second control point
3137 % o y2: y ordinate of second control point
3139 % o x: x ordinate of termination point
3141 % o y: y ordinate of termination point
3145 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3146 const double x2,const double y2,const double x,const double y)
3148 assert(wand != (DrawingWand *) NULL);
3149 assert(wand->signature == WandSignature);
3150 if (wand->debug != MagickFalse)
3151 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3152 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3153 (wand->path_mode != mode))
3155 wand->path_operation=PathCurveToSmoothOperation;
3156 wand->path_mode=mode;
3157 (void) MvgAutoWrapPrintf(wand,"%c%g,%g %g,%g",
3158 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y);
3161 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x2,y2,x,y);
3164 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3165 const double y2,const double x,const double y)
3167 assert(wand != (DrawingWand *) NULL);
3168 assert(wand->signature == WandSignature);
3169 if (wand->debug != MagickFalse)
3170 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3171 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3179 % 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 %
3183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3185 % DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3186 % point to (x,y) using relative coordinates. The first control point is
3187 % assumed to be the reflection of the second control point on the previous
3188 % command relative to the current point. (If there is no previous command or
3189 % if the previous command was not an DrawPathCurveToAbsolute,
3190 % DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3191 % DrawPathCurveToSmoothRelative, assume the first control point is coincident
3192 % with the current point.) (x2,y2) is the second control point (i.e., the
3193 % control point at the end of the curve). At the end of the command, the new
3194 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3196 % The format of the DrawPathCurveToSmoothRelative method is:
3198 % void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3199 % const double x2,const double y2,const double x,const double y)
3201 % A description of each parameter follows:
3203 % o wand: the drawing wand.
3205 % o x2: x ordinate of second control point
3207 % o y2: y ordinate of second control point
3209 % o x: x ordinate of termination point
3211 % o y: y ordinate of termination point
3214 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3215 const double y2,const double x,const double y)
3217 assert(wand != (DrawingWand *) NULL);
3218 assert(wand->signature == WandSignature);
3219 if (wand->debug != MagickFalse)
3220 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3221 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3229 % 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 %
3233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3235 % DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3236 % to (x, y) using absolute coordinates. The size and orientation of the
3237 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3238 % indicates how the ellipse as a whole is rotated relative to the current
3239 % coordinate system. The center (cx, cy) of the ellipse is calculated
3240 % automagically to satisfy the constraints imposed by the other parameters.
3241 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3242 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3243 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3244 % clock-wise rotation.
3246 % The format of the DrawPathEllipticArcAbsolute method is:
3248 % void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3249 % const double rx,const double ry,const double x_axis_rotation,
3250 % const MagickBooleanType large_arc_flag,
3251 % const MagickBooleanType sweep_flag,const double x,const double y)
3253 % A description of each parameter follows:
3255 % o wand: the drawing wand.
3261 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3262 % relative to the current coordinate system
3264 % o large_arc_flag: If non-zero (true) then draw the larger of the
3267 % o sweep_flag: If non-zero (true) then draw the arc matching a
3268 % clock-wise rotation
3273 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3274 const double rx,const double ry,const double x_axis_rotation,
3275 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3276 const double x,const double y)
3278 assert(wand != (DrawingWand *) NULL);
3279 assert(wand->signature == WandSignature);
3280 if (wand->debug != MagickFalse)
3281 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3282 if ((wand->path_operation != PathEllipticArcOperation) ||
3283 (wand->path_mode != mode))
3285 wand->path_operation=PathEllipticArcOperation;
3286 wand->path_mode=mode;
3287 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g %u %u %g,%g",
3288 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3289 large_arc_flag,sweep_flag,x,y);
3292 (void) MvgAutoWrapPrintf(wand," %g,%g %g %u %u %g,%g",rx,ry,
3293 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3296 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3297 const double ry,const double x_axis_rotation,
3298 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3299 const double x,const double y)
3301 assert(wand != (DrawingWand *) NULL);
3302 assert(wand->signature == WandSignature);
3303 if (wand->debug != MagickFalse)
3304 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3305 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3306 large_arc_flag,sweep_flag,x,y);
3310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3314 % 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 %
3318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3320 % DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3321 % to (x, y) using relative coordinates. The size and orientation of the
3322 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3323 % indicates how the ellipse as a whole is rotated relative to the current
3324 % coordinate system. The center (cx, cy) of the ellipse is calculated
3325 % automagically to satisfy the constraints imposed by the other parameters.
3326 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3327 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3328 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3329 % clock-wise rotation.
3331 % The format of the DrawPathEllipticArcRelative method is:
3333 % void DrawPathEllipticArcRelative(DrawingWand *wand,
3334 % const double rx,const double ry,const double x_axis_rotation,
3335 % const MagickBooleanType large_arc_flag,
3336 % const MagickBooleanType sweep_flag,const double x,const double y)
3338 % A description of each parameter follows:
3340 % o wand: the drawing wand.
3346 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3347 % relative to the current coordinate system
3349 % o large_arc_flag: If non-zero (true) then draw the larger of the
3352 % o sweep_flag: If non-zero (true) then draw the arc matching a
3353 % clock-wise rotation
3356 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3357 const double ry,const double x_axis_rotation,
3358 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3359 const double x,const double y)
3361 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3362 large_arc_flag,sweep_flag,x,y);
3366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3370 % D r a w P a t h F i n i s h %
3374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3376 % DrawPathFinish() terminates the current path.
3378 % The format of the DrawPathFinish method is:
3380 % void DrawPathFinish(DrawingWand *wand)
3382 % A description of each parameter follows:
3384 % o wand: the drawing wand.
3387 WandExport void DrawPathFinish(DrawingWand *wand)
3389 assert(wand != (DrawingWand *) NULL);
3390 assert(wand->signature == WandSignature);
3391 if (wand->debug != MagickFalse)
3392 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3393 (void) MvgPrintf(wand,"'\n");
3394 wand->path_operation=PathDefaultOperation;
3395 wand->path_mode=DefaultPathMode;
3399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3403 % D r a w P a t h L i n e T o A b s o l u t e %
3407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3409 % DrawPathLineToAbsolute() draws a line path from the current point to the
3410 % given coordinate using absolute coordinates. The coordinate then becomes
3411 % the new current point.
3413 % The format of the DrawPathLineToAbsolute method is:
3415 % void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3418 % A description of each parameter follows:
3420 % o wand: the drawing wand.
3422 % o x: target x ordinate
3424 % o y: target y ordinate
3427 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3428 const double x,const double y)
3430 assert(wand != (DrawingWand *) NULL);
3431 assert(wand->signature == WandSignature);
3432 if (wand->debug != MagickFalse)
3433 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3434 if ((wand->path_operation != PathLineToOperation) ||
3435 (wand->path_mode != mode))
3437 wand->path_operation=PathLineToOperation;
3438 wand->path_mode=mode;
3439 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3443 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3446 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3449 assert(wand != (DrawingWand *) NULL);
3450 assert(wand->signature == WandSignature);
3451 if (wand->debug != MagickFalse)
3452 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3453 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3461 % D r a w P a t h L i n e T o R e l a t i v e %
3465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3467 % DrawPathLineToRelative() draws a line path from the current point to the
3468 % given coordinate using relative coordinates. The coordinate then becomes
3469 % the new current point.
3471 % The format of the DrawPathLineToRelative method is:
3473 % void DrawPathLineToRelative(DrawingWand *wand,const double x,
3476 % A description of each parameter follows:
3478 % o wand: the drawing wand.
3480 % o x: target x ordinate
3482 % o y: target y ordinate
3485 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3488 assert(wand != (DrawingWand *) NULL);
3489 assert(wand->signature == WandSignature);
3490 if (wand->debug != MagickFalse)
3491 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3492 DrawPathLineTo(wand,RelativePathMode,x,y);
3496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3500 % 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 %
3504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3506 % DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3507 % current point to the target point using absolute coordinates. The target
3508 % point then becomes the new current point.
3510 % The format of the DrawPathLineToHorizontalAbsolute method is:
3512 % void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3513 % const PathMode mode,const double x)
3515 % A description of each parameter follows:
3517 % o wand: the drawing wand.
3519 % o x: target x ordinate
3523 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3526 assert(wand != (DrawingWand *) NULL);
3527 assert(wand->signature == WandSignature);
3528 if (wand->debug != MagickFalse)
3529 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3530 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3531 (wand->path_mode != mode))
3533 wand->path_operation=PathLineToHorizontalOperation;
3534 wand->path_mode=mode;
3535 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3539 (void) MvgAutoWrapPrintf(wand," %g",x);
3542 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3545 assert(wand != (DrawingWand *) NULL);
3546 assert(wand->signature == WandSignature);
3547 if (wand->debug != MagickFalse)
3548 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3549 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3557 % 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 %
3561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3563 % DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3564 % current point to the target point using relative coordinates. The target
3565 % point then becomes the new current point.
3567 % The format of the DrawPathLineToHorizontalRelative method is:
3569 % void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3572 % A description of each parameter follows:
3574 % o wand: the drawing wand.
3576 % o x: target x ordinate
3579 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3582 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3590 % 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 %
3594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3596 % DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3597 % current point to the target point using absolute coordinates. The target
3598 % point then becomes the new current point.
3600 % The format of the DrawPathLineToVerticalAbsolute method is:
3602 % void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3605 % A description of each parameter follows:
3607 % o wand: the drawing wand.
3609 % o y: target y ordinate
3613 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3616 assert(wand != (DrawingWand *) NULL);
3617 assert(wand->signature == WandSignature);
3618 if (wand->debug != MagickFalse)
3619 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3620 if ((wand->path_operation != PathLineToVerticalOperation) ||
3621 (wand->path_mode != mode))
3623 wand->path_operation=PathLineToVerticalOperation;
3624 wand->path_mode=mode;
3625 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3629 (void) MvgAutoWrapPrintf(wand," %g",y);
3632 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3634 assert(wand != (DrawingWand *) NULL);
3635 assert(wand->signature == WandSignature);
3636 if (wand->debug != MagickFalse)
3637 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3638 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3646 % 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 %
3650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3652 % DrawPathLineToVerticalRelative() draws a vertical line path from the
3653 % current point to the target point using relative coordinates. The target
3654 % point then becomes the new current point.
3656 % The format of the DrawPathLineToVerticalRelative method is:
3658 % void DrawPathLineToVerticalRelative(DrawingWand *wand,
3661 % A description of each parameter follows:
3663 % o wand: the drawing wand.
3665 % o y: target y ordinate
3668 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3670 assert(wand != (DrawingWand *) NULL);
3671 assert(wand->signature == WandSignature);
3672 if (wand->debug != MagickFalse)
3673 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3674 DrawPathLineToVertical(wand,RelativePathMode,y);
3677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3681 % D r a w P a t h M o v e T o A b s o l u t e %
3685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3687 % DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3688 % using absolute coordinates. The current point then becomes the
3689 % specified coordinate.
3691 % The format of the DrawPathMoveToAbsolute method is:
3693 % void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3696 % A description of each parameter follows:
3698 % o wand: the drawing wand.
3700 % o x: target x ordinate
3702 % o y: target y ordinate
3706 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3709 assert(wand != (DrawingWand *) NULL);
3710 assert(wand->signature == WandSignature);
3711 if (wand->debug != MagickFalse)
3712 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3713 if ((wand->path_operation != PathMoveToOperation) ||
3714 (wand->path_mode != mode))
3716 wand->path_operation=PathMoveToOperation;
3717 wand->path_mode=mode;
3718 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3722 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3725 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3728 assert(wand != (DrawingWand *) NULL);
3729 assert(wand->signature == WandSignature);
3730 if (wand->debug != MagickFalse)
3731 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3732 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3736 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3740 % D r a w P a t h M o v e T o R e l a t i v e %
3744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3746 % DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3747 % relative coordinates. The current point then becomes the specified
3750 % The format of the DrawPathMoveToRelative method is:
3752 % void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3755 % A description of each parameter follows:
3757 % o wand: the drawing wand.
3759 % o x: target x ordinate
3761 % o y: target y ordinate
3764 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3767 assert(wand != (DrawingWand *) NULL);
3768 assert(wand->signature == WandSignature);
3769 if (wand->debug != MagickFalse)
3770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3771 DrawPathMoveTo(wand,RelativePathMode,x,y);
3775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3779 % D r a w P a t h S t a r t %
3783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3785 % DrawPathStart() declares the start of a path drawing list which is terminated
3786 % by a matching DrawPathFinish() command. All other DrawPath commands must
3787 % be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3788 % is because path drawing commands are subordinate commands and they do not
3789 % function by themselves.
3791 % The format of the DrawPathStart method is:
3793 % void DrawPathStart(DrawingWand *wand)
3795 % A description of each parameter follows:
3797 % o wand: the drawing wand.
3800 WandExport void DrawPathStart(DrawingWand *wand)
3802 assert(wand != (DrawingWand *) NULL);
3803 assert(wand->signature == WandSignature);
3804 if (wand->debug != MagickFalse)
3805 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3806 (void) MvgPrintf(wand,"path '");
3807 wand->path_operation=PathDefaultOperation;
3808 wand->path_mode=DefaultPathMode;
3812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3816 % D r a w P o i n t %
3820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3822 % DrawPoint() draws a point using the current fill color.
3824 % The format of the DrawPoint method is:
3826 % void DrawPoint(DrawingWand *wand,const double x,const double y)
3828 % A description of each parameter follows:
3830 % o wand: the drawing wand.
3832 % o x: target x coordinate
3834 % o y: target y coordinate
3837 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3839 assert(wand != (DrawingWand *) NULL);
3840 assert(wand->signature == WandSignature);
3841 if (wand->debug != MagickFalse)
3842 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3843 (void) MvgPrintf(wand,"point %g,%g\n",x,y);
3847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3851 % D r a w P o l y g o n %
3855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3857 % DrawPolygon() draws a polygon using the current stroke, stroke width, and
3858 % fill color or texture, using the specified array of coordinates.
3860 % The format of the DrawPolygon method is:
3862 % void DrawPolygon(DrawingWand *wand,
3863 % const size_t number_coordinates,const PointInfo *coordinates)
3865 % A description of each parameter follows:
3867 % o wand: the drawing wand.
3869 % o number_coordinates: number of coordinates
3871 % o coordinates: coordinate array
3874 WandExport void DrawPolygon(DrawingWand *wand,
3875 const size_t number_coordinates,const PointInfo *coordinates)
3877 assert(wand != (DrawingWand *) NULL);
3878 assert(wand->signature == WandSignature);
3879 if (wand->debug != MagickFalse)
3880 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3881 MvgAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3889 % D r a w P o l y l i n e %
3893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3895 % DrawPolyline() draws a polyline using the current stroke, stroke width, and
3896 % fill color or texture, using the specified array of coordinates.
3898 % The format of the DrawPolyline method is:
3900 % void DrawPolyline(DrawingWand *wand,
3901 % const size_t number_coordinates,const PointInfo *coordinates)
3903 % A description of each parameter follows:
3905 % o wand: the drawing wand.
3907 % o number_coordinates: number of coordinates
3909 % o coordinates: coordinate array
3912 WandExport void DrawPolyline(DrawingWand *wand,
3913 const size_t number_coordinates,const PointInfo *coordinates)
3915 assert(wand != (DrawingWand *) NULL);
3916 assert(wand->signature == WandSignature);
3917 if (wand->debug != MagickFalse)
3918 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3919 MvgAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
3923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3927 % D r a w P o p C l i p P a t h %
3931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3933 % DrawPopClipPath() terminates a clip path definition.
3935 % The format of the DrawPopClipPath method is:
3937 % void DrawPopClipPath(DrawingWand *wand)
3939 % A description of each parameter follows:
3941 % o wand: the drawing wand.
3944 WandExport void DrawPopClipPath(DrawingWand *wand)
3946 assert(wand != (DrawingWand *) NULL);
3947 assert(wand->signature == WandSignature);
3948 if (wand->debug != MagickFalse)
3949 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3950 if (wand->indent_depth > 0)
3951 wand->indent_depth--;
3952 (void) MvgPrintf(wand,"pop clip-path\n");
3956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3960 % D r a w P o p D e f s %
3964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3966 % DrawPopDefs() terminates a definition list.
3968 % The format of the DrawPopDefs method is:
3970 % void DrawPopDefs(DrawingWand *wand)
3972 % A description of each parameter follows:
3974 % o wand: the drawing wand.
3977 WandExport void DrawPopDefs(DrawingWand *wand)
3979 assert(wand != (DrawingWand *) NULL);
3980 assert(wand->signature == WandSignature);
3981 if (wand->debug != MagickFalse)
3982 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3983 if (wand->indent_depth > 0)
3984 wand->indent_depth--;
3985 (void) MvgPrintf(wand,"pop defs\n");
3989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3993 % D r a w P o p P a t t e r n %
3997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3999 % DrawPopPattern() terminates a pattern definition.
4001 % The format of the DrawPopPattern method is:
4003 % MagickBooleanType DrawPopPattern(DrawingWand *wand)
4005 % A description of each parameter follows:
4007 % o wand: the drawing wand.
4010 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4013 geometry[MaxTextExtent],
4016 assert(wand != (DrawingWand *) NULL);
4017 assert(wand->signature == WandSignature);
4018 if (wand->debug != MagickFalse)
4019 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4020 if (wand->image == (Image *) NULL)
4021 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4022 if (wand->pattern_id == (const char *) NULL)
4024 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4026 return(MagickFalse);
4028 (void) FormatMagickString(key,MaxTextExtent,"%s",wand->pattern_id);
4029 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4030 (void) FormatMagickString(geometry,MaxTextExtent,"%.20gx%.20g%+.20g%+.20g",
4031 (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
4032 (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
4033 (void) SetImageArtifact(wand->image,key,geometry);
4034 wand->pattern_id=DestroyString(wand->pattern_id);
4035 wand->pattern_offset=0;
4036 wand->pattern_bounds.x=0;
4037 wand->pattern_bounds.y=0;
4038 wand->pattern_bounds.width=0;
4039 wand->pattern_bounds.height=0;
4040 wand->filter_off=MagickTrue;
4041 if (wand->indent_depth > 0)
4042 wand->indent_depth--;
4043 (void) MvgPrintf(wand,"pop pattern\n");
4048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4052 % D r a w P u s h C l i p P a t h %
4056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4058 % DrawPushClipPath() starts a clip path definition which is comprized of any
4059 % number of drawing commands and terminated by a DrawPopClipPath() command.
4061 % The format of the DrawPushClipPath method is:
4063 % void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4065 % A description of each parameter follows:
4067 % o wand: the drawing wand.
4069 % o clip_mask_id: string identifier to associate with the clip path for
4073 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4075 assert(wand != (DrawingWand *) NULL);
4076 assert(wand->signature == WandSignature);
4077 if (wand->debug != MagickFalse)
4078 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4079 assert(clip_mask_id != (const char *) NULL);
4080 (void) MvgPrintf(wand,"push clip-path %s\n",clip_mask_id);
4081 wand->indent_depth++;
4085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4089 % D r a w P u s h D e f s %
4093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4095 % DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4096 % command create named elements (e.g. clip-paths, textures, etc.) which
4097 % may safely be processed earlier for the sake of efficiency.
4099 % The format of the DrawPushDefs method is:
4101 % void DrawPushDefs(DrawingWand *wand)
4103 % A description of each parameter follows:
4105 % o wand: the drawing wand.
4108 WandExport void DrawPushDefs(DrawingWand *wand)
4110 assert(wand != (DrawingWand *) NULL);
4111 assert(wand->signature == WandSignature);
4112 if (wand->debug != MagickFalse)
4113 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4114 (void) MvgPrintf(wand,"push defs\n");
4115 wand->indent_depth++;
4119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4123 % D r a w P u s h P a t t e r n %
4127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4129 % DrawPushPattern() indicates that subsequent commands up to a
4130 % DrawPopPattern() command comprise the definition of a named pattern.
4131 % The pattern space is assigned top left corner coordinates, a width
4132 % and height, and becomes its own drawing space. Anything which can
4133 % be drawn may be used in a pattern definition.
4134 % Named patterns may be used as stroke or brush definitions.
4136 % The format of the DrawPushPattern method is:
4138 % MagickBooleanType DrawPushPattern(DrawingWand *wand,
4139 % const char *pattern_id,const double x,const double y,
4140 % const double width,const double height)
4142 % A description of each parameter follows:
4144 % o wand: the drawing wand.
4146 % o pattern_id: pattern identification for later reference
4148 % o x: x ordinate of top left corner
4150 % o y: y ordinate of top left corner
4152 % o width: width of pattern space
4154 % o height: height of pattern space
4157 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4158 const char *pattern_id,const double x,const double y,const double width,
4159 const double height)
4161 assert(wand != (DrawingWand *) NULL);
4162 assert(wand->signature == WandSignature);
4163 if (wand->debug != MagickFalse)
4164 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4165 assert(pattern_id != (const char *) NULL);
4166 if (wand->pattern_id != NULL)
4168 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4170 return(MagickFalse);
4172 wand->filter_off=MagickTrue;
4173 (void) MvgPrintf(wand,"push pattern %s %g,%g %g,%g\n",pattern_id,
4175 wand->indent_depth++;
4176 wand->pattern_id=AcquireString(pattern_id);
4177 wand->pattern_bounds.x=(ssize_t) ceil(x-0.5);
4178 wand->pattern_bounds.y=(ssize_t) ceil(y-0.5);
4179 wand->pattern_bounds.width=(size_t) floor(width+0.5);
4180 wand->pattern_bounds.height=(size_t) floor(height+0.5);
4181 wand->pattern_offset=wand->mvg_length;
4186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4190 % D r a w R e c t a n g l e %
4194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4196 % DrawRectangle() draws a rectangle given two coordinates and using the
4197 % current stroke, stroke width, and fill settings.
4199 % The format of the DrawRectangle method is:
4201 % void DrawRectangle(DrawingWand *wand,const double x1,
4202 % const double y1,const double x2,const double y2)
4204 % A description of each parameter follows:
4206 % o x1: x ordinate of first coordinate
4208 % o y1: y ordinate of first coordinate
4210 % o x2: x ordinate of second coordinate
4212 % o y2: y ordinate of second coordinate
4215 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4216 const double x2,const double y2)
4218 assert(wand != (DrawingWand *) NULL);
4219 assert(wand->signature == WandSignature);
4220 if (wand->debug != MagickFalse)
4221 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4222 (void) MvgPrintf(wand,"rectangle %g,%g %g,%g\n",x1,y1,x2,y2);
4226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4230 + D r a w R e n d e r %
4234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4236 % DrawRender() renders all preceding drawing commands onto the image.
4238 % The format of the DrawRender method is:
4240 % MagickBooleanType DrawRender(DrawingWand *wand)
4242 % A description of each parameter follows:
4244 % o wand: the drawing wand.
4247 WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4252 assert(wand != (const DrawingWand *) NULL);
4253 assert(wand->signature == WandSignature);
4254 if (wand->debug != MagickFalse)
4255 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4256 CurrentContext->primitive=wand->mvg;
4257 if (wand->debug != MagickFalse)
4258 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4259 if (wand->image == (Image *) NULL)
4260 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4261 status=DrawImage(wand->image,CurrentContext);
4262 InheritException(wand->exception,&wand->image->exception);
4263 CurrentContext->primitive=(char *) NULL;
4268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4272 % D r a w R e s e t V e c t o r G r a p h i c s %
4276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4278 % DrawResetVectorGraphics() resets the vector graphics associated with the
4281 % The format of the DrawResetVectorGraphics method is:
4283 % void DrawResetVectorGraphics(DrawingWand *wand)
4285 % A description of each parameter follows:
4287 % o wand: the drawing wand.
4290 WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4292 assert(wand != (DrawingWand *) NULL);
4293 assert(wand->signature == WandSignature);
4294 if (wand->debug != MagickFalse)
4295 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4296 if (wand->mvg != (char *) NULL)
4297 wand->mvg=DestroyString(wand->mvg);
4304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4308 % D r a w R o t a t e %
4312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4314 % DrawRotate() applies the specified rotation to the current coordinate space.
4316 % The format of the DrawRotate method is:
4318 % void DrawRotate(DrawingWand *wand,const double degrees)
4320 % A description of each parameter follows:
4322 % o wand: the drawing wand.
4324 % o degrees: degrees of rotation
4327 WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4329 assert(wand != (DrawingWand *) NULL);
4330 assert(wand->signature == WandSignature);
4331 if (wand->debug != MagickFalse)
4332 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4333 (void) MvgPrintf(wand,"rotate %g\n",degrees);
4337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4341 % D r a w R o u n d R e c t a n g l e %
4345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4347 % DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4348 % x & y corner radiuses and using the current stroke, stroke width,
4349 % and fill settings.
4351 % The format of the DrawRoundRectangle method is:
4353 % void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4354 % double x2,double y2,double rx,double ry)
4356 % A description of each parameter follows:
4358 % o wand: the drawing wand.
4360 % o x1: x ordinate of first coordinate
4362 % o y1: y ordinate of first coordinate
4364 % o x2: x ordinate of second coordinate
4366 % o y2: y ordinate of second coordinate
4368 % o rx: radius of corner in horizontal direction
4370 % o ry: radius of corner in vertical direction
4373 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4374 double x2,double y2,double rx,double ry)
4376 assert(wand != (DrawingWand *) NULL);
4377 assert(wand->signature == WandSignature);
4378 if (wand->debug != MagickFalse)
4379 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4380 (void) MvgPrintf(wand,"roundrectangle %g,%g %g,%g %g,%g\n",
4385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4389 % D r a w S c a l e %
4393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4395 % DrawScale() adjusts the scaling factor to apply in the horizontal and
4396 % vertical directions to the current coordinate space.
4398 % The format of the DrawScale method is:
4400 % void DrawScale(DrawingWand *wand,const double x,const double y)
4402 % A description of each parameter follows:
4404 % o wand: the drawing wand.
4406 % o x: horizontal scale factor
4408 % o y: vertical scale factor
4411 WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4413 assert(wand != (DrawingWand *) NULL);
4414 assert(wand->signature == WandSignature);
4415 if (wand->debug != MagickFalse)
4416 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4417 (void) MvgPrintf(wand,"scale %g,%g\n",x,y);
4421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4425 % D r a w S e t B o r d e r C o l o r %
4429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4431 % DrawSetBorderColor() sets the border color to be used for drawing bordered
4434 % The format of the DrawSetBorderColor method is:
4436 % void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4438 % A description of each parameter follows:
4440 % o wand: the drawing wand.
4442 % o border_wand: border wand.
4446 static inline MagickBooleanType IsColorEqual(const PixelPacket *p,
4447 const PixelPacket *q)
4449 if (p->red != q->red)
4450 return(MagickFalse);
4451 if (p->green != q->green)
4452 return(MagickFalse);
4453 if (p->blue != q->blue)
4454 return(MagickFalse);
4455 if (p->opacity != q->opacity)
4456 return(MagickFalse);
4460 WandExport void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4467 assert(wand != (DrawingWand *) NULL);
4468 assert(wand->signature == WandSignature);
4469 if (wand->debug != MagickFalse)
4470 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4471 assert(border_wand != (const PixelWand *) NULL);
4472 PixelGetQuantumColor(border_wand,&border_color);
4473 new_border=border_color;
4474 current_border=(&CurrentContext->border_color);
4475 if ((wand->filter_off != MagickFalse) ||
4476 (IsColorEqual(current_border,&new_border) == MagickFalse))
4478 CurrentContext->border_color=new_border;
4479 (void) MvgPrintf(wand,"border-color '");
4480 MvgAppendColor(wand,&border_color);
4481 (void) MvgPrintf(wand,"'\n");
4486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4490 % D r a w S e t C l i p P a t h %
4494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4496 % DrawSetClipPath() associates a named clipping path with the image. Only
4497 % the areas drawn on by the clipping path will be modified as ssize_t as it
4498 % remains in effect.
4500 % The format of the DrawSetClipPath method is:
4502 % MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4503 % const char *clip_mask)
4505 % A description of each parameter follows:
4507 % o wand: the drawing wand.
4509 % o clip_mask: name of clipping path to associate with image
4512 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4513 const char *clip_mask)
4515 if (wand->debug != MagickFalse)
4516 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4517 assert(wand != (DrawingWand *) NULL);
4518 assert(wand->signature == WandSignature);
4519 assert(clip_mask != (const char *) NULL);
4520 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4521 (wand->filter_off != MagickFalse) ||
4522 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4524 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4525 #if DRAW_BINARY_IMPLEMENTATION
4526 if (wand->image == (Image *) NULL)
4527 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4528 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4530 (void) MvgPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4540 % D r a w S e t C l i p R u l e %
4544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4546 % DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4548 % The format of the DrawSetClipRule method is:
4550 % void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4552 % A description of each parameter follows:
4554 % o wand: the drawing wand.
4556 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4559 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4561 assert(wand != (DrawingWand *) NULL);
4562 assert(wand->signature == WandSignature);
4563 if (wand->debug != MagickFalse)
4564 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4565 if ((wand->filter_off != MagickFalse) ||
4566 (CurrentContext->fill_rule != fill_rule))
4568 CurrentContext->fill_rule=fill_rule;
4569 (void) MvgPrintf(wand, "clip-rule '%s'\n",MagickOptionToMnemonic(
4570 MagickFillRuleOptions,(ssize_t) fill_rule));
4575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4579 % D r a w S e t C l i p U n i t s %
4583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4585 % DrawSetClipUnits() sets the interpretation of clip path units.
4587 % The format of the DrawSetClipUnits method is:
4589 % void DrawSetClipUnits(DrawingWand *wand,
4590 % const ClipPathUnits clip_units)
4592 % A description of each parameter follows:
4594 % o wand: the drawing wand.
4596 % o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4597 % ObjectBoundingBox)
4600 WandExport void DrawSetClipUnits(DrawingWand *wand,
4601 const ClipPathUnits clip_units)
4603 assert(wand != (DrawingWand *) NULL);
4604 assert(wand->signature == WandSignature);
4605 if (wand->debug != MagickFalse)
4606 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4607 if ((wand->filter_off != MagickFalse) ||
4608 (CurrentContext->clip_units != clip_units))
4610 CurrentContext->clip_units=clip_units;
4611 if (clip_units == ObjectBoundingBox)
4616 GetAffineMatrix(&affine);
4617 affine.sx=CurrentContext->bounds.x2;
4618 affine.sy=CurrentContext->bounds.y2;
4619 affine.tx=CurrentContext->bounds.x1;
4620 affine.ty=CurrentContext->bounds.y1;
4621 AdjustAffine(wand,&affine);
4623 (void) MvgPrintf(wand, "clip-units '%s'\n",MagickOptionToMnemonic(
4624 MagickClipPathOptions,(ssize_t) clip_units));
4629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4633 % D r a w S e t F i l l C o l o r %
4637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4639 % DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4641 % The format of the DrawSetFillColor method is:
4643 % void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4645 % A description of each parameter follows:
4647 % o wand: the drawing wand.
4649 % o fill_wand: fill wand.
4652 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4659 assert(wand != (DrawingWand *) NULL);
4660 assert(wand->signature == WandSignature);
4661 if (wand->debug != MagickFalse)
4662 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4663 assert(fill_wand != (const PixelWand *) NULL);
4664 PixelGetQuantumColor(fill_wand,&fill_color);
4665 new_fill=fill_color;
4666 current_fill=(&CurrentContext->fill);
4667 if ((wand->filter_off != MagickFalse) ||
4668 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4670 CurrentContext->fill=new_fill;
4671 (void) MvgPrintf(wand,"fill '");
4672 MvgAppendColor(wand,&fill_color);
4673 (void) MvgPrintf(wand,"'\n");
4678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4682 % D r a w S e t F i l l O p a c i t y %
4686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4688 % DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4689 % color or fill texture. Fully opaque is 1.0.
4691 % The format of the DrawSetFillOpacity method is:
4693 % void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4695 % A description of each parameter follows:
4697 % o wand: the drawing wand.
4699 % o fill_opacity: fill opacity
4702 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4707 assert(wand != (DrawingWand *) NULL);
4708 assert(wand->signature == WandSignature);
4709 if (wand->debug != MagickFalse)
4710 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4711 opacity=ClampToQuantum((double) QuantumRange*(1.0-fill_opacity));
4712 if ((wand->filter_off != MagickFalse) ||
4713 (CurrentContext->fill.opacity != opacity))
4715 CurrentContext->fill.opacity=opacity;
4716 (void) MvgPrintf(wand,"fill-opacity %g\n",fill_opacity);
4721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4725 % D r a w S e t O p a c i t y %
4729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4731 % DrawSetOpacity() sets the opacity to use when drawing using the fill or
4732 % stroke color or texture. Fully opaque is 1.0.
4734 % The format of the DrawSetOpacity method is:
4736 % void DrawSetOpacity(DrawingWand *wand,const double opacity)
4738 % A description of each parameter follows:
4740 % o wand: the drawing wand.
4742 % o opacity: fill opacity
4745 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4750 assert(wand != (DrawingWand *) NULL);
4751 assert(wand->signature == WandSignature);
4752 if (wand->debug != MagickFalse)
4753 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4754 quantum_opacity=ClampToQuantum((double) QuantumRange*(1.0-opacity));
4755 if ((wand->filter_off != MagickFalse) ||
4756 (CurrentContext->opacity != quantum_opacity))
4758 CurrentContext->opacity=(Quantum) opacity;
4759 (void) MvgPrintf(wand,"opacity %g\n",opacity);
4764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4768 % D r a w S e t F i l l P a t t e r n U R L %
4772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4774 % DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4775 % objects. Only local URLs ("#identifier") are supported at this time. These
4776 % local URLs are normally created by defining a named fill pattern with
4777 % DrawPushPattern/DrawPopPattern.
4779 % The format of the DrawSetFillPatternURL method is:
4781 % MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4782 % const char *fill_url)
4784 % A description of each parameter follows:
4786 % o wand: the drawing wand.
4788 % o fill_url: URL to use to obtain fill pattern.
4791 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4792 const char *fill_url)
4795 pattern[MaxTextExtent],
4796 pattern_spec[MaxTextExtent];
4798 assert(wand != (DrawingWand *) NULL);
4799 assert(wand->signature == WandSignature);
4800 if (wand->debug != MagickFalse)
4801 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4802 if (wand->image == (Image *) NULL)
4803 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4804 assert(fill_url != (const char *) NULL);
4805 if (*fill_url != '#')
4807 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4808 return(MagickFalse);
4810 (void) FormatMagickString(pattern,MaxTextExtent,"%s",fill_url+1);
4811 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4813 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4814 return(MagickFalse);
4816 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",fill_url);
4817 #if DRAW_BINARY_IMPLEMENTATION
4818 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4819 &CurrentContext->fill_pattern);
4821 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4822 CurrentContext->fill.opacity=CurrentContext->opacity;
4823 (void) MvgPrintf(wand,"fill %s\n",pattern_spec);
4828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4832 % D r a w S e t F i l l R u l e %
4836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4838 % DrawSetFillRule() sets the fill rule to use while drawing polygons.
4840 % The format of the DrawSetFillRule method is:
4842 % void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4844 % A description of each parameter follows:
4846 % o wand: the drawing wand.
4848 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4851 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4853 assert(wand != (DrawingWand *) NULL);
4854 assert(wand->signature == WandSignature);
4855 if (wand->debug != MagickFalse)
4856 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4857 if ((wand->filter_off != MagickFalse) ||
4858 (CurrentContext->fill_rule != fill_rule))
4860 CurrentContext->fill_rule=fill_rule;
4861 (void) MvgPrintf(wand, "fill-rule '%s'\n",MagickOptionToMnemonic(
4862 MagickFillRuleOptions,(ssize_t) fill_rule));
4867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4871 % D r a w S e t F o n t %
4875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4877 % DrawSetFont() sets the fully-sepecified font to use when annotating with
4880 % The format of the DrawSetFont method is:
4882 % MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4884 % A description of each parameter follows:
4886 % o wand: the drawing wand.
4888 % o font_name: font name
4891 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4892 const char *font_name)
4894 assert(wand != (DrawingWand *) NULL);
4895 assert(wand->signature == WandSignature);
4896 if (wand->debug != MagickFalse)
4897 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4898 assert(font_name != (const char *) NULL);
4899 if ((wand->filter_off != MagickFalse) ||
4900 (CurrentContext->font == (char *) NULL) ||
4901 (LocaleCompare(CurrentContext->font,font_name) != 0))
4903 (void) CloneString(&CurrentContext->font,font_name);
4904 (void) MvgPrintf(wand,"font '%s'\n",font_name);
4910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4914 % D r a w S e t F o n t F a m i l y %
4918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4920 % DrawSetFontFamily() sets the font family to use when annotating with text.
4922 % The format of the DrawSetFontFamily method is:
4924 % MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4925 % const char *font_family)
4927 % A description of each parameter follows:
4929 % o wand: the drawing wand.
4931 % o font_family: font family
4934 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4935 const char *font_family)
4937 assert(wand != (DrawingWand *) NULL);
4938 assert(wand->signature == WandSignature);
4939 if (wand->debug != MagickFalse)
4940 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4941 assert(font_family != (const char *) NULL);
4942 if ((wand->filter_off != MagickFalse) ||
4943 (CurrentContext->family == (const char *) NULL) ||
4944 (LocaleCompare(CurrentContext->family,font_family) != 0))
4946 (void) CloneString(&CurrentContext->family,font_family);
4947 (void) MvgPrintf(wand,"font-family '%s'\n",font_family);
4953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4957 % D r a w S e t F o n t S i z e %
4961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4963 % DrawSetFontSize() sets the font pointsize to use when annotating with text.
4965 % The format of the DrawSetFontSize method is:
4967 % void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4969 % A description of each parameter follows:
4971 % o wand: the drawing wand.
4973 % o pointsize: text pointsize
4976 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4978 assert(wand != (DrawingWand *) NULL);
4979 assert(wand->signature == WandSignature);
4980 if (wand->debug != MagickFalse)
4981 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4982 if ((wand->filter_off != MagickFalse) ||
4983 (fabs(CurrentContext->pointsize-pointsize) > MagickEpsilon))
4985 CurrentContext->pointsize=pointsize;
4986 (void) MvgPrintf(wand,"font-size %g\n",pointsize);
4991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4995 % D r a w S e t F o n t S t r e t c h %
4999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5001 % DrawSetFontStretch() sets the font stretch to use when annotating with text.
5002 % The AnyStretch enumeration acts as a wild-card "don't care" option.
5004 % The format of the DrawSetFontStretch method is:
5006 % void DrawSetFontStretch(DrawingWand *wand,
5007 % const StretchType font_stretch)
5009 % A description of each parameter follows:
5011 % o wand: the drawing wand.
5013 % o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5014 % CondensedStretch, SemiCondensedStretch,
5015 % SemiExpandedStretch, ExpandedStretch,
5016 % ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5019 WandExport void DrawSetFontStretch(DrawingWand *wand,
5020 const StretchType font_stretch)
5022 assert(wand != (DrawingWand *) NULL);
5023 assert(wand->signature == WandSignature);
5024 if (wand->debug != MagickFalse)
5025 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5026 if ((wand->filter_off != MagickFalse) ||
5027 (CurrentContext->stretch != font_stretch))
5029 CurrentContext->stretch=font_stretch;
5030 (void) MvgPrintf(wand, "font-stretch '%s'\n",MagickOptionToMnemonic(
5031 MagickStretchOptions,(ssize_t) font_stretch));
5036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5040 % D r a w S e t F o n t S t y l e %
5044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5046 % DrawSetFontStyle() sets the font style to use when annotating with text.
5047 % The AnyStyle enumeration acts as a wild-card "don't care" option.
5049 % The format of the DrawSetFontStyle method is:
5051 % void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5053 % A description of each parameter follows:
5055 % o wand: the drawing wand.
5057 % o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5060 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5062 assert(wand != (DrawingWand *) NULL);
5063 assert(wand->signature == WandSignature);
5064 if (wand->debug != MagickFalse)
5065 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5066 if ((wand->filter_off != MagickFalse) ||
5067 (CurrentContext->style != style))
5069 CurrentContext->style=style;
5070 (void) MvgPrintf(wand, "font-style '%s'\n",MagickOptionToMnemonic(
5071 MagickStyleOptions,(ssize_t) style));
5076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5080 % D r a w S e t F o n t W e i g h t %
5084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5086 % DrawSetFontWeight() sets the font weight to use when annotating with text.
5088 % The format of the DrawSetFontWeight method is:
5090 % void DrawSetFontWeight(DrawingWand *wand,
5091 % const size_t font_weight)
5093 % A description of each parameter follows:
5095 % o wand: the drawing wand.
5097 % o font_weight: font weight (valid range 100-900)
5100 WandExport void DrawSetFontWeight(DrawingWand *wand,
5101 const size_t font_weight)
5103 assert(wand != (DrawingWand *) NULL);
5104 assert(wand->signature == WandSignature);
5105 if (wand->debug != MagickFalse)
5106 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5107 if ((wand->filter_off != MagickFalse) ||
5108 (CurrentContext->weight != font_weight))
5110 CurrentContext->weight=font_weight;
5111 (void) MvgPrintf(wand,"font-weight %.20g\n",(double) font_weight);
5116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5120 % D r a w S e t G r a v i t y %
5124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5126 % DrawSetGravity() sets the text placement gravity to use when annotating
5129 % The format of the DrawSetGravity method is:
5131 % void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5133 % A description of each parameter follows:
5135 % o wand: the drawing wand.
5137 % o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5138 % NorthEastGravity, WestGravity, CenterGravity,
5139 % EastGravity, SouthWestGravity, SouthGravity,
5143 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5145 assert(wand != (DrawingWand *) NULL);
5146 assert(wand->signature == WandSignature);
5147 if (wand->debug != MagickFalse)
5148 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5149 if ((wand->filter_off != MagickFalse) ||
5150 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5152 CurrentContext->gravity=gravity;
5153 (void) MvgPrintf(wand,"gravity '%s'\n",MagickOptionToMnemonic(
5154 MagickGravityOptions,(ssize_t) gravity));
5159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5163 % D r a w S e t S t r o k e C o l o r %
5167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5169 % DrawSetStrokeColor() sets the color used for stroking object outlines.
5171 % The format of the DrawSetStrokeColor method is:
5173 % void DrawSetStrokeColor(DrawingWand *wand,
5174 % const PixelWand *stroke_wand)
5176 % A description of each parameter follows:
5178 % o wand: the drawing wand.
5180 % o stroke_wand: stroke wand.
5183 WandExport void DrawSetStrokeColor(DrawingWand *wand,
5184 const PixelWand *stroke_wand)
5191 assert(wand != (DrawingWand *) NULL);
5192 assert(wand->signature == WandSignature);
5193 if (wand->debug != MagickFalse)
5194 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5195 assert(stroke_wand != (const PixelWand *) NULL);
5196 PixelGetQuantumColor(stroke_wand,&stroke_color);
5197 new_stroke=stroke_color;
5198 current_stroke=(&CurrentContext->stroke);
5199 if ((wand->filter_off != MagickFalse) ||
5200 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5202 CurrentContext->stroke=new_stroke;
5203 (void) MvgPrintf(wand,"stroke '");
5204 MvgAppendColor(wand,&stroke_color);
5205 (void) MvgPrintf(wand,"'\n");
5210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5214 % D r a w S e t S t r o k e P a t t e r n U R L %
5218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5220 % DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5222 % The format of the DrawSetStrokePatternURL method is:
5224 % MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5225 % const char *stroke_url)
5227 % A description of each parameter follows:
5229 % o wand: the drawing wand.
5231 % o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5234 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5235 const char *stroke_url)
5238 pattern[MaxTextExtent],
5239 pattern_spec[MaxTextExtent];
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->image == (Image *) NULL)
5246 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5247 assert(stroke_url != NULL);
5248 if (stroke_url[0] != '#')
5249 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5250 (void) FormatMagickString(pattern,MaxTextExtent,"%s",stroke_url+1);
5251 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5253 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5254 return(MagickFalse);
5256 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",stroke_url);
5257 #if DRAW_BINARY_IMPLEMENTATION
5258 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5259 &CurrentContext->stroke_pattern);
5261 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5262 CurrentContext->stroke.opacity=CurrentContext->opacity;
5263 (void) MvgPrintf(wand,"stroke %s\n",pattern_spec);
5268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5272 % D r a w S e t S t r o k e A n t i a l i a s %
5276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5278 % DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5279 % Stroked outlines are antialiased by default. When antialiasing is disabled
5280 % stroked pixels are thresholded to determine if the stroke color or
5281 % underlying canvas color should be used.
5283 % The format of the DrawSetStrokeAntialias method is:
5285 % void DrawSetStrokeAntialias(DrawingWand *wand,
5286 % const MagickBooleanType stroke_antialias)
5288 % A description of each parameter follows:
5290 % o wand: the drawing wand.
5292 % o stroke_antialias: set to false (zero) to disable antialiasing
5295 WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5296 const MagickBooleanType stroke_antialias)
5298 assert(wand != (DrawingWand *) NULL);
5299 assert(wand->signature == WandSignature);
5300 if (wand->debug != MagickFalse)
5301 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5302 if ((wand->filter_off != MagickFalse) ||
5303 (CurrentContext->stroke_antialias != stroke_antialias))
5305 CurrentContext->stroke_antialias=stroke_antialias;
5306 (void) MvgPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5316 % D r a w S e t S t r o k e D a s h A r r a y %
5320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5322 % DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5323 % stroke paths. The stroke dash array represents an array of numbers that
5324 % specify the lengths of alternating dashes and gaps in pixels. If an odd
5325 % number of values is provided, then the list of values is repeated to yield
5326 % an even number of values. To remove an existing dash array, pass a zero
5327 % number_elements argument and null dash_array. A typical stroke dash array
5328 % might contain the members 5 3 2.
5330 % The format of the DrawSetStrokeDashArray method is:
5332 % MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5333 % const size_t number_elements,const double *dash_array)
5335 % A description of each parameter follows:
5337 % o wand: the drawing wand.
5339 % o number_elements: number of elements in dash array
5341 % o dash_array: dash array values
5344 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5345 const size_t number_elements,const double *dash_array)
5350 register const double
5363 assert(wand != (DrawingWand *) NULL);
5364 assert(wand->signature == WandSignature);
5365 if (wand->debug != MagickFalse)
5366 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5367 n_new=number_elements;
5370 q=CurrentContext->dash_pattern;
5371 if (q != (const double *) NULL)
5374 if ((n_old == 0) && (n_new == 0))
5380 if ((CurrentContext->dash_pattern != (double *) NULL) &&
5381 (dash_array != (double *) NULL))
5384 q=CurrentContext->dash_pattern;
5385 for (i=0; i < (ssize_t) n_new; i++)
5387 if (fabs((*p)-(*q)) > MagickEpsilon)
5396 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5398 if (CurrentContext->dash_pattern != (double *) NULL)
5399 CurrentContext->dash_pattern=(double *)
5400 RelinquishMagickMemory(CurrentContext->dash_pattern);
5403 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5404 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5405 if (!CurrentContext->dash_pattern)
5407 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5409 return(MagickFalse);
5411 q=CurrentContext->dash_pattern;
5413 for (i=0; i < (ssize_t) n_new; i++)
5417 (void) MvgPrintf(wand,"stroke-dasharray ");
5419 (void) MvgPrintf(wand,"none\n");
5423 (void) MvgPrintf(wand,"%g",*p++);
5424 for (i=1; i < (ssize_t) n_new; i++)
5425 (void) MvgPrintf(wand,",%g",*p++);
5426 (void) MvgPrintf(wand,"\n");
5433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5437 % D r a w S e t S t r o k e D a s h O f f s e t %
5441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5443 % DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5446 % The format of the DrawSetStrokeDashOffset method is:
5448 % void DrawSetStrokeDashOffset(DrawingWand *wand,
5449 % const double dash_offset)
5451 % A description of each parameter follows:
5453 % o wand: the drawing wand.
5455 % o dash_offset: dash offset
5458 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5459 const double dash_offset)
5461 assert(wand != (DrawingWand *) NULL);
5462 assert(wand->signature == WandSignature);
5463 if (wand->debug != MagickFalse)
5464 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5465 if ((wand->filter_off != MagickFalse) ||
5466 (fabs(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
5468 CurrentContext->dash_offset=dash_offset;
5469 (void) MvgPrintf(wand,"stroke-dashoffset %g\n",dash_offset);
5474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5478 % D r a w S e t S t r o k e L i n e C a p %
5482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5484 % DrawSetStrokeLineCap() specifies the shape to be used at the end of
5485 % open subpaths when they are stroked. Values of LineCap are
5486 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
5488 % The format of the DrawSetStrokeLineCap method is:
5490 % void DrawSetStrokeLineCap(DrawingWand *wand,
5491 % const LineCap linecap)
5493 % A description of each parameter follows:
5495 % o wand: the drawing wand.
5497 % o linecap: linecap style
5500 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5502 assert(wand != (DrawingWand *) NULL);
5503 assert(wand->signature == WandSignature);
5504 if (wand->debug != MagickFalse)
5505 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5506 if ((wand->filter_off != MagickFalse) ||
5507 (CurrentContext->linecap != linecap))
5509 CurrentContext->linecap=linecap;
5510 (void) MvgPrintf(wand,"stroke-linecap '%s'\n",MagickOptionToMnemonic(
5511 MagickLineCapOptions,(ssize_t) linecap));
5516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5520 % D r a w S e t S t r o k e L i n e J o i n %
5524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5526 % DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5527 % paths (or other vector shapes) when they are stroked. Values of LineJoin are
5528 % UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5530 % The format of the DrawSetStrokeLineJoin method is:
5532 % void DrawSetStrokeLineJoin(DrawingWand *wand,
5533 % const LineJoin linejoin)
5535 % A description of each parameter follows:
5537 % o wand: the drawing wand.
5539 % o linejoin: line join style
5542 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5544 assert(wand != (DrawingWand *) NULL);
5545 assert(wand->signature == WandSignature);
5546 if (wand->debug != MagickFalse)
5547 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5548 if ((wand->filter_off != MagickFalse) ||
5549 (CurrentContext->linejoin != linejoin))
5551 CurrentContext->linejoin=linejoin;
5552 (void) MvgPrintf(wand, "stroke-linejoin '%s'\n",MagickOptionToMnemonic(
5553 MagickLineJoinOptions,(ssize_t) linejoin));
5558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5562 % D r a w S e t S t r o k e M i t e r L i m i t %
5566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5568 % DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5569 % segments meet at a sharp angle and miter joins have been specified for
5570 % 'lineJoin', it is possible for the miter to extend far beyond the
5571 % thickness of the line stroking the path. The miterLimit' imposes a
5572 % limit on the ratio of the miter length to the 'lineWidth'.
5574 % The format of the DrawSetStrokeMiterLimit method is:
5576 % void DrawSetStrokeMiterLimit(DrawingWand *wand,
5577 % const size_t miterlimit)
5579 % A description of each parameter follows:
5581 % o wand: the drawing wand.
5583 % o miterlimit: miter limit
5586 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
5587 const size_t miterlimit)
5589 assert(wand != (DrawingWand *) NULL);
5590 assert(wand->signature == WandSignature);
5591 if (wand->debug != MagickFalse)
5592 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5593 if (CurrentContext->miterlimit != miterlimit)
5595 CurrentContext->miterlimit=miterlimit;
5596 (void) MvgPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit);
5601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5605 % D r a w S e t S t r o k e O p a c i t y %
5609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5611 % DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5613 % The format of the DrawSetStrokeOpacity method is:
5615 % void DrawSetStrokeOpacity(DrawingWand *wand,
5616 % const double stroke_opacity)
5618 % A description of each parameter follows:
5620 % o wand: the drawing wand.
5622 % o stroke_opacity: stroke opacity. The value 1.0 is opaque.
5625 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5626 const double stroke_opacity)
5631 assert(wand != (DrawingWand *) NULL);
5632 assert(wand->signature == WandSignature);
5633 if (wand->debug != MagickFalse)
5634 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5635 opacity=ClampToQuantum((double) QuantumRange*(1.0-stroke_opacity));
5636 if ((wand->filter_off != MagickFalse) ||
5637 (CurrentContext->stroke.opacity != opacity))
5639 CurrentContext->stroke.opacity=opacity;
5640 (void) MvgPrintf(wand,"stroke-opacity %g\n",stroke_opacity);
5645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5649 % D r a w S e t S t r o k e W i d t h %
5653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5655 % DrawSetStrokeWidth() sets the width of the stroke used to draw object
5658 % The format of the DrawSetStrokeWidth method is:
5660 % void DrawSetStrokeWidth(DrawingWand *wand,
5661 % const double stroke_width)
5663 % A description of each parameter follows:
5665 % o wand: the drawing wand.
5667 % o stroke_width: stroke width
5670 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5672 assert(wand != (DrawingWand *) NULL);
5673 assert(wand->signature == WandSignature);
5674 if (wand->debug != MagickFalse)
5675 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5676 if ((wand->filter_off != MagickFalse) ||
5677 (fabs(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
5679 CurrentContext->stroke_width=stroke_width;
5680 (void) MvgPrintf(wand,"stroke-width %g\n",stroke_width);
5685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5689 % D r a w S e t T e x t A l i g n m e n t %
5693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5695 % DrawSetTextAlignment() specifies a text alignment to be applied when
5696 % annotating with text.
5698 % The format of the DrawSetTextAlignment method is:
5700 % void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5702 % A description of each parameter follows:
5704 % o wand: the drawing wand.
5706 % o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5707 % CenterAlign, or RightAlign.
5710 WandExport void DrawSetTextAlignment(DrawingWand *wand,
5711 const AlignType alignment)
5713 assert(wand != (DrawingWand *) NULL);
5714 assert(wand->signature == WandSignature);
5715 if (wand->debug != MagickFalse)
5716 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5717 if ((wand->filter_off != MagickFalse) ||
5718 (CurrentContext->align != alignment))
5720 CurrentContext->align=alignment;
5721 (void) MvgPrintf(wand,"text-align '%s'\n",MagickOptionToMnemonic(
5722 MagickAlignOptions,(ssize_t) alignment));
5727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5731 % D r a w S e t T e x t A n t i a l i a s %
5735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5737 % DrawSetTextAntialias() controls whether text is antialiased. Text is
5738 % antialiased by default.
5740 % The format of the DrawSetTextAntialias method is:
5742 % void DrawSetTextAntialias(DrawingWand *wand,
5743 % const MagickBooleanType text_antialias)
5745 % A description of each parameter follows:
5747 % o wand: the drawing wand.
5749 % o text_antialias: antialias boolean. Set to false (0) to disable
5753 WandExport void DrawSetTextAntialias(DrawingWand *wand,
5754 const MagickBooleanType text_antialias)
5756 assert(wand != (DrawingWand *) NULL);
5757 assert(wand->signature == WandSignature);
5758 if (wand->debug != MagickFalse)
5759 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5760 if ((wand->filter_off != MagickFalse) ||
5761 (CurrentContext->text_antialias != text_antialias))
5763 CurrentContext->text_antialias=text_antialias;
5764 (void) MvgPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5773 % D r a w S e t T e x t D e c o r a t i o n %
5777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5779 % DrawSetTextDecoration() specifies a decoration to be applied when
5780 % annotating with text.
5782 % The format of the DrawSetTextDecoration method is:
5784 % void DrawSetTextDecoration(DrawingWand *wand,
5785 % const DecorationType decoration)
5787 % A description of each parameter follows:
5789 % o wand: the drawing wand.
5791 % o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5792 % OverlineDecoration, or LineThroughDecoration
5795 WandExport void DrawSetTextDecoration(DrawingWand *wand,
5796 const DecorationType decoration)
5798 assert(wand != (DrawingWand *) NULL);
5799 assert(wand->signature == WandSignature);
5800 if (wand->debug != MagickFalse)
5801 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5802 if ((wand->filter_off != MagickFalse) ||
5803 (CurrentContext->decorate != decoration))
5805 CurrentContext->decorate=decoration;
5806 (void) MvgPrintf(wand,"decorate '%s'\n",MagickOptionToMnemonic(
5807 MagickDecorateOptions,(ssize_t) decoration));
5812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5816 % D r a w S e t T e x t E n c o d i n g %
5820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5822 % DrawSetTextEncoding() specifies the code set to use for text
5823 % annotations. The only character encoding which may be specified
5824 % at this time is "UTF-8" for representing Unicode as a sequence of
5825 % bytes. Specify an empty string to set text encoding to the system's
5826 % default. Successful text annotation using Unicode may require fonts
5827 % designed to support Unicode.
5829 % The format of the DrawSetTextEncoding method is:
5831 % void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5833 % A description of each parameter follows:
5835 % o wand: the drawing wand.
5837 % o encoding: character string specifying text encoding
5840 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5842 assert(wand != (DrawingWand *) NULL);
5843 assert(wand->signature == WandSignature);
5844 if (wand->debug != MagickFalse)
5845 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5846 assert(encoding != (char *) NULL);
5847 if ((wand->filter_off != MagickFalse) ||
5848 (CurrentContext->encoding == (char *) NULL) ||
5849 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
5851 (void) CloneString(&CurrentContext->encoding,encoding);
5852 (void) MvgPrintf(wand,"encoding '%s'\n",encoding);
5857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5861 % D r a w S e t T e x t K e r n i n g %
5865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5867 % DrawSetTextKerning() sets the spacing between characters in text.
5869 % The format of the DrawSetTextKerning method is:
5871 % void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5873 % A description of each parameter follows:
5875 % o wand: the drawing wand.
5877 % o kerning: text kerning
5880 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5882 assert(wand != (DrawingWand *) NULL);
5883 assert(wand->signature == WandSignature);
5885 if (wand->debug != MagickFalse)
5886 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5887 if ((wand->filter_off != MagickFalse) &&
5888 (CurrentContext->kerning != kerning))
5890 CurrentContext->kerning=kerning;
5891 (void) MvgPrintf(wand,"kerning %lf\n",kerning);
5896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5900 % 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 %
5904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5906 % DrawSetTextInterwordSpacing() sets the spacing between line in text.
5908 % The format of the DrawSetInterwordSpacing method is:
5910 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
5911 % const double interline_spacing)
5913 % A description of each parameter follows:
5915 % o wand: the drawing wand.
5917 % o interline_spacing: text line spacing
5920 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
5921 const double interline_spacing)
5923 assert(wand != (DrawingWand *) NULL);
5924 assert(wand->signature == WandSignature);
5926 if (wand->debug != MagickFalse)
5927 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5928 if ((wand->filter_off != MagickFalse) &&
5929 (CurrentContext->interline_spacing != interline_spacing))
5931 CurrentContext->interline_spacing=interline_spacing;
5932 (void) MvgPrintf(wand,"interline-spacing %lf\n",interline_spacing);
5937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5941 % 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 %
5945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5947 % DrawSetTextInterwordSpacing() sets the spacing between words in text.
5949 % The format of the DrawSetInterwordSpacing method is:
5951 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
5952 % const double interword_spacing)
5954 % A description of each parameter follows:
5956 % o wand: the drawing wand.
5958 % o interword_spacing: text word spacing
5961 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
5962 const double interword_spacing)
5964 assert(wand != (DrawingWand *) NULL);
5965 assert(wand->signature == WandSignature);
5967 if (wand->debug != MagickFalse)
5968 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5969 if ((wand->filter_off != MagickFalse) &&
5970 (CurrentContext->interword_spacing != interword_spacing))
5972 CurrentContext->interword_spacing=interword_spacing;
5973 (void) MvgPrintf(wand,"interword-spacing %lf\n",interword_spacing);
5978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5982 % D r a w S e t T e x t U n d e r C o l o r %
5986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5988 % DrawSetTextUnderColor() specifies the color of a background rectangle
5989 % to place under text annotations.
5991 % The format of the DrawSetTextUnderColor method is:
5993 % void DrawSetTextUnderColor(DrawingWand *wand,
5994 % const PixelWand *under_wand)
5996 % A description of each parameter follows:
5998 % o wand: the drawing wand.
6000 % o under_wand: text under wand.
6003 WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6004 const PixelWand *under_wand)
6009 assert(wand != (DrawingWand *) NULL);
6010 assert(wand->signature == WandSignature);
6011 if (wand->debug != MagickFalse)
6012 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6013 assert(under_wand != (const PixelWand *) NULL);
6014 PixelGetQuantumColor(under_wand,&under_color);
6015 if ((wand->filter_off != MagickFalse) ||
6016 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6018 CurrentContext->undercolor=under_color;
6019 (void) MvgPrintf(wand,"text-undercolor '");
6020 MvgAppendColor(wand,&under_color);
6021 (void) MvgPrintf(wand,"'\n");
6026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6030 % D r a w S e t V e c t o r G r a p h i c s %
6034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6036 % DrawSetVectorGraphics() sets the vector graphics associated with the
6037 % specified wand. Use this method with DrawGetVectorGraphics() as a method
6038 % to persist the vector graphics state.
6040 % The format of the DrawSetVectorGraphics method is:
6042 % MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6045 % A description of each parameter follows:
6047 % o wand: the drawing wand.
6049 % o xml: the drawing wand XML.
6053 static inline MagickBooleanType IsPoint(const char *point)
6061 value=strtol(point,&p,10);
6062 return(p != point ? MagickTrue : MagickFalse);
6065 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6075 assert(wand != (DrawingWand *) NULL);
6076 assert(wand->signature == WandSignature);
6077 if (wand->debug != MagickFalse)
6078 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6079 CurrentContext=DestroyDrawInfo(CurrentContext);
6080 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6081 if (xml == (const char *) NULL)
6082 return(MagickFalse);
6083 xml_info=NewXMLTree(xml,wand->exception);
6084 if (xml_info == (XMLTreeInfo *) NULL)
6085 return(MagickFalse);
6086 child=GetXMLTreeChild(xml_info,"clip-path");
6087 if (child != (XMLTreeInfo *) NULL)
6088 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6089 child=GetXMLTreeChild(xml_info,"clip-units");
6090 if (child != (XMLTreeInfo *) NULL)
6092 value=GetXMLTreeContent(child);
6093 if (value != (const char *) NULL)
6094 CurrentContext->clip_units=(ClipPathUnits) ParseMagickOption(
6095 MagickClipPathOptions,MagickFalse,value);
6097 child=GetXMLTreeChild(xml_info,"decorate");
6098 if (child != (XMLTreeInfo *) NULL)
6100 value=GetXMLTreeContent(child);
6101 if (value != (const char *) NULL)
6102 CurrentContext->decorate=(DecorationType) ParseMagickOption(
6103 MagickDecorateOptions,MagickFalse,value);
6105 child=GetXMLTreeChild(xml_info,"encoding");
6106 if (child != (XMLTreeInfo *) NULL)
6107 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6108 child=GetXMLTreeChild(xml_info,"fill");
6109 if (child != (XMLTreeInfo *) NULL)
6111 value=GetXMLTreeContent(child);
6112 if (value != (const char *) NULL)
6113 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6115 child=GetXMLTreeChild(xml_info,"fill-opacity");
6116 if (child != (XMLTreeInfo *) NULL)
6118 value=GetXMLTreeContent(child);
6119 if (value != (const char *) NULL)
6120 CurrentContext->fill.opacity=ClampToQuantum((MagickRealType)
6121 QuantumRange*(1.0-StringToDouble(value)));
6123 child=GetXMLTreeChild(xml_info,"fill-rule");
6124 if (child != (XMLTreeInfo *) NULL)
6126 value=GetXMLTreeContent(child);
6127 if (value != (const char *) NULL)
6128 CurrentContext->fill_rule=(FillRule) ParseMagickOption(
6129 MagickFillRuleOptions,MagickFalse,value);
6131 child=GetXMLTreeChild(xml_info,"font");
6132 if (child != (XMLTreeInfo *) NULL)
6133 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6134 child=GetXMLTreeChild(xml_info,"font-family");
6135 if (child != (XMLTreeInfo *) NULL)
6136 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6137 child=GetXMLTreeChild(xml_info,"font-size");
6138 if (child != (XMLTreeInfo *) NULL)
6140 value=GetXMLTreeContent(child);
6141 if (value != (const char *) NULL)
6142 CurrentContext->pointsize=StringToDouble(value);
6144 child=GetXMLTreeChild(xml_info,"font-stretch");
6145 if (child != (XMLTreeInfo *) NULL)
6147 value=GetXMLTreeContent(child);
6148 if (value != (const char *) NULL)
6149 CurrentContext->stretch=(StretchType) ParseMagickOption(
6150 MagickStretchOptions,MagickFalse,value);
6152 child=GetXMLTreeChild(xml_info,"font-style");
6153 if (child != (XMLTreeInfo *) NULL)
6155 value=GetXMLTreeContent(child);
6156 if (value != (const char *) NULL)
6157 CurrentContext->style=(StyleType) ParseMagickOption(MagickStyleOptions,
6160 child=GetXMLTreeChild(xml_info,"font-weight");
6161 if (child != (XMLTreeInfo *) NULL)
6163 value=GetXMLTreeContent(child);
6164 if (value != (const char *) NULL)
6165 CurrentContext->weight=StringToUnsignedLong(value);
6167 child=GetXMLTreeChild(xml_info,"gravity");
6168 if (child != (XMLTreeInfo *) NULL)
6170 value=GetXMLTreeContent(child);
6171 if (value != (const char *) NULL)
6172 CurrentContext->gravity=(GravityType) ParseMagickOption(
6173 MagickGravityOptions,MagickFalse,value);
6175 child=GetXMLTreeChild(xml_info,"stroke");
6176 if (child != (XMLTreeInfo *) NULL)
6178 value=GetXMLTreeContent(child);
6179 if (value != (const char *) NULL)
6180 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6183 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6184 if (child != (XMLTreeInfo *) NULL)
6186 value=GetXMLTreeContent(child);
6187 if (value != (const char *) NULL)
6188 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6191 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6192 if (child != (XMLTreeInfo *) NULL)
6195 token[MaxTextExtent];
6206 value=GetXMLTreeContent(child);
6207 if (value != (const char *) NULL)
6209 if (CurrentContext->dash_pattern != (double *) NULL)
6210 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6211 CurrentContext->dash_pattern);
6213 if (IsPoint(q) != MagickFalse)
6219 GetMagickToken(p,&p,token);
6221 GetMagickToken(p,&p,token);
6222 for (x=0; IsPoint(token) != MagickFalse; x++)
6224 GetMagickToken(p,&p,token);
6226 GetMagickToken(p,&p,token);
6228 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6229 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6230 if (CurrentContext->dash_pattern == (double *) NULL)
6231 ThrowWandFatalException(ResourceLimitFatalError,
6232 "MemoryAllocationFailed",wand->name);
6233 for (j=0; j < x; j++)
6235 GetMagickToken(q,&q,token);
6237 GetMagickToken(q,&q,token);
6238 CurrentContext->dash_pattern[j]=StringToDouble(token);
6240 if ((x & 0x01) != 0)
6241 for ( ; j < (2*x); j++)
6242 CurrentContext->dash_pattern[j]=
6243 CurrentContext->dash_pattern[j-x];
6244 CurrentContext->dash_pattern[j]=0.0;
6248 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6249 if (child != (XMLTreeInfo *) NULL)
6251 value=GetXMLTreeContent(child);
6252 if (value != (const char *) NULL)
6253 CurrentContext->dash_offset=StringToDouble(value);
6255 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6256 if (child != (XMLTreeInfo *) NULL)
6258 value=GetXMLTreeContent(child);
6259 if (value != (const char *) NULL)
6260 CurrentContext->linecap=(LineCap) ParseMagickOption(
6261 MagickLineCapOptions,MagickFalse,value);
6263 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6264 if (child != (XMLTreeInfo *) NULL)
6266 value=GetXMLTreeContent(child);
6267 if (value != (const char *) NULL)
6268 CurrentContext->linejoin=(LineJoin) ParseMagickOption(
6269 MagickLineJoinOptions,MagickFalse,value);
6271 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6272 if (child != (XMLTreeInfo *) NULL)
6274 value=GetXMLTreeContent(child);
6275 if (value != (const char *) NULL)
6276 CurrentContext->miterlimit=StringToUnsignedLong(value);
6278 child=GetXMLTreeChild(xml_info,"stroke-opacity");
6279 if (child != (XMLTreeInfo *) NULL)
6281 value=GetXMLTreeContent(child);
6282 if (value != (const char *) NULL)
6283 CurrentContext->stroke.opacity=ClampToQuantum((MagickRealType)
6284 QuantumRange*(1.0-StringToDouble(value)));
6286 child=GetXMLTreeChild(xml_info,"stroke-width");
6287 if (child != (XMLTreeInfo *) NULL)
6289 value=GetXMLTreeContent(child);
6290 if (value != (const char *) NULL)
6291 CurrentContext->stroke_width=StringToDouble(value);
6293 child=GetXMLTreeChild(xml_info,"text-align");
6294 if (child != (XMLTreeInfo *) NULL)
6296 value=GetXMLTreeContent(child);
6297 if (value != (const char *) NULL)
6298 CurrentContext->align=(AlignType) ParseMagickOption(MagickAlignOptions,
6301 child=GetXMLTreeChild(xml_info,"text-antialias");
6302 if (child != (XMLTreeInfo *) NULL)
6304 value=GetXMLTreeContent(child);
6305 if (value != (const char *) NULL)
6306 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6309 child=GetXMLTreeChild(xml_info,"text-undercolor");
6310 if (child != (XMLTreeInfo *) NULL)
6312 value=GetXMLTreeContent(child);
6313 if (value != (const char *) NULL)
6314 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6317 child=GetXMLTreeChild(xml_info,"vector-graphics");
6318 if (child != (XMLTreeInfo *) NULL)
6320 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6321 wand->mvg_length=strlen(wand->mvg);
6322 wand->mvg_alloc=wand->mvg_length+1;
6324 xml_info=DestroyXMLTree(xml_info);
6329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6333 % D r a w S k e w X %
6337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6339 % DrawSkewX() skews the current coordinate system in the horizontal
6342 % The format of the DrawSkewX method is:
6344 % void DrawSkewX(DrawingWand *wand,const double degrees)
6346 % A description of each parameter follows:
6348 % o wand: the drawing wand.
6350 % o degrees: number of degrees to skew the coordinates
6353 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6355 assert(wand != (DrawingWand *) NULL);
6356 assert(wand->signature == WandSignature);
6357 if (wand->debug != MagickFalse)
6358 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6359 (void) MvgPrintf(wand,"skewX %g\n",degrees);
6363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6367 % D r a w S k e w Y %
6371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6373 % DrawSkewY() skews the current coordinate system in the vertical
6376 % The format of the DrawSkewY method is:
6378 % void DrawSkewY(DrawingWand *wand,const double degrees)
6380 % A description of each parameter follows:
6382 % o wand: the drawing wand.
6384 % o degrees: number of degrees to skew the coordinates
6387 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6389 assert(wand != (DrawingWand *) NULL);
6390 assert(wand->signature == WandSignature);
6391 if (wand->debug != MagickFalse)
6392 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6393 (void) MvgPrintf(wand,"skewY %g\n",degrees);
6397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6401 % D r a w T r a n s l a t e %
6405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6407 % DrawTranslate() applies a translation to the current coordinate
6408 % system which moves the coordinate system origin to the specified
6411 % The format of the DrawTranslate method is:
6413 % void DrawTranslate(DrawingWand *wand,const double x,
6416 % A description of each parameter follows:
6418 % o wand: the drawing wand.
6420 % o x: new x ordinate for coordinate system origin
6422 % o y: new y ordinate for coordinate system origin
6425 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6427 assert(wand != (DrawingWand *) NULL);
6428 assert(wand->signature == WandSignature);
6429 if (wand->debug != MagickFalse)
6430 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6431 (void) MvgPrintf(wand,"translate %g,%g\n",x,y);
6435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6439 % D r a w S e t V i e w b o x %
6443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6445 % DrawSetViewbox() sets the overall canvas size to be recorded with the
6446 % drawing vector data. Usually this will be specified using the same
6447 % size as the canvas image. When the vector data is saved to SVG or MVG
6448 % formats, the viewbox is use to specify the size of the canvas image that
6449 % a viewer will render the vector data on.
6451 % The format of the DrawSetViewbox method is:
6453 % void DrawSetViewbox(DrawingWand *wand,size_t x1,
6454 % size_t y1,size_t x2,size_t y2)
6456 % A description of each parameter follows:
6458 % o wand: the drawing wand.
6460 % o x1: left x ordinate
6462 % o y1: top y ordinate
6464 % o x2: right x ordinate
6466 % o y2: bottom y ordinate
6469 WandExport void DrawSetViewbox(DrawingWand *wand,ssize_t x1,ssize_t y1,
6470 ssize_t x2,ssize_t y2)
6472 assert(wand != (DrawingWand *) NULL);
6473 assert(wand->signature == WandSignature);
6474 if (wand->debug != MagickFalse)
6475 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6476 (void) MvgPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",(double) x1,
6477 (double) y1,(double) x2,(double) y2);
6481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6485 % I s D r a w i n g W a n d %
6489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6491 % IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6493 % The format of the IsDrawingWand method is:
6495 % MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6497 % A description of each parameter follows:
6499 % o wand: the drawing wand.
6502 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6504 if (wand == (const DrawingWand *) NULL)
6505 return(MagickFalse);
6506 if (wand->signature != WandSignature)
6507 return(MagickFalse);
6508 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6509 return(MagickFalse);
6514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6518 % N e w D r a w i n g W a n d %
6522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6524 % NewDrawingWand() returns a drawing wand required for all other methods in
6527 % The format of the NewDrawingWand method is:
6529 % DrawingWand NewDrawingWand(void)
6532 WandExport DrawingWand *NewDrawingWand(void)
6543 quantum=GetMagickQuantumDepth(&depth);
6544 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6545 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
6546 wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand));
6547 if (wand == (DrawingWand *) NULL)
6548 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6549 GetExceptionMessage(errno));
6550 (void) ResetMagickMemory(wand,0,sizeof(*wand));
6551 wand->id=AcquireWandId();
6552 (void) FormatMagickString(wand->name,MaxTextExtent,"%s-%.20g",DrawingWandId,
6554 if (wand->debug != MagickFalse)
6555 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6556 wand->mvg=(char *) NULL;
6560 wand->pattern_id=(char *) NULL;
6561 wand->pattern_offset=0;
6562 wand->pattern_bounds.x=0;
6563 wand->pattern_bounds.y=0;
6564 wand->pattern_bounds.width=0;
6565 wand->pattern_bounds.height=0;
6567 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(
6568 *wand->graphic_context));
6569 if (wand->graphic_context == (DrawInfo **) NULL)
6570 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6571 GetExceptionMessage(errno));
6572 wand->filter_off=MagickTrue;
6573 wand->indent_depth=0;
6574 wand->path_operation=PathDefaultOperation;
6575 wand->path_mode=DefaultPathMode;
6576 wand->image=AcquireImage((const ImageInfo *) NULL);
6577 wand->exception=AcquireExceptionInfo();
6578 wand->destroy=MagickTrue;
6579 wand->debug=IsEventLogging();
6580 wand->signature=WandSignature;
6581 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6590 % P e e k D r a w i n g W a n d %
6594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6596 % PeekDrawingWand() returns the current drawing wand.
6598 % The format of the PeekDrawingWand method is:
6600 % DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6602 % A description of each parameter follows:
6604 % o wand: the drawing wand.
6607 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6612 assert(wand != (const DrawingWand *) NULL);
6613 assert(wand->signature == WandSignature);
6614 if (wand->debug != MagickFalse)
6615 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6616 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6617 GetAffineMatrix(&draw_info->affine);
6618 (void) CloneString(&draw_info->primitive,wand->mvg);
6623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6627 % P o p D r a w i n g W a n d %
6631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6633 % PopDrawingWand() destroys the current drawing wand and returns to the
6634 % previously pushed drawing wand. Multiple drawing wands may exist. It is an
6635 % error to attempt to pop more drawing wands than have been pushed, and it is
6636 % proper form to pop all drawing wands which have been pushed.
6638 % The format of the PopDrawingWand method is:
6640 % MagickBooleanType PopDrawingWand(DrawingWand *wand)
6642 % A description of each parameter follows:
6644 % o wand: the drawing wand.
6647 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6649 assert(wand != (DrawingWand *) NULL);
6650 assert(wand->signature == WandSignature);
6651 if (wand->debug != MagickFalse)
6652 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6653 if (wand->index == 0)
6655 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6656 return(MagickFalse);
6659 Destroy clip path if not same in preceding wand.
6661 #if DRAW_BINARY_IMPLEMENTATION
6662 if (wand->image == (Image *) NULL)
6663 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6664 if (CurrentContext->clip_mask != (char *) NULL)
6665 if (LocaleCompare(CurrentContext->clip_mask,
6666 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6667 (void) SetImageClipMask(wand->image,(Image *) NULL);
6669 CurrentContext=DestroyDrawInfo(CurrentContext);
6671 if (wand->indent_depth > 0)
6672 wand->indent_depth--;
6673 (void) MvgPrintf(wand,"pop graphic-context\n");
6678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6682 % P u s h D r a w i n g W a n d %
6686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6688 % PushDrawingWand() clones the current drawing wand to create a new drawing
6689 % wand. The original drawing wand(s) may be returned to by invoking
6690 % PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6691 % For every Pop there must have already been an equivalent Push.
6693 % The format of the PushDrawingWand method is:
6695 % MagickBooleanType PushDrawingWand(DrawingWand *wand)
6697 % A description of each parameter follows:
6699 % o wand: the drawing wand.
6702 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6704 assert(wand != (DrawingWand *) NULL);
6705 assert(wand->signature == WandSignature);
6706 if (wand->debug != MagickFalse)
6707 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6709 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6710 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6711 if (wand->graphic_context == (DrawInfo **) NULL)
6713 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6715 return(MagickFalse);
6717 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6718 wand->graphic_context[wand->index-1]);
6719 (void) MvgPrintf(wand,"push graphic-context\n");
6720 wand->indent_depth++;