49#include "wand/studio.h"
50#include "wand/MagickWand.h"
51#include "wand/magick-wand-private.h"
53#include "magick/image-private.h"
54#include "magick/string-private.h"
59#define DRAW_BINARY_IMPLEMENTATION 0
61#define CurrentContext (wand->graphic_context[wand->index])
62#define DrawingWandId "DrawingWand"
63#define ThrowDrawException(severity,tag,reason) (void) ThrowMagickException( \
64 wand->exception,GetMagickModule(),severity,tag,"`%s'",reason);
74 PathCurveToQuadraticBezierOperation,
75 PathCurveToQuadraticBezierSmoothOperation,
76 PathCurveToSmoothOperation,
77 PathEllipticArcOperation,
78 PathLineToHorizontalOperation,
80 PathLineToVerticalOperation,
160 MVGPrintf(
DrawingWand *,
const char *,...) wand_attribute((format
162 MVGAutoWrapPrintf(
DrawingWand *,const
char *,...) wand_attribute((format
171static
int MVGPrintf(
DrawingWand *wand,const
char *format,...)
177 if (wand->debug != MagickFalse)
178 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",format);
179 assert(wand->signature == WandSignature);
180 extent=20UL*MaxTextExtent;
181 if (wand->mvg == (
char *) NULL)
183 wand->mvg=(
char *) AcquireQuantumMemory(extent,
sizeof(*wand->mvg));
184 if (wand->mvg == (
char *) NULL)
186 ThrowDrawException(ResourceLimitError,
"MemoryAllocationFailed",
190 wand->mvg_alloc=extent;
193 if (wand->mvg_alloc < (wand->mvg_length+10*MaxTextExtent))
195 extent+=wand->mvg_alloc;
196 wand->mvg=(
char *) ResizeQuantumMemory(wand->mvg,extent,
198 if (wand->mvg == (
char *) NULL)
200 ThrowDrawException(ResourceLimitError,
"MemoryAllocationFailed",
204 wand->mvg_alloc=extent;
216 while (wand->mvg_width < wand->indent_depth)
218 wand->mvg[wand->mvg_length]=
' ';
222 wand->mvg[wand->mvg_length]=
'\0';
224 offset=(ssize_t) wand->mvg_alloc-wand->mvg_length-1;
227 va_start(argp,format);
228#if defined(MAGICKCORE_HAVE_VSNPRINTF)
229 count=vsnprintf(wand->mvg+wand->mvg_length,(
size_t) offset,format,argp);
231 count=vsprintf(wand->mvg+wand->mvg_length,format,argp);
235 if ((count < 0) || (count > (
int) offset))
236 ThrowDrawException(DrawError,
"UnableToPrint",format)
239 wand->mvg_length+=count;
240 wand->mvg_width+=count;
242 wand->mvg[wand->mvg_length]=
'\0';
243 if ((wand->mvg_length > 1) && (wand->mvg[wand->mvg_length-1] ==
'\n'))
245 assert((wand->mvg_length+1) < wand->mvg_alloc);
250static int MVGAutoWrapPrintf(
DrawingWand *wand,
const char *format,...)
253 buffer[MaxTextExtent];
261 va_start(argp,format);
262#if defined(MAGICKCORE_HAVE_VSNPRINTF)
263 count=vsnprintf(buffer,
sizeof(buffer)-1,format,argp);
265 count=vsprintf(buffer,format,argp);
268 buffer[
sizeof(buffer)-1]=
'\0';
270 ThrowDrawException(DrawError,
"UnableToPrint",format)
273 if (((wand->mvg_width + count) > 78) && (buffer[count-1] !=
'\n'))
274 (void) MVGPrintf(wand,
"\n");
275 (void) MVGPrintf(wand,
"%s",buffer);
280static void MVGAppendColor(
DrawingWand *wand,
const PixelPacket *color)
282 if ((GetPixelRed(color) == 0) && (GetPixelGreen(color) == 0) &&
283 (GetPixelBlue(color) == 0) &&
284 (GetPixelOpacity(color) == (Quantum) TransparentOpacity))
285 (void) MVGPrintf(wand,
"none");
289 tuple[MaxTextExtent];
294 GetMagickPixelPacket(wand->image,&pixel);
295 pixel.colorspace=sRGBColorspace;
296 pixel.matte=color->opacity != OpaqueOpacity ? MagickTrue : MagickFalse;
297 pixel.red=(MagickRealType) GetPixelRed(color);
298 pixel.green=(MagickRealType) GetPixelGreen(color);
299 pixel.blue=(MagickRealType) GetPixelBlue(color);
300 pixel.opacity=(MagickRealType) GetPixelOpacity(color);
301 GetColorTuple(&pixel,MagickTrue,tuple);
302 (void) MVGPrintf(wand,
"%s",tuple);
306static void MVGAppendPointsCommand(
DrawingWand *wand,
const char *command,
307 const size_t number_coordinates,
const PointInfo *coordinates)
315 (void) MVGPrintf(wand,
"%s",command);
316 for (i=number_coordinates, coordinate=coordinates; i != 0; i--)
318 (void) MVGAutoWrapPrintf(wand,
" %.20g %.20g",coordinate->x,coordinate->y);
321 (void) MVGPrintf(wand,
"\n");
324static void AdjustAffine(
DrawingWand *wand,
const AffineMatrix *affine)
327 assert(wand->signature == WandSignature);
328 if (wand->debug != MagickFalse)
329 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
330 if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) ||
331 (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0))
336 current=CurrentContext->affine;
337 CurrentContext->affine.sx=affine->sx*current.sx+affine->ry*current.rx;
338 CurrentContext->affine.rx=affine->rx*current.sx+affine->sy*current.rx;
339 CurrentContext->affine.ry=affine->sx*current.ry+affine->ry*current.sy;
340 CurrentContext->affine.sy=affine->rx*current.ry+affine->sy*current.sy;
341 CurrentContext->affine.tx=affine->sx*current.tx+affine->ry*current.ty+
343 CurrentContext->affine.ty=affine->rx*current.tx+affine->sy*current.ty+
373WandExport
DrawingWand *AcquireDrawingWand(
const DrawInfo *draw_info,
379 wand=NewDrawingWand();
380 if (draw_info != (
const DrawInfo *) NULL)
382 CurrentContext=DestroyDrawInfo(CurrentContext);
383 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info);
385 wand->image=DestroyImage(wand->image);
386 if (image != (Image *) NULL)
387 wand->destroy=MagickFalse;
417 assert(wand->signature == WandSignature);
418 if (wand->debug != MagickFalse)
419 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
420 for ( ; wand->index > 0; wand->index--)
421 CurrentContext=DestroyDrawInfo(CurrentContext);
422 CurrentContext=DestroyDrawInfo(CurrentContext);
423 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
424 wand->graphic_context);
425 if (wand->pattern_id != (
char *) NULL)
426 wand->pattern_id=DestroyString(wand->pattern_id);
427 wand->mvg=DestroyString(wand->mvg);
428 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
429 wand->image=DestroyImage(wand->image);
431 wand->image=(Image *) NULL;
432 wand->mvg=(
char *) NULL;
436 wand->pattern_id=(
char *) NULL;
437 wand->pattern_offset=0;
438 wand->pattern_bounds.x=0;
439 wand->pattern_bounds.y=0;
440 wand->pattern_bounds.width=0;
441 wand->pattern_bounds.height=0;
443 wand->graphic_context=(DrawInfo **) AcquireQuantumMemory(1,
444 sizeof(*wand->graphic_context));
445 if (wand->graphic_context == (DrawInfo **) NULL)
447 ThrowDrawException(ResourceLimitError,
"MemoryAllocationFailed",
451 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
452 wand->filter_off=MagickTrue;
453 wand->indent_depth=0;
454 wand->path_operation=PathDefaultOperation;
455 wand->path_mode=DefaultPathMode;
456 wand->image=AcquireImage((
const ImageInfo *) NULL);
457 ClearMagickException(wand->exception);
458 wand->destroy=MagickTrue;
459 wand->debug=IsEventLogging();
493 assert(wand->signature == WandSignature);
494 if (wand->debug != MagickFalse)
495 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
496 clone_wand=(
DrawingWand *) AcquireMagickMemory(
sizeof(*clone_wand));
498 ThrowWandFatalException(ResourceLimitFatalError,
499 "MemoryAllocationFailed",GetExceptionMessage(errno));
500 (void) memset(clone_wand,0,
sizeof(*clone_wand));
501 clone_wand->id=AcquireWandId();
502 (void) FormatLocaleString(clone_wand->name,MaxTextExtent,
"DrawingWand-%.20g",
503 (
double) clone_wand->id);
504 clone_wand->exception=AcquireExceptionInfo();
505 InheritException(clone_wand->exception,wand->exception);
506 clone_wand->mvg=AcquireString(wand->mvg);
507 clone_wand->mvg_length=strlen(clone_wand->mvg);
508 clone_wand->mvg_alloc=wand->mvg_length+1;
509 clone_wand->mvg_width=wand->mvg_width;
510 clone_wand->pattern_id=AcquireString(wand->pattern_id);
511 clone_wand->pattern_offset=wand->pattern_offset;
512 clone_wand->pattern_bounds=wand->pattern_bounds;
513 clone_wand->index=wand->index;
514 clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((
size_t)
515 wand->index+1UL,
sizeof(*wand->graphic_context));
516 if (clone_wand->graphic_context == (DrawInfo **) NULL)
517 ThrowWandFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed",
518 GetExceptionMessage(errno));
519 for (i=0; i <= (ssize_t) wand->index; i++)
520 clone_wand->graphic_context[i]=
521 CloneDrawInfo((ImageInfo *) NULL,wand->graphic_context[i]);
522 clone_wand->filter_off=wand->filter_off;
523 clone_wand->indent_depth=wand->indent_depth;
524 clone_wand->path_operation=wand->path_operation;
525 clone_wand->path_mode=wand->path_mode;
526 clone_wand->image=wand->image;
527 if (wand->image != (Image *) NULL)
528 clone_wand->image=CloneImage(wand->image,0,0,MagickTrue,
529 clone_wand->exception);
530 clone_wand->destroy=MagickTrue;
531 clone_wand->debug=IsEventLogging();
532 if (clone_wand->debug != MagickFalse)
533 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",clone_wand->name);
534 clone_wand->signature=WandSignature;
565 assert(wand->signature == WandSignature);
566 if (wand->debug != MagickFalse)
567 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
568 for ( ; wand->index > 0; wand->index--)
569 CurrentContext=DestroyDrawInfo(CurrentContext);
570 CurrentContext=DestroyDrawInfo(CurrentContext);
571 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory(
572 wand->graphic_context);
573 if (wand->pattern_id != (
char *) NULL)
574 wand->pattern_id=DestroyString(wand->pattern_id);
575 wand->mvg=DestroyString(wand->mvg);
576 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL))
577 wand->image=DestroyImage(wand->image);
578 wand->image=(Image *) NULL;
579 wand->exception=DestroyExceptionInfo(wand->exception);
580 wand->signature=(~WandSignature);
581 RelinquishWandId(wand->id);
612WandExport
void DrawAffine(
DrawingWand *wand,
const AffineMatrix *affine)
615 assert(wand->signature == WandSignature);
616 if (wand->debug != MagickFalse)
617 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
618 assert(affine != (
const AffineMatrix *) NULL);
619 AdjustAffine(wand,affine);
620 (void) MVGPrintf(wand,
"affine %.20g %.20g %.20g %.20g %.20g %.20g\n",
621 affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty);
653WandExport
void DrawAnnotation(
DrawingWand *wand,
const double x,
const double y,
654 const unsigned char *text)
660 assert(wand->signature == WandSignature);
661 if (wand->debug != MagickFalse)
662 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
663 assert(text != (
const unsigned char *) NULL);
664 escaped_text=EscapeString((
const char *) text,
'\'');
665 if (escaped_text != (
char *) NULL)
667 (void) MVGPrintf(wand,
"text %.20g %.20g '%s'\n",x,y,escaped_text);
668 escaped_text=DestroyString(escaped_text);
708WandExport
void DrawArc(
DrawingWand *wand,
const double sx,
const double sy,
709 const double ex,
const double ey,
const double sd,
const double ed)
712 assert(wand->signature == WandSignature);
713 if (wand->debug != MagickFalse)
714 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
715 (void) MVGPrintf(wand,
"arc %.20g %.20g %.20g %.20g %.20g %.20g\n",sx,sy,ex,
747 const size_t number_coordinates,
const PointInfo *coordinates)
750 assert(wand->signature == WandSignature);
751 if (wand->debug != MagickFalse)
752 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
753 assert(coordinates != (
const PointInfo *) NULL);
754 MVGAppendPointsCommand(wand,
"bezier",number_coordinates,coordinates);
788WandExport
void DrawCircle(
DrawingWand *wand,
const double ox,
const double oy,
789 const double px,
const double py)
792 assert(wand->signature == WandSignature);
793 if (wand->debug != MagickFalse)
794 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
795 (void) MVGPrintf(wand,
"circle %.20g %.20g %.20g %.20g\n",ox,oy,px,py);
820WandExport MagickBooleanType DrawClearException(
DrawingWand *wand)
823 assert(wand->signature == WandSignature);
824 if (wand->debug != MagickFalse)
825 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
826 ClearMagickException(wand->exception);
871WandExport MagickBooleanType DrawComposite(
DrawingWand *wand,
872 const CompositeOperator compose,
const double x,
const double y,
873 const double width,
const double height,
MagickWand *magick_wand)
904 assert(wand->signature == WandSignature);
905 if (wand->debug != MagickFalse)
906 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
908 image=GetImageFromMagickWand(magick_wand);
909 if (image == (Image *) NULL)
911 clone_image=CloneImage(image,0,0,MagickTrue,wand->exception);
912 if (clone_image == (Image *) NULL)
914 image_info=AcquireImageInfo();
915 (void) CopyMagickString(image_info->magick,
"MIFF",MaxTextExtent);
917 blob=(
unsigned char *) ImageToBlob(image_info,clone_image,&blob_length,
919 image_info=DestroyImageInfo(image_info);
920 clone_image=DestroyImageList(clone_image);
921 if (blob == (
void *) NULL)
924 base64=Base64Encode(blob,blob_length,&encoded_length);
925 blob=(
unsigned char *) RelinquishMagickMemory(blob);
926 if (base64 == (
char *) NULL)
929 buffer[MaxTextExtent];
931 (void) FormatLocaleString(buffer,MaxTextExtent,
"%.20g bytes",(
double)
932 (4L*blob_length/3L+4L));
933 ThrowDrawException(ResourceLimitWarning,
"MemoryAllocationFailed",
937 mode=CommandOptionToMnemonic(MagickComposeOptions,(ssize_t) compose);
938 media_type=MagickToMime(image->magick);
939 (void) MVGPrintf(wand,
"image %s %.20g %.20g %.20g %.20g 'data:%s;base64,\n",
940 mode,x,y,width,height,media_type);
942 for (i=(ssize_t) encoded_length; i > 0; i-=76)
944 (void) MVGPrintf(wand,
"%.76s",p);
947 (void) MVGPrintf(wand,
"\n");
949 (void) MVGPrintf(wand,
"'\n");
950 media_type=DestroyString(media_type);
951 base64=DestroyString(base64);
991WandExport
void DrawColor(
DrawingWand *wand,
const double x,
const double y,
992 const PaintMethod paint_method)
995 assert(wand->signature == WandSignature);
996 if (wand->debug != MagickFalse)
997 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
998 (void) MVGPrintf(wand,
"color %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
999 MagickMethodOptions,(ssize_t) paint_method));
1026WandExport
void DrawComment(
DrawingWand *wand,
const char *comment)
1028 (void) MVGPrintf(wand,
"#%s\n",comment);
1066WandExport
void DrawEllipse(
DrawingWand *wand,
const double ox,
const double oy,
1067 const double rx,
const double ry,
const double start,
const double end)
1070 assert(wand->signature == WandSignature);
1071 if (wand->debug != MagickFalse)
1072 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1073 (void) MVGPrintf(wand,
"ellipse %.20g %.20g %.20g %.20g %.20g %.20g\n",ox,oy,
1103WandExport
void DrawGetBorderColor(
const DrawingWand *wand,
1107 assert(wand->signature == WandSignature);
1108 assert(border_color != (
PixelWand *) NULL);
1109 if (wand->debug != MagickFalse)
1110 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1111 PixelSetQuantumColor(border_color,&CurrentContext->border_color);
1137WandExport
char *DrawGetClipPath(
const DrawingWand *wand)
1140 assert(wand->signature == WandSignature);
1141 if (wand->debug != MagickFalse)
1142 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1143 if (CurrentContext->clip_mask != (
char *) NULL)
1144 return((
char *) AcquireString(CurrentContext->clip_mask));
1145 return((
char *) NULL);
1171WandExport FillRule DrawGetClipRule(
const DrawingWand *wand)
1174 assert(wand->signature == WandSignature);
1175 if (wand->debug != MagickFalse)
1176 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1177 return(CurrentContext->fill_rule);
1202WandExport ClipPathUnits DrawGetClipUnits(
const DrawingWand *wand)
1205 assert(wand->signature == WandSignature);
1206 if (wand->debug != MagickFalse)
1207 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1208 return(CurrentContext->clip_units);
1234WandExport
char *DrawGetDensity(
const DrawingWand *wand)
1237 assert(wand->signature == MagickCoreSignature);
1238 if (wand->debug != MagickFalse)
1239 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1240 if (CurrentContext->density != (
char *) NULL)
1241 return((
char *) AcquireString(CurrentContext->density));
1242 return((
char *) NULL);
1271WandExport
char *DrawGetException(
const DrawingWand *wand,
1272 ExceptionType *severity)
1278 assert(wand->signature == WandSignature);
1279 if (wand->debug != MagickFalse)
1280 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1281 assert(severity != (ExceptionType *) NULL);
1282 *severity=wand->exception->severity;
1283 description=(
char *) AcquireQuantumMemory(2UL*MaxTextExtent,
1284 sizeof(*description));
1285 if (description == (
char *) NULL)
1286 ThrowWandFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed",
1289 if (wand->exception->reason != (
char *) NULL)
1290 (void) CopyMagickString(description,GetLocaleExceptionMessage(
1291 wand->exception->severity,wand->exception->reason),
1293 if (wand->exception->description != (
char *) NULL)
1295 (void) ConcatenateMagickString(description,
" (",MaxTextExtent);
1296 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
1297 wand->exception->severity,wand->exception->description),
1299 (void) ConcatenateMagickString(description,
")",MaxTextExtent);
1301 return(description);
1327WandExport ExceptionType DrawGetExceptionType(
const DrawingWand *wand)
1330 assert(wand->signature == WandSignature);
1331 if (wand->debug != MagickFalse)
1332 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1333 return(wand->exception->severity);
1364 assert(wand->signature == WandSignature);
1365 assert(fill_color != (
PixelWand *) NULL);
1366 if (wand->debug != MagickFalse)
1367 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1368 PixelSetQuantumColor(fill_color,&CurrentContext->fill);
1394WandExport
double DrawGetFillOpacity(
const DrawingWand *wand)
1400 assert(wand->signature == WandSignature);
1401 if (wand->debug != MagickFalse)
1402 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1403 alpha=QuantumScale*((double) QuantumRange-(double)
1404 CurrentContext->fill.opacity);
1430WandExport FillRule DrawGetFillRule(
const DrawingWand *wand)
1433 assert(wand->signature == WandSignature);
1434 if (wand->debug != MagickFalse)
1435 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1436 return(CurrentContext->fill_rule);
1463WandExport
char *DrawGetFont(
const DrawingWand *wand)
1466 assert(wand->signature == WandSignature);
1467 if (wand->debug != MagickFalse)
1468 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1469 if (CurrentContext->font != (
char *) NULL)
1470 return(AcquireString(CurrentContext->font));
1471 return((
char *) NULL);
1497WandExport
char *DrawGetFontFamily(
const DrawingWand *wand)
1500 assert(wand->signature == WandSignature);
1501 if (wand->debug != MagickFalse)
1502 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1503 if (CurrentContext->family != NULL)
1504 return(AcquireString(CurrentContext->family));
1505 return((
char *) NULL);
1535WandExport MagickBooleanType DrawGetFontResolution(
const DrawingWand *wand,
1536 double *x,
double *y)
1539 assert(wand->signature == WandSignature);
1540 if (wand->debug != MagickFalse)
1541 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1542 *x=DefaultResolution;
1543 *y=DefaultResolution;
1544 if (CurrentContext->density != (
char *) NULL)
1552 flags=ParseGeometry(CurrentContext->density,&geometry_info);
1553 *x=geometry_info.rho;
1554 *y=geometry_info.sigma;
1555 if ((flags & SigmaValue) == MagickFalse)
1583WandExport
double DrawGetFontSize(
const DrawingWand *wand)
1586 assert(wand->signature == WandSignature);
1587 if (wand->debug != MagickFalse)
1588 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1589 return(CurrentContext->pointsize);
1614WandExport StretchType DrawGetFontStretch(
const DrawingWand *wand)
1617 assert(wand->signature == WandSignature);
1618 if (wand->debug != MagickFalse)
1619 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1620 return(CurrentContext->stretch);
1645WandExport StyleType DrawGetFontStyle(
const DrawingWand *wand)
1648 assert(wand->signature == WandSignature);
1649 if (wand->debug != MagickFalse)
1650 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1651 return(CurrentContext->style);
1676WandExport
size_t DrawGetFontWeight(
const DrawingWand *wand)
1679 assert(wand->signature == WandSignature);
1680 if (wand->debug != MagickFalse)
1681 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1682 return(CurrentContext->weight);
1708WandExport GravityType DrawGetGravity(
const DrawingWand *wand)
1711 assert(wand->signature == WandSignature);
1712 if (wand->debug != MagickFalse)
1713 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1714 return(CurrentContext->gravity);
1740WandExport
double DrawGetOpacity(
const DrawingWand *wand)
1746 assert(wand->signature == WandSignature);
1747 if (wand->debug != MagickFalse)
1748 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1749 alpha=QuantumScale*((double) QuantumRange-(double) CurrentContext->opacity);
1778WandExport MagickBooleanType DrawGetStrokeAntialias(
const DrawingWand *wand)
1781 assert(wand->signature == WandSignature);
1782 if (wand->debug != MagickFalse)
1783 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1784 return(CurrentContext->stroke_antialias);
1812WandExport
void DrawGetStrokeColor(
const DrawingWand *wand,
1816 assert(wand->signature == WandSignature);
1817 assert(stroke_color != (
PixelWand *) NULL);
1818 if (wand->debug != MagickFalse)
1819 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1820 PixelSetQuantumColor(stroke_color,&CurrentContext->stroke);
1850WandExport
double *DrawGetStrokeDashArray(
const DrawingWand *wand,
1851 size_t *number_elements)
1867 assert(wand->signature == WandSignature);
1868 if (wand->debug != MagickFalse)
1869 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1870 assert(number_elements != (
size_t *) NULL);
1871 p=CurrentContext->dash_pattern;
1872 if (p != (
const double *) NULL)
1873 while (fabs(*p++) >= MagickEpsilon)
1876 dasharray=(
double *) NULL;
1879 dasharray=(
double *) AcquireQuantumMemory((
size_t) n+1UL,
1880 sizeof(*dasharray));
1881 if (dasharray != (
double *) NULL)
1883 p=CurrentContext->dash_pattern;
1885 for (i=0; i < (ssize_t) n; i++)
1916WandExport
double DrawGetStrokeDashOffset(
const DrawingWand *wand)
1919 assert(wand->signature == WandSignature);
1920 if (wand->debug != MagickFalse)
1921 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1922 return(CurrentContext->dash_offset);
1949WandExport LineCap DrawGetStrokeLineCap(
const DrawingWand *wand)
1952 assert(wand->signature == WandSignature);
1953 if (wand->debug != MagickFalse)
1954 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1955 return(CurrentContext->linecap);
1983WandExport LineJoin DrawGetStrokeLineJoin(
const DrawingWand *wand)
1986 assert(wand->signature == WandSignature);
1987 if (wand->debug != MagickFalse)
1988 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1989 return(CurrentContext->linejoin);
2018WandExport
size_t DrawGetStrokeMiterLimit(
const DrawingWand *wand)
2021 assert(wand->signature == WandSignature);
2022 if (wand->debug != MagickFalse)
2023 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2024 return CurrentContext->miterlimit;
2049WandExport
double DrawGetStrokeOpacity(
const DrawingWand *wand)
2055 assert(wand->signature == WandSignature);
2056 if (wand->debug != MagickFalse)
2057 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2058 alpha=QuantumScale*((double) QuantumRange-(double)
2059 CurrentContext->stroke.opacity);
2086WandExport
double DrawGetStrokeWidth(
const DrawingWand *wand)
2089 assert(wand->signature == WandSignature);
2090 if (wand->debug != MagickFalse)
2091 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2092 return(CurrentContext->stroke_width);
2118WandExport AlignType DrawGetTextAlignment(
const DrawingWand *wand)
2121 assert(wand->signature == WandSignature);
2122 if (wand->debug != MagickFalse)
2123 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2124 return(CurrentContext->align);
2150WandExport MagickBooleanType DrawGetTextAntialias(
const DrawingWand *wand)
2153 assert(wand->signature == WandSignature);
2154 if (wand->debug != MagickFalse)
2155 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2156 return(CurrentContext->text_antialias);
2182WandExport DecorationType DrawGetTextDecoration(
const DrawingWand *wand)
2185 assert(wand->signature == WandSignature);
2186 if (wand->debug != MagickFalse)
2187 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2188 return(CurrentContext->decorate);
2214WandExport DirectionType DrawGetTextDirection(
const DrawingWand *wand)
2217 assert(wand->signature == WandSignature);
2218 if (wand->debug != MagickFalse)
2219 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2220 return(CurrentContext->direction);
2247WandExport
char *DrawGetTextEncoding(
const DrawingWand *wand)
2250 assert(wand->signature == WandSignature);
2251 if (wand->debug != MagickFalse)
2252 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2253 if (CurrentContext->encoding != (
char *) NULL)
2254 return((
char *) AcquireString(CurrentContext->encoding));
2255 return((
char *) NULL);
2280WandExport
double DrawGetTextKerning(
DrawingWand *wand)
2283 assert(wand->signature == WandSignature);
2285 if (wand->debug != MagickFalse)
2286 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2287 return(CurrentContext->kerning);
2312WandExport
double DrawGetTextInterlineSpacing(
DrawingWand *wand)
2315 assert(wand->signature == WandSignature);
2316 if (wand->debug != MagickFalse)
2317 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2318 return(CurrentContext->interline_spacing);
2343WandExport
double DrawGetTextInterwordSpacing(
DrawingWand *wand)
2346 assert(wand->signature == WandSignature);
2347 if (wand->debug != MagickFalse)
2348 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2349 return(CurrentContext->interword_spacing);
2378static inline void SetMagickPixelPacket(
const Image *image,
2379 const PixelPacket *color,
const IndexPacket *index,MagickPixelPacket *pixel)
2381 pixel->red=(MagickRealType) GetPixelRed(color);
2382 pixel->green=(MagickRealType) GetPixelGreen(color);
2383 pixel->blue=(MagickRealType) GetPixelBlue(color);
2384 if (image->matte != MagickFalse)
2385 pixel->opacity=(MagickRealType) GetPixelOpacity(color);
2386 if (((image->colorspace == CMYKColorspace) ||
2387 (image->storage_class == PseudoClass)) &&
2388 (index != (
const IndexPacket *) NULL))
2389 pixel->index=(MagickRealType) GetPixelIndex(index);
2392WandExport
char *DrawGetVectorGraphics(
DrawingWand *wand)
2395 value[MaxTextExtent],
2409 assert(wand->signature == WandSignature);
2410 if (wand->debug != MagickFalse)
2411 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2412 xml_info=NewXMLTreeTag(
"drawing-wand");
2413 if (xml_info == (XMLTreeInfo *) NULL)
2414 return((
char *) NULL);
2415 (void) SetXMLTreeContent(xml_info,
" ");
2416 GetMagickPixelPacket(wand->image,&pixel);
2417 child=AddChildToXMLTree(xml_info,
"clip-path",0);
2418 if (child != (XMLTreeInfo *) NULL)
2419 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2420 child=AddChildToXMLTree(xml_info,
"clip-units",0);
2421 if (child != (XMLTreeInfo *) NULL)
2423 (void) CopyMagickString(value,CommandOptionToMnemonic(
2424 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),
2426 (void) SetXMLTreeContent(child,value);
2428 child=AddChildToXMLTree(xml_info,
"decorate",0);
2429 if (child != (XMLTreeInfo *) NULL)
2431 (void) CopyMagickString(value,CommandOptionToMnemonic(
2432 MagickDecorateOptions,(ssize_t) CurrentContext->decorate),
2434 (void) SetXMLTreeContent(child,value);
2436 child=AddChildToXMLTree(xml_info,
"encoding",0);
2437 if (child != (XMLTreeInfo *) NULL)
2438 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2439 child=AddChildToXMLTree(xml_info,
"fill",0);
2440 if (child != (XMLTreeInfo *) NULL)
2442 if (CurrentContext->fill.opacity != OpaqueOpacity)
2443 pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2444 MagickTrue : MagickFalse;
2445 SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2446 (
const IndexPacket *) NULL,&pixel);
2447 GetColorTuple(&pixel,MagickTrue,value);
2448 (void) SetXMLTreeContent(child,value);
2450 child=AddChildToXMLTree(xml_info,
"fill-opacity",0);
2451 if (child != (XMLTreeInfo *) NULL)
2453 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2454 QuantumScale*((
double) QuantumRange-(
double)
2455 CurrentContext->fill.opacity));
2456 (void) SetXMLTreeContent(child,value);
2458 child=AddChildToXMLTree(xml_info,
"fill-rule",0);
2459 if (child != (XMLTreeInfo *) NULL)
2461 (void) CopyMagickString(value,CommandOptionToMnemonic(
2462 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),
2464 (void) SetXMLTreeContent(child,value);
2466 child=AddChildToXMLTree(xml_info,
"font",0);
2467 if (child != (XMLTreeInfo *) NULL)
2468 (void) SetXMLTreeContent(child,CurrentContext->font);
2469 child=AddChildToXMLTree(xml_info,
"font-family",0);
2470 if (child != (XMLTreeInfo *) NULL)
2471 (void) SetXMLTreeContent(child,CurrentContext->family);
2472 child=AddChildToXMLTree(xml_info,
"font-size",0);
2473 if (child != (XMLTreeInfo *) NULL)
2475 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2476 CurrentContext->pointsize);
2477 (void) SetXMLTreeContent(child,value);
2479 child=AddChildToXMLTree(xml_info,
"font-stretch",0);
2480 if (child != (XMLTreeInfo *) NULL)
2482 (void) CopyMagickString(value,CommandOptionToMnemonic(
2483 MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
2484 (void) SetXMLTreeContent(child,value);
2486 child=AddChildToXMLTree(xml_info,
"font-style",0);
2487 if (child != (XMLTreeInfo *) NULL)
2489 (void) CopyMagickString(value,CommandOptionToMnemonic(
2490 MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
2491 (void) SetXMLTreeContent(child,value);
2493 child=AddChildToXMLTree(xml_info,
"font-weight",0);
2494 if (child != (XMLTreeInfo *) NULL)
2496 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",(
double)
2497 CurrentContext->weight);
2498 (void) SetXMLTreeContent(child,value);
2500 child=AddChildToXMLTree(xml_info,
"gravity",0);
2501 if (child != (XMLTreeInfo *) NULL)
2503 (void) CopyMagickString(value,CommandOptionToMnemonic(
2504 MagickGravityOptions,(ssize_t) CurrentContext->gravity),MaxTextExtent);
2505 (void) SetXMLTreeContent(child,value);
2507 child=AddChildToXMLTree(xml_info,
"stroke",0);
2508 if (child != (XMLTreeInfo *) NULL)
2510 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2511 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2512 MagickTrue : MagickFalse;
2513 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2514 (
const IndexPacket *) NULL,&pixel);
2515 GetColorTuple(&pixel,MagickTrue,value);
2516 (void) SetXMLTreeContent(child,value);
2518 child=AddChildToXMLTree(xml_info,
"stroke-antialias",0);
2519 if (child != (XMLTreeInfo *) NULL)
2521 (void) FormatLocaleString(value,MaxTextExtent,
"%d",
2522 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2523 (void) SetXMLTreeContent(child,value);
2525 child=AddChildToXMLTree(xml_info,
"stroke-dasharray",0);
2526 if ((child != (XMLTreeInfo *) NULL) &&
2527 (CurrentContext->dash_pattern != (
double *) NULL))
2532 dash_pattern=AcquireString((
char *) NULL);
2533 for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++)
2536 (void) ConcatenateString(&dash_pattern,
",");
2537 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2538 CurrentContext->dash_pattern[i]);
2539 (void) ConcatenateString(&dash_pattern,value);
2541 (void) SetXMLTreeContent(child,dash_pattern);
2542 dash_pattern=DestroyString(dash_pattern);
2544 child=AddChildToXMLTree(xml_info,
"stroke-dashoffset",0);
2545 if (child != (XMLTreeInfo *) NULL)
2547 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2548 CurrentContext->dash_offset);
2549 (void) SetXMLTreeContent(child,value);
2551 child=AddChildToXMLTree(xml_info,
"stroke-linecap",0);
2552 if (child != (XMLTreeInfo *) NULL)
2554 (void) CopyMagickString(value,CommandOptionToMnemonic(
2555 MagickLineCapOptions,(ssize_t) CurrentContext->linecap),MaxTextExtent);
2556 (void) SetXMLTreeContent(child,value);
2558 child=AddChildToXMLTree(xml_info,
"stroke-linejoin",0);
2559 if (child != (XMLTreeInfo *) NULL)
2561 (void) CopyMagickString(value,CommandOptionToMnemonic(
2562 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2564 (void) SetXMLTreeContent(child,value);
2566 child=AddChildToXMLTree(xml_info,
"stroke-miterlimit",0);
2567 if (child != (XMLTreeInfo *) NULL)
2569 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",(
double)
2570 CurrentContext->miterlimit);
2571 (void) SetXMLTreeContent(child,value);
2573 child=AddChildToXMLTree(xml_info,
"stroke-opacity",0);
2574 if (child != (XMLTreeInfo *) NULL)
2576 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",QuantumScale*
2577 ((
double) QuantumRange-(
double) CurrentContext->stroke.opacity));
2578 (void) SetXMLTreeContent(child,value);
2580 child=AddChildToXMLTree(xml_info,
"stroke-width",0);
2581 if (child != (XMLTreeInfo *) NULL)
2583 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2584 CurrentContext->stroke_width);
2585 (void) SetXMLTreeContent(child,value);
2587 child=AddChildToXMLTree(xml_info,
"text-align",0);
2588 if (child != (XMLTreeInfo *) NULL)
2590 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
2591 (ssize_t) CurrentContext->align),MaxTextExtent);
2592 (void) SetXMLTreeContent(child,value);
2594 child=AddChildToXMLTree(xml_info,
"text-antialias",0);
2595 if (child != (XMLTreeInfo *) NULL)
2597 (void) FormatLocaleString(value,MaxTextExtent,
"%d",
2598 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2599 (void) SetXMLTreeContent(child,value);
2601 child=AddChildToXMLTree(xml_info,
"text-undercolor",0);
2602 if (child != (XMLTreeInfo *) NULL)
2604 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2605 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2606 MagickTrue : MagickFalse;
2607 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2608 (
const IndexPacket *) NULL,&pixel);
2609 GetColorTuple(&pixel,MagickTrue,value);
2610 (void) SetXMLTreeContent(child,value);
2612 child=AddChildToXMLTree(xml_info,
"vector-graphics",0);
2613 if (child != (XMLTreeInfo *) NULL)
2614 (void) SetXMLTreeContent(child,wand->mvg);
2615 xml=XMLTreeInfoToXML(xml_info);
2616 xml_info=DestroyXMLTree(xml_info);
2646WandExport
void DrawGetTextUnderColor(
const DrawingWand *wand,
2650 assert(wand->signature == WandSignature);
2651 assert(under_color != (
PixelWand *) NULL);
2652 if (wand->debug != MagickFalse)
2653 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2654 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2689WandExport
void DrawLine(
DrawingWand *wand,
const double sx,
const double sy,
2690 const double ex,
const double ey)
2693 assert(wand->signature == WandSignature);
2694 if (wand->debug != MagickFalse)
2695 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2696 (void) MVGPrintf(wand,
"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey);
2738WandExport
void DrawMatte(
DrawingWand *wand,
const double x,
const double y,
2739 const PaintMethod paint_method)
2742 assert(wand->signature == WandSignature);
2743 if (wand->debug != MagickFalse)
2744 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2745 (void) MVGPrintf(wand,
"matte %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
2746 MagickMethodOptions,(ssize_t) paint_method));
2777 assert(wand->signature == WandSignature);
2778 if (wand->debug != MagickFalse)
2779 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2780 (void) MVGAutoWrapPrintf(wand,
"%s",wand->path_mode == AbsolutePathMode ?
2825static void DrawPathCurveTo(
DrawingWand *wand,
const PathMode mode,
2826 const double x1,
const double y1,
const double x2,
const double y2,
2827 const double x,
const double y)
2830 assert(wand->signature == WandSignature);
2831 if (wand->debug != MagickFalse)
2832 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2833 if ((wand->path_operation != PathCurveToOperation) ||
2834 (wand->path_mode != mode))
2836 wand->path_operation=PathCurveToOperation;
2837 wand->path_mode=mode;
2838 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %.20g %.20g %.20g",
2839 mode == AbsolutePathMode ?
'C' :
'c',x1,y1,x2,y2,x,y);
2842 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1,
2846WandExport
void DrawPathCurveToAbsolute(
DrawingWand *wand,
const double x1,
2847 const double y1,
const double x2,
const double y2,
const double x,
const double y)
2850 assert(wand->signature == WandSignature);
2851 if (wand->debug != MagickFalse)
2852 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2853 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2896WandExport
void DrawPathCurveToRelative(
DrawingWand *wand,
const double x1,
2897 const double y1,
const double x2,
const double y2,
const double x,
const double y)
2900 assert(wand->signature == WandSignature);
2901 if (wand->debug != MagickFalse)
2902 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2903 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2941static void DrawPathCurveToQuadraticBezier(
DrawingWand *wand,
2942 const PathMode mode,
const double x1,
double y1,
const double x,
const double y)
2945 assert(wand->signature == WandSignature);
2946 if (wand->debug != MagickFalse)
2947 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2948 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2949 (wand->path_mode != mode))
2951 wand->path_operation=PathCurveToQuadraticBezierOperation;
2952 wand->path_mode=mode;
2953 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %.20g",
2954 mode == AbsolutePathMode ?
'Q' :
'q',x1,y1,x,y);
2957 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %.20g",x1,y1,x,y);
2960WandExport
void DrawPathCurveToQuadraticBezierAbsolute(
DrawingWand *wand,
2961 const double x1,
const double y1,
const double x,
const double y)
2964 assert(wand->signature == WandSignature);
2965 if (wand->debug != MagickFalse)
2966 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2967 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
3004WandExport
void DrawPathCurveToQuadraticBezierRelative(
DrawingWand *wand,
3005 const double x1,
const double y1,
const double x,
const double y)
3008 assert(wand->signature == WandSignature);
3009 if (wand->debug != MagickFalse)
3010 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3011 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
3053static void DrawPathCurveToQuadraticBezierSmooth(
DrawingWand *wand,
3054 const PathMode mode,
const double x,
const double y)
3057 assert(wand->signature == WandSignature);
3058 if (wand->debug != MagickFalse)
3059 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3060 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3061 (wand->path_mode != mode))
3063 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3064 wand->path_mode=mode;
3065 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g",mode == AbsolutePathMode ?
3069 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g",x,y);
3072WandExport
void DrawPathCurveToQuadraticBezierSmoothAbsolute(
DrawingWand *wand,
3073 const double x,
const double y)
3076 assert(wand->signature == WandSignature);
3077 if (wand->debug != MagickFalse)
3078 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3079 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3119WandExport
void DrawPathCurveToQuadraticBezierSmoothRelative(
DrawingWand *wand,
3120 const double x,
const double y)
3122 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3167static void DrawPathCurveToSmooth(
DrawingWand *wand,
const PathMode mode,
3168 const double x2,
const double y2,
const double x,
const double y)
3171 assert(wand->signature == WandSignature);
3172 if (wand->debug != MagickFalse)
3173 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3174 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3175 (wand->path_mode != mode))
3177 wand->path_operation=PathCurveToSmoothOperation;
3178 wand->path_mode=mode;
3179 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %.20g",
3180 mode == AbsolutePathMode ?
'S' :
's',x2,y2,x,y);
3183 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %.20g",x2,y2,x,y);
3186WandExport
void DrawPathCurveToSmoothAbsolute(
DrawingWand *wand,
const double x2,
3187 const double y2,
const double x,
const double y)
3190 assert(wand->signature == WandSignature);
3191 if (wand->debug != MagickFalse)
3192 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3193 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3236WandExport
void DrawPathCurveToSmoothRelative(
DrawingWand *wand,
const double x2,
3237 const double y2,
const double x,
const double y)
3240 assert(wand->signature == WandSignature);
3241 if (wand->debug != MagickFalse)
3242 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3243 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3295static void DrawPathEllipticArc(
DrawingWand *wand,
const PathMode mode,
3296 const double rx,
const double ry,
const double x_axis_rotation,
3297 const MagickBooleanType large_arc_flag,
const MagickBooleanType sweep_flag,
3298 const double x,
const double y)
3301 assert(wand->signature == WandSignature);
3302 if (wand->debug != MagickFalse)
3303 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3304 if ((wand->path_operation != PathEllipticArcOperation) ||
3305 (wand->path_mode != mode))
3307 wand->path_operation=PathEllipticArcOperation;
3308 wand->path_mode=mode;
3309 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %u %u %.20g %.20g",
3310 mode == AbsolutePathMode ?
'A' :
'a',rx,ry,x_axis_rotation,
3311 large_arc_flag,sweep_flag,x,y);
3314 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry,
3315 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3318WandExport
void DrawPathEllipticArcAbsolute(
DrawingWand *wand,
const double rx,
3319 const double ry,
const double x_axis_rotation,
3320 const MagickBooleanType large_arc_flag,
const MagickBooleanType sweep_flag,
3321 const double x,
const double y)
3324 assert(wand->signature == WandSignature);
3325 if (wand->debug != MagickFalse)
3326 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3327 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3328 large_arc_flag,sweep_flag,x,y);
3378WandExport
void DrawPathEllipticArcRelative(
DrawingWand *wand,
const double rx,
3379 const double ry,
const double x_axis_rotation,
3380 const MagickBooleanType large_arc_flag,
const MagickBooleanType sweep_flag,
3381 const double x,
const double y)
3383 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3384 large_arc_flag,sweep_flag,x,y);
3412 assert(wand->signature == WandSignature);
3413 if (wand->debug != MagickFalse)
3414 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3415 (void) MVGPrintf(wand,
"'\n");
3416 wand->path_operation=PathDefaultOperation;
3417 wand->path_mode=DefaultPathMode;
3449static void DrawPathLineTo(
DrawingWand *wand,
const PathMode mode,
3450 const double x,
const double y)
3453 assert(wand->signature == WandSignature);
3454 if (wand->debug != MagickFalse)
3455 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3456 if ((wand->path_operation != PathLineToOperation) ||
3457 (wand->path_mode != mode))
3459 wand->path_operation=PathLineToOperation;
3460 wand->path_mode=mode;
3461 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g",mode == AbsolutePathMode ?
3465 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g",x,y);
3468WandExport
void DrawPathLineToAbsolute(
DrawingWand *wand,
const double x,
3472 assert(wand->signature == WandSignature);
3473 if (wand->debug != MagickFalse)
3474 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3475 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3507WandExport
void DrawPathLineToRelative(
DrawingWand *wand,
const double x,
3511 assert(wand->signature == WandSignature);
3512 if (wand->debug != MagickFalse)
3513 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3514 DrawPathLineTo(wand,RelativePathMode,x,y);
3545static void DrawPathLineToHorizontal(
DrawingWand *wand,
const PathMode mode,
3549 assert(wand->signature == WandSignature);
3550 if (wand->debug != MagickFalse)
3551 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3552 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3553 (wand->path_mode != mode))
3555 wand->path_operation=PathLineToHorizontalOperation;
3556 wand->path_mode=mode;
3557 (void) MVGAutoWrapPrintf(wand,
"%c%.20g",mode == AbsolutePathMode ?
3561 (
void) MVGAutoWrapPrintf(wand,
" %.20g",x);
3564WandExport
void DrawPathLineToHorizontalAbsolute(
DrawingWand *wand,
3568 assert(wand->signature == WandSignature);
3569 if (wand->debug != MagickFalse)
3570 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3571 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3601WandExport
void DrawPathLineToHorizontalRelative(
DrawingWand *wand,
3604 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3635static void DrawPathLineToVertical(
DrawingWand *wand,
const PathMode mode,
3639 assert(wand->signature == WandSignature);
3640 if (wand->debug != MagickFalse)
3641 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3642 if ((wand->path_operation != PathLineToVerticalOperation) ||
3643 (wand->path_mode != mode))
3645 wand->path_operation=PathLineToVerticalOperation;
3646 wand->path_mode=mode;
3647 (void) MVGAutoWrapPrintf(wand,
"%c%.20g",mode == AbsolutePathMode ?
3651 (
void) MVGAutoWrapPrintf(wand,
" %.20g",y);
3654WandExport
void DrawPathLineToVerticalAbsolute(
DrawingWand *wand,
const double y)
3657 assert(wand->signature == WandSignature);
3658 if (wand->debug != MagickFalse)
3659 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3660 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3690WandExport
void DrawPathLineToVerticalRelative(
DrawingWand *wand,
const double y)
3693 assert(wand->signature == WandSignature);
3694 if (wand->debug != MagickFalse)
3695 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3696 DrawPathLineToVertical(wand,RelativePathMode,y);
3728static void DrawPathMoveTo(
DrawingWand *wand,
const PathMode mode,
const double x,
3732 assert(wand->signature == WandSignature);
3733 if (wand->debug != MagickFalse)
3734 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3735 if ((wand->path_operation != PathMoveToOperation) ||
3736 (wand->path_mode != mode))
3738 wand->path_operation=PathMoveToOperation;
3739 wand->path_mode=mode;
3740 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g",mode == AbsolutePathMode ?
3744 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g",x,y);
3747WandExport
void DrawPathMoveToAbsolute(
DrawingWand *wand,
const double x,
3751 assert(wand->signature == WandSignature);
3752 if (wand->debug != MagickFalse)
3753 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3754 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3786WandExport
void DrawPathMoveToRelative(
DrawingWand *wand,
const double x,
3790 assert(wand->signature == WandSignature);
3791 if (wand->debug != MagickFalse)
3792 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3793 DrawPathMoveTo(wand,RelativePathMode,x,y);
3825 assert(wand->signature == WandSignature);
3826 if (wand->debug != MagickFalse)
3827 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3828 (void) MVGPrintf(wand,
"path '");
3829 wand->path_operation=PathDefaultOperation;
3830 wand->path_mode=DefaultPathMode;
3859WandExport
void DrawPoint(
DrawingWand *wand,
const double x,
const double y)
3862 assert(wand->signature == WandSignature);
3863 if (wand->debug != MagickFalse)
3864 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3865 (void) MVGPrintf(wand,
"point %.20g %.20g\n",x,y);
3897 const size_t number_coordinates,
const PointInfo *coordinates)
3900 assert(wand->signature == WandSignature);
3901 if (wand->debug != MagickFalse)
3902 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3903 MVGAppendPointsCommand(wand,
"polygon",number_coordinates,coordinates);
3935 const size_t number_coordinates,
const PointInfo *coordinates)
3938 assert(wand->signature == WandSignature);
3939 if (wand->debug != MagickFalse)
3940 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3941 MVGAppendPointsCommand(wand,
"polyline",number_coordinates,coordinates);
3969 assert(wand->signature == WandSignature);
3970 if (wand->debug != MagickFalse)
3971 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3972 if (wand->indent_depth > 0)
3973 wand->indent_depth--;
3974 (void) MVGPrintf(wand,
"pop clip-path\n");
4002 assert(wand->signature == WandSignature);
4003 if (wand->debug != MagickFalse)
4004 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4005 if (wand->indent_depth > 0)
4006 wand->indent_depth--;
4007 (void) MVGPrintf(wand,
"pop defs\n");
4032WandExport MagickBooleanType DrawPopPattern(
DrawingWand *wand)
4035 geometry[MaxTextExtent],
4039 assert(wand->signature == WandSignature);
4040 if (wand->debug != MagickFalse)
4041 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4042 if (wand->image == (Image *) NULL)
4043 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4044 if (wand->pattern_id == (
const char *) NULL)
4046 ThrowDrawException(DrawWarning,
"NotCurrentlyPushingPatternDefinition",
4048 return(MagickFalse);
4050 (void) FormatLocaleString(key,MaxTextExtent,
"%s",wand->pattern_id);
4051 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4052 (void) FormatLocaleString(geometry,MaxTextExtent,
"%.20gx%.20g%+.20g%+.20g",
4053 (
double) wand->pattern_bounds.width,(
double) wand->pattern_bounds.height,
4054 (
double) wand->pattern_bounds.x,(
double) wand->pattern_bounds.y);
4055 (void) SetImageArtifact(wand->image,key,geometry);
4056 wand->pattern_id=DestroyString(wand->pattern_id);
4057 wand->pattern_offset=0;
4058 wand->pattern_bounds.x=0;
4059 wand->pattern_bounds.y=0;
4060 wand->pattern_bounds.width=0;
4061 wand->pattern_bounds.height=0;
4062 wand->filter_off=MagickTrue;
4063 if (wand->indent_depth > 0)
4064 wand->indent_depth--;
4065 (void) MVGPrintf(wand,
"pop pattern\n");
4095WandExport
void DrawPushClipPath(
DrawingWand *wand,
const char *clip_mask_id)
4098 assert(wand->signature == WandSignature);
4099 if (wand->debug != MagickFalse)
4100 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4101 assert(clip_mask_id != (
const char *) NULL);
4102 (void) MVGPrintf(wand,
"push clip-path \"%s\"\n",clip_mask_id);
4103 wand->indent_depth++;
4133 assert(wand->signature == WandSignature);
4134 if (wand->debug != MagickFalse)
4135 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4136 (void) MVGPrintf(wand,
"push defs\n");
4137 wand->indent_depth++;
4179WandExport MagickBooleanType DrawPushPattern(
DrawingWand *wand,
4180 const char *pattern_id,
const double x,
const double y,
const double width,
4181 const double height)
4184 assert(wand->signature == WandSignature);
4185 if (wand->debug != MagickFalse)
4186 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4187 assert(pattern_id != (
const char *) NULL);
4188 if (wand->pattern_id != NULL)
4190 ThrowDrawException(DrawError,
"AlreadyPushingPatternDefinition",
4192 return(MagickFalse);
4194 wand->filter_off=MagickTrue;
4195 (void) MVGPrintf(wand,
"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id,
4197 wand->indent_depth++;
4198 wand->pattern_id=AcquireString(pattern_id);
4199 wand->pattern_bounds.x=CastDoubleToLong(ceil(x-0.5));
4200 wand->pattern_bounds.y=CastDoubleToLong(ceil(y-0.5));
4201 wand->pattern_bounds.width=(size_t) CastDoubleToLong(floor(width+0.5));
4202 wand->pattern_bounds.height=(size_t) CastDoubleToLong(floor(height+0.5));
4203 wand->pattern_offset=wand->mvg_length;
4237WandExport
void DrawRectangle(
DrawingWand *wand,
const double x1,
const double y1,
4238 const double x2,
const double y2)
4241 assert(wand->signature == WandSignature);
4242 if (wand->debug != MagickFalse)
4243 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4244 if ((fabs(x2-x1) < MagickEpsilon) && (fabs(y2-y1) < MagickEpsilon))
4245 (void) MVGPrintf(wand,
"point %.20g %.20g\n",x1,y1);
4247 (
void) MVGPrintf(wand,
"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
4272WandExport MagickBooleanType DrawRender(
DrawingWand *wand)
4278 assert(wand->signature == WandSignature);
4279 if (wand->debug != MagickFalse)
4280 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4281 CurrentContext->primitive=wand->mvg;
4282 if (wand->debug != MagickFalse)
4283 (void) LogMagickEvent(DrawEvent,GetMagickModule(),
"MVG:\n'%s'\n",wand->mvg);
4284 if (wand->image == (Image *) NULL)
4285 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4286 status=DrawImage(wand->image,CurrentContext);
4287 InheritException(wand->exception,&wand->image->exception);
4288 CurrentContext->primitive=(
char *) NULL;
4315WandExport
void DrawResetVectorGraphics(
DrawingWand *wand)
4318 assert(wand->signature == WandSignature);
4319 if (wand->debug != MagickFalse)
4320 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4321 if (wand->mvg != (
char *) NULL)
4322 wand->mvg=DestroyString(wand->mvg);
4352WandExport
void DrawRotate(
DrawingWand *wand,
const double degrees)
4355 assert(wand->signature == WandSignature);
4356 if (wand->debug != MagickFalse)
4357 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4358 (void) MVGPrintf(wand,
"rotate %.20g\n",degrees);
4398WandExport
void DrawRoundRectangle(
DrawingWand *wand,
double x1,
double y1,
4399 double x2,
double y2,
double rx,
double ry)
4402 assert(wand->signature == WandSignature);
4403 if (wand->debug != MagickFalse)
4404 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4405 (void) MVGPrintf(wand,
"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n",
4436WandExport
void DrawScale(
DrawingWand *wand,
const double x,
const double y)
4439 assert(wand->signature == WandSignature);
4440 if (wand->debug != MagickFalse)
4441 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4442 (void) MVGPrintf(wand,
"scale %.20g %.20g\n",x,y);
4471static inline MagickBooleanType IsColorEqual(
const PixelPacket *p,
4472 const PixelPacket *q)
4474 if (GetPixelRed(p) != GetPixelRed(q))
4475 return(MagickFalse);
4476 if (GetPixelGreen(p) != GetPixelGreen(q))
4477 return(MagickFalse);
4478 if (GetPixelBlue(p) != GetPixelBlue(q))
4479 return(MagickFalse);
4480 if (GetPixelOpacity(p) != GetPixelOpacity(q))
4481 return(MagickFalse);
4485WandExport
void DrawSetBorderColor(
DrawingWand *wand,
4494 assert(wand->signature == WandSignature);
4495 if (wand->debug != MagickFalse)
4496 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4497 assert(border_wand != (
const PixelWand *) NULL);
4498 PixelGetQuantumColor(border_wand,&border_color);
4499 new_border=border_color;
4500 current_border=(&CurrentContext->border_color);
4501 if ((wand->filter_off != MagickFalse) ||
4502 (IsColorEqual(current_border,&new_border) == MagickFalse))
4504 CurrentContext->border_color=new_border;
4505 (void) MVGPrintf(wand,
"border-color '");
4506 MVGAppendColor(wand,&border_color);
4507 (void) MVGPrintf(wand,
"'\n");
4538WandExport MagickBooleanType DrawSetClipPath(
DrawingWand *wand,
4539 const char *clip_mask)
4542 if (wand->debug != MagickFalse)
4543 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",clip_mask);
4544 assert(wand->signature == WandSignature);
4545 assert(clip_mask != (
const char *) NULL);
4546 if ((CurrentContext->clip_mask == (
const char *) NULL) ||
4547 (wand->filter_off != MagickFalse) ||
4548 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4550 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4551#if DRAW_BINARY_IMPLEMENTATION
4552 if (wand->image == (Image *) NULL)
4553 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4554 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4556 (void) MVGPrintf(wand,
"clip-path url(#%s)\n",clip_mask);
4585WandExport
void DrawSetClipRule(
DrawingWand *wand,
const FillRule fill_rule)
4588 assert(wand->signature == WandSignature);
4589 if (wand->debug != MagickFalse)
4590 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4591 if ((wand->filter_off != MagickFalse) ||
4592 (CurrentContext->fill_rule != fill_rule))
4594 CurrentContext->fill_rule=fill_rule;
4595 (void) MVGPrintf(wand,
"clip-rule '%s'\n",CommandOptionToMnemonic(
4596 MagickFillRuleOptions,(ssize_t) fill_rule));
4626WandExport
void DrawSetClipUnits(
DrawingWand *wand,
4627 const ClipPathUnits clip_units)
4630 assert(wand->signature == WandSignature);
4631 if (wand->debug != MagickFalse)
4632 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4633 if ((wand->filter_off != MagickFalse) ||
4634 (CurrentContext->clip_units != clip_units))
4636 CurrentContext->clip_units=clip_units;
4637 if (clip_units == ObjectBoundingBox)
4642 GetAffineMatrix(&affine);
4643 affine.sx=CurrentContext->bounds.x2;
4644 affine.sy=CurrentContext->bounds.y2;
4645 affine.tx=CurrentContext->bounds.x1;
4646 affine.ty=CurrentContext->bounds.y1;
4647 AdjustAffine(wand,&affine);
4649 (void) MVGPrintf(wand,
"clip-units '%s'\n",CommandOptionToMnemonic(
4650 MagickClipPathOptions,(ssize_t) clip_units));
4679WandExport MagickBooleanType DrawSetDensity(
DrawingWand *wand,
4680 const char *density)
4683 if (wand->debug != MagickFalse)
4684 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",density);
4685 assert(wand->signature == MagickCoreSignature);
4686 assert(density != (
const char *) NULL);
4687 if ((CurrentContext->density == (
const char *) NULL) ||
4688 (wand->filter_off != MagickFalse) ||
4689 (LocaleCompare(CurrentContext->density,density) != 0))
4691 (void) CloneString(&CurrentContext->density,density);
4692 (void) MVGPrintf(wand,
"density '%s'\n",density);
4729 assert(wand->signature == WandSignature);
4730 if (wand->debug != MagickFalse)
4731 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4732 assert(fill_wand != (
const PixelWand *) NULL);
4733 PixelGetQuantumColor(fill_wand,&fill_color);
4734 new_fill=fill_color;
4735 current_fill=(&CurrentContext->fill);
4736 if ((wand->filter_off != MagickFalse) ||
4737 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4739 CurrentContext->fill=new_fill;
4740 (void) MVGPrintf(wand,
"fill '");
4741 MVGAppendColor(wand,&fill_color);
4742 (void) MVGPrintf(wand,
"'\n");
4771WandExport
void DrawSetFillOpacity(
DrawingWand *wand,
const double fill_opacity)
4777 assert(wand->signature == WandSignature);
4778 if (wand->debug != MagickFalse)
4779 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4780 opacity=ClampToQuantum((
double) QuantumRange*(1.0-fill_opacity));
4781 if ((wand->filter_off != MagickFalse) ||
4782 (CurrentContext->fill.opacity != opacity))
4784 CurrentContext->fill.opacity=opacity;
4785 (void) MVGPrintf(wand,
"fill-opacity %.20g\n",fill_opacity);
4816WandExport MagickBooleanType DrawSetFontResolution(
DrawingWand *wand,
4817 const double x_resolution,
const double y_resolution)
4820 density[MaxTextExtent];
4823 assert(wand->signature == WandSignature);
4824 if (wand->debug != MagickFalse)
4825 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4826 (void) FormatLocaleString(density,MaxTextExtent,
"%.20gx%.20g",x_resolution,
4828 (void) CloneString(&CurrentContext->density,density);
4857WandExport
void DrawSetOpacity(
DrawingWand *wand,
const double opacity)
4863 assert(wand->signature == WandSignature);
4864 if (wand->debug != MagickFalse)
4865 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4866 quantum_opacity=ClampToQuantum((
double) QuantumRange*(1.0-opacity));
4867 if ((wand->filter_off != MagickFalse) ||
4868 (CurrentContext->opacity != quantum_opacity))
4870 CurrentContext->opacity=quantum_opacity;
4871 (void) MVGPrintf(wand,
"opacity %.20g\n",opacity);
4903WandExport MagickBooleanType DrawSetFillPatternURL(
DrawingWand *wand,
4904 const char *fill_url)
4907 pattern[MaxTextExtent],
4908 pattern_spec[MaxTextExtent];
4911 assert(wand->signature == WandSignature);
4912 if (wand->debug != MagickFalse)
4913 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",fill_url);
4914 if (wand->image == (Image *) NULL)
4915 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4916 assert(fill_url != (
const char *) NULL);
4917 if (*fill_url !=
'#')
4919 ThrowDrawException(DrawError,
"NotARelativeURL",fill_url);
4920 return(MagickFalse);
4922 (void) FormatLocaleString(pattern,MaxTextExtent,
"%s",fill_url+1);
4923 if (GetImageArtifact(wand->image,pattern) == (
const char *) NULL)
4925 ThrowDrawException(DrawError,
"URLNotFound",fill_url)
4926 return(MagickFalse);
4928 (void) FormatLocaleString(pattern_spec,MaxTextExtent,
"url(%s)",fill_url);
4929#if DRAW_BINARY_IMPLEMENTATION
4930 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4931 &CurrentContext->fill_pattern);
4933 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4934 CurrentContext->fill.opacity=CurrentContext->opacity;
4935 (void) MVGPrintf(wand,
"fill %s\n",pattern_spec);
4963WandExport
void DrawSetFillRule(
DrawingWand *wand,
const FillRule fill_rule)
4966 assert(wand->signature == WandSignature);
4967 if (wand->debug != MagickFalse)
4968 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4969 if ((wand->filter_off != MagickFalse) ||
4970 (CurrentContext->fill_rule != fill_rule))
4972 CurrentContext->fill_rule=fill_rule;
4973 (void) MVGPrintf(wand,
"fill-rule '%s'\n",CommandOptionToMnemonic(
4974 MagickFillRuleOptions,(ssize_t) fill_rule));
5003WandExport MagickBooleanType DrawSetFont(
DrawingWand *wand,
5004 const char *font_name)
5007 assert(wand->signature == WandSignature);
5008 if (wand->debug != MagickFalse)
5009 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5010 assert(font_name != (
const char *) NULL);
5011 if ((wand->filter_off != MagickFalse) ||
5012 (CurrentContext->font == (
char *) NULL) ||
5013 (LocaleCompare(CurrentContext->font,font_name) != 0))
5015 (void) CloneString(&CurrentContext->font,font_name);
5016 (void) MVGPrintf(wand,
"font '%s'\n",font_name);
5046WandExport MagickBooleanType DrawSetFontFamily(
DrawingWand *wand,
5047 const char *font_family)
5050 assert(wand->signature == WandSignature);
5051 if (wand->debug != MagickFalse)
5052 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5053 assert(font_family != (
const char *) NULL);
5054 if ((wand->filter_off != MagickFalse) ||
5055 (CurrentContext->family == (
const char *) NULL) ||
5056 (LocaleCompare(CurrentContext->family,font_family) != 0))
5058 (void) CloneString(&CurrentContext->family,font_family);
5059 (void) MVGPrintf(wand,
"font-family '%s'\n",font_family);
5088WandExport
void DrawSetFontSize(
DrawingWand *wand,
const double pointsize)
5091 assert(wand->signature == WandSignature);
5092 if (wand->debug != MagickFalse)
5093 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5094 if ((wand->filter_off != MagickFalse) ||
5095 (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon))
5097 CurrentContext->pointsize=pointsize;
5098 (void) MVGPrintf(wand,
"font-size %.20g\n",pointsize);
5131WandExport
void DrawSetFontStretch(
DrawingWand *wand,
5132 const StretchType font_stretch)
5135 assert(wand->signature == WandSignature);
5136 if (wand->debug != MagickFalse)
5137 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5138 if ((wand->filter_off != MagickFalse) ||
5139 (CurrentContext->stretch != font_stretch))
5141 CurrentContext->stretch=font_stretch;
5142 (void) MVGPrintf(wand,
"font-stretch '%s'\n",CommandOptionToMnemonic(
5143 MagickStretchOptions,(ssize_t) font_stretch));
5172WandExport
void DrawSetFontStyle(
DrawingWand *wand,
const StyleType style)
5175 assert(wand->signature == WandSignature);
5176 if (wand->debug != MagickFalse)
5177 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5178 if ((wand->filter_off != MagickFalse) ||
5179 (CurrentContext->style != style))
5181 CurrentContext->style=style;
5182 (void) MVGPrintf(wand,
"font-style '%s'\n",CommandOptionToMnemonic(
5183 MagickStyleOptions,(ssize_t) style));
5212WandExport
void DrawSetFontWeight(
DrawingWand *wand,
5213 const size_t font_weight)
5216 assert(wand->signature == WandSignature);
5217 if (wand->debug != MagickFalse)
5218 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5219 if ((wand->filter_off != MagickFalse) ||
5220 (CurrentContext->weight != font_weight))
5222 CurrentContext->weight=font_weight;
5223 (void) MVGPrintf(wand,
"font-weight %.20g\n",(
double) font_weight);
5255WandExport
void DrawSetGravity(
DrawingWand *wand,
const GravityType gravity)
5258 assert(wand->signature == WandSignature);
5259 if (wand->debug != MagickFalse)
5260 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5261 if ((wand->filter_off != MagickFalse) ||
5262 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5264 CurrentContext->gravity=gravity;
5265 (void) MVGPrintf(wand,
"gravity '%s'\n",CommandOptionToMnemonic(
5266 MagickGravityOptions,(ssize_t) gravity));
5295WandExport
void DrawSetStrokeColor(
DrawingWand *wand,
5304 assert(wand->signature == WandSignature);
5305 if (wand->debug != MagickFalse)
5306 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5307 assert(stroke_wand != (
const PixelWand *) NULL);
5308 PixelGetQuantumColor(stroke_wand,&stroke_color);
5309 new_stroke=stroke_color;
5310 current_stroke=(&CurrentContext->stroke);
5311 if ((wand->filter_off != MagickFalse) ||
5312 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5314 CurrentContext->stroke=new_stroke;
5315 (void) MVGPrintf(wand,
"stroke '");
5316 MVGAppendColor(wand,&stroke_color);
5317 (void) MVGPrintf(wand,
"'\n");
5346WandExport MagickBooleanType DrawSetStrokePatternURL(
DrawingWand *wand,
5347 const char *stroke_url)
5350 pattern[MaxTextExtent],
5351 pattern_spec[MaxTextExtent];
5354 assert(wand->signature == WandSignature);
5355 if (wand->debug != MagickFalse)
5356 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5357 if (wand->image == (Image *) NULL)
5358 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
5359 assert(stroke_url != NULL);
5360 if (stroke_url[0] !=
'#')
5361 ThrowDrawException(DrawError,
"NotARelativeURL",stroke_url);
5362 (void) FormatLocaleString(pattern,MaxTextExtent,
"%s",stroke_url+1);
5363 if (GetImageArtifact(wand->image,pattern) == (
const char *) NULL)
5365 ThrowDrawException(DrawError,
"URLNotFound",stroke_url)
5366 return(MagickFalse);
5368 (void) FormatLocaleString(pattern_spec,MaxTextExtent,
"url(%s)",stroke_url);
5369#if DRAW_BINARY_IMPLEMENTATION
5370 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5371 &CurrentContext->stroke_pattern);
5373 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5374 CurrentContext->stroke.opacity=CurrentContext->opacity;
5375 (void) MVGPrintf(wand,
"stroke %s\n",pattern_spec);
5407WandExport
void DrawSetStrokeAntialias(
DrawingWand *wand,
5408 const MagickBooleanType stroke_antialias)
5411 assert(wand->signature == WandSignature);
5412 if (wand->debug != MagickFalse)
5413 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5414 if ((wand->filter_off != MagickFalse) ||
5415 (CurrentContext->stroke_antialias != stroke_antialias))
5417 CurrentContext->stroke_antialias=stroke_antialias;
5418 (void) MVGPrintf(wand,
"stroke-antialias %i\n",stroke_antialias != 0 ?
5456WandExport MagickBooleanType DrawSetStrokeDashArray(
DrawingWand *wand,
5457 const size_t number_elements,
const double *dasharray)
5476 assert(wand->signature == WandSignature);
5477 if (wand->debug != MagickFalse)
5478 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5479 n_new=number_elements;
5480 if (dasharray == (
const double *) NULL)
5484 q=CurrentContext->dash_pattern;
5485 if (q != (
const double *) NULL)
5486 while (fabs(*q++) < MagickEpsilon)
5488 if ((n_old == 0) && (n_new == 0))
5494 if ((CurrentContext->dash_pattern != (
double *) NULL) &&
5495 (dasharray != (
double *) NULL))
5498 q=CurrentContext->dash_pattern;
5499 for (i=0; i < (ssize_t) n_new; i++)
5501 if (fabs((*p)-(*q)) >= MagickEpsilon)
5510 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5512 if (CurrentContext->dash_pattern != (
double *) NULL)
5513 CurrentContext->dash_pattern=(
double *)
5514 RelinquishMagickMemory(CurrentContext->dash_pattern);
5517 CurrentContext->dash_pattern=(
double *) AcquireQuantumMemory((
size_t)
5518 n_new+1UL,
sizeof(*CurrentContext->dash_pattern));
5519 if (CurrentContext->dash_pattern == (
double *) NULL)
5521 ThrowDrawException(ResourceLimitError,
"MemoryAllocationFailed",
5523 return(MagickFalse);
5525 for (i=0; i < (ssize_t) n_new; i++)
5527 CurrentContext->dash_pattern[i]=0.0;
5528 if (dasharray != (
double *) NULL)
5529 CurrentContext->dash_pattern[i]=dasharray[i];
5531 CurrentContext->dash_pattern[n_new]=0.0;
5533 (void) MVGPrintf(wand,
"stroke-dasharray ");
5535 (void) MVGPrintf(wand,
"none\n");
5537 if (dasharray != (
double *) NULL)
5539 for (i=0; i < (ssize_t) n_new; i++)
5542 (void) MVGPrintf(wand,
",");
5543 (void) MVGPrintf(wand,
"%.20g",dasharray[i]);
5545 (void) MVGPrintf(wand,
"\n");
5577WandExport
void DrawSetStrokeDashOffset(
DrawingWand *wand,
5578 const double dash_offset)
5581 assert(wand->signature == WandSignature);
5582 if (wand->debug != MagickFalse)
5583 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5584 if ((wand->filter_off != MagickFalse) ||
5585 (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon))
5587 CurrentContext->dash_offset=dash_offset;
5588 (void) MVGPrintf(wand,
"stroke-dashoffset %.20g\n",dash_offset);
5619WandExport
void DrawSetStrokeLineCap(
DrawingWand *wand,
const LineCap linecap)
5622 assert(wand->signature == WandSignature);
5623 if (wand->debug != MagickFalse)
5624 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5625 if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap))
5627 CurrentContext->linecap=linecap;
5628 (void) MVGPrintf(wand,
"stroke-linecap '%s'\n",CommandOptionToMnemonic(
5629 MagickLineCapOptions,(ssize_t) linecap));
5660WandExport
void DrawSetStrokeLineJoin(
DrawingWand *wand,
const LineJoin linejoin)
5663 assert(wand->signature == WandSignature);
5664 if (wand->debug != MagickFalse)
5665 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5666 if ((wand->filter_off != MagickFalse) ||
5667 (CurrentContext->linejoin != linejoin))
5669 CurrentContext->linejoin=linejoin;
5670 (void) MVGPrintf(wand,
"stroke-linejoin '%s'\n",CommandOptionToMnemonic(
5671 MagickLineJoinOptions,(ssize_t) linejoin));
5704WandExport
void DrawSetStrokeMiterLimit(
DrawingWand *wand,
5705 const size_t miterlimit)
5708 assert(wand->signature == WandSignature);
5709 if (wand->debug != MagickFalse)
5710 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5711 if (CurrentContext->miterlimit != miterlimit)
5713 CurrentContext->miterlimit=miterlimit;
5714 (void) MVGPrintf(wand,
"stroke-miterlimit %.20g\n",(
double) miterlimit);
5743WandExport
void DrawSetStrokeOpacity(
DrawingWand *wand,
5744 const double stroke_opacity)
5750 assert(wand->signature == WandSignature);
5751 if (wand->debug != MagickFalse)
5752 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5753 opacity=ClampToQuantum((
double) QuantumRange*(1.0-stroke_opacity));
5754 if ((wand->filter_off != MagickFalse) ||
5755 (CurrentContext->stroke.opacity != opacity))
5757 CurrentContext->stroke.opacity=opacity;
5758 (void) MVGPrintf(wand,
"stroke-opacity %.20g\n",stroke_opacity);
5788WandExport
void DrawSetStrokeWidth(
DrawingWand *wand,
const double stroke_width)
5791 assert(wand->signature == WandSignature);
5792 if (wand->debug != MagickFalse)
5793 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5794 if ((wand->filter_off != MagickFalse) ||
5795 (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon))
5797 CurrentContext->stroke_width=stroke_width;
5798 (void) MVGPrintf(wand,
"stroke-width %.20g\n",stroke_width);
5828WandExport
void DrawSetTextAlignment(
DrawingWand *wand,
5829 const AlignType alignment)
5832 assert(wand->signature == WandSignature);
5833 if (wand->debug != MagickFalse)
5834 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5835 if ((wand->filter_off != MagickFalse) ||
5836 (CurrentContext->align != alignment))
5838 CurrentContext->align=alignment;
5839 (void) MVGPrintf(wand,
"text-align '%s'\n",CommandOptionToMnemonic(
5840 MagickAlignOptions,(ssize_t) alignment));
5871WandExport
void DrawSetTextAntialias(
DrawingWand *wand,
5872 const MagickBooleanType text_antialias)
5875 assert(wand->signature == WandSignature);
5876 if (wand->debug != MagickFalse)
5877 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5878 if ((wand->filter_off != MagickFalse) ||
5879 (CurrentContext->text_antialias != text_antialias))
5881 CurrentContext->text_antialias=text_antialias;
5882 (void) MVGPrintf(wand,
"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5913WandExport
void DrawSetTextDecoration(
DrawingWand *wand,
5914 const DecorationType decoration)
5917 assert(wand->signature == WandSignature);
5918 if (wand->debug != MagickFalse)
5919 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5920 if ((wand->filter_off != MagickFalse) ||
5921 (CurrentContext->decorate != decoration))
5923 CurrentContext->decorate=decoration;
5924 (void) MVGPrintf(wand,
"decorate '%s'\n",CommandOptionToMnemonic(
5925 MagickDecorateOptions,(ssize_t) decoration));
5956WandExport
void DrawSetTextDirection(
DrawingWand *wand,
5957 const DirectionType direction)
5960 assert(wand->signature == WandSignature);
5962 if (wand->debug != MagickFalse)
5963 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5964 if ((wand->filter_off != MagickFalse) ||
5965 (CurrentContext->direction != direction))
5967 CurrentContext->direction=direction;
5968 (void) MVGPrintf(wand,
"direction '%s'\n",CommandOptionToMnemonic(
5969 MagickDirectionOptions,(ssize_t) direction));
6002WandExport
void DrawSetTextEncoding(
DrawingWand *wand,
const char *encoding)
6005 assert(wand->signature == WandSignature);
6006 if (wand->debug != MagickFalse)
6007 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6008 assert(encoding != (
char *) NULL);
6009 if ((wand->filter_off != MagickFalse) ||
6010 (CurrentContext->encoding == (
char *) NULL) ||
6011 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
6013 (void) CloneString(&CurrentContext->encoding,encoding);
6014 (void) MVGPrintf(wand,
"encoding '%s'\n",encoding);
6042WandExport
void DrawSetTextKerning(
DrawingWand *wand,
const double kerning)
6045 assert(wand->signature == WandSignature);
6047 if (wand->debug != MagickFalse)
6048 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6049 if ((wand->filter_off != MagickFalse) &&
6050 (fabs((CurrentContext->kerning-kerning)) >= MagickEpsilon))
6052 CurrentContext->kerning=kerning;
6053 (void) MVGPrintf(wand,
"kerning %lf\n",kerning);
6082WandExport
void DrawSetTextInterlineSpacing(
DrawingWand *wand,
6083 const double interline_spacing)
6086 assert(wand->signature == WandSignature);
6088 if (wand->debug != MagickFalse)
6089 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6090 if ((wand->filter_off != MagickFalse) &&
6091 (fabs((CurrentContext->interline_spacing-
6092 interline_spacing)) >= MagickEpsilon))
6094 CurrentContext->interline_spacing=interline_spacing;
6095 (void) MVGPrintf(wand,
"interline-spacing %lf\n",interline_spacing);
6124WandExport
void DrawSetTextInterwordSpacing(
DrawingWand *wand,
6125 const double interword_spacing)
6128 assert(wand->signature == WandSignature);
6130 if (wand->debug != MagickFalse)
6131 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6132 if ((wand->filter_off != MagickFalse) &&
6133 (fabs((CurrentContext->interword_spacing-
6134 interword_spacing)) >= MagickEpsilon))
6136 CurrentContext->interword_spacing=interword_spacing;
6137 (void) MVGPrintf(wand,
"interword-spacing %lf\n",interword_spacing);
6167WandExport
void DrawSetTextUnderColor(
DrawingWand *wand,
6174 assert(wand->signature == WandSignature);
6175 if (wand->debug != MagickFalse)
6176 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6177 assert(under_wand != (
const PixelWand *) NULL);
6178 PixelGetQuantumColor(under_wand,&under_color);
6179 if ((wand->filter_off != MagickFalse) ||
6180 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6182 CurrentContext->undercolor=under_color;
6183 (void) MVGPrintf(wand,
"text-undercolor '");
6184 MVGAppendColor(wand,&under_color);
6185 (void) MVGPrintf(wand,
"'\n");
6217static inline MagickBooleanType IsPoint(
const char *point)
6225 value=strtol(point,&p,10);
6227 return(p != point ? MagickTrue : MagickFalse);
6230WandExport MagickBooleanType DrawSetVectorGraphics(
DrawingWand *wand,
6241 assert(wand->signature == WandSignature);
6242 if (wand->debug != MagickFalse)
6243 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6244 CurrentContext=DestroyDrawInfo(CurrentContext);
6245 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6246 if (xml == (
const char *) NULL)
6247 return(MagickFalse);
6248 xml_info=NewXMLTree(xml,wand->exception);
6249 if (xml_info == (XMLTreeInfo *) NULL)
6250 return(MagickFalse);
6251 child=GetXMLTreeChild(xml_info,
"clip-path");
6252 if (child != (XMLTreeInfo *) NULL)
6253 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6254 child=GetXMLTreeChild(xml_info,
"clip-units");
6255 if (child != (XMLTreeInfo *) NULL)
6257 value=GetXMLTreeContent(child);
6258 if (value != (
const char *) NULL)
6259 CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption(
6260 MagickClipPathOptions,MagickFalse,value);
6262 child=GetXMLTreeChild(xml_info,
"decorate");
6263 if (child != (XMLTreeInfo *) NULL)
6265 value=GetXMLTreeContent(child);
6266 if (value != (
const char *) NULL)
6267 CurrentContext->decorate=(DecorationType) ParseCommandOption(
6268 MagickDecorateOptions,MagickFalse,value);
6270 child=GetXMLTreeChild(xml_info,
"encoding");
6271 if (child != (XMLTreeInfo *) NULL)
6272 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6273 child=GetXMLTreeChild(xml_info,
"fill");
6274 if (child != (XMLTreeInfo *) NULL)
6276 value=GetXMLTreeContent(child);
6277 if (value != (
const char *) NULL)
6278 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6280 child=GetXMLTreeChild(xml_info,
"fill-opacity");
6281 if (child != (XMLTreeInfo *) NULL)
6283 value=GetXMLTreeContent(child);
6284 if (value != (
const char *) NULL)
6285 CurrentContext->fill.opacity=ClampToQuantum((MagickRealType)
6286 QuantumRange*(1.0-StringToDouble(value,(
char **) NULL)));
6288 child=GetXMLTreeChild(xml_info,
"fill-rule");
6289 if (child != (XMLTreeInfo *) NULL)
6291 value=GetXMLTreeContent(child);
6292 if (value != (
const char *) NULL)
6293 CurrentContext->fill_rule=(FillRule) ParseCommandOption(
6294 MagickFillRuleOptions,MagickFalse,value);
6296 child=GetXMLTreeChild(xml_info,
"font");
6297 if (child != (XMLTreeInfo *) NULL)
6298 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6299 child=GetXMLTreeChild(xml_info,
"font-family");
6300 if (child != (XMLTreeInfo *) NULL)
6301 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6302 child=GetXMLTreeChild(xml_info,
"font-size");
6303 if (child != (XMLTreeInfo *) NULL)
6305 value=GetXMLTreeContent(child);
6306 if (value != (
const char *) NULL)
6307 CurrentContext->pointsize=StringToDouble(value,(
char **) NULL);
6309 child=GetXMLTreeChild(xml_info,
"font-stretch");
6310 if (child != (XMLTreeInfo *) NULL)
6312 value=GetXMLTreeContent(child);
6313 if (value != (
const char *) NULL)
6314 CurrentContext->stretch=(StretchType) ParseCommandOption(
6315 MagickStretchOptions,MagickFalse,value);
6317 child=GetXMLTreeChild(xml_info,
"font-style");
6318 if (child != (XMLTreeInfo *) NULL)
6320 value=GetXMLTreeContent(child);
6321 if (value != (
const char *) NULL)
6322 CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
6325 child=GetXMLTreeChild(xml_info,
"font-weight");
6326 if (child != (XMLTreeInfo *) NULL)
6328 value=GetXMLTreeContent(child);
6329 if (value != (
const char *) NULL)
6330 CurrentContext->weight=StringToUnsignedLong(value);
6332 child=GetXMLTreeChild(xml_info,
"gravity");
6333 if (child != (XMLTreeInfo *) NULL)
6335 value=GetXMLTreeContent(child);
6336 if (value != (
const char *) NULL)
6337 CurrentContext->gravity=(GravityType) ParseCommandOption(
6338 MagickGravityOptions,MagickFalse,value);
6340 child=GetXMLTreeChild(xml_info,
"stroke");
6341 if (child != (XMLTreeInfo *) NULL)
6343 value=GetXMLTreeContent(child);
6344 if (value != (
const char *) NULL)
6345 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6348 child=GetXMLTreeChild(xml_info,
"stroke-antialias");
6349 if (child != (XMLTreeInfo *) NULL)
6351 value=GetXMLTreeContent(child);
6352 if (value != (
const char *) NULL)
6353 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6356 child=GetXMLTreeChild(xml_info,
"stroke-dasharray");
6357 if (child != (XMLTreeInfo *) NULL)
6360 token[MaxTextExtent];
6371 value=GetXMLTreeContent(child);
6372 if (value != (
const char *) NULL)
6374 if (CurrentContext->dash_pattern != (
double *) NULL)
6375 CurrentContext->dash_pattern=(
double *) RelinquishMagickMemory(
6376 CurrentContext->dash_pattern);
6378 if (IsPoint(q) != MagickFalse)
6384 (void) GetNextToken(p,&p,MaxTextExtent,token);
6386 (void) GetNextToken(p,&p,MaxTextExtent,token);
6387 for (x=0; IsPoint(token) != MagickFalse; x++)
6389 (void) GetNextToken(p,&p,MaxTextExtent,token);
6391 (void) GetNextToken(p,&p,MaxTextExtent,token);
6393 CurrentContext->dash_pattern=(
double *) AcquireQuantumMemory(
6394 (
size_t) (2UL*x)+1UL,
sizeof(*CurrentContext->dash_pattern));
6395 if (CurrentContext->dash_pattern == (
double *) NULL)
6396 ThrowWandFatalException(ResourceLimitFatalError,
6397 "MemoryAllocationFailed",wand->name);
6398 for (j=0; j < x; j++)
6400 (void) GetNextToken(q,&q,MaxTextExtent,token);
6402 (void) GetNextToken(q,&q,MaxTextExtent,token);
6403 CurrentContext->dash_pattern[j]=StringToDouble(token,
6406 if ((x & 0x01) != 0)
6407 for ( ; j < (2*x); j++)
6408 CurrentContext->dash_pattern[j]=
6409 CurrentContext->dash_pattern[j-x];
6410 CurrentContext->dash_pattern[j]=0.0;
6414 child=GetXMLTreeChild(xml_info,
"stroke-dashoffset");
6415 if (child != (XMLTreeInfo *) NULL)
6417 value=GetXMLTreeContent(child);
6418 if (value != (
const char *) NULL)
6419 CurrentContext->dash_offset=StringToDouble(value,(
char **) NULL);
6421 child=GetXMLTreeChild(xml_info,
"stroke-linecap");
6422 if (child != (XMLTreeInfo *) NULL)
6424 value=GetXMLTreeContent(child);
6425 if (value != (
const char *) NULL)
6426 CurrentContext->linecap=(LineCap) ParseCommandOption(
6427 MagickLineCapOptions,MagickFalse,value);
6429 child=GetXMLTreeChild(xml_info,
"stroke-linejoin");
6430 if (child != (XMLTreeInfo *) NULL)
6432 value=GetXMLTreeContent(child);
6433 if (value != (
const char *) NULL)
6434 CurrentContext->linejoin=(LineJoin) ParseCommandOption(
6435 MagickLineJoinOptions,MagickFalse,value);
6437 child=GetXMLTreeChild(xml_info,
"stroke-miterlimit");
6438 if (child != (XMLTreeInfo *) NULL)
6440 value=GetXMLTreeContent(child);
6441 if (value != (
const char *) NULL)
6442 CurrentContext->miterlimit=StringToUnsignedLong(value);
6444 child=GetXMLTreeChild(xml_info,
"stroke-opacity");
6445 if (child != (XMLTreeInfo *) NULL)
6447 value=GetXMLTreeContent(child);
6448 if (value != (
const char *) NULL)
6449 CurrentContext->stroke.opacity=ClampToQuantum((MagickRealType)
6450 QuantumRange*(1.0-StringToDouble(value,(
char **) NULL)));
6452 child=GetXMLTreeChild(xml_info,
"stroke-width");
6453 if (child != (XMLTreeInfo *) NULL)
6455 value=GetXMLTreeContent(child);
6456 if (value != (
const char *) NULL)
6461 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
6463 weight=(ssize_t) StringToUnsignedLong(value);
6464 CurrentContext->stroke_width=(double) weight;
6467 child=GetXMLTreeChild(xml_info,
"text-align");
6468 if (child != (XMLTreeInfo *) NULL)
6470 value=GetXMLTreeContent(child);
6471 if (value != (
const char *) NULL)
6472 CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
6475 child=GetXMLTreeChild(xml_info,
"text-antialias");
6476 if (child != (XMLTreeInfo *) NULL)
6478 value=GetXMLTreeContent(child);
6479 if (value != (
const char *) NULL)
6480 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6483 child=GetXMLTreeChild(xml_info,
"text-undercolor");
6484 if (child != (XMLTreeInfo *) NULL)
6486 value=GetXMLTreeContent(child);
6487 if (value != (
const char *) NULL)
6488 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6491 child=GetXMLTreeChild(xml_info,
"vector-graphics");
6492 if (child != (XMLTreeInfo *) NULL)
6494 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6495 wand->mvg_length=strlen(wand->mvg);
6496 wand->mvg_alloc=wand->mvg_length+1;
6498 xml_info=DestroyXMLTree(xml_info);
6527WandExport
void DrawSkewX(
DrawingWand *wand,
const double degrees)
6530 assert(wand->signature == WandSignature);
6531 if (wand->debug != MagickFalse)
6532 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6533 (void) MVGPrintf(wand,
"skewX %.20g\n",degrees);
6561WandExport
void DrawSkewY(
DrawingWand *wand,
const double degrees)
6564 assert(wand->signature == WandSignature);
6565 if (wand->debug != MagickFalse)
6566 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6567 (void) MVGPrintf(wand,
"skewY %.20g\n",degrees);
6599WandExport
void DrawTranslate(
DrawingWand *wand,
const double x,
const double y)
6602 assert(wand->signature == WandSignature);
6603 if (wand->debug != MagickFalse)
6604 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6605 (void) MVGPrintf(wand,
"translate %.20g %.20g\n",x,y);
6643WandExport
void DrawSetViewbox(
DrawingWand *wand,ssize_t x1,ssize_t y1,
6644 ssize_t x2,ssize_t y2)
6647 assert(wand->signature == WandSignature);
6648 if (wand->debug != MagickFalse)
6649 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6650 (void) MVGPrintf(wand,
"viewbox %.20g %.20g %.20g %.20g\n",(
double) x1,
6651 (
double) y1,(
double) x2,(
double) y2);
6676WandExport MagickBooleanType IsDrawingWand(
const DrawingWand *wand)
6679 return(MagickFalse);
6680 if (wand->signature != WandSignature)
6681 return(MagickFalse);
6682 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6683 return(MagickFalse);
6717 quantum=GetMagickQuantumDepth(&depth);
6718 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6719 ThrowWandFatalException(WandError,
"QuantumDepthMismatch",quantum);
6720 wand=(
DrawingWand *) AcquireMagickMemory(
sizeof(*wand));
6722 ThrowWandFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed",
6723 GetExceptionMessage(errno));
6724 (void) memset(wand,0,
sizeof(*wand));
6725 wand->id=AcquireWandId();
6726 (void) FormatLocaleString(wand->name,MaxTextExtent,
"%s-%.20g",DrawingWandId,
6728 if (wand->debug != MagickFalse)
6729 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6730 wand->mvg=(
char *) NULL;
6734 wand->pattern_id=(
char *) NULL;
6735 wand->pattern_offset=0;
6736 wand->pattern_bounds.x=0;
6737 wand->pattern_bounds.y=0;
6738 wand->pattern_bounds.width=0;
6739 wand->pattern_bounds.height=0;
6741 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
sizeof(
6742 *wand->graphic_context));
6743 if (wand->graphic_context == (DrawInfo **) NULL)
6744 ThrowWandFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed",
6745 GetExceptionMessage(errno));
6746 wand->filter_off=MagickTrue;
6747 wand->indent_depth=0;
6748 wand->path_operation=PathDefaultOperation;
6749 wand->path_mode=DefaultPathMode;
6750 wand->image=AcquireImage((
const ImageInfo *) NULL);
6751 wand->exception=AcquireExceptionInfo();
6752 wand->destroy=MagickTrue;
6753 wand->debug=IsEventLogging();
6754 wand->signature=WandSignature;
6755 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6781WandExport DrawInfo *PeekDrawingWand(
const DrawingWand *wand)
6787 assert(wand->signature == WandSignature);
6788 if (wand->debug != MagickFalse)
6789 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6790 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6791 (void) CloneString(&draw_info->primitive,wand->mvg);
6820WandExport MagickBooleanType PopDrawingWand(
DrawingWand *wand)
6823 assert(wand->signature == WandSignature);
6824 if (wand->debug != MagickFalse)
6825 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6826 if (wand->index == 0)
6828 ThrowDrawException(DrawError,
"UnbalancedGraphicContextPushPop",wand->name)
6829 return(MagickFalse);
6834#if DRAW_BINARY_IMPLEMENTATION
6835 if (wand->image == (Image *) NULL)
6836 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
6837 if (CurrentContext->clip_mask != (
char *) NULL)
6838 if (LocaleCompare(CurrentContext->clip_mask,
6839 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6840 (
void) SetImageClippingMask(wand->image,(Image *) NULL);
6842 CurrentContext=DestroyDrawInfo(CurrentContext);
6844 if (wand->indent_depth > 0)
6845 wand->indent_depth--;
6846 (
void) MVGPrintf(wand,
"pop graphic-context\n");
6875WandExport MagickBooleanType PushDrawingWand(
DrawingWand *wand)
6878 assert(wand->signature == WandSignature);
6879 if (wand->debug != MagickFalse)
6880 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6882 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6883 (
size_t) wand->index+1UL,
sizeof(*wand->graphic_context));
6884 if (wand->graphic_context == (DrawInfo **) NULL)
6887 ThrowDrawException(ResourceLimitError,
"MemoryAllocationFailed",
6889 return(MagickFalse);
6891 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6892 wand->graphic_context[wand->index-1]);
6893 (void) MVGPrintf(wand,
"push graphic-context\n");
6894 wand->indent_depth++;