2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % DDDD RRRR AAA W W IIIII N N GGGG %
7 % D D R R A A W W I NN N G %
8 % D D RRRR AAAAA W W I N N N G GG %
9 % D D R R A A W W W I N NN G G %
10 % DDDD R R A A W W IIIII N N GGG %
14 % W W W AAAAA N N N D D %
15 % WW WW A A N NN D D %
19 % MagickWand Image Vector Drawing Methods %
26 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
27 % dedicated to making software imaging solutions freely available. %
29 % You may not use this file except in compliance with the License. You may %
30 % obtain a copy of the License at %
32 % http://www.imagemagick.org/script/license.php %
34 % Unless required by applicable law or agreed to in writing, software %
35 % distributed under the License is distributed on an "AS IS" BASIS, %
36 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37 % See the License for the specific language governing permissions and %
38 % limitations under the License. %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 #include "wand/studio.h"
50 #include "wand/MagickWand.h"
51 #include "wand/magick-wand-private.h"
52 #include "wand/wand.h"
53 #include "magick/string-private.h"
58 #define DRAW_BINARY_IMPLEMENTATION 0
60 #define CurrentContext (wand->graphic_context[wand->index])
61 #define DrawingWandId "DrawingWand"
62 #define ThrowDrawException(severity,tag,reason) (void) ThrowMagickException( \
63 wand->exception,GetMagickModule(),severity,tag,"`%s'",reason);
71 PathCloseOperation, /* Z|z (none) */
72 PathCurveToOperation, /* C|c (x1 y1 x2 y2 x y)+ */
73 PathCurveToQuadraticBezierOperation, /* Q|q (x1 y1 x y)+ */
74 PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */
75 PathCurveToSmoothOperation, /* S|s (x2 y2 x y)+ */
76 PathEllipticArcOperation, /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */
77 PathLineToHorizontalOperation, /* H|h x+ */
78 PathLineToOperation, /* L|l (x y)+ */
79 PathLineToVerticalOperation, /* V|v y+ */
80 PathMoveToOperation /* M|m (x y)+ */
98 /* Support structures */
105 /* MVG output string and housekeeping */
110 mvg_alloc, /* total allocated memory */
111 mvg_length; /* total MVG length */
114 mvg_width; /* current line width */
116 /* Pattern support */
128 index; /* array index */
134 filter_off; /* true if not filtering attributes */
136 /* Pretty-printing depth */
138 indent_depth; /* number of left-hand pad characters */
140 /* Path operation support */
155 /* Vector table for invoking subordinate renderers */
158 DrawingWand *(*DestroyDrawingWand) (DrawingWand *);
159 void (*DrawAnnotation)(DrawingWand *,const double,const double,
160 const unsigned char *);
161 void (*DrawArc)(DrawingWand *,const double,const double,const double,
162 const double,const double,const double);
163 void (*DrawBezier)(DrawingWand *,const unsigned long,const PointInfo *);
164 void (*DrawCircle)(DrawingWand *,const double,const double,const double,
166 void (*DrawColor)(DrawingWand *,const double,const double,const PaintMethod);
167 void (*DrawComment)(DrawingWand *,const char *);
168 void (*DrawEllipse)(DrawingWand *,const double,const double,const double,
169 const double,const double,const double);
170 MagickBooleanType (*DrawComposite)(DrawingWand *,const CompositeOperator,
171 const double,const double,const double,const double,const Image *);
172 void (*DrawLine)(DrawingWand *,const double,const double,const double,
174 void (*DrawMatte)(DrawingWand *,const double,const double,const PaintMethod);
175 void (*DrawPathClose)(DrawingWand *);
176 void (*DrawPathCurveToAbsolute)(DrawingWand *,const double,const double,
177 const double,const double,const double,const double);
178 void (*DrawPathCurveToRelative)(DrawingWand *,const double,const double,
179 const double,const double,const double,const double);
180 void (*DrawPathCurveToQuadraticBezierAbsolute)(DrawingWand *,const double,
181 const double,const double,const double);
182 void (*DrawPathCurveToQuadraticBezierRelative)(DrawingWand *,const double,
183 const double,const double,const double);
184 void (*DrawPathCurveToQuadraticBezierSmoothAbsolute)(DrawingWand *,
185 const double,const double);
186 void (*DrawPathCurveToQuadraticBezierSmoothRelative)(DrawingWand *,
187 const double,const double);
188 void (*DrawPathCurveToSmoothAbsolute)(DrawingWand *,const double,
189 const double,const double,const double);
190 void (*DrawPathCurveToSmoothRelative)(DrawingWand *,const double,
191 const double,const double,const double);
192 void (*DrawPathEllipticArcAbsolute)(DrawingWand *,const double,const double,
193 const double,const MagickBooleanType,const MagickBooleanType,const double,
195 void (*DrawPathEllipticArcRelative)(DrawingWand *,const double,const double,
196 const double,const MagickBooleanType,const MagickBooleanType,const double,
198 void (*DrawPathFinish)(DrawingWand *);
199 void (*DrawPathLineToAbsolute)(DrawingWand *,const double,const double);
200 void (*DrawPathLineToRelative)(DrawingWand *,const double,const double);
201 void (*DrawPathLineToHorizontalAbsolute)(DrawingWand *,const double);
202 void (*DrawPathLineToHorizontalRelative)(DrawingWand *,const double);
203 void (*DrawPathLineToVerticalAbsolute)(DrawingWand *,const double);
204 void (*DrawPathLineToVerticalRelative)(DrawingWand *,const double);
205 void (*DrawPathMoveToAbsolute)(DrawingWand *,const double,const double);
206 void (*DrawPathMoveToRelative)(DrawingWand *,const double,const double);
207 void (*DrawPathStart)(DrawingWand *);
208 void (*DrawPoint)(DrawingWand *,const double,const double);
209 void (*DrawPolygon)(DrawingWand *,const unsigned long,const PointInfo *);
210 void (*DrawPolyline)(DrawingWand *,const unsigned long,const PointInfo *);
211 void (*DrawPopClipPath)(DrawingWand *);
212 void (*DrawPopDefs)(DrawingWand *);
213 MagickBooleanType (*DrawPopPattern)(DrawingWand *);
214 void (*DrawPushClipPath)(DrawingWand *,const char *);
215 void (*DrawPushDefs)(DrawingWand *);
216 MagickBooleanType (*DrawPushPattern)(DrawingWand *,const char *,const double,
217 const double,const double,const double);
218 void (*DrawRectangle)(DrawingWand *,const double,const double,const double,
220 void (*DrawRoundRectangle)(DrawingWand *,double,double,double,double,
222 void (*DrawAffine)(DrawingWand *,const AffineMatrix *);
223 MagickBooleanType (*DrawSetClipPath)(DrawingWand *,const char *);
224 void (*DrawSetBorderColor)(DrawingWand *,const PixelWand *);
225 void (*DrawSetClipRule)(DrawingWand *,const FillRule);
226 void (*DrawSetClipUnits)(DrawingWand *,const ClipPathUnits);
227 void (*DrawSetFillColor)(DrawingWand *,const PixelWand *);
228 void (*DrawSetFillRule)(DrawingWand *,const FillRule);
229 MagickBooleanType (*DrawSetFillPatternURL)(DrawingWand *,const char *);
230 MagickBooleanType (*DrawSetFont)(DrawingWand *,const char *);
231 MagickBooleanType (*DrawSetFontFamily)(DrawingWand *,const char *);
232 void (*DrawSetTextKerning)(DrawingWand *,const double);
233 void (*DrawSetTextInterwordSpacing)(DrawingWand *,const double);
234 double (*DrawGetTextKerning)(DrawingWand *);
235 double (*DrawGetTextInterwordSpacing)(DrawingWand *);
236 void (*DrawSetFontSize)(DrawingWand *,const double);
237 void (*DrawSetFontStretch)(DrawingWand *,const StretchType);
238 void (*DrawSetFontStyle)(DrawingWand *,const StyleType);
239 void (*DrawSetFontWeight)(DrawingWand *,const unsigned long);
240 void (*DrawSetGravity)(DrawingWand *,const GravityType);
241 void (*DrawRotate)(DrawingWand *,const double);
242 void (*DrawScale)(DrawingWand *,const double,const double);
243 void (*DrawSkewX)(DrawingWand *,const double);
244 void (*DrawSkewY)(DrawingWand *,const double);
245 void (*DrawSetStrokeAntialias)(DrawingWand *,const MagickBooleanType);
246 void (*DrawSetStrokeColor)(DrawingWand *,const PixelWand *);
247 MagickBooleanType (*DrawSetStrokeDashArray)(DrawingWand *,const double *);
248 void (*DrawSetStrokeDashOffset)(DrawingWand *,const double);
249 void (*DrawSetStrokeLineCap)(DrawingWand *,const LineCap);
250 void (*DrawSetStrokeLineJoin)(DrawingWand *,const LineJoin);
251 void (*DrawSetStrokeMiterLimit)(DrawingWand *,const unsigned long);
252 MagickBooleanType (*DrawSetStrokePatternURL)(DrawingWand *,const char *);
253 void (*DrawSetStrokeWidth)(DrawingWand *,const double);
254 void (*DrawSetTextAntialias)(DrawingWand *,const MagickBooleanType);
255 void (*DrawSetTextDecoration)(DrawingWand *,const DecorationType);
256 void (*DrawSetTextUnderColor)(DrawingWand *,const PixelWand *);
257 void (*DrawTranslate)(DrawingWand *,const double,const double);
258 void (*DrawSetViewbox)(DrawingWand *,unsigned long,unsigned long,
259 unsigned long,unsigned long);
260 void (*PeekDrawingWand)(DrawingWand *);
261 MagickBooleanType (*PopDrawingWand)(DrawingWand *);
262 MagickBooleanType (*PushDrawingWand)(DrawingWand *);
266 Forward declarations.
269 MvgPrintf(DrawingWand *,const char *,...) wand_attribute((format
271 MvgAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format
275 MvgAppendColor(DrawingWand *,const PixelPacket *);
278 "Printf" for MVG commands
280 static int MvgPrintf(DrawingWand *wand,const char *format,...)
285 if (wand->debug != MagickFalse)
286 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format);
287 assert(wand != (DrawingWand *) NULL);
288 assert(wand->signature == WandSignature);
289 alloc_size=20UL*MaxTextExtent;
290 if (wand->mvg == (char *) NULL)
292 wand->mvg=(char *) AcquireQuantumMemory(alloc_size,sizeof(*wand->mvg));
293 if (wand->mvg == (char *) NULL)
295 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
299 wand->mvg_alloc=alloc_size;
302 if (wand->mvg_alloc < (wand->mvg_length+10*MaxTextExtent))
307 realloc_size=wand->mvg_alloc+alloc_size;
308 wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,realloc_size,
310 if (wand->mvg == (char *) NULL)
312 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
316 wand->mvg_alloc=realloc_size;
325 while (wand->mvg_width < wand->indent_depth)
327 wand->mvg[wand->mvg_length]=' ';
331 wand->mvg[wand->mvg_length]='\0';
332 va_start(argp, format);
333 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
334 formatted_length=vsnprintf(wand->mvg+wand->mvg_length,
335 wand->mvg_alloc-wand->mvg_length-1,format,argp);
337 formatted_length=vsprintf(wand->mvg+wand->mvg_length,
341 if (formatted_length < 0)
342 ThrowDrawException(DrawError,"UnableToPrint",format)
345 wand->mvg_length+=formatted_length;
346 wand->mvg_width+=formatted_length;
348 wand->mvg[wand->mvg_length]='\0';
349 if ((wand->mvg_length > 1) &&
350 (wand->mvg[wand->mvg_length-1] == '\n'))
352 assert((wand->mvg_length+1) < wand->mvg_alloc);
353 return formatted_length;
357 static int MvgAutoWrapPrintf(DrawingWand *wand,const char *format,...)
360 buffer[MaxTextExtent];
368 va_start(argp,format);
369 #if defined(MAGICKCORE_HAVE_VSNPRINTF)
370 formatted_length=vsnprintf(buffer,sizeof(buffer)-1,format,argp);
372 formatted_length=vsprintf(buffer,format,argp);
375 *(buffer+sizeof(buffer)-1)='\0';
376 if (formatted_length < 0)
377 ThrowDrawException(DrawError,"UnableToPrint",format)
380 if (((wand->mvg_width + formatted_length) > 78) &&
381 (buffer[formatted_length-1] != '\n'))
382 (void) MvgPrintf(wand, "\n");
383 (void) MvgPrintf(wand,"%s",buffer);
385 return(formatted_length);
388 static void MvgAppendColor(DrawingWand *wand,const PixelPacket *color)
390 if ((color->red == 0) && (color->green == 0) && (color->blue == 0) &&
391 (color->opacity == (Quantum) TransparentOpacity))
392 (void) MvgPrintf(wand,"none");
396 tuple[MaxTextExtent];
401 GetMagickPixelPacket(wand->image,&pixel);
402 pixel.colorspace=RGBColorspace;
403 pixel.matte=color->opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
404 pixel.red=(MagickRealType) color->red;
405 pixel.green=(MagickRealType) color->green;
406 pixel.blue=(MagickRealType) color->blue;
407 pixel.opacity=(MagickRealType) color->opacity;
408 GetColorTuple(&pixel,MagickTrue,tuple);
409 (void) MvgPrintf(wand,"%s",tuple);
413 static void MvgAppendPointsCommand(DrawingWand *wand,const char *command,
414 const unsigned long number_coordinates,const PointInfo *coordinates)
422 (void) MvgPrintf(wand,"%s",command);
423 for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
425 (void) MvgAutoWrapPrintf(wand," %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=current.sx*affine->sx+current.ry*affine->rx;
445 CurrentContext->affine.rx=current.rx*affine->sx+current.sy*affine->rx;
446 CurrentContext->affine.ry=current.sx*affine->ry+current.ry*affine->sy;
447 CurrentContext->affine.sy=current.rx*affine->ry+current.sy*affine->sy;
448 CurrentContext->affine.tx=current.sx*affine->tx+current.ry*affine->ty+
450 CurrentContext->affine.ty=current.rx*affine->tx+current.sy*affine->ty+
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
460 % C l e a r D r a w i n g W a n d %
464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
466 % ClearDrawingWand() clear resources associated with the drawing wand.
468 % The format of the ClearDrawingWand method is:
470 % DrawingWand *ClearDrawingWand(DrawingWand *wand)
472 % A description of each parameter follows:
474 % o wand: the drawing wand. to destroy
477 WandExport void ClearDrawingWand(DrawingWand *wand)
479 assert(wand != (DrawingWand *) NULL);
480 assert(wand->signature == WandSignature);
481 if (wand->debug != MagickFalse)
482 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
483 for ( ; wand->index > 0; wand->index--)
484 CurrentContext=DestroyDrawInfo(CurrentContext);
485 CurrentContext=DestroyDrawInfo(CurrentContext);
486 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
487 wand->graphic_context);
488 if (wand->pattern_id != (char *) NULL)
489 wand->pattern_id=DestroyString(wand->pattern_id);
490 wand->mvg=DestroyString(wand->mvg);
491 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
492 wand->image=DestroyImage(wand->image);
494 wand->image=(Image *) NULL;
495 wand->mvg=(char *) NULL;
499 wand->pattern_id=(char *) NULL;
500 wand->pattern_offset=0;
501 wand->pattern_bounds.x=0;
502 wand->pattern_bounds.y=0;
503 wand->pattern_bounds.width=0;
504 wand->pattern_bounds.height=0;
506 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
507 sizeof(*wand->graphic_context));
508 if (wand->graphic_context == (DrawInfo **) NULL)
510 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
514 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
515 wand->filter_off=MagickTrue;
516 wand->indent_depth=0;
517 wand->path_operation=PathDefaultOperation;
518 wand->path_mode=DefaultPathMode;
519 wand->image=AcquireImage((const ImageInfo *) NULL);
520 ClearMagickException(wand->exception);
521 wand->destroy=MagickTrue;
522 wand->debug=IsEventLogging();
526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530 % C l o n e D r a w i n g W a n d %
534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536 % CloneDrawingWand() makes an exact copy of the specified wand.
538 % The format of the CloneDrawingWand method is:
540 % DrawingWand *CloneDrawingWand(const DrawingWand *wand)
542 % A description of each parameter follows:
544 % o wand: the magick wand.
547 WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand)
555 assert(wand != (DrawingWand *) NULL);
556 assert(wand->signature == WandSignature);
557 if (wand->debug != MagickFalse)
558 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
559 clone_wand=(DrawingWand *) AcquireAlignedMemory(1,sizeof(*clone_wand));
560 if (clone_wand == (DrawingWand *) NULL)
561 ThrowWandFatalException(ResourceLimitFatalError,
562 "MemoryAllocationFailed",GetExceptionMessage(errno));
563 (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
564 clone_wand->id=AcquireWandId();
565 (void) FormatMagickString(clone_wand->name,MaxTextExtent,"DrawingWand-%lu",
567 clone_wand->exception=AcquireExceptionInfo();
568 InheritException(clone_wand->exception,wand->exception);
569 clone_wand->mvg=AcquireString(wand->mvg);
570 clone_wand->mvg_length=strlen(clone_wand->mvg);
571 clone_wand->mvg_alloc=wand->mvg_length+1;
572 clone_wand->mvg_width=wand->mvg_width;
573 clone_wand->pattern_id=AcquireString(wand->pattern_id);
574 clone_wand->pattern_offset=wand->pattern_offset;
575 clone_wand->pattern_bounds=wand->pattern_bounds;
576 clone_wand->index=wand->index;
577 clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((size_t)
578 wand->index+1UL,sizeof(*wand->graphic_context));
579 if (clone_wand->graphic_context == (DrawInfo **) NULL)
580 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
581 GetExceptionMessage(errno));
582 for (i=0; i <= (long) wand->index; i++)
583 clone_wand->graphic_context[i]=
584 CloneDrawInfo((ImageInfo *) NULL,wand->graphic_context[i]);
585 clone_wand->filter_off=wand->filter_off;
586 clone_wand->indent_depth=wand->indent_depth;
587 clone_wand->path_operation=wand->path_operation;
588 clone_wand->path_mode=wand->path_mode;
589 clone_wand->image=wand->image;
590 if (wand->image != (Image *) NULL)
591 clone_wand->image=CloneImage(wand->image,0,0,MagickTrue,
592 clone_wand->exception);
593 clone_wand->destroy=MagickTrue;
594 clone_wand->debug=IsEventLogging();
595 if (clone_wand->debug != MagickFalse)
596 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
597 clone_wand->signature=WandSignature;
602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606 % D e s t r o y D r a w i n g W a n d %
610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
612 % DestroyDrawingWand() frees all resources associated with the drawing wand.
613 % Once the drawing wand has been freed, it should not be used and further
614 % unless it re-allocated.
616 % The format of the DestroyDrawingWand method is:
618 % DrawingWand *DestroyDrawingWand(DrawingWand *wand)
620 % A description of each parameter follows:
622 % o wand: the drawing wand. to destroy
625 WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand)
627 assert(wand != (DrawingWand *) NULL);
628 assert(wand->signature == WandSignature);
629 if (wand->debug != MagickFalse)
630 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
631 for ( ; wand->index > 0; wand->index--)
632 CurrentContext=DestroyDrawInfo(CurrentContext);
633 CurrentContext=DestroyDrawInfo(CurrentContext);
634 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
635 wand->graphic_context);
636 if (wand->pattern_id != (char *) NULL)
637 wand->pattern_id=DestroyString(wand->pattern_id);
638 wand->mvg=DestroyString(wand->mvg);
639 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
640 wand->image=DestroyImage(wand->image);
641 wand->image=(Image *) NULL;
642 wand->exception=DestroyExceptionInfo(wand->exception);
643 wand->signature=(~WandSignature);
644 RelinquishWandId(wand->id);
645 wand=(DrawingWand *) RelinquishMagickMemory(wand);
650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654 % D r a w A f f i n e %
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660 % DrawAffine() adjusts the current affine transformation matrix with
661 % the specified affine transformation matrix. Note that the current affine
662 % transform is adjusted rather than replaced.
664 % The format of the DrawAffine method is:
666 % void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
668 % A description of each parameter follows:
670 % o wand: Drawing wand
672 % o affine: Affine matrix parameters
675 WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine)
677 assert(wand != (DrawingWand *) NULL);
678 assert(wand->signature == WandSignature);
679 if (wand->debug != MagickFalse)
680 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
681 assert(affine != (const AffineMatrix *) NULL);
682 AdjustAffine(wand,affine);
683 (void) MvgPrintf(wand,"affine %g,%g,%g,%g,%g,%g\n",affine->sx,affine->rx,
684 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,ey,sd,ed);
824 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 % D r a w B e z i e r %
832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834 % DrawBezier() draws a bezier curve through a set of points on the image.
836 % The format of the DrawBezier method is:
838 % void DrawBezier(DrawingWand *wand,
839 % const unsigned long number_coordinates,const PointInfo *coordinates)
841 % A description of each parameter follows:
843 % o wand: the drawing wand.
845 % o number_coordinates: number of coordinates
847 % o coordinates: coordinates
850 WandExport void DrawBezier(DrawingWand *wand,
851 const unsigned long number_coordinates,const PointInfo *coordinates)
853 assert(wand != (DrawingWand *) NULL);
854 assert(wand->signature == WandSignature);
855 if (wand->debug != MagickFalse)
856 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
857 assert(coordinates != (const PointInfo *) NULL);
858 MvgAppendPointsCommand(wand,"bezier",number_coordinates,coordinates);
862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866 % D r a w C i r c l e %
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872 % DrawCircle() draws a circle on the image.
874 % The format of the DrawCircle method is:
876 % void DrawCircle(DrawingWand *wand,const double ox,
877 % const double oy,const double px, const double py)
879 % A description of each parameter follows:
881 % o wand: the drawing wand.
883 % o ox: origin x ordinate
885 % o oy: origin y ordinate
887 % o px: perimeter x ordinate
889 % o py: perimeter y ordinate
892 WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy,
893 const double px,const double py)
895 assert(wand != (DrawingWand *) NULL);
896 assert(wand->signature == WandSignature);
897 if (wand->debug != MagickFalse)
898 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
899 (void) MvgPrintf(wand,"circle %g,%g %g,%g\n",ox,oy,px,py);
903 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
907 % D r a w C l e a r E x c e p t i o n %
911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913 % DrawClearException() clear any exceptions associated with the wand.
915 % The format of the DrawClearException method is:
917 % MagickBooleanType DrawClearException(DrawWand *wand)
919 % A description of each parameter follows:
921 % o wand: the drawing wand.
924 WandExport MagickBooleanType DrawClearException(DrawingWand *wand)
926 assert(wand != (DrawingWand *) NULL);
927 assert(wand->signature == WandSignature);
928 if (wand->debug != MagickFalse)
929 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
930 ClearMagickException(wand->exception);
935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939 % D r a w C o m p o s i t e %
943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 % DrawComposite() composites an image onto the current image, using the
946 % specified composition operator, specified position, and at the specified
949 % The format of the DrawComposite method is:
951 % MagickBooleanType DrawComposite(DrawingWand *wand,
952 % const CompositeOperator compose,const double x,
953 % const double y,const double width,const double height,
954 % MagickWand *magick_wand)
956 % A description of each parameter follows:
958 % o wand: the drawing wand.
960 % o compose: composition operator
962 % o x: x ordinate of top left corner
964 % o y: y ordinate of top left corner
966 % o width: Width to resize image to prior to compositing. Specify zero to
967 % use existing width.
969 % o height: Height to resize image to prior to compositing. Specify zero
970 % to use existing height.
972 % o magick_wand: Image to composite is obtained from this wand.
975 WandExport MagickBooleanType DrawComposite(DrawingWand *wand,
976 const CompositeOperator compose,const double x,const double y,
977 const double width,const double height,MagickWand *magick_wand)
1007 assert(wand != (DrawingWand *) NULL);
1008 assert(wand->signature == WandSignature);
1009 if (wand->debug != MagickFalse)
1010 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1011 assert(magick_wand != (MagickWand *) NULL);
1012 image=GetImageFromMagickWand(magick_wand);
1013 if (image == (Image *) NULL)
1014 return(MagickFalse);
1015 clone_image=CloneImage(image,0,0,MagickTrue,wand->exception);
1016 if (clone_image == (Image *) NULL)
1017 return(MagickFalse);
1018 image_info=AcquireImageInfo();
1019 (void) CopyMagickString(image_info->magick,"MIFF",MaxTextExtent);
1021 blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
1023 image_info=DestroyImageInfo(image_info);
1024 clone_image=DestroyImageList(clone_image);
1025 if (blob == (void *) NULL)
1026 return(MagickFalse);
1028 base64=Base64Encode(blob,blob_length,&encoded_length);
1029 blob=(unsigned char *) RelinquishMagickMemory(blob);
1030 if (base64 == (char *) NULL)
1033 buffer[MaxTextExtent];
1035 (void) FormatMagickString(buffer,MaxTextExtent,"%ld bytes",
1036 (4L*blob_length/3L+4L));
1037 ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed",
1039 return(MagickFalse);
1041 mode=MagickOptionToMnemonic(MagickComposeOptions,(long) compose);
1042 media_type=MagickToMime(image->magick);
1043 (void) MvgPrintf(wand,"image %s %g,%g %g,%g 'data:%s;base64,\n",mode,x,y,
1044 width,height,media_type);
1046 for (i=(long) encoded_length; i > 0; i-=76)
1048 (void) MvgPrintf(wand,"%.76s",p);
1051 (void) MvgPrintf(wand,"\n");
1053 (void) MvgPrintf(wand,"'\n");
1054 media_type=DestroyString(media_type);
1055 base64=DestroyString(base64);
1060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1064 % D r a w C o l o r %
1068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070 % DrawColor() draws color on image using the current fill color, starting at
1071 % specified position, and using specified paint method. The available paint
1074 % PointMethod: Recolors the target pixel
1075 % ReplaceMethod: Recolor any pixel that matches the target pixel.
1076 % FloodfillMethod: Recolors target pixels and matching neighbors.
1077 % ResetMethod: Recolor all pixels.
1079 % The format of the DrawColor method is:
1081 % void DrawColor(DrawingWand *wand,const double x,const double y,
1082 % const PaintMethod paint_method)
1084 % A description of each parameter follows:
1086 % o wand: the drawing wand.
1092 % o paint_method: paint method.
1095 WandExport void DrawColor(DrawingWand *wand,const double x,const double y,
1096 const PaintMethod paint_method)
1098 assert(wand != (DrawingWand *) NULL);
1099 assert(wand->signature == WandSignature);
1100 if (wand->debug != MagickFalse)
1101 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1102 (void) MvgPrintf(wand,"color %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
1103 MagickMethodOptions,(long) paint_method));
1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1111 % D r a w C o m m e n t %
1115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1117 % DrawComment() adds a comment to a vector output stream.
1119 % The format of the DrawComment method is:
1121 % void DrawComment(DrawingWand *wand,const char *comment)
1123 % A description of each parameter follows:
1125 % o wand: the drawing wand.
1127 % o comment: comment text
1130 WandExport void DrawComment(DrawingWand *wand,const char *comment)
1132 (void) MvgPrintf(wand,"#%s\n",comment);
1136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1140 % D r a w E l l i p s e %
1144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1146 % DrawEllipse() draws an ellipse on the image.
1148 % The format of the DrawEllipse method is:
1150 % void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1151 % const double rx,const double ry,const double start,const double end)
1153 % A description of each parameter follows:
1155 % o wand: the drawing wand.
1157 % o ox: origin x ordinate
1159 % o oy: origin y ordinate
1165 % o start: starting rotation in degrees
1167 % o end: ending rotation in degrees
1170 WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy,
1171 const double rx,const double ry,const double start,const double end)
1173 assert(wand != (DrawingWand *) NULL);
1174 assert(wand->signature == WandSignature);
1175 if (wand->debug != MagickFalse)
1176 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1177 (void) MvgPrintf(wand,"ellipse %g,%g %g,%g %g,%g\n",ox,oy,rx,ry,start,end);
1181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185 % D r a w G e t B o r d e r C o l o r %
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191 % DrawGetBorderColor() returns the border color used for drawing bordered
1194 % The format of the DrawGetBorderColor method is:
1196 % void DrawGetBorderColor(const DrawingWand *wand,
1197 % PixelWand *border_color)
1199 % A description of each parameter follows:
1201 % o wand: the drawing wand.
1203 % o border_color: Return the border color.
1206 WandExport void DrawGetBorderColor(const DrawingWand *wand,
1207 PixelWand *border_color)
1209 assert(wand != (const DrawingWand *) NULL);
1210 assert(wand->signature == WandSignature);
1211 assert(border_color != (PixelWand *) NULL);
1212 if (wand->debug != MagickFalse)
1213 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1214 PixelSetQuantumColor(border_color,&CurrentContext->border_color);
1218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222 % D r a w G e t C l i p P a t h %
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 % DrawGetClipPath() obtains the current clipping path ID. The value returned
1229 % must be deallocated by the user when it is no longer needed.
1231 % The format of the DrawGetClipPath method is:
1233 % char *DrawGetClipPath(const DrawingWand *wand)
1235 % A description of each parameter follows:
1237 % o wand: the drawing wand.
1240 WandExport char *DrawGetClipPath(const DrawingWand *wand)
1242 assert(wand != (const DrawingWand *) NULL);
1243 assert(wand->signature == WandSignature);
1244 if (wand->debug != MagickFalse)
1245 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1246 if (CurrentContext->clip_mask != (char *) NULL)
1247 return((char *) AcquireString(CurrentContext->clip_mask));
1248 return((char *) NULL);
1252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1256 % D r a w G e t C l i p R u l e %
1260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262 % DrawGetClipRule() returns the current polygon fill rule to be used by the
1265 % The format of the DrawGetClipRule method is:
1267 % FillRule DrawGetClipRule(const DrawingWand *wand)
1269 % A description of each parameter follows:
1271 % o wand: the drawing wand.
1274 WandExport FillRule DrawGetClipRule(const DrawingWand *wand)
1276 assert(wand != (const DrawingWand *) NULL);
1277 assert(wand->signature == WandSignature);
1278 if (wand->debug != MagickFalse)
1279 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1280 return(CurrentContext->fill_rule);
1284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288 % D r a w G e t C l i p U n i t s %
1292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1294 % DrawGetClipUnits() returns the interpretation of clip path units.
1296 % The format of the DrawGetClipUnits method is:
1298 % ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1300 % A description of each parameter follows:
1302 % o wand: the drawing wand.
1305 WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand)
1307 assert(wand != (const DrawingWand *) NULL);
1308 assert(wand->signature == WandSignature);
1309 if (wand->debug != MagickFalse)
1310 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1311 return(CurrentContext->clip_units);
1315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319 % D r a w G e t E x c e p t i o n %
1323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1325 % DrawGetException() returns the severity, reason, and description of any
1326 % error that occurs when using other methods in this API.
1328 % The format of the DrawGetException method is:
1330 % char *DrawGetException(const DrawWand *wand,
1331 % ExceptionType *severity)
1333 % A description of each parameter follows:
1335 % o wand: the drawing wand.
1337 % o severity: the severity of the error is returned here.
1340 WandExport char *DrawGetException(const DrawingWand *wand,
1341 ExceptionType *severity)
1346 assert(wand != (const DrawingWand *) NULL);
1347 assert(wand->signature == WandSignature);
1348 if (wand->debug != MagickFalse)
1349 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1350 assert(severity != (ExceptionType *) NULL);
1351 *severity=wand->exception->severity;
1352 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
1353 sizeof(*description));
1354 if (description == (char *) NULL)
1355 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1358 if (wand->exception->reason != (char *) NULL)
1359 (void) CopyMagickString(description,GetLocaleExceptionMessage(
1360 wand->exception->severity,wand->exception->reason),
1362 if (wand->exception->description != (char *) NULL)
1364 (void) ConcatenateMagickString(description," (",MaxTextExtent);
1365 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
1366 wand->exception->severity,wand->exception->description),
1368 (void) ConcatenateMagickString(description,")",MaxTextExtent);
1370 return(description);
1374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1378 % P i x e l G e t E x c e p t i o n T y p e %
1382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1384 % DrawGetExceptionType() the exception type associated with the wand. If
1385 % no exception has occurred, UndefinedExceptionType is returned.
1387 % The format of the DrawGetExceptionType method is:
1389 % ExceptionType DrawGetExceptionType(const DrawWand *wand)
1391 % A description of each parameter follows:
1393 % o wand: the magick wand.
1396 WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand)
1398 assert(wand != (const DrawingWand *) NULL);
1399 assert(wand->signature == WandSignature);
1400 if (wand->debug != MagickFalse)
1401 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1402 return(wand->exception->severity);
1406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410 % D r a w G e t F i l l C o l o r %
1414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1416 % DrawGetFillColor() returns the fill color used for drawing filled objects.
1418 % The format of the DrawGetFillColor method is:
1420 % void DrawGetFillColor(const DrawingWand *wand,
1421 % PixelWand *fill_color)
1423 % A description of each parameter follows:
1425 % o wand: the drawing wand.
1427 % o fill_color: Return the fill color.
1430 WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color)
1432 assert(wand != (const DrawingWand *) NULL);
1433 assert(wand->signature == WandSignature);
1434 assert(fill_color != (PixelWand *) NULL);
1435 if (wand->debug != MagickFalse)
1436 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1437 PixelSetQuantumColor(fill_color,&CurrentContext->fill);
1441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1445 % D r a w G e t F i l l O p a c i t y %
1449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1451 % DrawGetFillOpacity() returns the opacity used when drawing using the fill
1452 % color or fill texture. Fully opaque is 1.0.
1454 % The format of the DrawGetFillOpacity method is:
1456 % double DrawGetFillOpacity(const DrawingWand *wand)
1458 % A description of each parameter follows:
1460 % o wand: the drawing wand.
1463 WandExport double DrawGetFillOpacity(const DrawingWand *wand)
1468 assert(wand != (const DrawingWand *) NULL);
1469 assert(wand->signature == WandSignature);
1470 if (wand->debug != MagickFalse)
1471 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1472 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity);
1477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1481 % D r a w G e t F i l l R u l e %
1485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1487 % DrawGetFillRule() returns the fill rule used while drawing polygons.
1489 % The format of the DrawGetFillRule method is:
1491 % FillRule DrawGetFillRule(const DrawingWand *wand)
1493 % A description of each parameter follows:
1495 % o wand: the drawing wand.
1498 WandExport FillRule DrawGetFillRule(const DrawingWand *wand)
1500 assert(wand != (const DrawingWand *) NULL);
1501 assert(wand->signature == WandSignature);
1502 if (wand->debug != MagickFalse)
1503 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1504 return(CurrentContext->fill_rule);
1508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1512 % D r a w G e t F o n t %
1516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1518 % DrawGetFont() returns a null-terminaged string specifying the font used
1519 % when annotating with text. The value returned must be freed by the user
1520 % when no longer needed.
1522 % The format of the DrawGetFont method is:
1524 % char *DrawGetFont(const DrawingWand *wand)
1526 % A description of each parameter follows:
1528 % o wand: the drawing wand.
1531 WandExport char *DrawGetFont(const DrawingWand *wand)
1533 assert(wand != (const DrawingWand *) NULL);
1534 assert(wand->signature == WandSignature);
1535 if (wand->debug != MagickFalse)
1536 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1537 if (CurrentContext->font != (char *) NULL)
1538 return(AcquireString(CurrentContext->font));
1539 return((char *) NULL);
1543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1547 % D r a w G e t F o n t F a m i l y %
1551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1553 % DrawGetFontFamily() returns the font family to use when annotating with text.
1554 % The value returned must be freed by the user when it is no longer needed.
1556 % The format of the DrawGetFontFamily method is:
1558 % char *DrawGetFontFamily(const DrawingWand *wand)
1560 % A description of each parameter follows:
1562 % o wand: the drawing wand.
1565 WandExport char *DrawGetFontFamily(const DrawingWand *wand)
1567 assert(wand != (const DrawingWand *) NULL);
1568 assert(wand->signature == WandSignature);
1569 if (wand->debug != MagickFalse)
1570 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1571 if (CurrentContext->family != NULL)
1572 return(AcquireString(CurrentContext->family));
1573 return((char *) NULL);
1577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1581 % D r a w G e t F o n t S i z e %
1585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1587 % DrawGetFontSize() returns the font pointsize used when annotating with text.
1589 % The format of the DrawGetFontSize method is:
1591 % double DrawGetFontSize(const DrawingWand *wand)
1593 % A description of each parameter follows:
1595 % o wand: the drawing wand.
1598 WandExport double DrawGetFontSize(const DrawingWand *wand)
1600 assert(wand != (const DrawingWand *) NULL);
1601 assert(wand->signature == WandSignature);
1602 if (wand->debug != MagickFalse)
1603 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1604 return(CurrentContext->pointsize);
1608 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1612 % D r a w G e t F o n t S t r e t c h %
1616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1618 % DrawGetFontStretch() returns the font stretch used when annotating with text.
1620 % The format of the DrawGetFontStretch method is:
1622 % StretchType DrawGetFontStretch(const DrawingWand *wand)
1624 % A description of each parameter follows:
1626 % o wand: the drawing wand.
1629 WandExport StretchType DrawGetFontStretch(const DrawingWand *wand)
1631 assert(wand != (const DrawingWand *) NULL);
1632 assert(wand->signature == WandSignature);
1633 if (wand->debug != MagickFalse)
1634 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1635 return(CurrentContext->stretch);
1639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1643 % D r a w G e t F o n t S t y l e %
1647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1649 % DrawGetFontStyle() returns the font style used when annotating with text.
1651 % The format of the DrawGetFontStyle method is:
1653 % StyleType DrawGetFontStyle(const DrawingWand *wand)
1655 % A description of each parameter follows:
1657 % o wand: the drawing wand.
1660 WandExport StyleType DrawGetFontStyle(const DrawingWand *wand)
1662 assert(wand != (const DrawingWand *) NULL);
1663 assert(wand->signature == WandSignature);
1664 if (wand->debug != MagickFalse)
1665 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1666 return(CurrentContext->style);
1670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1674 % D r a w G e t F o n t W e i g h t %
1678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1680 % DrawGetFontWeight() returns the font weight used when annotating with text.
1682 % The format of the DrawGetFontWeight method is:
1684 % unsigned long DrawGetFontWeight(const DrawingWand *wand)
1686 % A description of each parameter follows:
1688 % o wand: the drawing wand.
1691 WandExport unsigned long DrawGetFontWeight(const DrawingWand *wand)
1693 assert(wand != (const DrawingWand *) NULL);
1694 assert(wand->signature == WandSignature);
1695 if (wand->debug != MagickFalse)
1696 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1697 return(CurrentContext->weight);
1701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1705 % D r a w G e t G r a v i t y %
1709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1711 % DrawGetGravity() returns the text placement gravity used when annotating
1714 % The format of the DrawGetGravity method is:
1716 % GravityType DrawGetGravity(const DrawingWand *wand)
1718 % A description of each parameter follows:
1720 % o wand: the drawing wand.
1723 WandExport GravityType DrawGetGravity(const DrawingWand *wand)
1725 assert(wand != (const DrawingWand *) NULL);
1726 assert(wand->signature == WandSignature);
1727 if (wand->debug != MagickFalse)
1728 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1729 return(CurrentContext->gravity);
1733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1737 % D r a w G e t O p a c i t y %
1741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1743 % DrawGetOpacity() returns the opacity used when drawing with the fill
1744 % or stroke color or texture. Fully opaque is 1.0.
1746 % The format of the DrawGetOpacity method is:
1748 % double DrawGetOpacity(const DrawingWand *wand)
1750 % A description of each parameter follows:
1752 % o wand: the drawing wand.
1755 WandExport double DrawGetOpacity(const DrawingWand *wand)
1760 assert(wand != (const DrawingWand *) NULL);
1761 assert(wand->signature == WandSignature);
1762 if (wand->debug != MagickFalse)
1763 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1764 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->opacity);
1769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1773 % D r a w G e t S t r o k e A n t i a l i a s %
1777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1779 % DrawGetStrokeAntialias() returns the current stroke antialias setting.
1780 % Stroked outlines are antialiased by default. When antialiasing is disabled
1781 % stroked pixels are thresholded to determine if the stroke color or
1782 % underlying canvas color should be used.
1784 % The format of the DrawGetStrokeAntialias method is:
1786 % MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1788 % A description of each parameter follows:
1790 % o wand: the drawing wand.
1793 WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand)
1795 assert(wand != (const DrawingWand *) NULL);
1796 assert(wand->signature == WandSignature);
1797 if (wand->debug != MagickFalse)
1798 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1799 return(CurrentContext->stroke_antialias);
1803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1807 % D r a w G e t S t r o k e C o l o r %
1811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1813 % DrawGetStrokeColor() returns the color used for stroking object outlines.
1815 % The format of the DrawGetStrokeColor method is:
1817 % void DrawGetStrokeColor(const DrawingWand *wand,
1818 $ PixelWand *stroke_color)
1820 % A description of each parameter follows:
1822 % o wand: the drawing wand.
1824 % o stroke_color: Return the stroke color.
1827 WandExport void DrawGetStrokeColor(const DrawingWand *wand,
1828 PixelWand *stroke_color)
1830 assert(wand != (const DrawingWand *) NULL);
1831 assert(wand->signature == WandSignature);
1832 assert(stroke_color != (PixelWand *) NULL);
1833 if (wand->debug != MagickFalse)
1834 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1835 PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
1839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1843 % D r a w G e t S t r o k e D a s h A r r a y %
1847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1849 % DrawGetStrokeDashArray() returns an array representing the pattern of
1850 % dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The
1851 % array must be freed once it is no longer required by the user.
1853 % The format of the DrawGetStrokeDashArray method is:
1855 % double *DrawGetStrokeDashArray(const DrawingWand *wand,
1856 % unsigned long *number_elements)
1858 % A description of each parameter follows:
1860 % o wand: the drawing wand.
1862 % o number_elements: address to place number of elements in dash array
1865 WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand,
1866 unsigned long *number_elements)
1871 register const double
1883 assert(wand != (const DrawingWand *) NULL);
1884 assert(wand->signature == WandSignature);
1885 if (wand->debug != MagickFalse)
1886 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1887 assert(number_elements != (unsigned long *) NULL);
1889 p=CurrentContext->dash_pattern;
1890 if (p != (const double *) NULL)
1894 dash_array=(double *) NULL;
1897 dash_array=(double *) AcquireQuantumMemory((size_t) n,
1898 sizeof(*dash_array));
1899 p=CurrentContext->dash_pattern;
1901 for (i=0; i < (long) n; i++)
1908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1912 % D r a w G e t S t r o k e D a s h O f f s e t %
1916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1918 % DrawGetStrokeDashOffset() returns the offset into the dash pattern to
1921 % The format of the DrawGetStrokeDashOffset method is:
1923 % double DrawGetStrokeDashOffset(const DrawingWand *wand)
1925 % A description of each parameter follows:
1927 % o wand: the drawing wand.
1930 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand)
1932 assert(wand != (const DrawingWand *) NULL);
1933 assert(wand->signature == WandSignature);
1934 if (wand->debug != MagickFalse)
1935 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1936 return(CurrentContext->dash_offset);
1940 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1944 % D r a w G e t S t r o k e L i n e C a p %
1948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1950 % DrawGetStrokeLineCap() returns the shape to be used at the end of
1951 % open subpaths when they are stroked. Values of LineCap are
1952 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
1954 % The format of the DrawGetStrokeLineCap method is:
1956 % LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1958 % A description of each parameter follows:
1960 % o wand: the drawing wand.
1963 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand)
1965 assert(wand != (const DrawingWand *) NULL);
1966 assert(wand->signature == WandSignature);
1967 if (wand->debug != MagickFalse)
1968 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1969 return(CurrentContext->linecap);
1973 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1977 % D r a w G e t S t r o k e L i n e J o i n %
1981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1983 % DrawGetStrokeLineJoin() returns the shape to be used at the
1984 % corners of paths (or other vector shapes) when they are
1985 % stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin,
1988 % The format of the DrawGetStrokeLineJoin method is:
1990 % LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
1992 % A description of each parameter follows:
1994 % o wand: the drawing wand.
1997 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand)
1999 assert(wand != (const DrawingWand *) NULL);
2000 assert(wand->signature == WandSignature);
2001 if (wand->debug != MagickFalse)
2002 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2003 return(CurrentContext->linejoin);
2007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2011 % D r a w G e t S t r o k e M i t e r L i m i t %
2015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2017 % DrawGetStrokeMiterLimit() returns the miter limit. When two line
2018 % segments meet at a sharp angle and miter joins have been specified for
2019 % 'lineJoin', it is possible for the miter to extend far beyond the
2020 % thickness of the line stroking the path. The miterLimit' imposes a
2021 % limit on the ratio of the miter length to the 'lineWidth'.
2023 % The format of the DrawGetStrokeMiterLimit method is:
2025 % unsigned long DrawGetStrokeMiterLimit(const DrawingWand *wand)
2027 % A description of each parameter follows:
2029 % o wand: the drawing wand.
2032 WandExport unsigned long DrawGetStrokeMiterLimit(const DrawingWand *wand)
2034 assert(wand != (const DrawingWand *) NULL);
2035 assert(wand->signature == WandSignature);
2036 if (wand->debug != MagickFalse)
2037 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2038 return CurrentContext->miterlimit;
2042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2046 % D r a w G e t S t r o k e O p a c i t y %
2050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2052 % DrawGetStrokeOpacity() returns the opacity of stroked object outlines.
2054 % The format of the DrawGetStrokeOpacity method is:
2056 % double DrawGetStrokeOpacity(const DrawingWand *wand)
2058 % A description of each parameter follows:
2060 % o wand: the drawing wand.
2063 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand)
2068 assert(wand != (const DrawingWand *) NULL);
2069 assert(wand->signature == WandSignature);
2070 if (wand->debug != MagickFalse)
2071 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2072 alpha=(double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity);
2077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2081 % D r a w G e t S t r o k e W i d t h %
2085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2087 % DrawGetStrokeWidth() returns the width of the stroke used to draw object
2090 % The format of the DrawGetStrokeWidth method is:
2092 % double DrawGetStrokeWidth(const DrawingWand *wand)
2094 % A description of each parameter follows:
2096 % o wand: the drawing wand.
2099 WandExport double DrawGetStrokeWidth(const DrawingWand *wand)
2101 assert(wand != (const DrawingWand *) NULL);
2102 assert(wand->signature == WandSignature);
2103 if (wand->debug != MagickFalse)
2104 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2105 return(CurrentContext->stroke_width);
2109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2113 % D r a w G e t T e x t A l i g n m e n t %
2117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2119 % DrawGetTextAlignment() returns the alignment applied when annotating with
2122 % The format of the DrawGetTextAlignment method is:
2124 % AlignType DrawGetTextAlignment(DrawingWand *wand)
2126 % A description of each parameter follows:
2128 % o wand: the drawing wand.
2131 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand)
2133 assert(wand != (const DrawingWand *) NULL);
2134 assert(wand->signature == WandSignature);
2135 if (wand->debug != MagickFalse)
2136 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2137 return(CurrentContext->align);
2141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2145 % D r a w G e t T e x t A n t i a l i a s %
2149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2151 % DrawGetTextAntialias() returns the current text antialias setting, which
2152 % determines whether text is antialiased. Text is antialiased by default.
2154 % The format of the DrawGetTextAntialias method is:
2156 % MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2158 % A description of each parameter follows:
2160 % o wand: the drawing wand.
2163 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand)
2165 assert(wand != (const DrawingWand *) NULL);
2166 assert(wand->signature == WandSignature);
2167 if (wand->debug != MagickFalse)
2168 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2169 return(CurrentContext->text_antialias);
2173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2177 % D r a w G e t T e x t D e c o r a t i o n %
2181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2183 % DrawGetTextDecoration() returns the decoration applied when annotating with
2186 % The format of the DrawGetTextDecoration method is:
2188 % DecorationType DrawGetTextDecoration(DrawingWand *wand)
2190 % A description of each parameter follows:
2192 % o wand: the drawing wand.
2195 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand)
2197 assert(wand != (const DrawingWand *) NULL);
2198 assert(wand->signature == WandSignature);
2199 if (wand->debug != MagickFalse)
2200 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2201 return(CurrentContext->decorate);
2205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2209 % D r a w G e t T e x t E n c o d i n g %
2213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2215 % DrawGetTextEncoding() returns a null-terminated string which specifies the
2216 % code set used for text annotations. The string must be freed by the user
2217 % once it is no longer required.
2219 % The format of the DrawGetTextEncoding method is:
2221 % char *DrawGetTextEncoding(const DrawingWand *wand)
2223 % A description of each parameter follows:
2225 % o wand: the drawing wand.
2228 WandExport char *DrawGetTextEncoding(const DrawingWand *wand)
2230 assert(wand != (const DrawingWand *) NULL);
2231 assert(wand->signature == WandSignature);
2232 if (wand->debug != MagickFalse)
2233 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2234 if (CurrentContext->encoding != (char *) NULL)
2235 return((char *) AcquireString(CurrentContext->encoding));
2236 return((char *) NULL);
2240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2244 % D r a w G e t T e x t K e r n i n g %
2248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2250 % DrawGetTextKerning() gets the spacing between characters in text.
2252 % The format of the DrawSetFontKerning method is:
2254 % double DrawGetTextKerning(DrawingWand *wand)
2256 % A description of each parameter follows:
2258 % o wand: the drawing wand.
2261 WandExport double DrawGetTextKerning(DrawingWand *wand)
2263 assert(wand != (DrawingWand *) NULL);
2264 assert(wand->signature == WandSignature);
2266 if (wand->debug != MagickFalse)
2267 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2268 return(CurrentContext->kerning);
2272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2276 % 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 %
2280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2282 % DrawGetTextInterwordSpacing() gets the spacing between lines in text.
2284 % The format of the DrawSetFontKerning method is:
2286 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2288 % A description of each parameter follows:
2290 % o wand: the drawing wand.
2293 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand)
2295 assert(wand != (DrawingWand *) NULL);
2296 assert(wand->signature == WandSignature);
2297 if (wand->debug != MagickFalse)
2298 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2299 return(CurrentContext->interline_spacing);
2303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2307 % 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 %
2311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2313 % DrawGetTextInterwordSpacing() gets the spacing between words in text.
2315 % The format of the DrawSetFontKerning method is:
2317 % double DrawGetTextInterwordSpacing(DrawingWand *wand)
2319 % A description of each parameter follows:
2321 % o wand: the drawing wand.
2324 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand)
2326 assert(wand != (DrawingWand *) NULL);
2327 assert(wand->signature == WandSignature);
2328 if (wand->debug != MagickFalse)
2329 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2330 return(CurrentContext->interword_spacing);
2334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2338 % D r a w G e t V e c t o r G r a p h i c s %
2342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2344 % DrawGetVectorGraphics() returns a null-terminated string which specifies the
2345 % vector graphics generated by any graphics calls made since the wand was
2346 % instantiated. The string must be freed by the user once it is no longer
2349 % The format of the DrawGetVectorGraphics method is:
2351 % char *DrawGetVectorGraphics(const DrawingWand *wand)
2353 % A description of each parameter follows:
2355 % o wand: the drawing wand.
2359 static inline void SetMagickPixelPacket(const Image *image,
2360 const PixelPacket *color,const IndexPacket *index,MagickPixelPacket *pixel)
2362 pixel->red=(MagickRealType) color->red;
2363 pixel->green=(MagickRealType) color->green;
2364 pixel->blue=(MagickRealType) color->blue;
2365 if (image->matte != MagickFalse)
2366 pixel->opacity=(MagickRealType) color->opacity;
2367 if (((image->colorspace == CMYKColorspace) ||
2368 (image->storage_class == PseudoClass)) &&
2369 (index != (const IndexPacket *) NULL))
2370 pixel->index=(MagickRealType) *index;
2373 WandExport char *DrawGetVectorGraphics(DrawingWand *wand)
2376 value[MaxTextExtent],
2389 assert(wand != (const DrawingWand *) NULL);
2390 assert(wand->signature == WandSignature);
2391 if (wand->debug != MagickFalse)
2392 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2393 xml_info=NewXMLTreeTag("drawing-wand");
2394 if (xml_info == (XMLTreeInfo *) NULL)
2395 return(char *) NULL;
2396 GetMagickPixelPacket(wand->image,&pixel);
2397 child=AddChildToXMLTree(xml_info,"clip-path",0);
2398 if (child != (XMLTreeInfo *) NULL)
2399 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2400 child=AddChildToXMLTree(xml_info,"clip-units",0);
2401 if (child != (XMLTreeInfo *) NULL)
2403 (void) CopyMagickString(value,MagickOptionToMnemonic(
2404 MagickClipPathOptions,(long) CurrentContext->clip_units),MaxTextExtent);
2405 (void) SetXMLTreeContent(child,value);
2407 child=AddChildToXMLTree(xml_info,"decorate",0);
2408 if (child != (XMLTreeInfo *) NULL)
2410 (void) CopyMagickString(value,MagickOptionToMnemonic(
2411 MagickDecorateOptions,(long) CurrentContext->decorate),MaxTextExtent);
2412 (void) SetXMLTreeContent(child,value);
2414 child=AddChildToXMLTree(xml_info,"encoding",0);
2415 if (child != (XMLTreeInfo *) NULL)
2416 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2417 child=AddChildToXMLTree(xml_info,"fill",0);
2418 if (child != (XMLTreeInfo *) NULL)
2420 if (CurrentContext->fill.opacity != OpaqueOpacity)
2421 pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2422 MagickTrue : MagickFalse;
2423 SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2424 (const IndexPacket *) NULL,&pixel);
2425 GetColorTuple(&pixel,MagickTrue,value);
2426 (void) SetXMLTreeContent(child,value);
2428 child=AddChildToXMLTree(xml_info,"fill-opacity",0);
2429 if (child != (XMLTreeInfo *) NULL)
2431 (void) FormatMagickString(value,MaxTextExtent,"%g",
2432 (double) QuantumScale*(QuantumRange-CurrentContext->fill.opacity));
2433 (void) SetXMLTreeContent(child,value);
2435 child=AddChildToXMLTree(xml_info,"fill-rule",0);
2436 if (child != (XMLTreeInfo *) NULL)
2438 (void) CopyMagickString(value,MagickOptionToMnemonic(
2439 MagickFillRuleOptions,(long) CurrentContext->fill_rule),MaxTextExtent);
2440 (void) SetXMLTreeContent(child,value);
2442 child=AddChildToXMLTree(xml_info,"font",0);
2443 if (child != (XMLTreeInfo *) NULL)
2444 (void) SetXMLTreeContent(child,CurrentContext->font);
2445 child=AddChildToXMLTree(xml_info,"font-family",0);
2446 if (child != (XMLTreeInfo *) NULL)
2447 (void) SetXMLTreeContent(child,CurrentContext->family);
2448 child=AddChildToXMLTree(xml_info,"font-size",0);
2449 if (child != (XMLTreeInfo *) NULL)
2451 (void) FormatMagickString(value,MaxTextExtent,"%g",
2452 CurrentContext->pointsize);
2453 (void) SetXMLTreeContent(child,value);
2455 child=AddChildToXMLTree(xml_info,"font-stretch",0);
2456 if (child != (XMLTreeInfo *) NULL)
2458 (void) CopyMagickString(value,MagickOptionToMnemonic(
2459 MagickStretchOptions,(long) CurrentContext->stretch),MaxTextExtent);
2460 (void) SetXMLTreeContent(child,value);
2462 child=AddChildToXMLTree(xml_info,"font-style",0);
2463 if (child != (XMLTreeInfo *) NULL)
2465 (void) CopyMagickString(value,MagickOptionToMnemonic(
2466 MagickStyleOptions,(long) CurrentContext->style),MaxTextExtent);
2467 (void) SetXMLTreeContent(child,value);
2469 child=AddChildToXMLTree(xml_info,"font-weight",0);
2470 if (child != (XMLTreeInfo *) NULL)
2472 (void) FormatMagickString(value,MaxTextExtent,"%lu",
2473 CurrentContext->weight);
2474 (void) SetXMLTreeContent(child,value);
2476 child=AddChildToXMLTree(xml_info,"gravity",0);
2477 if (child != (XMLTreeInfo *) NULL)
2479 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickGravityOptions,
2480 (long) CurrentContext->gravity),MaxTextExtent);
2481 (void) SetXMLTreeContent(child,value);
2483 child=AddChildToXMLTree(xml_info,"stroke",0);
2484 if (child != (XMLTreeInfo *) NULL)
2486 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2487 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2488 MagickTrue : MagickFalse;
2489 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2490 (const IndexPacket *) NULL,&pixel);
2491 GetColorTuple(&pixel,MagickTrue,value);
2492 (void) SetXMLTreeContent(child,value);
2494 child=AddChildToXMLTree(xml_info,"stroke-antialias",0);
2495 if (child != (XMLTreeInfo *) NULL)
2497 (void) FormatMagickString(value,MaxTextExtent,"%d",
2498 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2499 (void) SetXMLTreeContent(child,value);
2501 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0);
2502 if ((child != (XMLTreeInfo *) NULL) &&
2503 (CurrentContext->dash_pattern != (double *) NULL))
2508 dash_pattern=AcquireString((char *) NULL);
2509 for (i=0; CurrentContext->dash_pattern[i] != 0.0; i++)
2512 (void) ConcatenateString(&dash_pattern,",");
2513 (void) FormatMagickString(value,MaxTextExtent,"%g",
2514 CurrentContext->dash_pattern[i]);
2515 (void) ConcatenateString(&dash_pattern,value);
2517 (void) SetXMLTreeContent(child,dash_pattern);
2518 dash_pattern=DestroyString(dash_pattern);
2520 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0);
2521 if (child != (XMLTreeInfo *) NULL)
2523 (void) FormatMagickString(value,MaxTextExtent,"%g",
2524 CurrentContext->dash_offset);
2525 (void) SetXMLTreeContent(child,value);
2527 child=AddChildToXMLTree(xml_info,"stroke-linecap",0);
2528 if (child != (XMLTreeInfo *) NULL)
2530 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickLineCapOptions,
2531 (long) CurrentContext->linecap),MaxTextExtent);
2532 (void) SetXMLTreeContent(child,value);
2534 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0);
2535 if (child != (XMLTreeInfo *) NULL)
2537 (void) CopyMagickString(value,MagickOptionToMnemonic(
2538 MagickLineJoinOptions,(long) CurrentContext->linejoin),MaxTextExtent);
2539 (void) SetXMLTreeContent(child,value);
2541 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0);
2542 if (child != (XMLTreeInfo *) NULL)
2544 (void) FormatMagickString(value,MaxTextExtent,"%lu",
2545 CurrentContext->miterlimit);
2546 (void) SetXMLTreeContent(child,value);
2548 child=AddChildToXMLTree(xml_info,"stroke-opacity",0);
2549 if (child != (XMLTreeInfo *) NULL)
2551 (void) FormatMagickString(value,MaxTextExtent,"%g",
2552 (double) QuantumScale*(QuantumRange-CurrentContext->stroke.opacity));
2553 (void) SetXMLTreeContent(child,value);
2555 child=AddChildToXMLTree(xml_info,"stroke-width",0);
2556 if (child != (XMLTreeInfo *) NULL)
2558 (void) FormatMagickString(value,MaxTextExtent,"%g",
2559 CurrentContext->stroke_width);
2560 (void) SetXMLTreeContent(child,value);
2562 child=AddChildToXMLTree(xml_info,"text-align",0);
2563 if (child != (XMLTreeInfo *) NULL)
2565 (void) CopyMagickString(value,MagickOptionToMnemonic(MagickAlignOptions,
2566 (long) CurrentContext->align),MaxTextExtent);
2567 (void) SetXMLTreeContent(child,value);
2569 child=AddChildToXMLTree(xml_info,"text-antialias",0);
2570 if (child != (XMLTreeInfo *) NULL)
2572 (void) FormatMagickString(value,MaxTextExtent,"%d",
2573 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2574 (void) SetXMLTreeContent(child,value);
2576 child=AddChildToXMLTree(xml_info,"text-undercolor",0);
2577 if (child != (XMLTreeInfo *) NULL)
2579 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2580 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2581 MagickTrue : MagickFalse;
2582 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2583 (const IndexPacket *) NULL,&pixel);
2584 GetColorTuple(&pixel,MagickTrue,value);
2585 (void) SetXMLTreeContent(child,value);
2587 child=AddChildToXMLTree(xml_info,"vector-graphics",0);
2588 if (child != (XMLTreeInfo *) NULL)
2589 (void) SetXMLTreeContent(child,wand->mvg);
2590 xml=XMLTreeInfoToXML(xml_info);
2591 xml_info=DestroyXMLTree(xml_info);
2596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2600 % D r a w G e t T e x t U n d e r C o l o r %
2604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2606 % DrawGetTextUnderColor() returns the color of a background rectangle
2607 % to place under text annotations.
2609 % The format of the DrawGetTextUnderColor method is:
2611 % void DrawGetTextUnderColor(const DrawingWand *wand,
2612 % PixelWand *under_color)
2614 % A description of each parameter follows:
2616 % o wand: the drawing wand.
2618 % o under_color: Return the under color.
2621 WandExport void DrawGetTextUnderColor(const DrawingWand *wand,
2622 PixelWand *under_color)
2624 assert(wand != (const DrawingWand *) NULL);
2625 assert(wand->signature == WandSignature);
2626 assert(under_color != (PixelWand *) NULL);
2627 if (wand->debug != MagickFalse)
2628 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2629 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2643 % DrawLine() draws a line on the image using the current stroke color,
2644 % stroke opacity, and stroke width.
2646 % The format of the DrawLine method is:
2648 % void DrawLine(DrawingWand *wand,const double sx,const double sy,
2649 % const double ex,const double ey)
2651 % A description of each parameter follows:
2653 % o wand: the drawing wand.
2655 % o sx: starting x ordinate
2657 % o sy: starting y ordinate
2659 % o ex: ending x ordinate
2661 % o ey: ending y ordinate
2664 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy,
2665 const double ex,const double ey)
2667 assert(wand != (DrawingWand *) NULL);
2668 assert(wand->signature == WandSignature);
2669 if (wand->debug != MagickFalse)
2670 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2671 (void) MvgPrintf(wand,"line %g,%g %g,%g\n",sx,sy,ex,ey);
2675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2679 % D r a w M a t t e %
2683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2685 % DrawMatte() paints on the image's opacity channel in order to set effected
2686 % pixels to transparent.
2687 % to influence the opacity of pixels. The available paint
2690 % PointMethod: Select the target pixel
2691 % ReplaceMethod: Select any pixel that matches the target pixel.
2692 % FloodfillMethod: Select the target pixel and matching neighbors.
2693 % FillToBorderMethod: Select the target pixel and neighbors not matching
2695 % ResetMethod: Select all pixels.
2697 % The format of the DrawMatte method is:
2699 % void DrawMatte(DrawingWand *wand,const double x,const double y,
2700 % const PaintMethod paint_method)
2702 % A description of each parameter follows:
2704 % o wand: the drawing wand.
2710 % o paint_method: paint method.
2713 WandExport void DrawMatte(DrawingWand *wand,const double x,const double y,
2714 const PaintMethod paint_method)
2716 assert(wand != (DrawingWand *) NULL);
2717 assert(wand->signature == WandSignature);
2718 if (wand->debug != MagickFalse)
2719 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2720 (void) MvgPrintf(wand,"matte %g,%g '%s'\n",x,y,MagickOptionToMnemonic(
2721 MagickMethodOptions,(long) paint_method));
2725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2729 % D r a w P a t h C l o s e %
2733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2735 % DrawPathClose() adds a path element to the current path which closes the
2736 % current subpath by drawing a straight line from the current point to the
2737 % current subpath's most recent starting point (usually, the most recent
2740 % The format of the DrawPathClose method is:
2742 % void DrawPathClose(DrawingWand *wand)
2744 % A description of each parameter follows:
2746 % o wand: the drawing wand.
2749 WandExport void DrawPathClose(DrawingWand *wand)
2751 assert(wand != (DrawingWand *) NULL);
2752 assert(wand->signature == WandSignature);
2753 if (wand->debug != MagickFalse)
2754 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2755 (void) MvgAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ?
2760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2764 % D r a w P a t h C u r v e T o A b s o l u t e %
2768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2770 % DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current
2771 % point to (x,y) using (x1,y1) as the control point at the beginning of
2772 % the curve and (x2,y2) as the control point at the end of the curve using
2773 % absolute coordinates. At the end of the command, the new current point
2774 % becomes the final (x,y) coordinate pair used in the polybezier.
2776 % The format of the DrawPathCurveToAbsolute method is:
2778 % void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2779 % const double y1,const double x2,const double y2,const double x,
2782 % A description of each parameter follows:
2784 % o wand: the drawing wand.
2786 % o x1: x ordinate of control point for curve beginning
2788 % o y1: y ordinate of control point for curve beginning
2790 % o x2: x ordinate of control point for curve ending
2792 % o y2: y ordinate of control point for curve ending
2794 % o x: x ordinate of the end of the curve
2796 % o y: y ordinate of the end of the curve
2800 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode,
2801 const double x1,const double y1,const double x2,const double y2,
2802 const double x,const double y)
2804 assert(wand != (DrawingWand *) NULL);
2805 assert(wand->signature == WandSignature);
2806 if (wand->debug != MagickFalse)
2807 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2808 if ((wand->path_operation != PathCurveToOperation) ||
2809 (wand->path_mode != mode))
2811 wand->path_operation=PathCurveToOperation;
2812 wand->path_mode=mode;
2813 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g %g,%g",
2814 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y);
2817 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g %g,%g",x1,y1,x2,y2,x,y);
2820 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1,
2821 const double y1,const double x2,const double y2,const double x,const double y)
2823 assert(wand != (DrawingWand *) NULL);
2824 assert(wand->signature == WandSignature);
2825 if (wand->debug != MagickFalse)
2826 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2827 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2835 % D r a w P a t h C u r v e T o R e l a t i v e %
2839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2841 % DrawPathCurveToRelative() draws a cubic Bezier curve from the current
2842 % point to (x,y) using (x1,y1) as the control point at the beginning of
2843 % the curve and (x2,y2) as the control point at the end of the curve using
2844 % relative coordinates. At the end of the command, the new current point
2845 % becomes the final (x,y) coordinate pair used in the polybezier.
2847 % The format of the DrawPathCurveToRelative method is:
2849 % void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2850 % const double y1,const double x2,const double y2,const double x,
2853 % A description of each parameter follows:
2855 % o wand: the drawing wand.
2857 % o x1: x ordinate of control point for curve beginning
2859 % o y1: y ordinate of control point for curve beginning
2861 % o x2: x ordinate of control point for curve ending
2863 % o y2: y ordinate of control point for curve ending
2865 % o x: x ordinate of the end of the curve
2867 % o y: y ordinate of the end of the curve
2870 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1,
2871 const double y1,const double x2,const double y2,const double x,const double y)
2873 assert(wand != (DrawingWand *) NULL);
2874 assert(wand->signature == WandSignature);
2875 if (wand->debug != MagickFalse)
2876 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2877 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2885 % 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 %
2889 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2891 % DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve
2892 % from the current point to (x,y) using (x1,y1) as the control point using
2893 % absolute coordinates. At the end of the command, the new current point
2894 % becomes the final (x,y) coordinate pair used in the polybezier.
2896 % The format of the DrawPathCurveToQuadraticBezierAbsolute method is:
2898 % void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2899 % const double x1,const double y1,onst double x,const double y)
2901 % A description of each parameter follows:
2903 % o wand: the drawing wand.
2905 % o x1: x ordinate of the control point
2907 % o y1: y ordinate of the control point
2909 % o x: x ordinate of final point
2911 % o y: y ordinate of final point
2915 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand,
2916 const PathMode mode,const double x1,double y1,const double x,const double y)
2918 assert(wand != (DrawingWand *) NULL);
2919 assert(wand->signature == WandSignature);
2920 if (wand->debug != MagickFalse)
2921 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2922 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2923 (wand->path_mode != mode))
2925 wand->path_operation=PathCurveToQuadraticBezierOperation;
2926 wand->path_mode=mode;
2927 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g,%g",mode == AbsolutePathMode ?
2928 'Q' : 'q',x1,y1,x,y);
2931 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x1,y1,x,y);
2934 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand,
2935 const double x1,const double y1,const double x,const double y)
2937 assert(wand != (DrawingWand *) NULL);
2938 assert(wand->signature == WandSignature);
2939 if (wand->debug != MagickFalse)
2940 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2941 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
2945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2949 % 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
2953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2955 % DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve
2956 % from the current point to (x,y) using (x1,y1) as the control point using
2957 % relative coordinates. At the end of the command, the new current point
2958 % becomes the final (x,y) coordinate pair used in the polybezier.
2960 % The format of the DrawPathCurveToQuadraticBezierRelative method is:
2962 % void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2963 % const double x1,const double y1,const double x,const double y)
2965 % A description of each parameter follows:
2967 % o wand: the drawing wand.
2969 % o x1: x ordinate of the control point
2971 % o y1: y ordinate of the control point
2973 % o x: x ordinate of final point
2975 % o y: y ordinate of final point
2978 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand,
2979 const double x1,const double y1,const double x,const double y)
2981 assert(wand != (DrawingWand *) NULL);
2982 assert(wand->signature == WandSignature);
2983 if (wand->debug != MagickFalse)
2984 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2985 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
2989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2993 % 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 %
2997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2999 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic
3000 % Bezier curve (using absolute coordinates) from the current point to
3001 % (x,y). The control point is assumed to be the reflection of the
3002 % control point on the previous command relative to the current
3003 % point. (If there is no previous command or if the previous command was
3004 % not a DrawPathCurveToQuadraticBezierAbsolute,
3005 % DrawPathCurveToQuadraticBezierRelative,
3006 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3007 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point
3008 % is coincident with the current point.). At the end of the command, the
3009 % new current point becomes the final (x,y) coordinate pair used in the
3012 % The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is:
3014 % void DrawPathCurveToQuadraticBezierSmoothAbsolute(
3015 % DrawingWand *wand,const double x,const double y)
3017 % A description of each parameter follows:
3019 % o wand: the drawing wand.
3021 % o x: x ordinate of final point
3023 % o y: y ordinate of final point
3027 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand,
3028 const PathMode mode,const double x,const double y)
3030 assert(wand != (DrawingWand *) NULL);
3031 assert(wand->signature == WandSignature);
3032 if (wand->debug != MagickFalse)
3033 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3034 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3035 (wand->path_mode != mode))
3037 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3038 wand->path_mode=mode;
3039 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3043 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3046 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand,
3047 const double x,const double y)
3049 assert(wand != (DrawingWand *) NULL);
3050 assert(wand->signature == WandSignature);
3051 if (wand->debug != MagickFalse)
3052 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3053 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3061 % 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 %
3065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3067 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic Bezier
3068 % curve (using relative coordinates) from the current point to (x,y). The
3069 % control point is assumed to be the reflection of the control point on the
3070 % previous command relative to the current point. (If there is no previous
3071 % command or if the previous command was not a
3072 % DrawPathCurveToQuadraticBezierAbsolute,
3073 % DrawPathCurveToQuadraticBezierRelative,
3074 % DrawPathCurveToQuadraticBezierSmoothAbsolute or
3075 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is
3076 % coincident with the current point.). At the end of the command, the new
3077 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3079 % The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is:
3081 % void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3082 % const double x,const double y)
3084 % A description of each parameter follows:
3086 % o wand: the drawing wand.
3088 % o x: x ordinate of final point
3090 % o y: y ordinate of final point
3093 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand,
3094 const double x,const double y)
3096 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3104 % 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 %
3108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3110 % DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the
3111 % current point to (x,y) using absolute coordinates. The first control
3112 % point is assumed to be the reflection of the second control point on
3113 % the previous command relative to the current point. (If there is no
3114 % previous command or if the previous command was not an
3115 % DrawPathCurveToAbsolute, DrawPathCurveToRelative,
3116 % DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume
3117 % the first control point is coincident with the current point.) (x2,y2)
3118 % is the second control point (i.e., the control point at the end of the
3119 % curve). At the end of the command, the new current point becomes the
3120 % final (x,y) coordinate pair used in the polybezier.
3122 % The format of the DrawPathCurveToSmoothAbsolute method is:
3124 % void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,
3125 % const double x2const double y2,const double x,const double y)
3127 % A description of each parameter follows:
3129 % o wand: the drawing wand.
3131 % o x2: x ordinate of second control point
3133 % o y2: y ordinate of second control point
3135 % o x: x ordinate of termination point
3137 % o y: y ordinate of termination point
3141 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode,
3142 const double x2,const double y2,const double x,const double y)
3144 assert(wand != (DrawingWand *) NULL);
3145 assert(wand->signature == WandSignature);
3146 if (wand->debug != MagickFalse)
3147 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3148 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3149 (wand->path_mode != mode))
3151 wand->path_operation=PathCurveToSmoothOperation;
3152 wand->path_mode=mode;
3153 (void) MvgAutoWrapPrintf(wand,"%c%g,%g %g,%g",mode == AbsolutePathMode ?
3154 'S' : 's',x2,y2,x,y);
3157 (void) MvgAutoWrapPrintf(wand," %g,%g %g,%g",x2,y2,x,y);
3160 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2,
3161 const double y2,const double x,const double y)
3163 assert(wand != (DrawingWand *) NULL);
3164 assert(wand->signature == WandSignature);
3165 if (wand->debug != MagickFalse)
3166 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3167 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3175 % 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 %
3179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3181 % DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current
3182 % point to (x,y) using relative coordinates. The first control point is
3183 % assumed to be the reflection of the second control point on the previous
3184 % command relative to the current point. (If there is no previous command or
3185 % if the previous command was not an DrawPathCurveToAbsolute,
3186 % DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or
3187 % DrawPathCurveToSmoothRelative, assume the first control point is coincident
3188 % with the current point.) (x2,y2) is the second control point (i.e., the
3189 % control point at the end of the curve). At the end of the command, the new
3190 % current point becomes the final (x,y) coordinate pair used in the polybezier.
3192 % The format of the DrawPathCurveToSmoothRelative method is:
3194 % void DrawPathCurveToSmoothRelative(DrawingWand *wand,
3195 % const double x2,const double y2,const double x,const double y)
3197 % A description of each parameter follows:
3199 % o wand: the drawing wand.
3201 % o x2: x ordinate of second control point
3203 % o y2: y ordinate of second control point
3205 % o x: x ordinate of termination point
3207 % o y: y ordinate of termination point
3210 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2,
3211 const double y2,const double x,const double y)
3213 assert(wand != (DrawingWand *) NULL);
3214 assert(wand->signature == WandSignature);
3215 if (wand->debug != MagickFalse)
3216 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3217 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3225 % 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 %
3229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3231 % DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point
3232 % to (x, y) using absolute coordinates. The size and orientation of the
3233 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3234 % indicates how the ellipse as a whole is rotated relative to the current
3235 % coordinate system. The center (cx, cy) of the ellipse is calculated
3236 % automagically to satisfy the constraints imposed by the other parameters.
3237 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3238 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3239 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3240 % clock-wise rotation.
3242 % The format of the DrawPathEllipticArcAbsolute method is:
3244 % void DrawPathEllipticArcAbsolute(DrawingWand *wand,
3245 % const double rx,const double ry,const double x_axis_rotation,
3246 % const MagickBooleanType large_arc_flag,
3247 % const MagickBooleanType sweep_flag,const double x,const double y)
3249 % A description of each parameter follows:
3251 % o wand: the drawing wand.
3257 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3258 % relative to the current coordinate system
3260 % o large_arc_flag: If non-zero (true) then draw the larger of the
3263 % o sweep_flag: If non-zero (true) then draw the arc matching a
3264 % clock-wise rotation
3269 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode,
3270 const double rx,const double ry,const double x_axis_rotation,
3271 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3272 const double x,const double y)
3274 assert(wand != (DrawingWand *) NULL);
3275 assert(wand->signature == WandSignature);
3276 if (wand->debug != MagickFalse)
3277 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3278 if ((wand->path_operation != PathEllipticArcOperation) ||
3279 (wand->path_mode != mode))
3281 wand->path_operation=PathEllipticArcOperation;
3282 wand->path_mode=mode;
3283 (void) MvgAutoWrapPrintf(wand, "%c%g,%g %g %u %u %g,%g",
3284 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation,
3285 large_arc_flag,sweep_flag,x,y);
3288 (void) MvgAutoWrapPrintf(wand," %g,%g %g %u %u %g,%g",rx,ry,x_axis_rotation,
3289 large_arc_flag,sweep_flag,x,y);
3292 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx,
3293 const double ry,const double x_axis_rotation,
3294 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3295 const double x,const double y)
3297 assert(wand != (DrawingWand *) NULL);
3298 assert(wand->signature == WandSignature);
3299 if (wand->debug != MagickFalse)
3300 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3301 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3302 large_arc_flag,sweep_flag,x,y);
3306 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3310 % 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 %
3314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3316 % DrawPathEllipticArcRelative() draws an elliptical arc from the current point
3317 % to (x, y) using relative coordinates. The size and orientation of the
3318 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which
3319 % indicates how the ellipse as a whole is rotated relative to the current
3320 % coordinate system. The center (cx, cy) of the ellipse is calculated
3321 % automagically to satisfy the constraints imposed by the other parameters.
3322 % largeArcFlag and sweepFlag contribute to the automatic calculations and help
3323 % determine how the arc is drawn. If largeArcFlag is true then draw the larger
3324 % of the available arcs. If sweepFlag is true, then draw the arc matching a
3325 % clock-wise rotation.
3327 % The format of the DrawPathEllipticArcRelative method is:
3329 % void DrawPathEllipticArcRelative(DrawingWand *wand,
3330 % const double rx,const double ry,const double x_axis_rotation,
3331 % const MagickBooleanType large_arc_flag,
3332 % const MagickBooleanType sweep_flag,const double x,const double y)
3334 % A description of each parameter follows:
3336 % o wand: the drawing wand.
3342 % o x_axis_rotation: indicates how the ellipse as a whole is rotated
3343 % relative to the current coordinate system
3345 % o large_arc_flag: If non-zero (true) then draw the larger of the
3348 % o sweep_flag: If non-zero (true) then draw the arc matching a
3349 % clock-wise rotation
3352 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx,
3353 const double ry,const double x_axis_rotation,
3354 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag,
3355 const double x,const double y)
3357 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3358 large_arc_flag,sweep_flag,x,y);
3362 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3366 % D r a w P a t h F i n i s h %
3370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3372 % DrawPathFinish() terminates the current path.
3374 % The format of the DrawPathFinish method is:
3376 % void DrawPathFinish(DrawingWand *wand)
3378 % A description of each parameter follows:
3380 % o wand: the drawing wand.
3383 WandExport void DrawPathFinish(DrawingWand *wand)
3385 assert(wand != (DrawingWand *) NULL);
3386 assert(wand->signature == WandSignature);
3387 if (wand->debug != MagickFalse)
3388 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3389 (void) MvgPrintf(wand,"'\n");
3390 wand->path_operation=PathDefaultOperation;
3391 wand->path_mode=DefaultPathMode;
3395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3399 % D r a w P a t h L i n e T o A b s o l u t e %
3403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3405 % DrawPathLineToAbsolute() draws a line path from the current point to the
3406 % given coordinate using absolute coordinates. The coordinate then becomes
3407 % the new current point.
3409 % The format of the DrawPathLineToAbsolute method is:
3411 % void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3414 % A description of each parameter follows:
3416 % o wand: the drawing wand.
3418 % o x: target x ordinate
3420 % o y: target y ordinate
3423 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode,
3424 const double x,const double y)
3426 assert(wand != (DrawingWand *) NULL);
3427 assert(wand->signature == WandSignature);
3428 if (wand->debug != MagickFalse)
3429 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3430 if ((wand->path_operation != PathLineToOperation) ||
3431 (wand->path_mode != mode))
3433 wand->path_operation=PathLineToOperation;
3434 wand->path_mode=mode;
3435 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3439 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3442 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x,
3445 assert(wand != (DrawingWand *) NULL);
3446 assert(wand->signature == WandSignature);
3447 if (wand->debug != MagickFalse)
3448 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3449 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3457 % D r a w P a t h L i n e T o R e l a t i v e %
3461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3463 % DrawPathLineToRelative() draws a line path from the current point to the
3464 % given coordinate using relative coordinates. The coordinate then becomes
3465 % the new current point.
3467 % The format of the DrawPathLineToRelative method is:
3469 % void DrawPathLineToRelative(DrawingWand *wand,const double x,
3472 % A description of each parameter follows:
3474 % o wand: the drawing wand.
3476 % o x: target x ordinate
3478 % o y: target y ordinate
3481 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x,
3484 assert(wand != (DrawingWand *) NULL);
3485 assert(wand->signature == WandSignature);
3486 if (wand->debug != MagickFalse)
3487 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3488 DrawPathLineTo(wand,RelativePathMode,x,y);
3492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3496 % 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 %
3500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3502 % DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the
3503 % current point to the target point using absolute coordinates. The target
3504 % point then becomes the new current point.
3506 % The format of the DrawPathLineToHorizontalAbsolute method is:
3508 % void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3509 % const PathMode mode,const double x)
3511 % A description of each parameter follows:
3513 % o wand: the drawing wand.
3515 % o x: target x ordinate
3519 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode,
3522 assert(wand != (DrawingWand *) NULL);
3523 assert(wand->signature == WandSignature);
3524 if (wand->debug != MagickFalse)
3525 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3526 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3527 (wand->path_mode != mode))
3529 wand->path_operation=PathLineToHorizontalOperation;
3530 wand->path_mode=mode;
3531 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3535 (void) MvgAutoWrapPrintf(wand," %g",x);
3538 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,
3541 assert(wand != (DrawingWand *) NULL);
3542 assert(wand->signature == WandSignature);
3543 if (wand->debug != MagickFalse)
3544 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3545 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3553 % D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e %
3557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3559 % DrawPathLineToHorizontalRelative() draws a horizontal line path from the
3560 % current point to the target point using relative coordinates. The target
3561 % point then becomes the new current point.
3563 % The format of the DrawPathLineToHorizontalRelative method is:
3565 % void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3568 % A description of each parameter follows:
3570 % o wand: the drawing wand.
3572 % o x: target x ordinate
3575 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand,
3578 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3586 % 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 %
3590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3592 % DrawPathLineToVerticalAbsolute() draws a vertical line path from the
3593 % current point to the target point using absolute coordinates. The target
3594 % point then becomes the new current point.
3596 % The format of the DrawPathLineToVerticalAbsolute method is:
3598 % void DrawPathLineToVerticalAbsolute(DrawingWand *wand,
3601 % A description of each parameter follows:
3603 % o wand: the drawing wand.
3605 % o y: target y ordinate
3609 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode,
3612 assert(wand != (DrawingWand *) NULL);
3613 assert(wand->signature == WandSignature);
3614 if (wand->debug != MagickFalse)
3615 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3616 if ((wand->path_operation != PathLineToVerticalOperation) ||
3617 (wand->path_mode != mode))
3619 wand->path_operation=PathLineToVerticalOperation;
3620 wand->path_mode=mode;
3621 (void) MvgAutoWrapPrintf(wand,"%c%g",mode == AbsolutePathMode ?
3625 (void) MvgAutoWrapPrintf(wand," %g",y);
3628 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y)
3630 assert(wand != (DrawingWand *) NULL);
3631 assert(wand->signature == WandSignature);
3632 if (wand->debug != MagickFalse)
3633 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3634 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3642 % 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 %
3646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3648 % DrawPathLineToVerticalRelative() draws a vertical line path from the
3649 % current point to the target point using relative coordinates. The target
3650 % point then becomes the new current point.
3652 % The format of the DrawPathLineToVerticalRelative method is:
3654 % void DrawPathLineToVerticalRelative(DrawingWand *wand,
3657 % A description of each parameter follows:
3659 % o wand: the drawing wand.
3661 % o y: target y ordinate
3664 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y)
3666 assert(wand != (DrawingWand *) NULL);
3667 assert(wand->signature == WandSignature);
3668 if (wand->debug != MagickFalse)
3669 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3670 DrawPathLineToVertical(wand,RelativePathMode,y);
3673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3677 % D r a w P a t h M o v e T o A b s o l u t e %
3681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3683 % DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate
3684 % using absolute coordinates. The current point then becomes the
3685 % specified coordinate.
3687 % The format of the DrawPathMoveToAbsolute method is:
3689 % void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3692 % A description of each parameter follows:
3694 % o wand: the drawing wand.
3696 % o x: target x ordinate
3698 % o y: target y ordinate
3702 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x,
3705 assert(wand != (DrawingWand *) NULL);
3706 assert(wand->signature == WandSignature);
3707 if (wand->debug != MagickFalse)
3708 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3709 if ((wand->path_operation != PathMoveToOperation) ||
3710 (wand->path_mode != mode))
3712 wand->path_operation=PathMoveToOperation;
3713 wand->path_mode=mode;
3714 (void) MvgAutoWrapPrintf(wand,"%c%g,%g",mode == AbsolutePathMode ?
3718 (void) MvgAutoWrapPrintf(wand," %g,%g",x,y);
3721 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x,
3724 assert(wand != (DrawingWand *) NULL);
3725 assert(wand->signature == WandSignature);
3726 if (wand->debug != MagickFalse)
3727 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3728 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3736 % D r a w P a t h M o v e T o R e l a t i v e %
3740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3742 % DrawPathMoveToRelative() starts a new sub-path at the given coordinate using
3743 % relative coordinates. The current point then becomes the specified
3746 % The format of the DrawPathMoveToRelative method is:
3748 % void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3751 % A description of each parameter follows:
3753 % o wand: the drawing wand.
3755 % o x: target x ordinate
3757 % o y: target y ordinate
3760 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x,
3763 assert(wand != (DrawingWand *) NULL);
3764 assert(wand->signature == WandSignature);
3765 if (wand->debug != MagickFalse)
3766 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3767 DrawPathMoveTo(wand,RelativePathMode,x,y);
3771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3775 % D r a w P a t h S t a r t %
3779 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3781 % DrawPathStart() declares the start of a path drawing list which is terminated
3782 % by a matching DrawPathFinish() command. All other DrawPath commands must
3783 % be enclosed between a DrawPathStart() and a DrawPathFinish() command. This
3784 % is because path drawing commands are subordinate commands and they do not
3785 % function by themselves.
3787 % The format of the DrawPathStart method is:
3789 % void DrawPathStart(DrawingWand *wand)
3791 % A description of each parameter follows:
3793 % o wand: the drawing wand.
3796 WandExport void DrawPathStart(DrawingWand *wand)
3798 assert(wand != (DrawingWand *) NULL);
3799 assert(wand->signature == WandSignature);
3800 if (wand->debug != MagickFalse)
3801 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3802 (void) MvgPrintf(wand,"path '");
3803 wand->path_operation=PathDefaultOperation;
3804 wand->path_mode=DefaultPathMode;
3808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3812 % D r a w P o i n t %
3816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3818 % DrawPoint() draws a point using the current fill color.
3820 % The format of the DrawPoint method is:
3822 % void DrawPoint(DrawingWand *wand,const double x,const double y)
3824 % A description of each parameter follows:
3826 % o wand: the drawing wand.
3828 % o x: target x coordinate
3830 % o y: target y coordinate
3833 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y)
3835 assert(wand != (DrawingWand *) NULL);
3836 assert(wand->signature == WandSignature);
3837 if (wand->debug != MagickFalse)
3838 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3839 (void) MvgPrintf(wand,"point %g,%g\n",x,y);
3843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3847 % D r a w P o l y g o n %
3851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3853 % DrawPolygon() draws a polygon using the current stroke, stroke width, and
3854 % fill color or texture, using the specified array of coordinates.
3856 % The format of the DrawPolygon method is:
3858 % void DrawPolygon(DrawingWand *wand,
3859 % const unsigned long number_coordinates,const PointInfo *coordinates)
3861 % A description of each parameter follows:
3863 % o wand: the drawing wand.
3865 % o number_coordinates: number of coordinates
3867 % o coordinates: coordinate array
3870 WandExport void DrawPolygon(DrawingWand *wand,
3871 const unsigned long number_coordinates,const PointInfo *coordinates)
3873 assert(wand != (DrawingWand *) NULL);
3874 assert(wand->signature == WandSignature);
3875 if (wand->debug != MagickFalse)
3876 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3877 MvgAppendPointsCommand(wand,"polygon",number_coordinates,coordinates);
3881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3885 % D r a w P o l y l i n e %
3889 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3891 % DrawPolyline() draws a polyline using the current stroke, stroke width, and
3892 % fill color or texture, using the specified array of coordinates.
3894 % The format of the DrawPolyline method is:
3896 % void DrawPolyline(DrawingWand *wand,
3897 % const unsigned long number_coordinates,const PointInfo *coordinates)
3899 % A description of each parameter follows:
3901 % o wand: the drawing wand.
3903 % o number_coordinates: number of coordinates
3905 % o coordinates: coordinate array
3908 WandExport void DrawPolyline(DrawingWand *wand,
3909 const unsigned long number_coordinates,const PointInfo *coordinates)
3911 assert(wand != (DrawingWand *) NULL);
3912 assert(wand->signature == WandSignature);
3913 if (wand->debug != MagickFalse)
3914 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3915 MvgAppendPointsCommand(wand,"polyline",number_coordinates,coordinates);
3919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3923 % D r a w P o p C l i p P a t h %
3927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3929 % DrawPopClipPath() terminates a clip path definition.
3931 % The format of the DrawPopClipPath method is:
3933 % void DrawPopClipPath(DrawingWand *wand)
3935 % A description of each parameter follows:
3937 % o wand: the drawing wand.
3940 WandExport void DrawPopClipPath(DrawingWand *wand)
3942 assert(wand != (DrawingWand *) NULL);
3943 assert(wand->signature == WandSignature);
3944 if (wand->debug != MagickFalse)
3945 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3946 if (wand->indent_depth > 0)
3947 wand->indent_depth--;
3948 (void) MvgPrintf(wand,"pop clip-path\n");
3952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3956 % D r a w P o p D e f s %
3960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3962 % DrawPopDefs() terminates a definition list.
3964 % The format of the DrawPopDefs method is:
3966 % void DrawPopDefs(DrawingWand *wand)
3968 % A description of each parameter follows:
3970 % o wand: the drawing wand.
3973 WandExport void DrawPopDefs(DrawingWand *wand)
3975 assert(wand != (DrawingWand *) NULL);
3976 assert(wand->signature == WandSignature);
3977 if (wand->debug != MagickFalse)
3978 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
3979 if (wand->indent_depth > 0)
3980 wand->indent_depth--;
3981 (void) MvgPrintf(wand,"pop defs\n");
3985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3989 % D r a w P o p P a t t e r n %
3993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3995 % DrawPopPattern() terminates a pattern definition.
3997 % The format of the DrawPopPattern method is:
3999 % MagickBooleanType DrawPopPattern(DrawingWand *wand)
4001 % A description of each parameter follows:
4003 % o wand: the drawing wand.
4006 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand)
4009 geometry[MaxTextExtent],
4012 assert(wand != (DrawingWand *) NULL);
4013 assert(wand->signature == WandSignature);
4014 if (wand->debug != MagickFalse)
4015 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4016 if (wand->image == (Image *) NULL)
4017 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4018 if (wand->pattern_id == (const char *) NULL)
4020 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition",
4022 return(MagickFalse);
4024 (void) FormatMagickString(key,MaxTextExtent,"%s",wand->pattern_id);
4025 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4026 (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
4027 wand->pattern_bounds.width,wand->pattern_bounds.height,
4028 wand->pattern_bounds.x,wand->pattern_bounds.y);
4029 (void) SetImageArtifact(wand->image,key,geometry);
4030 wand->pattern_id=DestroyString(wand->pattern_id);
4031 wand->pattern_offset=0;
4032 wand->pattern_bounds.x=0;
4033 wand->pattern_bounds.y=0;
4034 wand->pattern_bounds.width=0;
4035 wand->pattern_bounds.height=0;
4036 wand->filter_off=MagickTrue;
4037 if (wand->indent_depth > 0)
4038 wand->indent_depth--;
4039 (void) MvgPrintf(wand,"pop pattern\n");
4044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4048 % D r a w P u s h C l i p P a t h %
4052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4054 % DrawPushClipPath() starts a clip path definition which is comprized of any
4055 % number of drawing commands and terminated by a DrawPopClipPath() command.
4057 % The format of the DrawPushClipPath method is:
4059 % void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4061 % A description of each parameter follows:
4063 % o wand: the drawing wand.
4065 % o clip_mask_id: string identifier to associate with the clip path for
4069 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id)
4071 assert(wand != (DrawingWand *) NULL);
4072 assert(wand->signature == WandSignature);
4073 if (wand->debug != MagickFalse)
4074 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4075 assert(clip_mask_id != (const char *) NULL);
4076 (void) MvgPrintf(wand,"push clip-path %s\n",clip_mask_id);
4077 wand->indent_depth++;
4081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4085 % D r a w P u s h D e f s %
4089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4091 % DrawPushDefs() indicates that commands up to a terminating DrawPopDefs()
4092 % command create named elements (e.g. clip-paths, textures, etc.) which
4093 % may safely be processed earlier for the sake of efficiency.
4095 % The format of the DrawPushDefs method is:
4097 % void DrawPushDefs(DrawingWand *wand)
4099 % A description of each parameter follows:
4101 % o wand: the drawing wand.
4104 WandExport void DrawPushDefs(DrawingWand *wand)
4106 assert(wand != (DrawingWand *) NULL);
4107 assert(wand->signature == WandSignature);
4108 if (wand->debug != MagickFalse)
4109 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4110 (void) MvgPrintf(wand,"push defs\n");
4111 wand->indent_depth++;
4115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4119 % D r a w P u s h P a t t e r n %
4123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4125 % DrawPushPattern() indicates that subsequent commands up to a
4126 % DrawPopPattern() command comprise the definition of a named pattern.
4127 % The pattern space is assigned top left corner coordinates, a width
4128 % and height, and becomes its own drawing space. Anything which can
4129 % be drawn may be used in a pattern definition.
4130 % Named patterns may be used as stroke or brush definitions.
4132 % The format of the DrawPushPattern method is:
4134 % MagickBooleanType DrawPushPattern(DrawingWand *wand,
4135 % const char *pattern_id,const double x,const double y,
4136 % const double width,const double height)
4138 % A description of each parameter follows:
4140 % o wand: the drawing wand.
4142 % o pattern_id: pattern identification for later reference
4144 % o x: x ordinate of top left corner
4146 % o y: y ordinate of top left corner
4148 % o width: width of pattern space
4150 % o height: height of pattern space
4153 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand,
4154 const char *pattern_id,const double x,const double y,const double width,
4155 const double height)
4157 assert(wand != (DrawingWand *) NULL);
4158 assert(wand->signature == WandSignature);
4159 if (wand->debug != MagickFalse)
4160 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4161 assert(pattern_id != (const char *) NULL);
4162 if (wand->pattern_id != NULL)
4164 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition",
4166 return(MagickFalse);
4168 wand->filter_off=MagickTrue;
4169 (void) MvgPrintf(wand,"push pattern %s %g,%g %g,%g\n",pattern_id,x,y,
4171 wand->indent_depth++;
4172 wand->pattern_id=AcquireString(pattern_id);
4173 wand->pattern_bounds.x=(long) ceil(x-0.5);
4174 wand->pattern_bounds.y=(long) ceil(y-0.5);
4175 wand->pattern_bounds.width=(unsigned long) (width+0.5);
4176 wand->pattern_bounds.height=(unsigned long) (height+0.5);
4177 wand->pattern_offset=wand->mvg_length;
4182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4186 % D r a w R e c t a n g l e %
4190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4192 % DrawRectangle() draws a rectangle given two coordinates and using the
4193 % current stroke, stroke width, and fill settings.
4195 % The format of the DrawRectangle method is:
4197 % void DrawRectangle(DrawingWand *wand,const double x1,
4198 % const double y1,const double x2,const double y2)
4200 % A description of each parameter follows:
4202 % o x1: x ordinate of first coordinate
4204 % o y1: y ordinate of first coordinate
4206 % o x2: x ordinate of second coordinate
4208 % o y2: y ordinate of second coordinate
4211 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1,
4212 const double x2,const double y2)
4214 assert(wand != (DrawingWand *) NULL);
4215 assert(wand->signature == WandSignature);
4216 if (wand->debug != MagickFalse)
4217 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4218 (void) MvgPrintf(wand,"rectangle %g,%g %g,%g\n",x1,y1,x2,y2);
4222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4226 + D r a w R e n d e r %
4230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4232 % DrawRender() renders all preceding drawing commands onto the image.
4234 % The format of the DrawRender method is:
4236 % MagickBooleanType DrawRender(DrawingWand *wand)
4238 % A description of each parameter follows:
4240 % o wand: the drawing wand.
4243 WandExport MagickBooleanType DrawRender(DrawingWand *wand)
4248 assert(wand != (const DrawingWand *) NULL);
4249 assert(wand->signature == WandSignature);
4250 if (wand->debug != MagickFalse)
4251 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4252 CurrentContext->primitive=wand->mvg;
4253 if (wand->debug != MagickFalse)
4254 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg);
4255 if (wand->image == (Image *) NULL)
4256 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4257 status=DrawImage(wand->image,CurrentContext);
4258 InheritException(wand->exception,&wand->image->exception);
4259 CurrentContext->primitive=(char *) NULL;
4264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4268 % D r a w R e s e t V e c t o r G r a p h i c s %
4272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4274 % DrawResetVectorGraphics() resets the vector graphics associated with the
4277 % The format of the DrawResetVectorGraphics method is:
4279 % void DrawResetVectorGraphics(DrawingWand *wand)
4281 % A description of each parameter follows:
4283 % o wand: the drawing wand.
4286 WandExport void DrawResetVectorGraphics(DrawingWand *wand)
4288 assert(wand != (DrawingWand *) NULL);
4289 assert(wand->signature == WandSignature);
4290 if (wand->debug != MagickFalse)
4291 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4292 if (wand->mvg != (char *) NULL)
4293 wand->mvg=DestroyString(wand->mvg);
4300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4304 % D r a w R o t a t e %
4308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4310 % DrawRotate() applies the specified rotation to the current coordinate space.
4312 % The format of the DrawRotate method is:
4314 % void DrawRotate(DrawingWand *wand,const double degrees)
4316 % A description of each parameter follows:
4318 % o wand: the drawing wand.
4320 % o degrees: degrees of rotation
4323 WandExport void DrawRotate(DrawingWand *wand,const double degrees)
4328 assert(wand != (DrawingWand *) NULL);
4329 assert(wand->signature == WandSignature);
4330 if (wand->debug != MagickFalse)
4331 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4332 GetAffineMatrix(&affine);
4333 affine.sx=cos(DegreesToRadians(fmod(degrees,360.0)));
4334 affine.rx=sin(DegreesToRadians(fmod(degrees,360.0)));
4335 affine.ry=(-sin(DegreesToRadians(fmod(degrees,360.0))));
4336 affine.sy=cos(DegreesToRadians(fmod(degrees,360.0)));
4337 AdjustAffine(wand,&affine);
4338 (void) MvgPrintf(wand,"rotate %g\n",degrees);
4342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4346 % D r a w R o u n d R e c t a n g l e %
4350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4352 % DrawRoundRectangle() draws a rounted rectangle given two coordinates,
4353 % x & y corner radiuses and using the current stroke, stroke width,
4354 % and fill settings.
4356 % The format of the DrawRoundRectangle method is:
4358 % void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4359 % double x2,double y2,double rx,double ry)
4361 % A description of each parameter follows:
4363 % o wand: the drawing wand.
4365 % o x1: x ordinate of first coordinate
4367 % o y1: y ordinate of first coordinate
4369 % o x2: x ordinate of second coordinate
4371 % o y2: y ordinate of second coordinate
4373 % o rx: radius of corner in horizontal direction
4375 % o ry: radius of corner in vertical direction
4378 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1,
4379 double x2,double y2,double rx,double ry)
4381 assert(wand != (DrawingWand *) NULL);
4382 assert(wand->signature == WandSignature);
4383 if (wand->debug != MagickFalse)
4384 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4385 (void) MvgPrintf(wand,"roundrectangle %g,%g %g,%g %g,%g\n",x1,y1,x2,y2,rx,ry);
4389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4393 % D r a w S c a l e %
4397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4399 % DrawScale() adjusts the scaling factor to apply in the horizontal and
4400 % vertical directions to the current coordinate space.
4402 % The format of the DrawScale method is:
4404 % void DrawScale(DrawingWand *wand,const double x,const double y)
4406 % A description of each parameter follows:
4408 % o wand: the drawing wand.
4410 % o x: horizontal scale factor
4412 % o y: vertical scale factor
4415 WandExport void DrawScale(DrawingWand *wand,const double x,const double y)
4420 assert(wand != (DrawingWand *) NULL);
4421 assert(wand->signature == WandSignature);
4422 if (wand->debug != MagickFalse)
4423 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4424 GetAffineMatrix(&affine);
4427 AdjustAffine(wand,&affine);
4428 (void) MvgPrintf(wand,"scale %g,%g\n",x,y);
4432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4436 % D r a w S e t B o r d e r C o l o r %
4440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4442 % DrawSetBorderColor() sets the border color to be used for drawing bordered
4445 % The format of the DrawSetBorderColor method is:
4447 % void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4449 % A description of each parameter follows:
4451 % o wand: the drawing wand.
4453 % o border_wand: border wand.
4457 static inline MagickBooleanType IsColorEqual(const PixelPacket *p,
4458 const PixelPacket *q)
4460 if (p->red != q->red)
4461 return(MagickFalse);
4462 if (p->green != q->green)
4463 return(MagickFalse);
4464 if (p->blue != q->blue)
4465 return(MagickFalse);
4466 if (p->opacity != q->opacity)
4467 return(MagickFalse);
4471 WandExport void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand)
4478 assert(wand != (DrawingWand *) NULL);
4479 assert(wand->signature == WandSignature);
4480 if (wand->debug != MagickFalse)
4481 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4482 assert(border_wand != (const PixelWand *) NULL);
4483 PixelGetQuantumColor(border_wand,&border_color);
4484 new_border=border_color;
4485 current_border=(&CurrentContext->border_color);
4486 if ((wand->filter_off != MagickFalse) ||
4487 (IsColorEqual(current_border,&new_border) == MagickFalse))
4489 CurrentContext->border_color=new_border;
4490 (void) MvgPrintf(wand,"border-color '");
4491 MvgAppendColor(wand,&border_color);
4492 (void) MvgPrintf(wand,"'\n");
4497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4501 % D r a w S e t C l i p P a t h %
4505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4507 % DrawSetClipPath() associates a named clipping path with the image. Only
4508 % the areas drawn on by the clipping path will be modified as long as it
4509 % remains in effect.
4511 % The format of the DrawSetClipPath method is:
4513 % MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4514 % const char *clip_mask)
4516 % A description of each parameter follows:
4518 % o wand: the drawing wand.
4520 % o clip_mask: name of clipping path to associate with image
4523 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand,
4524 const char *clip_mask)
4526 if (wand->debug != MagickFalse)
4527 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask);
4528 assert(wand != (DrawingWand *) NULL);
4529 assert(wand->signature == WandSignature);
4530 assert(clip_mask != (const char *) NULL);
4531 if ((CurrentContext->clip_mask == (const char *) NULL) ||
4532 (wand->filter_off != MagickFalse) ||
4533 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4535 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4536 #if DRAW_BINARY_IMPLEMENTATION
4537 if (wand->image == (Image *) NULL)
4538 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4539 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4541 (void) MvgPrintf(wand,"clip-path url(#%s)\n",clip_mask);
4547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4551 % D r a w S e t C l i p R u l e %
4555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4557 % DrawSetClipRule() set the polygon fill rule to be used by the clipping path.
4559 % The format of the DrawSetClipRule method is:
4561 % void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4563 % A description of each parameter follows:
4565 % o wand: the drawing wand.
4567 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4570 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule)
4572 assert(wand != (DrawingWand *) NULL);
4573 assert(wand->signature == WandSignature);
4574 if (wand->debug != MagickFalse)
4575 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4576 if ((wand->filter_off != MagickFalse) ||
4577 (CurrentContext->fill_rule != fill_rule))
4579 CurrentContext->fill_rule=fill_rule;
4580 (void) MvgPrintf(wand, "clip-rule '%s'\n",MagickOptionToMnemonic(
4581 MagickFillRuleOptions,(long) fill_rule));
4586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4590 % D r a w S e t C l i p U n i t s %
4594 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4596 % DrawSetClipUnits() sets the interpretation of clip path units.
4598 % The format of the DrawSetClipUnits method is:
4600 % void DrawSetClipUnits(DrawingWand *wand,
4601 % const ClipPathUnits clip_units)
4603 % A description of each parameter follows:
4605 % o wand: the drawing wand.
4607 % o clip_units: units to use (UserSpace, UserSpaceOnUse, or
4608 % ObjectBoundingBox)
4611 WandExport void DrawSetClipUnits(DrawingWand *wand,
4612 const ClipPathUnits clip_units)
4614 assert(wand != (DrawingWand *) NULL);
4615 assert(wand->signature == WandSignature);
4616 if (wand->debug != MagickFalse)
4617 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4618 if ((wand->filter_off != MagickFalse) ||
4619 (CurrentContext->clip_units != clip_units))
4621 CurrentContext->clip_units=clip_units;
4622 if (clip_units == ObjectBoundingBox)
4627 GetAffineMatrix(&affine);
4628 affine.sx=CurrentContext->bounds.x2;
4629 affine.sy=CurrentContext->bounds.y2;
4630 affine.tx=CurrentContext->bounds.x1;
4631 affine.ty=CurrentContext->bounds.y1;
4632 AdjustAffine(wand,&affine);
4634 (void) MvgPrintf(wand, "clip-units '%s'\n",MagickOptionToMnemonic(
4635 MagickClipPathOptions,(long) clip_units));
4640 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4644 % D r a w S e t F i l l C o l o r %
4648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4650 % DrawSetFillColor() sets the fill color to be used for drawing filled objects.
4652 % The format of the DrawSetFillColor method is:
4654 % void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4656 % A description of each parameter follows:
4658 % o wand: the drawing wand.
4660 % o fill_wand: fill wand.
4663 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand)
4670 assert(wand != (DrawingWand *) NULL);
4671 assert(wand->signature == WandSignature);
4672 if (wand->debug != MagickFalse)
4673 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4674 assert(fill_wand != (const PixelWand *) NULL);
4675 PixelGetQuantumColor(fill_wand,&fill_color);
4676 new_fill=fill_color;
4677 current_fill=(&CurrentContext->fill);
4678 if ((wand->filter_off != MagickFalse) ||
4679 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4681 CurrentContext->fill=new_fill;
4682 (void) MvgPrintf(wand,"fill '");
4683 MvgAppendColor(wand,&fill_color);
4684 (void) MvgPrintf(wand,"'\n");
4689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4693 % D r a w S e t F i l l O p a c i t y %
4697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4699 % DrawSetFillOpacity() sets the opacity to use when drawing using the fill
4700 % color or fill texture. Fully opaque is 1.0.
4702 % The format of the DrawSetFillOpacity method is:
4704 % void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4706 % A description of each parameter follows:
4708 % o wand: the drawing wand.
4710 % o fill_opacity: fill opacity
4713 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity)
4718 assert(wand != (DrawingWand *) NULL);
4719 assert(wand->signature == WandSignature);
4720 if (wand->debug != MagickFalse)
4721 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4722 opacity=RoundToQuantum((double) QuantumRange*(1.0-fill_opacity));
4723 if ((wand->filter_off != MagickFalse) ||
4724 (CurrentContext->fill.opacity != opacity))
4726 CurrentContext->fill.opacity=opacity;
4727 (void) MvgPrintf(wand,"fill-opacity %g\n",fill_opacity);
4732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4736 % D r a w S e t O p a c i t y %
4740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4742 % DrawSetOpacity() sets the opacity to use when drawing using the fill or
4743 % stroke color or texture. Fully opaque is 1.0.
4745 % The format of the DrawSetOpacity method is:
4747 % void DrawSetOpacity(DrawingWand *wand,const double opacity)
4749 % A description of each parameter follows:
4751 % o wand: the drawing wand.
4753 % o opacity: fill opacity
4756 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity)
4761 assert(wand != (DrawingWand *) NULL);
4762 assert(wand->signature == WandSignature);
4763 if (wand->debug != MagickFalse)
4764 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4765 quantum_opacity=RoundToQuantum((double) QuantumRange*(1.0-opacity));
4766 if ((wand->filter_off != MagickFalse) ||
4767 (CurrentContext->opacity != quantum_opacity))
4769 CurrentContext->opacity=opacity;
4770 (void) MvgPrintf(wand,"opacity %g\n",opacity);
4775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4779 % D r a w S e t F i l l P a t t e r n U R L %
4783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4785 % DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling
4786 % objects. Only local URLs ("#identifier") are supported at this time. These
4787 % local URLs are normally created by defining a named fill pattern with
4788 % DrawPushPattern/DrawPopPattern.
4790 % The format of the DrawSetFillPatternURL method is:
4792 % MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4793 % const char *fill_url)
4795 % A description of each parameter follows:
4797 % o wand: the drawing wand.
4799 % o fill_url: URL to use to obtain fill pattern.
4802 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand,
4803 const char *fill_url)
4806 pattern[MaxTextExtent],
4807 pattern_spec[MaxTextExtent];
4809 assert(wand != (DrawingWand *) NULL);
4810 assert(wand->signature == WandSignature);
4811 if (wand->debug != MagickFalse)
4812 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url);
4813 if (wand->image == (Image *) NULL)
4814 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
4815 assert(fill_url != (const char *) NULL);
4816 if (*fill_url != '#')
4818 ThrowDrawException(DrawError,"NotARelativeURL",fill_url);
4819 return(MagickFalse);
4821 (void) FormatMagickString(pattern,MaxTextExtent,"%s",fill_url+1);
4822 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
4824 ThrowDrawException(DrawError,"URLNotFound",fill_url)
4825 return(MagickFalse);
4827 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",fill_url);
4828 #if DRAW_BINARY_IMPLEMENTATION
4829 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4830 &CurrentContext->fill_pattern);
4832 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4833 CurrentContext->fill.opacity=CurrentContext->opacity;
4834 (void) MvgPrintf(wand,"fill %s\n",pattern_spec);
4839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4843 % D r a w S e t F i l l R u l e %
4847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4849 % DrawSetFillRule() sets the fill rule to use while drawing polygons.
4851 % The format of the DrawSetFillRule method is:
4853 % void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4855 % A description of each parameter follows:
4857 % o wand: the drawing wand.
4859 % o fill_rule: fill rule (EvenOddRule or NonZeroRule)
4862 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule)
4864 assert(wand != (DrawingWand *) NULL);
4865 assert(wand->signature == WandSignature);
4866 if (wand->debug != MagickFalse)
4867 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4868 if ((wand->filter_off != MagickFalse) ||
4869 (CurrentContext->fill_rule != fill_rule))
4871 CurrentContext->fill_rule=fill_rule;
4872 (void) MvgPrintf(wand, "fill-rule '%s'\n",MagickOptionToMnemonic(
4873 MagickFillRuleOptions,(long) fill_rule));
4878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4882 % D r a w S e t F o n t %
4886 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4888 % DrawSetFont() sets the fully-sepecified font to use when annotating with
4891 % The format of the DrawSetFont method is:
4893 % MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name)
4895 % A description of each parameter follows:
4897 % o wand: the drawing wand.
4899 % o font_name: font name
4902 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand,
4903 const char *font_name)
4905 assert(wand != (DrawingWand *) NULL);
4906 assert(wand->signature == WandSignature);
4907 if (wand->debug != MagickFalse)
4908 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4909 assert(font_name != (const char *) NULL);
4910 if ((wand->filter_off != MagickFalse) ||
4911 (CurrentContext->font == (char *) NULL) ||
4912 (LocaleCompare(CurrentContext->font,font_name) != 0))
4914 (void) CloneString(&CurrentContext->font,font_name);
4915 (void) MvgPrintf(wand,"font '%s'\n",font_name);
4921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4925 % D r a w S e t F o n t F a m i l y %
4929 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4931 % DrawSetFontFamily() sets the font family to use when annotating with text.
4933 % The format of the DrawSetFontFamily method is:
4935 % MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4936 % const char *font_family)
4938 % A description of each parameter follows:
4940 % o wand: the drawing wand.
4942 % o font_family: font family
4945 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand,
4946 const char *font_family)
4948 assert(wand != (DrawingWand *) NULL);
4949 assert(wand->signature == WandSignature);
4950 if (wand->debug != MagickFalse)
4951 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4952 assert(font_family != (const char *) NULL);
4953 if ((wand->filter_off != MagickFalse) ||
4954 (CurrentContext->family == (const char *) NULL) ||
4955 (LocaleCompare(CurrentContext->family,font_family) != 0))
4957 (void) CloneString(&CurrentContext->family,font_family);
4958 (void) MvgPrintf(wand,"font-family '%s'\n",font_family);
4964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4968 % D r a w S e t F o n t S i z e %
4972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4974 % DrawSetFontSize() sets the font pointsize to use when annotating with text.
4976 % The format of the DrawSetFontSize method is:
4978 % void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4980 % A description of each parameter follows:
4982 % o wand: the drawing wand.
4984 % o pointsize: text pointsize
4987 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize)
4989 assert(wand != (DrawingWand *) NULL);
4990 assert(wand->signature == WandSignature);
4991 if (wand->debug != MagickFalse)
4992 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
4993 if ((wand->filter_off != MagickFalse) ||
4994 (fabs(CurrentContext->pointsize-pointsize) > MagickEpsilon))
4996 CurrentContext->pointsize=pointsize;
4997 (void) MvgPrintf(wand,"font-size %g\n",pointsize);
5002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5006 % D r a w S e t F o n t S t r e t c h %
5010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5012 % DrawSetFontStretch() sets the font stretch to use when annotating with text.
5013 % The AnyStretch enumeration acts as a wild-card "don't care" option.
5015 % The format of the DrawSetFontStretch method is:
5017 % void DrawSetFontStretch(DrawingWand *wand,
5018 % const StretchType font_stretch)
5020 % A description of each parameter follows:
5022 % o wand: the drawing wand.
5024 % o font_stretch: font stretch (NormalStretch, UltraCondensedStretch,
5025 % CondensedStretch, SemiCondensedStretch,
5026 % SemiExpandedStretch, ExpandedStretch,
5027 % ExtraExpandedStretch, UltraExpandedStretch, AnyStretch)
5030 WandExport void DrawSetFontStretch(DrawingWand *wand,
5031 const StretchType font_stretch)
5033 assert(wand != (DrawingWand *) NULL);
5034 assert(wand->signature == WandSignature);
5035 if (wand->debug != MagickFalse)
5036 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5037 if ((wand->filter_off != MagickFalse) ||
5038 (CurrentContext->stretch != font_stretch))
5040 CurrentContext->stretch=font_stretch;
5041 (void) MvgPrintf(wand, "font-stretch '%s'\n",MagickOptionToMnemonic(
5042 MagickStretchOptions,(long) font_stretch));
5047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5051 % D r a w S e t F o n t S t y l e %
5055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5057 % DrawSetFontStyle() sets the font style to use when annotating with text.
5058 % The AnyStyle enumeration acts as a wild-card "don't care" option.
5060 % The format of the DrawSetFontStyle method is:
5062 % void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5064 % A description of each parameter follows:
5066 % o wand: the drawing wand.
5068 % o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle)
5071 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style)
5073 assert(wand != (DrawingWand *) NULL);
5074 assert(wand->signature == WandSignature);
5075 if (wand->debug != MagickFalse)
5076 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5077 if ((wand->filter_off != MagickFalse) ||
5078 (CurrentContext->style != style))
5080 CurrentContext->style=style;
5081 (void) MvgPrintf(wand, "font-style '%s'\n",MagickOptionToMnemonic(
5082 MagickStyleOptions,(long) style));
5087 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5091 % D r a w S e t F o n t W e i g h t %
5095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5097 % DrawSetFontWeight() sets the font weight to use when annotating with text.
5099 % The format of the DrawSetFontWeight method is:
5101 % void DrawSetFontWeight(DrawingWand *wand,
5102 % const unsigned long font_weight)
5104 % A description of each parameter follows:
5106 % o wand: the drawing wand.
5108 % o font_weight: font weight (valid range 100-900)
5111 WandExport void DrawSetFontWeight(DrawingWand *wand,
5112 const unsigned long font_weight)
5114 assert(wand != (DrawingWand *) NULL);
5115 assert(wand->signature == WandSignature);
5116 if (wand->debug != MagickFalse)
5117 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5118 if ((wand->filter_off != MagickFalse) ||
5119 (CurrentContext->weight != font_weight))
5121 CurrentContext->weight=font_weight;
5122 (void) MvgPrintf(wand,"font-weight %lu\n",font_weight);
5127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5131 % D r a w S e t G r a v i t y %
5135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5137 % DrawSetGravity() sets the text placement gravity to use when annotating
5140 % The format of the DrawSetGravity method is:
5142 % void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5144 % A description of each parameter follows:
5146 % o wand: the drawing wand.
5148 % o gravity: positioning gravity (NorthWestGravity, NorthGravity,
5149 % NorthEastGravity, WestGravity, CenterGravity,
5150 % EastGravity, SouthWestGravity, SouthGravity,
5154 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity)
5156 assert(wand != (DrawingWand *) NULL);
5157 assert(wand->signature == WandSignature);
5158 if (wand->debug != MagickFalse)
5159 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5160 if ((wand->filter_off != MagickFalse) ||
5161 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5163 CurrentContext->gravity=gravity;
5164 (void) MvgPrintf(wand,"gravity '%s'\n",MagickOptionToMnemonic(
5165 MagickGravityOptions,(long) gravity));
5170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5174 % D r a w S e t S t r o k e C o l o r %
5178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5180 % DrawSetStrokeColor() sets the color used for stroking object outlines.
5182 % The format of the DrawSetStrokeColor method is:
5184 % void DrawSetStrokeColor(DrawingWand *wand,
5185 % const PixelWand *stroke_wand)
5187 % A description of each parameter follows:
5189 % o wand: the drawing wand.
5191 % o stroke_wand: stroke wand.
5194 WandExport void DrawSetStrokeColor(DrawingWand *wand,
5195 const PixelWand *stroke_wand)
5202 assert(wand != (DrawingWand *) NULL);
5203 assert(wand->signature == WandSignature);
5204 if (wand->debug != MagickFalse)
5205 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5206 assert(stroke_wand != (const PixelWand *) NULL);
5207 PixelGetQuantumColor(stroke_wand,&stroke_color);
5208 new_stroke=stroke_color;
5209 current_stroke=(&CurrentContext->stroke);
5210 if ((wand->filter_off != MagickFalse) ||
5211 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5213 CurrentContext->stroke=new_stroke;
5214 (void) MvgPrintf(wand,"stroke '");
5215 MvgAppendColor(wand,&stroke_color);
5216 (void) MvgPrintf(wand,"'\n");
5221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5225 % D r a w S e t S t r o k e P a t t e r n U R L %
5229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5231 % DrawSetStrokePatternURL() sets the pattern used for stroking object outlines.
5233 % The format of the DrawSetStrokePatternURL method is:
5235 % MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5236 % const char *stroke_url)
5238 % A description of each parameter follows:
5240 % o wand: the drawing wand.
5242 % o stroke_url: URL specifying pattern ID (e.g. "#pattern_id")
5245 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand,
5246 const char *stroke_url)
5249 pattern[MaxTextExtent],
5250 pattern_spec[MaxTextExtent];
5252 assert(wand != (DrawingWand *) NULL);
5253 assert(wand->signature == WandSignature);
5254 if (wand->debug != MagickFalse)
5255 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5256 if (wand->image == (Image *) NULL)
5257 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
5258 assert(stroke_url != NULL);
5259 if (stroke_url[0] != '#')
5260 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url);
5261 (void) FormatMagickString(pattern,MaxTextExtent,"%s",stroke_url+1);
5262 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL)
5264 ThrowDrawException(DrawError,"URLNotFound",stroke_url)
5265 return(MagickFalse);
5267 (void) FormatMagickString(pattern_spec,MaxTextExtent,"url(%s)",stroke_url);
5268 #if DRAW_BINARY_IMPLEMENTATION
5269 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5270 &CurrentContext->stroke_pattern);
5272 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5273 CurrentContext->stroke.opacity=CurrentContext->opacity;
5274 (void) MvgPrintf(wand,"stroke %s\n",pattern_spec);
5279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5283 % D r a w S e t S t r o k e A n t i a l i a s %
5287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5289 % DrawSetStrokeAntialias() controls whether stroked outlines are antialiased.
5290 % Stroked outlines are antialiased by default. When antialiasing is disabled
5291 % stroked pixels are thresholded to determine if the stroke color or
5292 % underlying canvas color should be used.
5294 % The format of the DrawSetStrokeAntialias method is:
5296 % void DrawSetStrokeAntialias(DrawingWand *wand,
5297 % const MagickBooleanType stroke_antialias)
5299 % A description of each parameter follows:
5301 % o wand: the drawing wand.
5303 % o stroke_antialias: set to false (zero) to disable antialiasing
5306 WandExport void DrawSetStrokeAntialias(DrawingWand *wand,
5307 const MagickBooleanType stroke_antialias)
5309 assert(wand != (DrawingWand *) NULL);
5310 assert(wand->signature == WandSignature);
5311 if (wand->debug != MagickFalse)
5312 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5313 if ((wand->filter_off != MagickFalse) ||
5314 (CurrentContext->stroke_antialias != stroke_antialias))
5316 CurrentContext->stroke_antialias=stroke_antialias;
5317 (void) MvgPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ?
5323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5327 % D r a w S e t S t r o k e D a s h A r r a y %
5331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5333 % DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to
5334 % stroke paths. The stroke dash array represents an array of numbers that
5335 % specify the lengths of alternating dashes and gaps in pixels. If an odd
5336 % number of values is provided, then the list of values is repeated to yield
5337 % an even number of values. To remove an existing dash array, pass a zero
5338 % number_elements argument and null dash_array. A typical stroke dash array
5339 % might contain the members 5 3 2.
5341 % The format of the DrawSetStrokeDashArray method is:
5343 % MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5344 % const unsigned long number_elements,const double *dash_array)
5346 % A description of each parameter follows:
5348 % o wand: the drawing wand.
5350 % o number_elements: number of elements in dash array
5352 % o dash_array: dash array values
5355 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand,
5356 const unsigned long number_elements,const double *dash_array)
5361 register const double
5374 assert(wand != (DrawingWand *) NULL);
5375 assert(wand->signature == WandSignature);
5376 if (wand->debug != MagickFalse)
5377 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5378 n_new=number_elements;
5381 q=CurrentContext->dash_pattern;
5382 if (q != (const double *) NULL)
5385 if ((n_old == 0) && (n_new == 0))
5391 if ((CurrentContext->dash_pattern != (double *) NULL) &&
5392 (dash_array != (double *) NULL))
5395 q=CurrentContext->dash_pattern;
5396 for (i=0; i < (long) n_new; i++)
5398 if (fabs((*p)-(*q)) > MagickEpsilon)
5407 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5409 if (CurrentContext->dash_pattern != (double *) NULL)
5410 CurrentContext->dash_pattern=(double *)
5411 RelinquishMagickMemory(CurrentContext->dash_pattern);
5414 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t)
5415 n_new+1UL,sizeof(*CurrentContext->dash_pattern));
5416 if (!CurrentContext->dash_pattern)
5418 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
5420 return(MagickFalse);
5422 q=CurrentContext->dash_pattern;
5424 for (i=0; i < (long) n_new; i++)
5428 (void) MvgPrintf(wand,"stroke-dasharray ");
5430 (void) MvgPrintf(wand,"none\n");
5434 (void) MvgPrintf(wand,"%g",*p++);
5435 for (i=1; i < (long) n_new; i++)
5436 (void) MvgPrintf(wand,",%g",*p++);
5437 (void) MvgPrintf(wand,"\n");
5444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5448 % D r a w S e t S t r o k e D a s h O f f s e t %
5452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5454 % DrawSetStrokeDashOffset() specifies the offset into the dash pattern to
5457 % The format of the DrawSetStrokeDashOffset method is:
5459 % void DrawSetStrokeDashOffset(DrawingWand *wand,
5460 % const double dash_offset)
5462 % A description of each parameter follows:
5464 % o wand: the drawing wand.
5466 % o dash_offset: dash offset
5469 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand,
5470 const double dash_offset)
5472 assert(wand != (DrawingWand *) NULL);
5473 assert(wand->signature == WandSignature);
5474 if (wand->debug != MagickFalse)
5475 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5476 if ((wand->filter_off != MagickFalse) ||
5477 (fabs(CurrentContext->dash_offset-dash_offset) > MagickEpsilon))
5479 CurrentContext->dash_offset=dash_offset;
5480 (void) MvgPrintf(wand,"stroke-dashoffset %g\n",dash_offset);
5485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5489 % D r a w S e t S t r o k e L i n e C a p %
5493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5495 % DrawSetStrokeLineCap() specifies the shape to be used at the end of
5496 % open subpaths when they are stroked. Values of LineCap are
5497 % UndefinedCap, ButtCap, RoundCap, and SquareCap.
5499 % The format of the DrawSetStrokeLineCap method is:
5501 % void DrawSetStrokeLineCap(DrawingWand *wand,
5502 % const LineCap linecap)
5504 % A description of each parameter follows:
5506 % o wand: the drawing wand.
5508 % o linecap: linecap style
5511 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap)
5513 assert(wand != (DrawingWand *) NULL);
5514 assert(wand->signature == WandSignature);
5515 if (wand->debug != MagickFalse)
5516 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5517 if ((wand->filter_off != MagickFalse) ||
5518 (CurrentContext->linecap != linecap))
5520 CurrentContext->linecap=linecap;
5521 (void) MvgPrintf(wand,"stroke-linecap '%s'\n",MagickOptionToMnemonic(
5522 MagickLineCapOptions,(long) linecap));
5527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5531 % D r a w S e t S t r o k e L i n e J o i n %
5535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5537 % DrawSetStrokeLineJoin() specifies the shape to be used at the corners of
5538 % paths (or other vector shapes) when they are stroked. Values of LineJoin are
5539 % UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
5541 % The format of the DrawSetStrokeLineJoin method is:
5543 % void DrawSetStrokeLineJoin(DrawingWand *wand,
5544 % const LineJoin linejoin)
5546 % A description of each parameter follows:
5548 % o wand: the drawing wand.
5550 % o linejoin: line join style
5553 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin)
5555 assert(wand != (DrawingWand *) NULL);
5556 assert(wand->signature == WandSignature);
5557 if (wand->debug != MagickFalse)
5558 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5559 if ((wand->filter_off != MagickFalse) ||
5560 (CurrentContext->linejoin != linejoin))
5562 CurrentContext->linejoin=linejoin;
5563 (void) MvgPrintf(wand, "stroke-linejoin '%s'\n",MagickOptionToMnemonic(
5564 MagickLineJoinOptions,(long) linejoin));
5569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5573 % D r a w S e t S t r o k e M i t e r L i m i t %
5577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5579 % DrawSetStrokeMiterLimit() specifies the miter limit. When two line
5580 % segments meet at a sharp angle and miter joins have been specified for
5581 % 'lineJoin', it is possible for the miter to extend far beyond the
5582 % thickness of the line stroking the path. The miterLimit' imposes a
5583 % limit on the ratio of the miter length to the 'lineWidth'.
5585 % The format of the DrawSetStrokeMiterLimit method is:
5587 % void DrawSetStrokeMiterLimit(DrawingWand *wand,
5588 % const unsigned long miterlimit)
5590 % A description of each parameter follows:
5592 % o wand: the drawing wand.
5594 % o miterlimit: miter limit
5597 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand,
5598 const unsigned long miterlimit)
5600 assert(wand != (DrawingWand *) NULL);
5601 assert(wand->signature == WandSignature);
5602 if (wand->debug != MagickFalse)
5603 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5604 if (CurrentContext->miterlimit != miterlimit)
5606 CurrentContext->miterlimit=miterlimit;
5607 (void) MvgPrintf(wand,"stroke-miterlimit %lu\n",miterlimit);
5612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5616 % D r a w S e t S t r o k e O p a c i t y %
5620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5622 % DrawSetStrokeOpacity() specifies the opacity of stroked object outlines.
5624 % The format of the DrawSetStrokeOpacity method is:
5626 % void DrawSetStrokeOpacity(DrawingWand *wand,
5627 % const double stroke_opacity)
5629 % A description of each parameter follows:
5631 % o wand: the drawing wand.
5633 % o stroke_opacity: stroke opacity. The value 1.0 is opaque.
5636 WandExport void DrawSetStrokeOpacity(DrawingWand *wand,
5637 const double stroke_opacity)
5642 assert(wand != (DrawingWand *) NULL);
5643 assert(wand->signature == WandSignature);
5644 if (wand->debug != MagickFalse)
5645 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5646 opacity=RoundToQuantum((double) QuantumRange*(1.0-stroke_opacity));
5647 if ((wand->filter_off != MagickFalse) ||
5648 (CurrentContext->stroke.opacity != opacity))
5650 CurrentContext->stroke.opacity=opacity;
5651 (void) MvgPrintf(wand,"stroke-opacity %g\n",stroke_opacity);
5656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5660 % D r a w S e t S t r o k e W i d t h %
5664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5666 % DrawSetStrokeWidth() sets the width of the stroke used to draw object
5669 % The format of the DrawSetStrokeWidth method is:
5671 % void DrawSetStrokeWidth(DrawingWand *wand,
5672 % const double stroke_width)
5674 % A description of each parameter follows:
5676 % o wand: the drawing wand.
5678 % o stroke_width: stroke width
5681 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width)
5683 assert(wand != (DrawingWand *) NULL);
5684 assert(wand->signature == WandSignature);
5685 if (wand->debug != MagickFalse)
5686 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5687 if ((wand->filter_off != MagickFalse) ||
5688 (fabs(CurrentContext->stroke_width-stroke_width) > MagickEpsilon))
5690 CurrentContext->stroke_width=stroke_width;
5691 (void) MvgPrintf(wand,"stroke-width %g\n",stroke_width);
5696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5700 % D r a w S e t T e x t A l i g n m e n t %
5704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5706 % DrawSetTextAlignment() specifies a text alignment to be applied when
5707 % annotating with text.
5709 % The format of the DrawSetTextAlignment method is:
5711 % void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment)
5713 % A description of each parameter follows:
5715 % o wand: the drawing wand.
5717 % o alignment: text alignment. One of UndefinedAlign, LeftAlign,
5718 % CenterAlign, or RightAlign.
5721 WandExport void DrawSetTextAlignment(DrawingWand *wand,
5722 const AlignType alignment)
5724 assert(wand != (DrawingWand *) NULL);
5725 assert(wand->signature == WandSignature);
5726 if (wand->debug != MagickFalse)
5727 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5728 if ((wand->filter_off != MagickFalse) ||
5729 (CurrentContext->align != alignment))
5731 CurrentContext->align=alignment;
5732 (void) MvgPrintf(wand,"text-align '%s'\n",MagickOptionToMnemonic(
5733 MagickAlignOptions,(long) alignment));
5738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5742 % D r a w S e t T e x t A n t i a l i a s %
5746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5748 % DrawSetTextAntialias() controls whether text is antialiased. Text is
5749 % antialiased by default.
5751 % The format of the DrawSetTextAntialias method is:
5753 % void DrawSetTextAntialias(DrawingWand *wand,
5754 % const MagickBooleanType text_antialias)
5756 % A description of each parameter follows:
5758 % o wand: the drawing wand.
5760 % o text_antialias: antialias boolean. Set to false (0) to disable
5764 WandExport void DrawSetTextAntialias(DrawingWand *wand,
5765 const MagickBooleanType text_antialias)
5767 assert(wand != (DrawingWand *) NULL);
5768 assert(wand->signature == WandSignature);
5769 if (wand->debug != MagickFalse)
5770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5771 if ((wand->filter_off != MagickFalse) ||
5772 (CurrentContext->text_antialias != text_antialias))
5774 CurrentContext->text_antialias=text_antialias;
5775 (void) MvgPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5784 % D r a w S e t T e x t D e c o r a t i o n %
5788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5790 % DrawSetTextDecoration() specifies a decoration to be applied when
5791 % annotating with text.
5793 % The format of the DrawSetTextDecoration method is:
5795 % void DrawSetTextDecoration(DrawingWand *wand,
5796 % const DecorationType decoration)
5798 % A description of each parameter follows:
5800 % o wand: the drawing wand.
5802 % o decoration: text decoration. One of NoDecoration, UnderlineDecoration,
5803 % OverlineDecoration, or LineThroughDecoration
5806 WandExport void DrawSetTextDecoration(DrawingWand *wand,
5807 const DecorationType decoration)
5809 assert(wand != (DrawingWand *) NULL);
5810 assert(wand->signature == WandSignature);
5811 if (wand->debug != MagickFalse)
5812 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5813 if ((wand->filter_off != MagickFalse) ||
5814 (CurrentContext->decorate != decoration))
5816 CurrentContext->decorate=decoration;
5817 (void) MvgPrintf(wand,"decorate '%s'\n",MagickOptionToMnemonic(
5818 MagickDecorateOptions,(long) decoration));
5823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5827 % D r a w S e t T e x t E n c o d i n g %
5831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5833 % DrawSetTextEncoding() specifies the code set to use for text
5834 % annotations. The only character encoding which may be specified
5835 % at this time is "UTF-8" for representing Unicode as a sequence of
5836 % bytes. Specify an empty string to set text encoding to the system's
5837 % default. Successful text annotation using Unicode may require fonts
5838 % designed to support Unicode.
5840 % The format of the DrawSetTextEncoding method is:
5842 % void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5844 % A description of each parameter follows:
5846 % o wand: the drawing wand.
5848 % o encoding: character string specifying text encoding
5851 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding)
5853 assert(wand != (DrawingWand *) NULL);
5854 assert(wand->signature == WandSignature);
5855 if (wand->debug != MagickFalse)
5856 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5857 assert(encoding != (char *) NULL);
5858 if ((wand->filter_off != MagickFalse) ||
5859 (CurrentContext->encoding == (char *) NULL) ||
5860 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
5862 (void) CloneString(&CurrentContext->encoding,encoding);
5863 (void) MvgPrintf(wand,"encoding '%s'\n",encoding);
5868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5872 % D r a w S e t T e x t K e r n i n g %
5876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5878 % DrawSetTextKerning() sets the spacing between characters in text.
5880 % The format of the DrawSetTextKerning method is:
5882 % void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5884 % A description of each parameter follows:
5886 % o wand: the drawing wand.
5888 % o kerning: text kerning
5891 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning)
5893 assert(wand != (DrawingWand *) NULL);
5894 assert(wand->signature == WandSignature);
5896 if (wand->debug != MagickFalse)
5897 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5898 if ((wand->filter_off != MagickFalse) &&
5899 (CurrentContext->kerning != kerning))
5901 CurrentContext->kerning=kerning;
5902 (void) MvgPrintf(wand,"kerning %lf\n",kerning);
5907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5911 % 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 %
5915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5917 % DrawSetTextInterwordSpacing() sets the spacing between line in text.
5919 % The format of the DrawSetInterwordSpacing method is:
5921 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
5922 % const double interline_spacing)
5924 % A description of each parameter follows:
5926 % o wand: the drawing wand.
5928 % o interline_spacing: text line spacing
5931 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand,
5932 const double interline_spacing)
5934 assert(wand != (DrawingWand *) NULL);
5935 assert(wand->signature == WandSignature);
5937 if (wand->debug != MagickFalse)
5938 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5939 if ((wand->filter_off != MagickFalse) &&
5940 (CurrentContext->interline_spacing != interline_spacing))
5942 CurrentContext->interline_spacing=interline_spacing;
5943 (void) MvgPrintf(wand,"interline-spacing %lf\n",interline_spacing);
5948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5952 % 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 %
5956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5958 % DrawSetTextInterwordSpacing() sets the spacing between words in text.
5960 % The format of the DrawSetInterwordSpacing method is:
5962 % void DrawSetTextInterwordSpacing(DrawingWand *wand,
5963 % const double interword_spacing)
5965 % A description of each parameter follows:
5967 % o wand: the drawing wand.
5969 % o interword_spacing: text word spacing
5972 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand,
5973 const double interword_spacing)
5975 assert(wand != (DrawingWand *) NULL);
5976 assert(wand->signature == WandSignature);
5978 if (wand->debug != MagickFalse)
5979 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
5980 if ((wand->filter_off != MagickFalse) &&
5981 (CurrentContext->interword_spacing != interword_spacing))
5983 CurrentContext->interword_spacing=interword_spacing;
5984 (void) MvgPrintf(wand,"interword-spacing %lf\n",interword_spacing);
5989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5993 % D r a w S e t T e x t U n d e r C o l o r %
5997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5999 % DrawSetTextUnderColor() specifies the color of a background rectangle
6000 % to place under text annotations.
6002 % The format of the DrawSetTextUnderColor method is:
6004 % void DrawSetTextUnderColor(DrawingWand *wand,
6005 % const PixelWand *under_wand)
6007 % A description of each parameter follows:
6009 % o wand: the drawing wand.
6011 % o under_wand: text under wand.
6014 WandExport void DrawSetTextUnderColor(DrawingWand *wand,
6015 const PixelWand *under_wand)
6020 assert(wand != (DrawingWand *) NULL);
6021 assert(wand->signature == WandSignature);
6022 if (wand->debug != MagickFalse)
6023 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6024 assert(under_wand != (const PixelWand *) NULL);
6025 PixelGetQuantumColor(under_wand,&under_color);
6026 if ((wand->filter_off != MagickFalse) ||
6027 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6029 CurrentContext->undercolor=under_color;
6030 (void) MvgPrintf(wand,"text-undercolor '");
6031 MvgAppendColor(wand,&under_color);
6032 (void) MvgPrintf(wand,"'\n");
6037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6041 % D r a w S e t V e c t o r G r a p h i c s %
6045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6047 % DrawSetVectorGraphics() sets the vector graphics associated with the
6048 % specified wand. Use this method with DrawGetVectorGraphics() as a method
6049 % to persist the vector graphics state.
6051 % The format of the DrawSetVectorGraphics method is:
6053 % MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6056 % A description of each parameter follows:
6058 % o wand: the drawing wand.
6060 % o xml: the drawing wand XML.
6064 static inline MagickBooleanType IsPoint(const char *point)
6072 value=strtol(point,&p,10);
6073 return(p != point ? MagickTrue : MagickFalse);
6076 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand,
6086 assert(wand != (DrawingWand *) NULL);
6087 assert(wand->signature == WandSignature);
6088 if (wand->debug != MagickFalse)
6089 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6090 CurrentContext=DestroyDrawInfo(CurrentContext);
6091 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6092 if (xml == (const char *) NULL)
6093 return(MagickFalse);
6094 xml_info=NewXMLTree(xml,wand->exception);
6095 if (xml_info == (XMLTreeInfo *) NULL)
6096 return(MagickFalse);
6097 child=GetXMLTreeChild(xml_info,"clip-path");
6098 if (child != (XMLTreeInfo *) NULL)
6099 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6100 child=GetXMLTreeChild(xml_info,"clip-units");
6101 if (child != (XMLTreeInfo *) NULL)
6103 value=GetXMLTreeContent(child);
6104 if (value != (const char *) NULL)
6105 CurrentContext->clip_units=(ClipPathUnits) ParseMagickOption(
6106 MagickClipPathOptions,MagickFalse,value);
6108 child=GetXMLTreeChild(xml_info,"decorate");
6109 if (child != (XMLTreeInfo *) NULL)
6111 value=GetXMLTreeContent(child);
6112 if (value != (const char *) NULL)
6113 CurrentContext->decorate=(DecorationType) ParseMagickOption(
6114 MagickDecorateOptions,MagickFalse,value);
6116 child=GetXMLTreeChild(xml_info,"encoding");
6117 if (child != (XMLTreeInfo *) NULL)
6118 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6119 child=GetXMLTreeChild(xml_info,"fill");
6120 if (child != (XMLTreeInfo *) NULL)
6122 value=GetXMLTreeContent(child);
6123 if (value != (const char *) NULL)
6124 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6126 child=GetXMLTreeChild(xml_info,"fill-opacity");
6127 if (child != (XMLTreeInfo *) NULL)
6129 value=GetXMLTreeContent(child);
6130 if (value != (const char *) NULL)
6131 CurrentContext->fill.opacity=RoundToQuantum((MagickRealType)
6132 QuantumRange*(1.0-StringToDouble(value)));
6134 child=GetXMLTreeChild(xml_info,"fill-rule");
6135 if (child != (XMLTreeInfo *) NULL)
6137 value=GetXMLTreeContent(child);
6138 if (value != (const char *) NULL)
6139 CurrentContext->fill_rule=(FillRule) ParseMagickOption(
6140 MagickFillRuleOptions,MagickFalse,value);
6142 child=GetXMLTreeChild(xml_info,"font");
6143 if (child != (XMLTreeInfo *) NULL)
6144 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6145 child=GetXMLTreeChild(xml_info,"font-family");
6146 if (child != (XMLTreeInfo *) NULL)
6147 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6148 child=GetXMLTreeChild(xml_info,"font-size");
6149 if (child != (XMLTreeInfo *) NULL)
6151 value=GetXMLTreeContent(child);
6152 if (value != (const char *) NULL)
6153 CurrentContext->pointsize=StringToDouble(value);
6155 child=GetXMLTreeChild(xml_info,"font-stretch");
6156 if (child != (XMLTreeInfo *) NULL)
6158 value=GetXMLTreeContent(child);
6159 if (value != (const char *) NULL)
6160 CurrentContext->stretch=(StretchType) ParseMagickOption(
6161 MagickStretchOptions,MagickFalse,value);
6163 child=GetXMLTreeChild(xml_info,"font-style");
6164 if (child != (XMLTreeInfo *) NULL)
6166 value=GetXMLTreeContent(child);
6167 if (value != (const char *) NULL)
6168 CurrentContext->style=(StyleType) ParseMagickOption(MagickStyleOptions,
6171 child=GetXMLTreeChild(xml_info,"font-weight");
6172 if (child != (XMLTreeInfo *) NULL)
6174 value=GetXMLTreeContent(child);
6175 if (value != (const char *) NULL)
6176 CurrentContext->weight=StringToUnsignedLong(value);
6178 child=GetXMLTreeChild(xml_info,"gravity");
6179 if (child != (XMLTreeInfo *) NULL)
6181 value=GetXMLTreeContent(child);
6182 if (value != (const char *) NULL)
6183 CurrentContext->gravity=(GravityType) ParseMagickOption(
6184 MagickGravityOptions,MagickFalse,value);
6186 child=GetXMLTreeChild(xml_info,"stroke");
6187 if (child != (XMLTreeInfo *) NULL)
6189 value=GetXMLTreeContent(child);
6190 if (value != (const char *) NULL)
6191 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6194 child=GetXMLTreeChild(xml_info,"stroke-antialias");
6195 if (child != (XMLTreeInfo *) NULL)
6197 value=GetXMLTreeContent(child);
6198 if (value != (const char *) NULL)
6199 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6202 child=GetXMLTreeChild(xml_info,"stroke-dasharray");
6203 if (child != (XMLTreeInfo *) NULL)
6206 token[MaxTextExtent];
6217 value=GetXMLTreeContent(child);
6218 if (value != (const char *) NULL)
6220 if (CurrentContext->dash_pattern != (double *) NULL)
6221 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory(
6222 CurrentContext->dash_pattern);
6224 if (IsPoint(q) != MagickFalse)
6230 GetMagickToken(p,&p,token);
6232 GetMagickToken(p,&p,token);
6233 for (x=0; IsPoint(token) != MagickFalse; x++)
6235 GetMagickToken(p,&p,token);
6237 GetMagickToken(p,&p,token);
6239 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory(
6240 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern));
6241 if (CurrentContext->dash_pattern == (double *) NULL)
6242 ThrowWandFatalException(ResourceLimitFatalError,
6243 "MemoryAllocationFailed",wand->name);
6244 for (j=0; j < x; j++)
6246 GetMagickToken(q,&q,token);
6248 GetMagickToken(q,&q,token);
6249 CurrentContext->dash_pattern[j]=StringToDouble(token);
6251 if ((x & 0x01) != 0)
6252 for ( ; j < (2*x); j++)
6253 CurrentContext->dash_pattern[j]=
6254 CurrentContext->dash_pattern[j-x];
6255 CurrentContext->dash_pattern[j]=0.0;
6259 child=GetXMLTreeChild(xml_info,"stroke-dashoffset");
6260 if (child != (XMLTreeInfo *) NULL)
6262 value=GetXMLTreeContent(child);
6263 if (value != (const char *) NULL)
6264 CurrentContext->dash_offset=StringToDouble(value);
6266 child=GetXMLTreeChild(xml_info,"stroke-linecap");
6267 if (child != (XMLTreeInfo *) NULL)
6269 value=GetXMLTreeContent(child);
6270 if (value != (const char *) NULL)
6271 CurrentContext->linecap=(LineCap) ParseMagickOption(
6272 MagickLineCapOptions,MagickFalse,value);
6274 child=GetXMLTreeChild(xml_info,"stroke-linejoin");
6275 if (child != (XMLTreeInfo *) NULL)
6277 value=GetXMLTreeContent(child);
6278 if (value != (const char *) NULL)
6279 CurrentContext->linejoin=(LineJoin) ParseMagickOption(
6280 MagickLineJoinOptions,MagickFalse,value);
6282 child=GetXMLTreeChild(xml_info,"stroke-miterlimit");
6283 if (child != (XMLTreeInfo *) NULL)
6285 value=GetXMLTreeContent(child);
6286 if (value != (const char *) NULL)
6287 CurrentContext->miterlimit=StringToUnsignedLong(value);
6289 child=GetXMLTreeChild(xml_info,"stroke-opacity");
6290 if (child != (XMLTreeInfo *) NULL)
6292 value=GetXMLTreeContent(child);
6293 if (value != (const char *) NULL)
6294 CurrentContext->stroke.opacity=RoundToQuantum((MagickRealType)
6295 QuantumRange*(1.0-StringToDouble(value)));
6297 child=GetXMLTreeChild(xml_info,"stroke-width");
6298 if (child != (XMLTreeInfo *) NULL)
6300 value=GetXMLTreeContent(child);
6301 if (value != (const char *) NULL)
6302 CurrentContext->stroke_width=StringToDouble(value);
6304 child=GetXMLTreeChild(xml_info,"text-align");
6305 if (child != (XMLTreeInfo *) NULL)
6307 value=GetXMLTreeContent(child);
6308 if (value != (const char *) NULL)
6309 CurrentContext->align=(AlignType) ParseMagickOption(MagickAlignOptions,
6312 child=GetXMLTreeChild(xml_info,"text-antialias");
6313 if (child != (XMLTreeInfo *) NULL)
6315 value=GetXMLTreeContent(child);
6316 if (value != (const char *) NULL)
6317 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6320 child=GetXMLTreeChild(xml_info,"text-undercolor");
6321 if (child != (XMLTreeInfo *) NULL)
6323 value=GetXMLTreeContent(child);
6324 if (value != (const char *) NULL)
6325 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6328 child=GetXMLTreeChild(xml_info,"vector-graphics");
6329 if (child != (XMLTreeInfo *) NULL)
6331 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6332 wand->mvg_length=strlen(wand->mvg);
6333 wand->mvg_alloc=wand->mvg_length+1;
6335 xml_info=DestroyXMLTree(xml_info);
6340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6344 % D r a w S k e w X %
6348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6350 % DrawSkewX() skews the current coordinate system in the horizontal
6353 % The format of the DrawSkewX method is:
6355 % void DrawSkewX(DrawingWand *wand,const double degrees)
6357 % A description of each parameter follows:
6359 % o wand: the drawing wand.
6361 % o degrees: number of degrees to skew the coordinates
6364 WandExport void DrawSkewX(DrawingWand *wand,const double degrees)
6369 assert(wand != (DrawingWand *) NULL);
6370 assert(wand->signature == WandSignature);
6371 if (wand->debug != MagickFalse)
6372 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6373 GetAffineMatrix(&affine);
6374 affine.ry=tan(DegreesToRadians(fmod(degrees,360.0)));
6375 AdjustAffine(wand,&affine);
6376 (void) MvgPrintf(wand,"skewX %g\n",degrees);
6380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6384 % D r a w S k e w Y %
6388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6390 % DrawSkewY() skews the current coordinate system in the vertical
6393 % The format of the DrawSkewY method is:
6395 % void DrawSkewY(DrawingWand *wand,const double degrees)
6397 % A description of each parameter follows:
6399 % o wand: the drawing wand.
6401 % o degrees: number of degrees to skew the coordinates
6404 WandExport void DrawSkewY(DrawingWand *wand,const double degrees)
6409 assert(wand != (DrawingWand *) NULL);
6410 assert(wand->signature == WandSignature);
6411 if (wand->debug != MagickFalse)
6412 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6413 GetAffineMatrix(&affine);
6414 affine.rx=tan(DegreesToRadians(fmod(degrees,360.0)));
6415 DrawAffine(wand,&affine);
6416 (void) MvgPrintf(wand,"skewY %g\n",degrees);
6420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6424 % D r a w T r a n s l a t e %
6428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6430 % DrawTranslate() applies a translation to the current coordinate
6431 % system which moves the coordinate system origin to the specified
6434 % The format of the DrawTranslate method is:
6436 % void DrawTranslate(DrawingWand *wand,const double x,
6439 % A description of each parameter follows:
6441 % o wand: the drawing wand.
6443 % o x: new x ordinate for coordinate system origin
6445 % o y: new y ordinate for coordinate system origin
6448 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y)
6453 assert(wand != (DrawingWand *) NULL);
6454 assert(wand->signature == WandSignature);
6455 if (wand->debug != MagickFalse)
6456 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6457 GetAffineMatrix(&affine);
6460 AdjustAffine(wand,&affine);
6461 (void) MvgPrintf(wand,"translate %g,%g\n",x,y);
6465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6469 % D r a w S e t V i e w b o x %
6473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6475 % DrawSetViewbox() sets the overall canvas size to be recorded with the
6476 % drawing vector data. Usually this will be specified using the same
6477 % size as the canvas image. When the vector data is saved to SVG or MVG
6478 % formats, the viewbox is use to specify the size of the canvas image that
6479 % a viewer will render the vector data on.
6481 % The format of the DrawSetViewbox method is:
6483 % void DrawSetViewbox(DrawingWand *wand,unsigned long x1,
6484 % unsigned long y1,unsigned long x2,unsigned long y2)
6486 % A description of each parameter follows:
6488 % o wand: the drawing wand.
6490 % o x1: left x ordinate
6492 % o y1: top y ordinate
6494 % o x2: right x ordinate
6496 % o y2: bottom y ordinate
6499 WandExport void DrawSetViewbox(DrawingWand *wand,unsigned long x1,
6500 unsigned long y1,unsigned long x2,unsigned long y2)
6502 assert(wand != (DrawingWand *) NULL);
6503 assert(wand->signature == WandSignature);
6504 if (wand->debug != MagickFalse)
6505 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6506 (void) MvgPrintf(wand,"viewbox %lu %lu %lu %lu\n",x1,y1,x2,y2);
6510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6514 % I s D r a w i n g W a n d %
6518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6520 % IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand.
6522 % The format of the IsDrawingWand method is:
6524 % MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6526 % A description of each parameter follows:
6528 % o wand: the drawing wand.
6531 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand)
6533 if (wand == (const DrawingWand *) NULL)
6534 return(MagickFalse);
6535 if (wand->signature != WandSignature)
6536 return(MagickFalse);
6537 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6538 return(MagickFalse);
6543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6547 % N e w D r a w i n g W a n d %
6551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6553 % NewDrawingWand() returns a drawing wand required for all other methods in
6556 % The format of the NewDrawingWand method is:
6558 % DrawingWand NewDrawingWand(void)
6561 WandExport DrawingWand *NewDrawingWand(void)
6572 quantum=GetMagickQuantumDepth(&depth);
6573 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6574 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
6575 wand=(DrawingWand *) AcquireAlignedMemory(1,sizeof(*wand));
6576 if (wand == (DrawingWand *) NULL)
6577 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6578 GetExceptionMessage(errno));
6579 (void) ResetMagickMemory(wand,0,sizeof(*wand));
6580 wand->id=AcquireWandId();
6581 (void) FormatMagickString(wand->name,MaxTextExtent,"%s-%lu",DrawingWandId,
6583 if (wand->debug != MagickFalse)
6584 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6585 wand->mvg=(char *) NULL;
6589 wand->pattern_id=(char *) NULL;
6590 wand->pattern_offset=0;
6591 wand->pattern_bounds.x=0;
6592 wand->pattern_bounds.y=0;
6593 wand->pattern_bounds.width=0;
6594 wand->pattern_bounds.height=0;
6596 wand->graphic_context=(DrawInfo **) AcquireAlignedMemory(1,sizeof(
6597 *wand->graphic_context));
6598 if (wand->graphic_context == (DrawInfo **) NULL)
6599 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
6600 GetExceptionMessage(errno));
6601 wand->filter_off=MagickTrue;
6602 wand->indent_depth=0;
6603 wand->path_operation=PathDefaultOperation;
6604 wand->path_mode=DefaultPathMode;
6605 wand->image=AcquireImage((const ImageInfo *) NULL);
6606 wand->exception=AcquireExceptionInfo();
6607 wand->destroy=MagickTrue;
6608 wand->debug=IsEventLogging();
6609 wand->signature=WandSignature;
6610 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6619 % P e e k D r a w i n g W a n d %
6623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6625 % PeekDrawingWand() returns the current drawing wand.
6627 % The format of the PeekDrawingWand method is:
6629 % DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6631 % A description of each parameter follows:
6633 % o wand: the drawing wand.
6636 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand)
6641 assert(wand != (const DrawingWand *) NULL);
6642 assert(wand->signature == WandSignature);
6643 if (wand->debug != MagickFalse)
6644 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6645 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6646 GetAffineMatrix(&draw_info->affine);
6647 (void) CloneString(&draw_info->primitive,wand->mvg);
6652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6656 % P o p D r a w i n g W a n d %
6660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6662 % PopDrawingWand() destroys the current drawing wand and returns to the
6663 % previously pushed drawing wand. Multiple drawing wands may exist. It is an
6664 % error to attempt to pop more drawing wands than have been pushed, and it is
6665 % proper form to pop all drawing wands which have been pushed.
6667 % The format of the PopDrawingWand method is:
6669 % MagickBooleanType PopDrawingWand(DrawingWand *wand)
6671 % A description of each parameter follows:
6673 % o wand: the drawing wand.
6676 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand)
6678 assert(wand != (DrawingWand *) NULL);
6679 assert(wand->signature == WandSignature);
6680 if (wand->debug != MagickFalse)
6681 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6682 if (wand->index == 0)
6684 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name)
6685 return(MagickFalse);
6688 Destroy clip path if not same in preceding wand.
6690 #if DRAW_BINARY_IMPLEMENTATION
6691 if (wand->image == (Image *) NULL)
6692 ThrowDrawException(WandError,"ContainsNoImages",wand->name);
6693 if (CurrentContext->clip_mask != (char *) NULL)
6694 if (LocaleCompare(CurrentContext->clip_mask,
6695 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6696 (void) SetImageClipMask(wand->image,(Image *) NULL);
6698 CurrentContext=DestroyDrawInfo(CurrentContext);
6700 if (wand->indent_depth > 0)
6701 wand->indent_depth--;
6702 (void) MvgPrintf(wand,"pop graphic-context\n");
6707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6711 % P u s h D r a w i n g W a n d %
6715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6717 % PushDrawingWand() clones the current drawing wand to create a new drawing
6718 % wand. The original drawing wand(s) may be returned to by invoking
6719 % PopDrawingWand(). The drawing wands are stored on a drawing wand stack.
6720 % For every Pop there must have already been an equivalent Push.
6722 % The format of the PushDrawingWand method is:
6724 % MagickBooleanType PushDrawingWand(DrawingWand *wand)
6726 % A description of each parameter follows:
6728 % o wand: the drawing wand.
6731 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand)
6733 assert(wand != (DrawingWand *) NULL);
6734 assert(wand->signature == WandSignature);
6735 if (wand->debug != MagickFalse)
6736 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
6738 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6739 (size_t) wand->index+1UL,sizeof(*wand->graphic_context));
6740 if (wand->graphic_context == (DrawInfo **) NULL)
6742 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed",
6744 return(MagickFalse);
6746 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6747 wand->graphic_context[wand->index-1]);
6748 (void) MvgPrintf(wand,"push graphic-context\n");
6749 wand->indent_depth++;