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)
1869 assert(wand->signature == WandSignature);
1870 if (wand->debug != MagickFalse)
1871 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1872 assert(number_elements != (
size_t *) NULL);
1874 p=CurrentContext->dash_pattern;
1875 if (p != (
const double *) NULL)
1876 while (fabs(*p++) >= MagickEpsilon)
1879 dasharray=(
double *) NULL;
1882 dasharray=(
double *) AcquireQuantumMemory((
size_t) n+1UL,
1883 sizeof(*dasharray));
1884 if (dasharray != (
double *) NULL)
1886 p=CurrentContext->dash_pattern;
1888 for (i=0; i < (ssize_t) n; i++)
1919WandExport
double DrawGetStrokeDashOffset(
const DrawingWand *wand)
1922 assert(wand->signature == WandSignature);
1923 if (wand->debug != MagickFalse)
1924 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1925 return(CurrentContext->dash_offset);
1952WandExport LineCap DrawGetStrokeLineCap(
const DrawingWand *wand)
1955 assert(wand->signature == WandSignature);
1956 if (wand->debug != MagickFalse)
1957 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1958 return(CurrentContext->linecap);
1986WandExport LineJoin DrawGetStrokeLineJoin(
const DrawingWand *wand)
1989 assert(wand->signature == WandSignature);
1990 if (wand->debug != MagickFalse)
1991 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
1992 return(CurrentContext->linejoin);
2021WandExport
size_t DrawGetStrokeMiterLimit(
const DrawingWand *wand)
2024 assert(wand->signature == WandSignature);
2025 if (wand->debug != MagickFalse)
2026 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2027 return CurrentContext->miterlimit;
2052WandExport
double DrawGetStrokeOpacity(
const DrawingWand *wand)
2058 assert(wand->signature == WandSignature);
2059 if (wand->debug != MagickFalse)
2060 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2061 alpha=QuantumScale*((double) QuantumRange-(
double)
2062 CurrentContext->stroke.opacity);
2089WandExport
double DrawGetStrokeWidth(
const DrawingWand *wand)
2092 assert(wand->signature == WandSignature);
2093 if (wand->debug != MagickFalse)
2094 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2095 return(CurrentContext->stroke_width);
2121WandExport AlignType DrawGetTextAlignment(
const DrawingWand *wand)
2124 assert(wand->signature == WandSignature);
2125 if (wand->debug != MagickFalse)
2126 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2127 return(CurrentContext->align);
2153WandExport MagickBooleanType DrawGetTextAntialias(
const DrawingWand *wand)
2156 assert(wand->signature == WandSignature);
2157 if (wand->debug != MagickFalse)
2158 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2159 return(CurrentContext->text_antialias);
2185WandExport DecorationType DrawGetTextDecoration(
const DrawingWand *wand)
2188 assert(wand->signature == WandSignature);
2189 if (wand->debug != MagickFalse)
2190 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2191 return(CurrentContext->decorate);
2217WandExport DirectionType DrawGetTextDirection(
const DrawingWand *wand)
2220 assert(wand->signature == WandSignature);
2221 if (wand->debug != MagickFalse)
2222 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2223 return(CurrentContext->direction);
2250WandExport
char *DrawGetTextEncoding(
const DrawingWand *wand)
2253 assert(wand->signature == WandSignature);
2254 if (wand->debug != MagickFalse)
2255 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2256 if (CurrentContext->encoding != (
char *) NULL)
2257 return((
char *) AcquireString(CurrentContext->encoding));
2258 return((
char *) NULL);
2283WandExport
double DrawGetTextKerning(
DrawingWand *wand)
2286 assert(wand->signature == WandSignature);
2288 if (wand->debug != MagickFalse)
2289 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2290 return(CurrentContext->kerning);
2315WandExport
double DrawGetTextInterlineSpacing(
DrawingWand *wand)
2318 assert(wand->signature == WandSignature);
2319 if (wand->debug != MagickFalse)
2320 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2321 return(CurrentContext->interline_spacing);
2346WandExport
double DrawGetTextInterwordSpacing(
DrawingWand *wand)
2349 assert(wand->signature == WandSignature);
2350 if (wand->debug != MagickFalse)
2351 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2352 return(CurrentContext->interword_spacing);
2381static inline void SetMagickPixelPacket(
const Image *image,
2382 const PixelPacket *color,
const IndexPacket *index,MagickPixelPacket *pixel)
2384 pixel->red=(MagickRealType) GetPixelRed(color);
2385 pixel->green=(MagickRealType) GetPixelGreen(color);
2386 pixel->blue=(MagickRealType) GetPixelBlue(color);
2387 if (image->matte != MagickFalse)
2388 pixel->opacity=(MagickRealType) GetPixelOpacity(color);
2389 if (((image->colorspace == CMYKColorspace) ||
2390 (image->storage_class == PseudoClass)) &&
2391 (index != (
const IndexPacket *) NULL))
2392 pixel->index=(MagickRealType) GetPixelIndex(index);
2395WandExport
char *DrawGetVectorGraphics(
DrawingWand *wand)
2398 value[MaxTextExtent],
2412 assert(wand->signature == WandSignature);
2413 if (wand->debug != MagickFalse)
2414 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2415 xml_info=NewXMLTreeTag(
"drawing-wand");
2416 if (xml_info == (XMLTreeInfo *) NULL)
2417 return((
char *) NULL);
2418 (void) SetXMLTreeContent(xml_info,
" ");
2419 GetMagickPixelPacket(wand->image,&pixel);
2420 child=AddChildToXMLTree(xml_info,
"clip-path",0);
2421 if (child != (XMLTreeInfo *) NULL)
2422 (void) SetXMLTreeContent(child,CurrentContext->clip_mask);
2423 child=AddChildToXMLTree(xml_info,
"clip-units",0);
2424 if (child != (XMLTreeInfo *) NULL)
2426 (void) CopyMagickString(value,CommandOptionToMnemonic(
2427 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units),
2429 (void) SetXMLTreeContent(child,value);
2431 child=AddChildToXMLTree(xml_info,
"decorate",0);
2432 if (child != (XMLTreeInfo *) NULL)
2434 (void) CopyMagickString(value,CommandOptionToMnemonic(
2435 MagickDecorateOptions,(ssize_t) CurrentContext->decorate),
2437 (void) SetXMLTreeContent(child,value);
2439 child=AddChildToXMLTree(xml_info,
"encoding",0);
2440 if (child != (XMLTreeInfo *) NULL)
2441 (void) SetXMLTreeContent(child,CurrentContext->encoding);
2442 child=AddChildToXMLTree(xml_info,
"fill",0);
2443 if (child != (XMLTreeInfo *) NULL)
2445 if (CurrentContext->fill.opacity != OpaqueOpacity)
2446 pixel.matte=CurrentContext->fill.opacity != OpaqueOpacity ?
2447 MagickTrue : MagickFalse;
2448 SetMagickPixelPacket(wand->image,&CurrentContext->fill,
2449 (
const IndexPacket *) NULL,&pixel);
2450 GetColorTuple(&pixel,MagickTrue,value);
2451 (void) SetXMLTreeContent(child,value);
2453 child=AddChildToXMLTree(xml_info,
"fill-opacity",0);
2454 if (child != (XMLTreeInfo *) NULL)
2456 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2457 QuantumScale*((
double) QuantumRange-(
double)
2458 CurrentContext->fill.opacity));
2459 (void) SetXMLTreeContent(child,value);
2461 child=AddChildToXMLTree(xml_info,
"fill-rule",0);
2462 if (child != (XMLTreeInfo *) NULL)
2464 (void) CopyMagickString(value,CommandOptionToMnemonic(
2465 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule),
2467 (void) SetXMLTreeContent(child,value);
2469 child=AddChildToXMLTree(xml_info,
"font",0);
2470 if (child != (XMLTreeInfo *) NULL)
2471 (void) SetXMLTreeContent(child,CurrentContext->font);
2472 child=AddChildToXMLTree(xml_info,
"font-family",0);
2473 if (child != (XMLTreeInfo *) NULL)
2474 (void) SetXMLTreeContent(child,CurrentContext->family);
2475 child=AddChildToXMLTree(xml_info,
"font-size",0);
2476 if (child != (XMLTreeInfo *) NULL)
2478 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2479 CurrentContext->pointsize);
2480 (void) SetXMLTreeContent(child,value);
2482 child=AddChildToXMLTree(xml_info,
"font-stretch",0);
2483 if (child != (XMLTreeInfo *) NULL)
2485 (void) CopyMagickString(value,CommandOptionToMnemonic(
2486 MagickStretchOptions,(ssize_t) CurrentContext->stretch),MaxTextExtent);
2487 (void) SetXMLTreeContent(child,value);
2489 child=AddChildToXMLTree(xml_info,
"font-style",0);
2490 if (child != (XMLTreeInfo *) NULL)
2492 (void) CopyMagickString(value,CommandOptionToMnemonic(
2493 MagickStyleOptions,(ssize_t) CurrentContext->style),MaxTextExtent);
2494 (void) SetXMLTreeContent(child,value);
2496 child=AddChildToXMLTree(xml_info,
"font-weight",0);
2497 if (child != (XMLTreeInfo *) NULL)
2499 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",(
double)
2500 CurrentContext->weight);
2501 (void) SetXMLTreeContent(child,value);
2503 child=AddChildToXMLTree(xml_info,
"gravity",0);
2504 if (child != (XMLTreeInfo *) NULL)
2506 (void) CopyMagickString(value,CommandOptionToMnemonic(
2507 MagickGravityOptions,(ssize_t) CurrentContext->gravity),MaxTextExtent);
2508 (void) SetXMLTreeContent(child,value);
2510 child=AddChildToXMLTree(xml_info,
"stroke",0);
2511 if (child != (XMLTreeInfo *) NULL)
2513 if (CurrentContext->stroke.opacity != OpaqueOpacity)
2514 pixel.matte=CurrentContext->stroke.opacity != OpaqueOpacity ?
2515 MagickTrue : MagickFalse;
2516 SetMagickPixelPacket(wand->image,&CurrentContext->stroke,
2517 (
const IndexPacket *) NULL,&pixel);
2518 GetColorTuple(&pixel,MagickTrue,value);
2519 (void) SetXMLTreeContent(child,value);
2521 child=AddChildToXMLTree(xml_info,
"stroke-antialias",0);
2522 if (child != (XMLTreeInfo *) NULL)
2524 (void) FormatLocaleString(value,MaxTextExtent,
"%d",
2525 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0);
2526 (void) SetXMLTreeContent(child,value);
2528 child=AddChildToXMLTree(xml_info,
"stroke-dasharray",0);
2529 if ((child != (XMLTreeInfo *) NULL) &&
2530 (CurrentContext->dash_pattern != (
double *) NULL))
2535 dash_pattern=AcquireString((
char *) NULL);
2536 for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++)
2539 (void) ConcatenateString(&dash_pattern,
",");
2540 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2541 CurrentContext->dash_pattern[i]);
2542 (void) ConcatenateString(&dash_pattern,value);
2544 (void) SetXMLTreeContent(child,dash_pattern);
2545 dash_pattern=DestroyString(dash_pattern);
2547 child=AddChildToXMLTree(xml_info,
"stroke-dashoffset",0);
2548 if (child != (XMLTreeInfo *) NULL)
2550 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2551 CurrentContext->dash_offset);
2552 (void) SetXMLTreeContent(child,value);
2554 child=AddChildToXMLTree(xml_info,
"stroke-linecap",0);
2555 if (child != (XMLTreeInfo *) NULL)
2557 (void) CopyMagickString(value,CommandOptionToMnemonic(
2558 MagickLineCapOptions,(ssize_t) CurrentContext->linecap),MaxTextExtent);
2559 (void) SetXMLTreeContent(child,value);
2561 child=AddChildToXMLTree(xml_info,
"stroke-linejoin",0);
2562 if (child != (XMLTreeInfo *) NULL)
2564 (void) CopyMagickString(value,CommandOptionToMnemonic(
2565 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin),
2567 (void) SetXMLTreeContent(child,value);
2569 child=AddChildToXMLTree(xml_info,
"stroke-miterlimit",0);
2570 if (child != (XMLTreeInfo *) NULL)
2572 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",(
double)
2573 CurrentContext->miterlimit);
2574 (void) SetXMLTreeContent(child,value);
2576 child=AddChildToXMLTree(xml_info,
"stroke-opacity",0);
2577 if (child != (XMLTreeInfo *) NULL)
2579 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",QuantumScale*
2580 ((
double) QuantumRange-(
double) CurrentContext->stroke.opacity));
2581 (void) SetXMLTreeContent(child,value);
2583 child=AddChildToXMLTree(xml_info,
"stroke-width",0);
2584 if (child != (XMLTreeInfo *) NULL)
2586 (void) FormatLocaleString(value,MaxTextExtent,
"%.20g",
2587 CurrentContext->stroke_width);
2588 (void) SetXMLTreeContent(child,value);
2590 child=AddChildToXMLTree(xml_info,
"text-align",0);
2591 if (child != (XMLTreeInfo *) NULL)
2593 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions,
2594 (ssize_t) CurrentContext->align),MaxTextExtent);
2595 (void) SetXMLTreeContent(child,value);
2597 child=AddChildToXMLTree(xml_info,
"text-antialias",0);
2598 if (child != (XMLTreeInfo *) NULL)
2600 (void) FormatLocaleString(value,MaxTextExtent,
"%d",
2601 CurrentContext->text_antialias != MagickFalse ? 1 : 0);
2602 (void) SetXMLTreeContent(child,value);
2604 child=AddChildToXMLTree(xml_info,
"text-undercolor",0);
2605 if (child != (XMLTreeInfo *) NULL)
2607 if (CurrentContext->undercolor.opacity != OpaqueOpacity)
2608 pixel.matte=CurrentContext->undercolor.opacity != OpaqueOpacity ?
2609 MagickTrue : MagickFalse;
2610 SetMagickPixelPacket(wand->image,&CurrentContext->undercolor,
2611 (
const IndexPacket *) NULL,&pixel);
2612 GetColorTuple(&pixel,MagickTrue,value);
2613 (void) SetXMLTreeContent(child,value);
2615 child=AddChildToXMLTree(xml_info,
"vector-graphics",0);
2616 if (child != (XMLTreeInfo *) NULL)
2617 (void) SetXMLTreeContent(child,wand->mvg);
2618 xml=XMLTreeInfoToXML(xml_info);
2619 xml_info=DestroyXMLTree(xml_info);
2649WandExport
void DrawGetTextUnderColor(
const DrawingWand *wand,
2653 assert(wand->signature == WandSignature);
2654 assert(under_color != (
PixelWand *) NULL);
2655 if (wand->debug != MagickFalse)
2656 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2657 PixelSetQuantumColor(under_color,&CurrentContext->undercolor);
2692WandExport
void DrawLine(
DrawingWand *wand,
const double sx,
const double sy,
2693 const double ex,
const double ey)
2696 assert(wand->signature == WandSignature);
2697 if (wand->debug != MagickFalse)
2698 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2699 (void) MVGPrintf(wand,
"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey);
2741WandExport
void DrawMatte(
DrawingWand *wand,
const double x,
const double y,
2742 const PaintMethod paint_method)
2745 assert(wand->signature == WandSignature);
2746 if (wand->debug != MagickFalse)
2747 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2748 (void) MVGPrintf(wand,
"matte %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic(
2749 MagickMethodOptions,(ssize_t) paint_method));
2780 assert(wand->signature == WandSignature);
2781 if (wand->debug != MagickFalse)
2782 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2783 (void) MVGAutoWrapPrintf(wand,
"%s",wand->path_mode == AbsolutePathMode ?
2828static void DrawPathCurveTo(
DrawingWand *wand,
const PathMode mode,
2829 const double x1,
const double y1,
const double x2,
const double y2,
2830 const double x,
const double y)
2833 assert(wand->signature == WandSignature);
2834 if (wand->debug != MagickFalse)
2835 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2836 if ((wand->path_operation != PathCurveToOperation) ||
2837 (wand->path_mode != mode))
2839 wand->path_operation=PathCurveToOperation;
2840 wand->path_mode=mode;
2841 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %.20g %.20g %.20g",
2842 mode == AbsolutePathMode ?
'C' :
'c',x1,y1,x2,y2,x,y);
2845 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1,
2849WandExport
void DrawPathCurveToAbsolute(
DrawingWand *wand,
const double x1,
2850 const double y1,
const double x2,
const double y2,
const double x,
const double y)
2853 assert(wand->signature == WandSignature);
2854 if (wand->debug != MagickFalse)
2855 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2856 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y);
2899WandExport
void DrawPathCurveToRelative(
DrawingWand *wand,
const double x1,
2900 const double y1,
const double x2,
const double y2,
const double x,
const double y)
2903 assert(wand->signature == WandSignature);
2904 if (wand->debug != MagickFalse)
2905 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2906 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y);
2944static void DrawPathCurveToQuadraticBezier(
DrawingWand *wand,
2945 const PathMode mode,
const double x1,
double y1,
const double x,
const double y)
2948 assert(wand->signature == WandSignature);
2949 if (wand->debug != MagickFalse)
2950 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2951 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) ||
2952 (wand->path_mode != mode))
2954 wand->path_operation=PathCurveToQuadraticBezierOperation;
2955 wand->path_mode=mode;
2956 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %.20g",
2957 mode == AbsolutePathMode ?
'Q' :
'q',x1,y1,x,y);
2960 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %.20g",x1,y1,x,y);
2963WandExport
void DrawPathCurveToQuadraticBezierAbsolute(
DrawingWand *wand,
2964 const double x1,
const double y1,
const double x,
const double y)
2967 assert(wand->signature == WandSignature);
2968 if (wand->debug != MagickFalse)
2969 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
2970 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y);
3007WandExport
void DrawPathCurveToQuadraticBezierRelative(
DrawingWand *wand,
3008 const double x1,
const double y1,
const double x,
const double y)
3011 assert(wand->signature == WandSignature);
3012 if (wand->debug != MagickFalse)
3013 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3014 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y);
3056static void DrawPathCurveToQuadraticBezierSmooth(
DrawingWand *wand,
3057 const PathMode mode,
const double x,
const double y)
3060 assert(wand->signature == WandSignature);
3061 if (wand->debug != MagickFalse)
3062 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3063 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) ||
3064 (wand->path_mode != mode))
3066 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation;
3067 wand->path_mode=mode;
3068 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g",mode == AbsolutePathMode ?
3072 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g",x,y);
3075WandExport
void DrawPathCurveToQuadraticBezierSmoothAbsolute(
DrawingWand *wand,
3076 const double x,
const double y)
3079 assert(wand->signature == WandSignature);
3080 if (wand->debug != MagickFalse)
3081 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3082 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y);
3122WandExport
void DrawPathCurveToQuadraticBezierSmoothRelative(
DrawingWand *wand,
3123 const double x,
const double y)
3125 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y);
3170static void DrawPathCurveToSmooth(
DrawingWand *wand,
const PathMode mode,
3171 const double x2,
const double y2,
const double x,
const double y)
3174 assert(wand->signature == WandSignature);
3175 if (wand->debug != MagickFalse)
3176 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3177 if ((wand->path_operation != PathCurveToSmoothOperation) ||
3178 (wand->path_mode != mode))
3180 wand->path_operation=PathCurveToSmoothOperation;
3181 wand->path_mode=mode;
3182 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %.20g",
3183 mode == AbsolutePathMode ?
'S' :
's',x2,y2,x,y);
3186 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %.20g",x2,y2,x,y);
3189WandExport
void DrawPathCurveToSmoothAbsolute(
DrawingWand *wand,
const double x2,
3190 const double y2,
const double x,
const double y)
3193 assert(wand->signature == WandSignature);
3194 if (wand->debug != MagickFalse)
3195 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3196 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y);
3239WandExport
void DrawPathCurveToSmoothRelative(
DrawingWand *wand,
const double x2,
3240 const double y2,
const double x,
const double y)
3243 assert(wand->signature == WandSignature);
3244 if (wand->debug != MagickFalse)
3245 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3246 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y);
3298static void DrawPathEllipticArc(
DrawingWand *wand,
const PathMode mode,
3299 const double rx,
const double ry,
const double x_axis_rotation,
3300 const MagickBooleanType large_arc_flag,
const MagickBooleanType sweep_flag,
3301 const double x,
const double y)
3304 assert(wand->signature == WandSignature);
3305 if (wand->debug != MagickFalse)
3306 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3307 if ((wand->path_operation != PathEllipticArcOperation) ||
3308 (wand->path_mode != mode))
3310 wand->path_operation=PathEllipticArcOperation;
3311 wand->path_mode=mode;
3312 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g %.20g %u %u %.20g %.20g",
3313 mode == AbsolutePathMode ?
'A' :
'a',rx,ry,x_axis_rotation,
3314 large_arc_flag,sweep_flag,x,y);
3317 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry,
3318 x_axis_rotation,large_arc_flag,sweep_flag,x,y);
3321WandExport
void DrawPathEllipticArcAbsolute(
DrawingWand *wand,
const double rx,
3322 const double ry,
const double x_axis_rotation,
3323 const MagickBooleanType large_arc_flag,
const MagickBooleanType sweep_flag,
3324 const double x,
const double y)
3327 assert(wand->signature == WandSignature);
3328 if (wand->debug != MagickFalse)
3329 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3330 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation,
3331 large_arc_flag,sweep_flag,x,y);
3381WandExport
void DrawPathEllipticArcRelative(
DrawingWand *wand,
const double rx,
3382 const double ry,
const double x_axis_rotation,
3383 const MagickBooleanType large_arc_flag,
const MagickBooleanType sweep_flag,
3384 const double x,
const double y)
3386 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation,
3387 large_arc_flag,sweep_flag,x,y);
3415 assert(wand->signature == WandSignature);
3416 if (wand->debug != MagickFalse)
3417 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3418 (void) MVGPrintf(wand,
"'\n");
3419 wand->path_operation=PathDefaultOperation;
3420 wand->path_mode=DefaultPathMode;
3452static void DrawPathLineTo(
DrawingWand *wand,
const PathMode mode,
3453 const double x,
const double y)
3456 assert(wand->signature == WandSignature);
3457 if (wand->debug != MagickFalse)
3458 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3459 if ((wand->path_operation != PathLineToOperation) ||
3460 (wand->path_mode != mode))
3462 wand->path_operation=PathLineToOperation;
3463 wand->path_mode=mode;
3464 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g",mode == AbsolutePathMode ?
3468 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g",x,y);
3471WandExport
void DrawPathLineToAbsolute(
DrawingWand *wand,
const double x,
3475 assert(wand->signature == WandSignature);
3476 if (wand->debug != MagickFalse)
3477 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3478 DrawPathLineTo(wand,AbsolutePathMode,x,y);
3510WandExport
void DrawPathLineToRelative(
DrawingWand *wand,
const double x,
3514 assert(wand->signature == WandSignature);
3515 if (wand->debug != MagickFalse)
3516 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3517 DrawPathLineTo(wand,RelativePathMode,x,y);
3548static void DrawPathLineToHorizontal(
DrawingWand *wand,
const PathMode mode,
3552 assert(wand->signature == WandSignature);
3553 if (wand->debug != MagickFalse)
3554 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3555 if ((wand->path_operation != PathLineToHorizontalOperation) ||
3556 (wand->path_mode != mode))
3558 wand->path_operation=PathLineToHorizontalOperation;
3559 wand->path_mode=mode;
3560 (void) MVGAutoWrapPrintf(wand,
"%c%.20g",mode == AbsolutePathMode ?
3564 (
void) MVGAutoWrapPrintf(wand,
" %.20g",x);
3567WandExport
void DrawPathLineToHorizontalAbsolute(
DrawingWand *wand,
3571 assert(wand->signature == WandSignature);
3572 if (wand->debug != MagickFalse)
3573 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3574 DrawPathLineToHorizontal(wand,AbsolutePathMode,x);
3604WandExport
void DrawPathLineToHorizontalRelative(
DrawingWand *wand,
3607 DrawPathLineToHorizontal(wand,RelativePathMode,x);
3638static void DrawPathLineToVertical(
DrawingWand *wand,
const PathMode mode,
3642 assert(wand->signature == WandSignature);
3643 if (wand->debug != MagickFalse)
3644 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3645 if ((wand->path_operation != PathLineToVerticalOperation) ||
3646 (wand->path_mode != mode))
3648 wand->path_operation=PathLineToVerticalOperation;
3649 wand->path_mode=mode;
3650 (void) MVGAutoWrapPrintf(wand,
"%c%.20g",mode == AbsolutePathMode ?
3654 (
void) MVGAutoWrapPrintf(wand,
" %.20g",y);
3657WandExport
void DrawPathLineToVerticalAbsolute(
DrawingWand *wand,
const double y)
3660 assert(wand->signature == WandSignature);
3661 if (wand->debug != MagickFalse)
3662 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3663 DrawPathLineToVertical(wand,AbsolutePathMode,y);
3693WandExport
void DrawPathLineToVerticalRelative(
DrawingWand *wand,
const double y)
3696 assert(wand->signature == WandSignature);
3697 if (wand->debug != MagickFalse)
3698 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3699 DrawPathLineToVertical(wand,RelativePathMode,y);
3731static void DrawPathMoveTo(
DrawingWand *wand,
const PathMode mode,
const double x,
3735 assert(wand->signature == WandSignature);
3736 if (wand->debug != MagickFalse)
3737 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3738 if ((wand->path_operation != PathMoveToOperation) ||
3739 (wand->path_mode != mode))
3741 wand->path_operation=PathMoveToOperation;
3742 wand->path_mode=mode;
3743 (void) MVGAutoWrapPrintf(wand,
"%c%.20g %.20g",mode == AbsolutePathMode ?
3747 (
void) MVGAutoWrapPrintf(wand,
" %.20g %.20g",x,y);
3750WandExport
void DrawPathMoveToAbsolute(
DrawingWand *wand,
const double x,
3754 assert(wand->signature == WandSignature);
3755 if (wand->debug != MagickFalse)
3756 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3757 DrawPathMoveTo(wand,AbsolutePathMode,x,y);
3789WandExport
void DrawPathMoveToRelative(
DrawingWand *wand,
const double x,
3793 assert(wand->signature == WandSignature);
3794 if (wand->debug != MagickFalse)
3795 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3796 DrawPathMoveTo(wand,RelativePathMode,x,y);
3828 assert(wand->signature == WandSignature);
3829 if (wand->debug != MagickFalse)
3830 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3831 (void) MVGPrintf(wand,
"path '");
3832 wand->path_operation=PathDefaultOperation;
3833 wand->path_mode=DefaultPathMode;
3862WandExport
void DrawPoint(
DrawingWand *wand,
const double x,
const double y)
3865 assert(wand->signature == WandSignature);
3866 if (wand->debug != MagickFalse)
3867 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3868 (void) MVGPrintf(wand,
"point %.20g %.20g\n",x,y);
3900 const size_t number_coordinates,
const PointInfo *coordinates)
3903 assert(wand->signature == WandSignature);
3904 if (wand->debug != MagickFalse)
3905 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3906 MVGAppendPointsCommand(wand,
"polygon",number_coordinates,coordinates);
3938 const size_t number_coordinates,
const PointInfo *coordinates)
3941 assert(wand->signature == WandSignature);
3942 if (wand->debug != MagickFalse)
3943 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3944 MVGAppendPointsCommand(wand,
"polyline",number_coordinates,coordinates);
3972 assert(wand->signature == WandSignature);
3973 if (wand->debug != MagickFalse)
3974 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
3975 if (wand->indent_depth > 0)
3976 wand->indent_depth--;
3977 (void) MVGPrintf(wand,
"pop clip-path\n");
4005 assert(wand->signature == WandSignature);
4006 if (wand->debug != MagickFalse)
4007 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4008 if (wand->indent_depth > 0)
4009 wand->indent_depth--;
4010 (void) MVGPrintf(wand,
"pop defs\n");
4035WandExport MagickBooleanType DrawPopPattern(
DrawingWand *wand)
4038 geometry[MaxTextExtent],
4042 assert(wand->signature == WandSignature);
4043 if (wand->debug != MagickFalse)
4044 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4045 if (wand->image == (Image *) NULL)
4046 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4047 if (wand->pattern_id == (
const char *) NULL)
4049 ThrowDrawException(DrawWarning,
"NotCurrentlyPushingPatternDefinition",
4051 return(MagickFalse);
4053 (void) FormatLocaleString(key,MaxTextExtent,
"%s",wand->pattern_id);
4054 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset);
4055 (void) FormatLocaleString(geometry,MaxTextExtent,
"%.20gx%.20g%+.20g%+.20g",
4056 (
double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height,
4057 (
double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y);
4058 (void) SetImageArtifact(wand->image,key,geometry);
4059 wand->pattern_id=DestroyString(wand->pattern_id);
4060 wand->pattern_offset=0;
4061 wand->pattern_bounds.x=0;
4062 wand->pattern_bounds.y=0;
4063 wand->pattern_bounds.width=0;
4064 wand->pattern_bounds.height=0;
4065 wand->filter_off=MagickTrue;
4066 if (wand->indent_depth > 0)
4067 wand->indent_depth--;
4068 (void) MVGPrintf(wand,
"pop pattern\n");
4098WandExport
void DrawPushClipPath(
DrawingWand *wand,
const char *clip_mask_id)
4101 assert(wand->signature == WandSignature);
4102 if (wand->debug != MagickFalse)
4103 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4104 assert(clip_mask_id != (
const char *) NULL);
4105 (void) MVGPrintf(wand,
"push clip-path \"%s\"\n",clip_mask_id);
4106 wand->indent_depth++;
4136 assert(wand->signature == WandSignature);
4137 if (wand->debug != MagickFalse)
4138 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4139 (void) MVGPrintf(wand,
"push defs\n");
4140 wand->indent_depth++;
4182WandExport MagickBooleanType DrawPushPattern(
DrawingWand *wand,
4183 const char *pattern_id,
const double x,
const double y,
const double width,
4184 const double height)
4187 assert(wand->signature == WandSignature);
4188 if (wand->debug != MagickFalse)
4189 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4190 assert(pattern_id != (
const char *) NULL);
4191 if (wand->pattern_id != NULL)
4193 ThrowDrawException(DrawError,
"AlreadyPushingPatternDefinition",
4195 return(MagickFalse);
4197 wand->filter_off=MagickTrue;
4198 (void) MVGPrintf(wand,
"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id,
4200 wand->indent_depth++;
4201 wand->pattern_id=AcquireString(pattern_id);
4202 wand->pattern_bounds.x=CastDoubleToLong(ceil(x-0.5));
4203 wand->pattern_bounds.y=CastDoubleToLong(ceil(y-0.5));
4204 wand->pattern_bounds.width=(size_t) CastDoubleToLong(floor(width+0.5));
4205 wand->pattern_bounds.height=(size_t) CastDoubleToLong(floor(height+0.5));
4206 wand->pattern_offset=wand->mvg_length;
4240WandExport
void DrawRectangle(
DrawingWand *wand,
const double x1,
const double y1,
4241 const double x2,
const double y2)
4244 assert(wand->signature == WandSignature);
4245 if (wand->debug != MagickFalse)
4246 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4247 if ((fabs(x2-x1) < MagickEpsilon) && (fabs(y2-y1) < MagickEpsilon))
4248 (void) MVGPrintf(wand,
"point %.20g %.20g\n",x1,y1);
4250 (
void) MVGPrintf(wand,
"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2);
4275WandExport MagickBooleanType DrawRender(
DrawingWand *wand)
4281 assert(wand->signature == WandSignature);
4282 if (wand->debug != MagickFalse)
4283 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4284 CurrentContext->primitive=wand->mvg;
4285 if (wand->debug != MagickFalse)
4286 (void) LogMagickEvent(DrawEvent,GetMagickModule(),
"MVG:\n'%s'\n",wand->mvg);
4287 if (wand->image == (Image *) NULL)
4288 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4289 status=DrawImage(wand->image,CurrentContext);
4290 InheritException(wand->exception,&wand->image->exception);
4291 CurrentContext->primitive=(
char *) NULL;
4318WandExport
void DrawResetVectorGraphics(
DrawingWand *wand)
4321 assert(wand->signature == WandSignature);
4322 if (wand->debug != MagickFalse)
4323 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4324 if (wand->mvg != (
char *) NULL)
4325 wand->mvg=DestroyString(wand->mvg);
4355WandExport
void DrawRotate(
DrawingWand *wand,
const double degrees)
4358 assert(wand->signature == WandSignature);
4359 if (wand->debug != MagickFalse)
4360 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4361 (void) MVGPrintf(wand,
"rotate %.20g\n",degrees);
4401WandExport
void DrawRoundRectangle(
DrawingWand *wand,
double x1,
double y1,
4402 double x2,
double y2,
double rx,
double ry)
4405 assert(wand->signature == WandSignature);
4406 if (wand->debug != MagickFalse)
4407 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4408 (void) MVGPrintf(wand,
"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n",
4439WandExport
void DrawScale(
DrawingWand *wand,
const double x,
const double y)
4442 assert(wand->signature == WandSignature);
4443 if (wand->debug != MagickFalse)
4444 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4445 (void) MVGPrintf(wand,
"scale %.20g %.20g\n",x,y);
4474static inline MagickBooleanType IsColorEqual(
const PixelPacket *p,
4475 const PixelPacket *q)
4477 if (GetPixelRed(p) != GetPixelRed(q))
4478 return(MagickFalse);
4479 if (GetPixelGreen(p) != GetPixelGreen(q))
4480 return(MagickFalse);
4481 if (GetPixelBlue(p) != GetPixelBlue(q))
4482 return(MagickFalse);
4483 if (GetPixelOpacity(p) != GetPixelOpacity(q))
4484 return(MagickFalse);
4488WandExport
void DrawSetBorderColor(
DrawingWand *wand,
4497 assert(wand->signature == WandSignature);
4498 if (wand->debug != MagickFalse)
4499 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4500 assert(border_wand != (
const PixelWand *) NULL);
4501 PixelGetQuantumColor(border_wand,&border_color);
4502 new_border=border_color;
4503 current_border=(&CurrentContext->border_color);
4504 if ((wand->filter_off != MagickFalse) ||
4505 (IsColorEqual(current_border,&new_border) == MagickFalse))
4507 CurrentContext->border_color=new_border;
4508 (void) MVGPrintf(wand,
"border-color '");
4509 MVGAppendColor(wand,&border_color);
4510 (void) MVGPrintf(wand,
"'\n");
4541WandExport MagickBooleanType DrawSetClipPath(
DrawingWand *wand,
4542 const char *clip_mask)
4545 if (wand->debug != MagickFalse)
4546 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",clip_mask);
4547 assert(wand->signature == WandSignature);
4548 assert(clip_mask != (
const char *) NULL);
4549 if ((CurrentContext->clip_mask == (
const char *) NULL) ||
4550 (wand->filter_off != MagickFalse) ||
4551 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0))
4553 (void) CloneString(&CurrentContext->clip_mask,clip_mask);
4554#if DRAW_BINARY_IMPLEMENTATION
4555 if (wand->image == (Image *) NULL)
4556 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4557 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask);
4559 (void) MVGPrintf(wand,
"clip-path url(#%s)\n",clip_mask);
4588WandExport
void DrawSetClipRule(
DrawingWand *wand,
const FillRule fill_rule)
4591 assert(wand->signature == WandSignature);
4592 if (wand->debug != MagickFalse)
4593 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4594 if ((wand->filter_off != MagickFalse) ||
4595 (CurrentContext->fill_rule != fill_rule))
4597 CurrentContext->fill_rule=fill_rule;
4598 (void) MVGPrintf(wand,
"clip-rule '%s'\n",CommandOptionToMnemonic(
4599 MagickFillRuleOptions,(ssize_t) fill_rule));
4629WandExport
void DrawSetClipUnits(
DrawingWand *wand,
4630 const ClipPathUnits clip_units)
4633 assert(wand->signature == WandSignature);
4634 if (wand->debug != MagickFalse)
4635 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4636 if ((wand->filter_off != MagickFalse) ||
4637 (CurrentContext->clip_units != clip_units))
4639 CurrentContext->clip_units=clip_units;
4640 if (clip_units == ObjectBoundingBox)
4645 GetAffineMatrix(&affine);
4646 affine.sx=CurrentContext->bounds.x2;
4647 affine.sy=CurrentContext->bounds.y2;
4648 affine.tx=CurrentContext->bounds.x1;
4649 affine.ty=CurrentContext->bounds.y1;
4650 AdjustAffine(wand,&affine);
4652 (void) MVGPrintf(wand,
"clip-units '%s'\n",CommandOptionToMnemonic(
4653 MagickClipPathOptions,(ssize_t) clip_units));
4682WandExport MagickBooleanType DrawSetDensity(
DrawingWand *wand,
4683 const char *density)
4686 if (wand->debug != MagickFalse)
4687 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",density);
4688 assert(wand->signature == MagickCoreSignature);
4689 assert(density != (
const char *) NULL);
4690 if ((CurrentContext->density == (
const char *) NULL) ||
4691 (wand->filter_off != MagickFalse) ||
4692 (LocaleCompare(CurrentContext->density,density) != 0))
4694 (void) CloneString(&CurrentContext->density,density);
4695 (void) MVGPrintf(wand,
"density '%s'\n",density);
4732 assert(wand->signature == WandSignature);
4733 if (wand->debug != MagickFalse)
4734 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4735 assert(fill_wand != (
const PixelWand *) NULL);
4736 PixelGetQuantumColor(fill_wand,&fill_color);
4737 new_fill=fill_color;
4738 current_fill=(&CurrentContext->fill);
4739 if ((wand->filter_off != MagickFalse) ||
4740 (IsColorEqual(current_fill,&new_fill) == MagickFalse))
4742 CurrentContext->fill=new_fill;
4743 (void) MVGPrintf(wand,
"fill '");
4744 MVGAppendColor(wand,&fill_color);
4745 (void) MVGPrintf(wand,
"'\n");
4774WandExport
void DrawSetFillOpacity(
DrawingWand *wand,
const double fill_opacity)
4780 assert(wand->signature == WandSignature);
4781 if (wand->debug != MagickFalse)
4782 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4783 opacity=ClampToQuantum((
double) QuantumRange*(1.0-fill_opacity));
4784 if ((wand->filter_off != MagickFalse) ||
4785 (CurrentContext->fill.opacity != opacity))
4787 CurrentContext->fill.opacity=opacity;
4788 (void) MVGPrintf(wand,
"fill-opacity %.20g\n",fill_opacity);
4819WandExport MagickBooleanType DrawSetFontResolution(
DrawingWand *wand,
4820 const double x_resolution,
const double y_resolution)
4823 density[MaxTextExtent];
4826 assert(wand->signature == WandSignature);
4827 if (wand->debug != MagickFalse)
4828 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4829 (void) FormatLocaleString(density,MaxTextExtent,
"%.20gx%.20g",x_resolution,
4831 (void) CloneString(&CurrentContext->density,density);
4860WandExport
void DrawSetOpacity(
DrawingWand *wand,
const double opacity)
4866 assert(wand->signature == WandSignature);
4867 if (wand->debug != MagickFalse)
4868 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4869 quantum_opacity=ClampToQuantum((
double) QuantumRange*(1.0-opacity));
4870 if ((wand->filter_off != MagickFalse) ||
4871 (CurrentContext->opacity != quantum_opacity))
4873 CurrentContext->opacity=quantum_opacity;
4874 (void) MVGPrintf(wand,
"opacity %.20g\n",opacity);
4906WandExport MagickBooleanType DrawSetFillPatternURL(
DrawingWand *wand,
4907 const char *fill_url)
4910 pattern[MaxTextExtent],
4911 pattern_spec[MaxTextExtent];
4914 assert(wand->signature == WandSignature);
4915 if (wand->debug != MagickFalse)
4916 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",fill_url);
4917 if (wand->image == (Image *) NULL)
4918 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
4919 assert(fill_url != (
const char *) NULL);
4920 if (*fill_url !=
'#')
4922 ThrowDrawException(DrawError,
"NotARelativeURL",fill_url);
4923 return(MagickFalse);
4925 (void) FormatLocaleString(pattern,MaxTextExtent,
"%s",fill_url+1);
4926 if (GetImageArtifact(wand->image,pattern) == (
const char *) NULL)
4928 ThrowDrawException(DrawError,
"URLNotFound",fill_url)
4929 return(MagickFalse);
4931 (void) FormatLocaleString(pattern_spec,MaxTextExtent,
"url(%s)",fill_url);
4932#if DRAW_BINARY_IMPLEMENTATION
4933 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
4934 &CurrentContext->fill_pattern);
4936 if (CurrentContext->fill.opacity != (Quantum) TransparentOpacity)
4937 CurrentContext->fill.opacity=CurrentContext->opacity;
4938 (void) MVGPrintf(wand,
"fill %s\n",pattern_spec);
4966WandExport
void DrawSetFillRule(
DrawingWand *wand,
const FillRule fill_rule)
4969 assert(wand->signature == WandSignature);
4970 if (wand->debug != MagickFalse)
4971 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
4972 if ((wand->filter_off != MagickFalse) ||
4973 (CurrentContext->fill_rule != fill_rule))
4975 CurrentContext->fill_rule=fill_rule;
4976 (void) MVGPrintf(wand,
"fill-rule '%s'\n",CommandOptionToMnemonic(
4977 MagickFillRuleOptions,(ssize_t) fill_rule));
5006WandExport MagickBooleanType DrawSetFont(
DrawingWand *wand,
5007 const char *font_name)
5010 assert(wand->signature == WandSignature);
5011 if (wand->debug != MagickFalse)
5012 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5013 assert(font_name != (
const char *) NULL);
5014 if ((wand->filter_off != MagickFalse) ||
5015 (CurrentContext->font == (
char *) NULL) ||
5016 (LocaleCompare(CurrentContext->font,font_name) != 0))
5018 (void) CloneString(&CurrentContext->font,font_name);
5019 (void) MVGPrintf(wand,
"font '%s'\n",font_name);
5049WandExport MagickBooleanType DrawSetFontFamily(
DrawingWand *wand,
5050 const char *font_family)
5053 assert(wand->signature == WandSignature);
5054 if (wand->debug != MagickFalse)
5055 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5056 assert(font_family != (
const char *) NULL);
5057 if ((wand->filter_off != MagickFalse) ||
5058 (CurrentContext->family == (
const char *) NULL) ||
5059 (LocaleCompare(CurrentContext->family,font_family) != 0))
5061 (void) CloneString(&CurrentContext->family,font_family);
5062 (void) MVGPrintf(wand,
"font-family '%s'\n",font_family);
5091WandExport
void DrawSetFontSize(
DrawingWand *wand,
const double pointsize)
5094 assert(wand->signature == WandSignature);
5095 if (wand->debug != MagickFalse)
5096 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5097 if ((wand->filter_off != MagickFalse) ||
5098 (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon))
5100 CurrentContext->pointsize=pointsize;
5101 (void) MVGPrintf(wand,
"font-size %.20g\n",pointsize);
5134WandExport
void DrawSetFontStretch(
DrawingWand *wand,
5135 const StretchType font_stretch)
5138 assert(wand->signature == WandSignature);
5139 if (wand->debug != MagickFalse)
5140 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5141 if ((wand->filter_off != MagickFalse) ||
5142 (CurrentContext->stretch != font_stretch))
5144 CurrentContext->stretch=font_stretch;
5145 (void) MVGPrintf(wand,
"font-stretch '%s'\n",CommandOptionToMnemonic(
5146 MagickStretchOptions,(ssize_t) font_stretch));
5175WandExport
void DrawSetFontStyle(
DrawingWand *wand,
const StyleType style)
5178 assert(wand->signature == WandSignature);
5179 if (wand->debug != MagickFalse)
5180 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5181 if ((wand->filter_off != MagickFalse) ||
5182 (CurrentContext->style != style))
5184 CurrentContext->style=style;
5185 (void) MVGPrintf(wand,
"font-style '%s'\n",CommandOptionToMnemonic(
5186 MagickStyleOptions,(ssize_t) style));
5215WandExport
void DrawSetFontWeight(
DrawingWand *wand,
5216 const size_t font_weight)
5219 assert(wand->signature == WandSignature);
5220 if (wand->debug != MagickFalse)
5221 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5222 if ((wand->filter_off != MagickFalse) ||
5223 (CurrentContext->weight != font_weight))
5225 CurrentContext->weight=font_weight;
5226 (void) MVGPrintf(wand,
"font-weight %.20g\n",(
double) font_weight);
5258WandExport
void DrawSetGravity(
DrawingWand *wand,
const GravityType gravity)
5261 assert(wand->signature == WandSignature);
5262 if (wand->debug != MagickFalse)
5263 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5264 if ((wand->filter_off != MagickFalse) ||
5265 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity))
5267 CurrentContext->gravity=gravity;
5268 (void) MVGPrintf(wand,
"gravity '%s'\n",CommandOptionToMnemonic(
5269 MagickGravityOptions,(ssize_t) gravity));
5298WandExport
void DrawSetStrokeColor(
DrawingWand *wand,
5307 assert(wand->signature == WandSignature);
5308 if (wand->debug != MagickFalse)
5309 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5310 assert(stroke_wand != (
const PixelWand *) NULL);
5311 PixelGetQuantumColor(stroke_wand,&stroke_color);
5312 new_stroke=stroke_color;
5313 current_stroke=(&CurrentContext->stroke);
5314 if ((wand->filter_off != MagickFalse) ||
5315 (IsColorEqual(current_stroke,&new_stroke) == MagickFalse))
5317 CurrentContext->stroke=new_stroke;
5318 (void) MVGPrintf(wand,
"stroke '");
5319 MVGAppendColor(wand,&stroke_color);
5320 (void) MVGPrintf(wand,
"'\n");
5349WandExport MagickBooleanType DrawSetStrokePatternURL(
DrawingWand *wand,
5350 const char *stroke_url)
5353 pattern[MaxTextExtent],
5354 pattern_spec[MaxTextExtent];
5357 assert(wand->signature == WandSignature);
5358 if (wand->debug != MagickFalse)
5359 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5360 if (wand->image == (Image *) NULL)
5361 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
5362 assert(stroke_url != NULL);
5363 if (stroke_url[0] !=
'#')
5364 ThrowDrawException(DrawError,
"NotARelativeURL",stroke_url);
5365 (void) FormatLocaleString(pattern,MaxTextExtent,
"%s",stroke_url+1);
5366 if (GetImageArtifact(wand->image,pattern) == (
const char *) NULL)
5368 ThrowDrawException(DrawError,
"URLNotFound",stroke_url)
5369 return(MagickFalse);
5371 (void) FormatLocaleString(pattern_spec,MaxTextExtent,
"url(%s)",stroke_url);
5372#if DRAW_BINARY_IMPLEMENTATION
5373 DrawPatternPath(wand->image,CurrentContext,pattern_spec,
5374 &CurrentContext->stroke_pattern);
5376 if (CurrentContext->stroke.opacity != (Quantum) TransparentOpacity)
5377 CurrentContext->stroke.opacity=CurrentContext->opacity;
5378 (void) MVGPrintf(wand,
"stroke %s\n",pattern_spec);
5410WandExport
void DrawSetStrokeAntialias(
DrawingWand *wand,
5411 const MagickBooleanType stroke_antialias)
5414 assert(wand->signature == WandSignature);
5415 if (wand->debug != MagickFalse)
5416 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5417 if ((wand->filter_off != MagickFalse) ||
5418 (CurrentContext->stroke_antialias != stroke_antialias))
5420 CurrentContext->stroke_antialias=stroke_antialias;
5421 (void) MVGPrintf(wand,
"stroke-antialias %i\n",stroke_antialias != 0 ?
5459WandExport MagickBooleanType DrawSetStrokeDashArray(
DrawingWand *wand,
5460 const size_t number_elements,
const double *dasharray)
5479 assert(wand->signature == WandSignature);
5480 if (wand->debug != MagickFalse)
5481 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5482 n_new=number_elements;
5483 if (dasharray == (
const double *) NULL)
5487 q=CurrentContext->dash_pattern;
5488 if (q != (
const double *) NULL)
5489 while (fabs(*q++) < MagickEpsilon)
5491 if ((n_old == 0) && (n_new == 0))
5497 if ((CurrentContext->dash_pattern != (
double *) NULL) &&
5498 (dasharray != (
double *) NULL))
5501 q=CurrentContext->dash_pattern;
5502 for (i=0; i < (ssize_t) n_new; i++)
5504 if (fabs((*p)-(*q)) >= MagickEpsilon)
5513 if ((wand->filter_off != MagickFalse) || (update != MagickFalse))
5515 if (CurrentContext->dash_pattern != (
double *) NULL)
5516 CurrentContext->dash_pattern=(
double *)
5517 RelinquishMagickMemory(CurrentContext->dash_pattern);
5520 CurrentContext->dash_pattern=(
double *) AcquireQuantumMemory((
size_t)
5521 n_new+1UL,
sizeof(*CurrentContext->dash_pattern));
5522 if (CurrentContext->dash_pattern == (
double *) NULL)
5524 ThrowDrawException(ResourceLimitError,
"MemoryAllocationFailed",
5526 return(MagickFalse);
5528 for (i=0; i < (ssize_t) n_new; i++)
5530 CurrentContext->dash_pattern[i]=0.0;
5531 if (dasharray != (
double *) NULL)
5532 CurrentContext->dash_pattern[i]=dasharray[i];
5534 CurrentContext->dash_pattern[n_new]=0.0;
5536 (void) MVGPrintf(wand,
"stroke-dasharray ");
5538 (void) MVGPrintf(wand,
"none\n");
5540 if (dasharray != (
double *) NULL)
5542 for (i=0; i < (ssize_t) n_new; i++)
5545 (void) MVGPrintf(wand,
",");
5546 (void) MVGPrintf(wand,
"%.20g",dasharray[i]);
5548 (void) MVGPrintf(wand,
"\n");
5580WandExport
void DrawSetStrokeDashOffset(
DrawingWand *wand,
5581 const double dash_offset)
5584 assert(wand->signature == WandSignature);
5585 if (wand->debug != MagickFalse)
5586 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5587 if ((wand->filter_off != MagickFalse) ||
5588 (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon))
5590 CurrentContext->dash_offset=dash_offset;
5591 (void) MVGPrintf(wand,
"stroke-dashoffset %.20g\n",dash_offset);
5622WandExport
void DrawSetStrokeLineCap(
DrawingWand *wand,
const LineCap linecap)
5625 assert(wand->signature == WandSignature);
5626 if (wand->debug != MagickFalse)
5627 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5628 if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap))
5630 CurrentContext->linecap=linecap;
5631 (void) MVGPrintf(wand,
"stroke-linecap '%s'\n",CommandOptionToMnemonic(
5632 MagickLineCapOptions,(ssize_t) linecap));
5663WandExport
void DrawSetStrokeLineJoin(
DrawingWand *wand,
const LineJoin linejoin)
5666 assert(wand->signature == WandSignature);
5667 if (wand->debug != MagickFalse)
5668 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5669 if ((wand->filter_off != MagickFalse) ||
5670 (CurrentContext->linejoin != linejoin))
5672 CurrentContext->linejoin=linejoin;
5673 (void) MVGPrintf(wand,
"stroke-linejoin '%s'\n",CommandOptionToMnemonic(
5674 MagickLineJoinOptions,(ssize_t) linejoin));
5707WandExport
void DrawSetStrokeMiterLimit(
DrawingWand *wand,
5708 const size_t miterlimit)
5711 assert(wand->signature == WandSignature);
5712 if (wand->debug != MagickFalse)
5713 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5714 if (CurrentContext->miterlimit != miterlimit)
5716 CurrentContext->miterlimit=miterlimit;
5717 (void) MVGPrintf(wand,
"stroke-miterlimit %.20g\n",(
double) miterlimit);
5746WandExport
void DrawSetStrokeOpacity(
DrawingWand *wand,
5747 const double stroke_opacity)
5753 assert(wand->signature == WandSignature);
5754 if (wand->debug != MagickFalse)
5755 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5756 opacity=ClampToQuantum((
double) QuantumRange*(1.0-stroke_opacity));
5757 if ((wand->filter_off != MagickFalse) ||
5758 (CurrentContext->stroke.opacity != opacity))
5760 CurrentContext->stroke.opacity=opacity;
5761 (void) MVGPrintf(wand,
"stroke-opacity %.20g\n",stroke_opacity);
5791WandExport
void DrawSetStrokeWidth(
DrawingWand *wand,
const double stroke_width)
5794 assert(wand->signature == WandSignature);
5795 if (wand->debug != MagickFalse)
5796 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5797 if ((wand->filter_off != MagickFalse) ||
5798 (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon))
5800 CurrentContext->stroke_width=stroke_width;
5801 (void) MVGPrintf(wand,
"stroke-width %.20g\n",stroke_width);
5831WandExport
void DrawSetTextAlignment(
DrawingWand *wand,
5832 const AlignType alignment)
5835 assert(wand->signature == WandSignature);
5836 if (wand->debug != MagickFalse)
5837 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5838 if ((wand->filter_off != MagickFalse) ||
5839 (CurrentContext->align != alignment))
5841 CurrentContext->align=alignment;
5842 (void) MVGPrintf(wand,
"text-align '%s'\n",CommandOptionToMnemonic(
5843 MagickAlignOptions,(ssize_t) alignment));
5874WandExport
void DrawSetTextAntialias(
DrawingWand *wand,
5875 const MagickBooleanType text_antialias)
5878 assert(wand->signature == WandSignature);
5879 if (wand->debug != MagickFalse)
5880 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5881 if ((wand->filter_off != MagickFalse) ||
5882 (CurrentContext->text_antialias != text_antialias))
5884 CurrentContext->text_antialias=text_antialias;
5885 (void) MVGPrintf(wand,
"text-antialias %i\n",text_antialias != 0 ? 1 : 0);
5916WandExport
void DrawSetTextDecoration(
DrawingWand *wand,
5917 const DecorationType decoration)
5920 assert(wand->signature == WandSignature);
5921 if (wand->debug != MagickFalse)
5922 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5923 if ((wand->filter_off != MagickFalse) ||
5924 (CurrentContext->decorate != decoration))
5926 CurrentContext->decorate=decoration;
5927 (void) MVGPrintf(wand,
"decorate '%s'\n",CommandOptionToMnemonic(
5928 MagickDecorateOptions,(ssize_t) decoration));
5959WandExport
void DrawSetTextDirection(
DrawingWand *wand,
5960 const DirectionType direction)
5963 assert(wand->signature == WandSignature);
5965 if (wand->debug != MagickFalse)
5966 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
5967 if ((wand->filter_off != MagickFalse) ||
5968 (CurrentContext->direction != direction))
5970 CurrentContext->direction=direction;
5971 (void) MVGPrintf(wand,
"direction '%s'\n",CommandOptionToMnemonic(
5972 MagickDirectionOptions,(ssize_t) direction));
6005WandExport
void DrawSetTextEncoding(
DrawingWand *wand,
const char *encoding)
6008 assert(wand->signature == WandSignature);
6009 if (wand->debug != MagickFalse)
6010 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6011 assert(encoding != (
char *) NULL);
6012 if ((wand->filter_off != MagickFalse) ||
6013 (CurrentContext->encoding == (
char *) NULL) ||
6014 (LocaleCompare(CurrentContext->encoding,encoding) != 0))
6016 (void) CloneString(&CurrentContext->encoding,encoding);
6017 (void) MVGPrintf(wand,
"encoding '%s'\n",encoding);
6045WandExport
void DrawSetTextKerning(
DrawingWand *wand,
const double kerning)
6048 assert(wand->signature == WandSignature);
6050 if (wand->debug != MagickFalse)
6051 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6052 if ((wand->filter_off != MagickFalse) &&
6053 (fabs((CurrentContext->kerning-kerning)) >= MagickEpsilon))
6055 CurrentContext->kerning=kerning;
6056 (void) MVGPrintf(wand,
"kerning %lf\n",kerning);
6085WandExport
void DrawSetTextInterlineSpacing(
DrawingWand *wand,
6086 const double interline_spacing)
6089 assert(wand->signature == WandSignature);
6091 if (wand->debug != MagickFalse)
6092 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6093 if ((wand->filter_off != MagickFalse) &&
6094 (fabs((CurrentContext->interline_spacing-
6095 interline_spacing)) >= MagickEpsilon))
6097 CurrentContext->interline_spacing=interline_spacing;
6098 (void) MVGPrintf(wand,
"interline-spacing %lf\n",interline_spacing);
6127WandExport
void DrawSetTextInterwordSpacing(
DrawingWand *wand,
6128 const double interword_spacing)
6131 assert(wand->signature == WandSignature);
6133 if (wand->debug != MagickFalse)
6134 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6135 if ((wand->filter_off != MagickFalse) &&
6136 (fabs((CurrentContext->interword_spacing-
6137 interword_spacing)) >= MagickEpsilon))
6139 CurrentContext->interword_spacing=interword_spacing;
6140 (void) MVGPrintf(wand,
"interword-spacing %lf\n",interword_spacing);
6170WandExport
void DrawSetTextUnderColor(
DrawingWand *wand,
6177 assert(wand->signature == WandSignature);
6178 if (wand->debug != MagickFalse)
6179 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6180 assert(under_wand != (
const PixelWand *) NULL);
6181 PixelGetQuantumColor(under_wand,&under_color);
6182 if ((wand->filter_off != MagickFalse) ||
6183 (IsColorEqual(&CurrentContext->undercolor,&under_color) == MagickFalse))
6185 CurrentContext->undercolor=under_color;
6186 (void) MVGPrintf(wand,
"text-undercolor '");
6187 MVGAppendColor(wand,&under_color);
6188 (void) MVGPrintf(wand,
"'\n");
6220static inline MagickBooleanType IsPoint(
const char *point)
6228 value=strtol(point,&p,10);
6230 return(p != point ? MagickTrue : MagickFalse);
6233WandExport MagickBooleanType DrawSetVectorGraphics(
DrawingWand *wand,
6244 assert(wand->signature == WandSignature);
6245 if (wand->debug != MagickFalse)
6246 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6247 CurrentContext=DestroyDrawInfo(CurrentContext);
6248 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6249 if (xml == (
const char *) NULL)
6250 return(MagickFalse);
6251 xml_info=NewXMLTree(xml,wand->exception);
6252 if (xml_info == (XMLTreeInfo *) NULL)
6253 return(MagickFalse);
6254 child=GetXMLTreeChild(xml_info,
"clip-path");
6255 if (child != (XMLTreeInfo *) NULL)
6256 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child));
6257 child=GetXMLTreeChild(xml_info,
"clip-units");
6258 if (child != (XMLTreeInfo *) NULL)
6260 value=GetXMLTreeContent(child);
6261 if (value != (
const char *) NULL)
6262 CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption(
6263 MagickClipPathOptions,MagickFalse,value);
6265 child=GetXMLTreeChild(xml_info,
"decorate");
6266 if (child != (XMLTreeInfo *) NULL)
6268 value=GetXMLTreeContent(child);
6269 if (value != (
const char *) NULL)
6270 CurrentContext->decorate=(DecorationType) ParseCommandOption(
6271 MagickDecorateOptions,MagickFalse,value);
6273 child=GetXMLTreeChild(xml_info,
"encoding");
6274 if (child != (XMLTreeInfo *) NULL)
6275 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child));
6276 child=GetXMLTreeChild(xml_info,
"fill");
6277 if (child != (XMLTreeInfo *) NULL)
6279 value=GetXMLTreeContent(child);
6280 if (value != (
const char *) NULL)
6281 (void) QueryColorDatabase(value,&CurrentContext->fill,wand->exception);
6283 child=GetXMLTreeChild(xml_info,
"fill-opacity");
6284 if (child != (XMLTreeInfo *) NULL)
6286 value=GetXMLTreeContent(child);
6287 if (value != (
const char *) NULL)
6288 CurrentContext->fill.opacity=ClampToQuantum((MagickRealType)
6289 QuantumRange*(1.0-StringToDouble(value,(
char **) NULL)));
6291 child=GetXMLTreeChild(xml_info,
"fill-rule");
6292 if (child != (XMLTreeInfo *) NULL)
6294 value=GetXMLTreeContent(child);
6295 if (value != (
const char *) NULL)
6296 CurrentContext->fill_rule=(FillRule) ParseCommandOption(
6297 MagickFillRuleOptions,MagickFalse,value);
6299 child=GetXMLTreeChild(xml_info,
"font");
6300 if (child != (XMLTreeInfo *) NULL)
6301 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child));
6302 child=GetXMLTreeChild(xml_info,
"font-family");
6303 if (child != (XMLTreeInfo *) NULL)
6304 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child));
6305 child=GetXMLTreeChild(xml_info,
"font-size");
6306 if (child != (XMLTreeInfo *) NULL)
6308 value=GetXMLTreeContent(child);
6309 if (value != (
const char *) NULL)
6310 CurrentContext->pointsize=StringToDouble(value,(
char **) NULL);
6312 child=GetXMLTreeChild(xml_info,
"font-stretch");
6313 if (child != (XMLTreeInfo *) NULL)
6315 value=GetXMLTreeContent(child);
6316 if (value != (
const char *) NULL)
6317 CurrentContext->stretch=(StretchType) ParseCommandOption(
6318 MagickStretchOptions,MagickFalse,value);
6320 child=GetXMLTreeChild(xml_info,
"font-style");
6321 if (child != (XMLTreeInfo *) NULL)
6323 value=GetXMLTreeContent(child);
6324 if (value != (
const char *) NULL)
6325 CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions,
6328 child=GetXMLTreeChild(xml_info,
"font-weight");
6329 if (child != (XMLTreeInfo *) NULL)
6331 value=GetXMLTreeContent(child);
6332 if (value != (
const char *) NULL)
6333 CurrentContext->weight=StringToUnsignedLong(value);
6335 child=GetXMLTreeChild(xml_info,
"gravity");
6336 if (child != (XMLTreeInfo *) NULL)
6338 value=GetXMLTreeContent(child);
6339 if (value != (
const char *) NULL)
6340 CurrentContext->gravity=(GravityType) ParseCommandOption(
6341 MagickGravityOptions,MagickFalse,value);
6343 child=GetXMLTreeChild(xml_info,
"stroke");
6344 if (child != (XMLTreeInfo *) NULL)
6346 value=GetXMLTreeContent(child);
6347 if (value != (
const char *) NULL)
6348 (void) QueryColorDatabase(value,&CurrentContext->stroke,
6351 child=GetXMLTreeChild(xml_info,
"stroke-antialias");
6352 if (child != (XMLTreeInfo *) NULL)
6354 value=GetXMLTreeContent(child);
6355 if (value != (
const char *) NULL)
6356 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue :
6359 child=GetXMLTreeChild(xml_info,
"stroke-dasharray");
6360 if (child != (XMLTreeInfo *) NULL)
6363 token[MaxTextExtent];
6374 value=GetXMLTreeContent(child);
6375 if (value != (
const char *) NULL)
6377 if (CurrentContext->dash_pattern != (
double *) NULL)
6378 CurrentContext->dash_pattern=(
double *) RelinquishMagickMemory(
6379 CurrentContext->dash_pattern);
6381 if (IsPoint(q) != MagickFalse)
6387 (void) GetNextToken(p,&p,MaxTextExtent,token);
6389 (void) GetNextToken(p,&p,MaxTextExtent,token);
6390 for (x=0; IsPoint(token) != MagickFalse; x++)
6392 (void) GetNextToken(p,&p,MaxTextExtent,token);
6394 (void) GetNextToken(p,&p,MaxTextExtent,token);
6396 CurrentContext->dash_pattern=(
double *) AcquireQuantumMemory(
6397 (
size_t) (2UL*x)+1UL,
sizeof(*CurrentContext->dash_pattern));
6398 if (CurrentContext->dash_pattern == (
double *) NULL)
6399 ThrowWandFatalException(ResourceLimitFatalError,
6400 "MemoryAllocationFailed",wand->name);
6401 for (j=0; j < x; j++)
6403 (void) GetNextToken(q,&q,MaxTextExtent,token);
6405 (void) GetNextToken(q,&q,MaxTextExtent,token);
6406 CurrentContext->dash_pattern[j]=StringToDouble(token,
6409 if ((x & 0x01) != 0)
6410 for ( ; j < (2*x); j++)
6411 CurrentContext->dash_pattern[j]=
6412 CurrentContext->dash_pattern[j-x];
6413 CurrentContext->dash_pattern[j]=0.0;
6417 child=GetXMLTreeChild(xml_info,
"stroke-dashoffset");
6418 if (child != (XMLTreeInfo *) NULL)
6420 value=GetXMLTreeContent(child);
6421 if (value != (
const char *) NULL)
6422 CurrentContext->dash_offset=StringToDouble(value,(
char **) NULL);
6424 child=GetXMLTreeChild(xml_info,
"stroke-linecap");
6425 if (child != (XMLTreeInfo *) NULL)
6427 value=GetXMLTreeContent(child);
6428 if (value != (
const char *) NULL)
6429 CurrentContext->linecap=(LineCap) ParseCommandOption(
6430 MagickLineCapOptions,MagickFalse,value);
6432 child=GetXMLTreeChild(xml_info,
"stroke-linejoin");
6433 if (child != (XMLTreeInfo *) NULL)
6435 value=GetXMLTreeContent(child);
6436 if (value != (
const char *) NULL)
6437 CurrentContext->linejoin=(LineJoin) ParseCommandOption(
6438 MagickLineJoinOptions,MagickFalse,value);
6440 child=GetXMLTreeChild(xml_info,
"stroke-miterlimit");
6441 if (child != (XMLTreeInfo *) NULL)
6443 value=GetXMLTreeContent(child);
6444 if (value != (
const char *) NULL)
6445 CurrentContext->miterlimit=StringToUnsignedLong(value);
6447 child=GetXMLTreeChild(xml_info,
"stroke-opacity");
6448 if (child != (XMLTreeInfo *) NULL)
6450 value=GetXMLTreeContent(child);
6451 if (value != (
const char *) NULL)
6452 CurrentContext->stroke.opacity=ClampToQuantum((MagickRealType)
6453 QuantumRange*(1.0-StringToDouble(value,(
char **) NULL)));
6455 child=GetXMLTreeChild(xml_info,
"stroke-width");
6456 if (child != (XMLTreeInfo *) NULL)
6458 value=GetXMLTreeContent(child);
6459 if (value != (
const char *) NULL)
6464 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value);
6466 weight=(ssize_t) StringToUnsignedLong(value);
6467 CurrentContext->stroke_width=(double) weight;
6470 child=GetXMLTreeChild(xml_info,
"text-align");
6471 if (child != (XMLTreeInfo *) NULL)
6473 value=GetXMLTreeContent(child);
6474 if (value != (
const char *) NULL)
6475 CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions,
6478 child=GetXMLTreeChild(xml_info,
"text-antialias");
6479 if (child != (XMLTreeInfo *) NULL)
6481 value=GetXMLTreeContent(child);
6482 if (value != (
const char *) NULL)
6483 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue :
6486 child=GetXMLTreeChild(xml_info,
"text-undercolor");
6487 if (child != (XMLTreeInfo *) NULL)
6489 value=GetXMLTreeContent(child);
6490 if (value != (
const char *) NULL)
6491 (void) QueryColorDatabase(value,&CurrentContext->undercolor,
6494 child=GetXMLTreeChild(xml_info,
"vector-graphics");
6495 if (child != (XMLTreeInfo *) NULL)
6497 (void) CloneString(&wand->mvg,GetXMLTreeContent(child));
6498 wand->mvg_length=strlen(wand->mvg);
6499 wand->mvg_alloc=wand->mvg_length+1;
6501 xml_info=DestroyXMLTree(xml_info);
6530WandExport
void DrawSkewX(
DrawingWand *wand,
const double degrees)
6533 assert(wand->signature == WandSignature);
6534 if (wand->debug != MagickFalse)
6535 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6536 (void) MVGPrintf(wand,
"skewX %.20g\n",degrees);
6564WandExport
void DrawSkewY(
DrawingWand *wand,
const double degrees)
6567 assert(wand->signature == WandSignature);
6568 if (wand->debug != MagickFalse)
6569 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6570 (void) MVGPrintf(wand,
"skewY %.20g\n",degrees);
6602WandExport
void DrawTranslate(
DrawingWand *wand,
const double x,
const double y)
6605 assert(wand->signature == WandSignature);
6606 if (wand->debug != MagickFalse)
6607 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6608 (void) MVGPrintf(wand,
"translate %.20g %.20g\n",x,y);
6646WandExport
void DrawSetViewbox(
DrawingWand *wand,ssize_t x1,ssize_t y1,
6647 ssize_t x2,ssize_t y2)
6650 assert(wand->signature == WandSignature);
6651 if (wand->debug != MagickFalse)
6652 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6653 (void) MVGPrintf(wand,
"viewbox %.20g %.20g %.20g %.20g\n",(
double) x1,
6654 (double) y1,(
double) x2,(double) y2);
6679WandExport MagickBooleanType IsDrawingWand(
const DrawingWand *wand)
6682 return(MagickFalse);
6683 if (wand->signature != WandSignature)
6684 return(MagickFalse);
6685 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0)
6686 return(MagickFalse);
6720 quantum=GetMagickQuantumDepth(&depth);
6721 if (depth != MAGICKCORE_QUANTUM_DEPTH)
6722 ThrowWandFatalException(WandError,
"QuantumDepthMismatch",quantum);
6723 wand=(
DrawingWand *) AcquireMagickMemory(
sizeof(*wand));
6725 ThrowWandFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed",
6726 GetExceptionMessage(errno));
6727 (void) memset(wand,0,
sizeof(*wand));
6728 wand->id=AcquireWandId();
6729 (void) FormatLocaleString(wand->name,MaxTextExtent,
"%s-%.20g",DrawingWandId,
6731 if (wand->debug != MagickFalse)
6732 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6733 wand->mvg=(
char *) NULL;
6737 wand->pattern_id=(
char *) NULL;
6738 wand->pattern_offset=0;
6739 wand->pattern_bounds.x=0;
6740 wand->pattern_bounds.y=0;
6741 wand->pattern_bounds.width=0;
6742 wand->pattern_bounds.height=0;
6744 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(
sizeof(
6745 *wand->graphic_context));
6746 if (wand->graphic_context == (DrawInfo **) NULL)
6747 ThrowWandFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed",
6748 GetExceptionMessage(errno));
6749 wand->filter_off=MagickTrue;
6750 wand->indent_depth=0;
6751 wand->path_operation=PathDefaultOperation;
6752 wand->path_mode=DefaultPathMode;
6753 wand->image=AcquireImage((
const ImageInfo *) NULL);
6754 wand->exception=AcquireExceptionInfo();
6755 wand->destroy=MagickTrue;
6756 wand->debug=IsEventLogging();
6757 wand->signature=WandSignature;
6758 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL);
6784WandExport DrawInfo *PeekDrawingWand(
const DrawingWand *wand)
6790 assert(wand->signature == WandSignature);
6791 if (wand->debug != MagickFalse)
6792 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6793 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext);
6794 (void) CloneString(&draw_info->primitive,wand->mvg);
6823WandExport MagickBooleanType PopDrawingWand(
DrawingWand *wand)
6826 assert(wand->signature == WandSignature);
6827 if (wand->debug != MagickFalse)
6828 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6829 if (wand->index == 0)
6831 ThrowDrawException(DrawError,
"UnbalancedGraphicContextPushPop",wand->name)
6832 return(MagickFalse);
6837#if DRAW_BINARY_IMPLEMENTATION
6838 if (wand->image == (Image *) NULL)
6839 ThrowDrawException(WandError,
"ContainsNoImages",wand->name);
6840 if (CurrentContext->clip_mask != (
char *) NULL)
6841 if (LocaleCompare(CurrentContext->clip_mask,
6842 wand->graphic_context[wand->index-1]->clip_mask) != 0)
6843 (void) SetImageClippingMask(wand->image,(Image *) NULL);
6845 CurrentContext=DestroyDrawInfo(CurrentContext);
6847 if (wand->indent_depth > 0)
6848 wand->indent_depth--;
6849 (void) MVGPrintf(wand,
"pop graphic-context\n");
6878WandExport MagickBooleanType PushDrawingWand(
DrawingWand *wand)
6881 assert(wand->signature == WandSignature);
6882 if (wand->debug != MagickFalse)
6883 (void) LogMagickEvent(WandEvent,GetMagickModule(),
"%s",wand->name);
6885 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context,
6886 (
size_t) wand->index+1UL,
sizeof(*wand->graphic_context));
6887 if (wand->graphic_context == (DrawInfo **) NULL)
6890 ThrowDrawException(ResourceLimitError,
"MemoryAllocationFailed",
6892 return(MagickFalse);
6894 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,
6895 wand->graphic_context[wand->index-1]);
6896 (void) MVGPrintf(wand,
"push graphic-context\n");
6897 wand->indent_depth++;