1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% DDDD RRRR AAA W W IIIII N N GGGG % 7% D D R R A A W W I NN N G % 8% D D RRRR AAAAA W W I N N N G GG % 9% D D R R A A W W W I N NN G G % 10% DDDD R R A A W W IIIII N N GGG % 11% % 12% W W AAA N N DDDD % 13% W W A A NN N D D % 14% W W W AAAAA N N N D D % 15% WW WW A A N NN D D % 16% W W A A N N DDDD % 17% % 18% % 19% MagickWand Image Vector Drawing Methods % 20% % 21% Software Design % 22% Bob Friesenhahn % 23% March 2002 % 24% % 25% % 26% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 27% dedicated to making software imaging solutions freely available. % 28% % 29% You may not use this file except in compliance with the License. You may % 30% obtain a copy of the License at % 31% % 32% http://www.imagemagick.org/script/license.php % 33% % 34% Unless required by applicable law or agreed to in writing, software % 35% distributed under the License is distributed on an "AS IS" BASIS, % 36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 37% See the License for the specific language governing permissions and % 38% limitations under the License. % 39% % 40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 41% 42% 43% 44*/ 45 46/* 47 Include declarations. 48*/ 49#include "MagickWand/studio.h" 50#include "MagickWand/MagickWand.h" 51#include "MagickWand/magick-wand-private.h" 52#include "MagickWand/wand.h" 53#include "MagickCore/string-private.h" 54 55/* 56 Define declarations. 57*/ 58#define DRAW_BINARY_IMPLEMENTATION 0 59 60#define CurrentContext (wand->graphic_context[wand->index]) 61#define DrawingWandId "DrawingWand" 62#define ThrowDrawException(severity,tag,reason) (void) ThrowMagickException( \ 63 wand->exception,GetMagickModule(),severity,tag,"`%s'",reason); 64 65/* 66 Typedef declarations. 67*/ 68typedef enum 69{ 70 PathDefaultOperation, 71 PathCloseOperation, /* Z|z (none) */ 72 PathCurveToOperation, /* C|c (x1 y1 x2 y2 x y)+ */ 73 PathCurveToQuadraticBezierOperation, /* Q|q (x1 y1 x y)+ */ 74 PathCurveToQuadraticBezierSmoothOperation, /* T|t (x y)+ */ 75 PathCurveToSmoothOperation, /* S|s (x2 y2 x y)+ */ 76 PathEllipticArcOperation, /* A|a (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+ */ 77 PathLineToHorizontalOperation, /* H|h x+ */ 78 PathLineToOperation, /* L|l (x y)+ */ 79 PathLineToVerticalOperation, /* V|v y+ */ 80 PathMoveToOperation /* M|m (x y)+ */ 81} PathOperation; 82 83typedef enum 84{ 85 DefaultPathMode, 86 AbsolutePathMode, 87 RelativePathMode 88} PathMode; 89 90struct _DrawingWand 91{ 92 size_t 93 id; 94 95 char 96 name[MagickPathExtent]; 97 98 /* Support structures */ 99 Image 100 *image; 101 102 ExceptionInfo 103 *exception; 104 105 /* MVG output string and housekeeping */ 106 char 107 *mvg; /* MVG data */ 108 109 size_t 110 mvg_alloc, /* total allocated memory */ 111 mvg_length; /* total MVG length */ 112 113 size_t 114 mvg_width; /* current line width */ 115 116 /* Pattern support */ 117 char 118 *pattern_id; 119 120 RectangleInfo 121 pattern_bounds; 122 123 size_t 124 pattern_offset; 125 126 /* Graphic wand */ 127 size_t 128 index; /* array index */ 129 130 DrawInfo 131 **graphic_context; 132 133 MagickBooleanType 134 filter_off; /* true if not filtering attributes */ 135 136 /* Pretty-printing depth */ 137 size_t 138 indent_depth; /* number of left-hand pad characters */ 139 140 /* Path operation support */ 141 PathOperation 142 path_operation; 143 144 PathMode 145 path_mode; 146 147 MagickBooleanType 148 destroy, 149 debug; 150 151 size_t 152 signature; 153}; 154 155/* 156 Forward declarations. 157*/ 158static int 159 MVGPrintf(DrawingWand *,const char *,...) wand_attribute((format 160 (printf,2,3))), 161 MVGAutoWrapPrintf(DrawingWand *,const char *,...) wand_attribute((format 162 (printf,2,3))); 163 164static void 165 MVGAppendColor(DrawingWand *,const PixelInfo *); 166 167/* 168 "Printf" for MVG commands 169*/ 170static int MVGPrintf(DrawingWand *wand,const char *format,...) 171{ 172 size_t 173 extent; 174 175 if (wand->debug != MagickFalse) 176 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format); 177 assert(wand != (DrawingWand *) NULL); 178 assert(wand->signature == MagickWandSignature); 179 extent=20UL*MagickPathExtent; 180 if (wand->mvg == (char *) NULL) 181 { 182 wand->mvg=(char *) AcquireQuantumMemory(extent,sizeof(*wand->mvg)); 183 if (wand->mvg == (char *) NULL) 184 { 185 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed", 186 wand->name); 187 return(-1); 188 } 189 wand->mvg_alloc=extent; 190 wand->mvg_length=0; 191 } 192 if (wand->mvg_alloc < (wand->mvg_length+10*MagickPathExtent)) 193 { 194 extent+=wand->mvg_alloc; 195 wand->mvg=(char *) ResizeQuantumMemory(wand->mvg,extent, 196 sizeof(*wand->mvg)); 197 if (wand->mvg == (char *) NULL) 198 { 199 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed", 200 wand->name); 201 return(-1); 202 } 203 wand->mvg_alloc=extent; 204 } 205 { 206 int 207 count; 208 209 ssize_t 210 offset; 211 212 va_list 213 argp; 214 215 while (wand->mvg_width < wand->indent_depth) 216 { 217 wand->mvg[wand->mvg_length]=' '; 218 wand->mvg_length++; 219 wand->mvg_width++; 220 } 221 wand->mvg[wand->mvg_length]='\0'; 222 count=(-1); 223 offset=(ssize_t) wand->mvg_alloc-wand->mvg_length-1; 224 if (offset > 0) 225 { 226 va_start(argp,format); 227#if defined(MAGICKCORE_HAVE_VSNPRINTF) 228 count=vsnprintf(wand->mvg+wand->mvg_length,(size_t) offset,format,argp); 229#else 230 count=vsprintf(wand->mvg+wand->mvg_length,format,argp); 231#endif 232 va_end(argp); 233 } 234 if ((count < 0) || (count > (int) offset)) 235 ThrowDrawException(DrawError,"UnableToPrint",format) 236 else 237 { 238 wand->mvg_length+=count; 239 wand->mvg_width+=count; 240 } 241 wand->mvg[wand->mvg_length]='\0'; 242 if ((wand->mvg_length > 1) && (wand->mvg[wand->mvg_length-1] == '\n')) 243 wand->mvg_width=0; 244 assert((wand->mvg_length+1) < wand->mvg_alloc); 245 return(count); 246 } 247} 248 249static int MVGAutoWrapPrintf(DrawingWand *wand,const char *format,...) 250{ 251 char 252 buffer[MagickPathExtent]; 253 254 int 255 count; 256 257 va_list 258 argp; 259 260 va_start(argp,format); 261#if defined(MAGICKCORE_HAVE_VSNPRINTF) 262 count=vsnprintf(buffer,sizeof(buffer)-1,format,argp); 263#else 264 count=vsprintf(buffer,format,argp); 265#endif 266 va_end(argp); 267 buffer[sizeof(buffer)-1]='\0'; 268 if (count < 0) 269 ThrowDrawException(DrawError,"UnableToPrint",format) 270 else 271 { 272 if (((wand->mvg_width + count) > 78) && (buffer[count-1] != '\n')) 273 (void) MVGPrintf(wand, "\n"); 274 (void) MVGPrintf(wand,"%s",buffer); 275 } 276 return(count); 277} 278 279static void MVGAppendColor(DrawingWand *wand,const PixelInfo *packet) 280{ 281 if ((packet->red == 0) && (packet->green == 0) && (packet->blue == 0) && 282 (packet->alpha == (Quantum) TransparentAlpha)) 283 (void) MVGPrintf(wand,"none"); 284 else 285 { 286 char 287 tuple[MagickPathExtent]; 288 289 PixelInfo 290 pixel; 291 292 GetPixelInfo(wand->image,&pixel); 293 pixel.colorspace=sRGBColorspace; 294 pixel.alpha_trait=packet->alpha != OpaqueAlpha ? BlendPixelTrait : 295 UndefinedPixelTrait; 296 pixel.red=(double) packet->red; 297 pixel.green=(double) packet->green; 298 pixel.blue=(double) packet->blue; 299 pixel.alpha=(double) packet->alpha; 300 GetColorTuple(&pixel,MagickTrue,tuple); 301 (void) MVGPrintf(wand,"%s",tuple); 302 } 303} 304 305static void MVGAppendPointsCommand(DrawingWand *wand,const char *command, 306 const size_t number_coordinates,const PointInfo *coordinates) 307{ 308 const PointInfo 309 *coordinate; 310 311 size_t 312 i; 313 314 (void) MVGPrintf(wand,"%s",command); 315 for (i=number_coordinates, coordinate=coordinates; i != 0; i--) 316 { 317 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",coordinate->x,coordinate->y); 318 coordinate++; 319 } 320 (void) MVGPrintf(wand, "\n"); 321} 322 323static void AdjustAffine(DrawingWand *wand,const AffineMatrix *affine) 324{ 325 assert(wand != (DrawingWand *) NULL); 326 assert(wand->signature == MagickWandSignature); 327 if (wand->debug != MagickFalse) 328 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 329 if ((affine->sx != 1.0) || (affine->rx != 0.0) || (affine->ry != 0.0) || 330 (affine->sy != 1.0) || (affine->tx != 0.0) || (affine->ty != 0.0)) 331 { 332 AffineMatrix 333 current; 334 335 current=CurrentContext->affine; 336 CurrentContext->affine.sx=affine->sx*current.sx+affine->ry*current.rx; 337 CurrentContext->affine.rx=affine->rx*current.sx+affine->sy*current.rx; 338 CurrentContext->affine.ry=affine->sx*current.ry+affine->ry*current.sy; 339 CurrentContext->affine.sy=affine->rx*current.ry+affine->sy*current.sy; 340 CurrentContext->affine.tx=affine->sx*current.tx+affine->ry*current.ty+ 341 affine->tx; 342 CurrentContext->affine.ty=affine->rx*current.tx+affine->sy*current.ty+ 343 affine->ty; 344 } 345} 346 347/* 348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 349% % 350% % 351% % 352+ A c q u i r e D r a w i n g W a n d % 353% % 354% % 355% % 356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 357% 358% AcquireDrawingWand() allocates an initial drawing wand which is an opaque 359% handle required by the remaining drawing methods. 360% 361% The format of the AcquireDrawingWand method is: 362% 363% DrawingWand AcquireDrawingWand(const DrawInfo *draw_info,Image *image) 364% 365% A description of each parameter follows: 366% 367% o draw_info: Initial drawing defaults. Set to NULL to use defaults. 368% 369% o image: the image to draw on. 370% 371*/ 372WandExport DrawingWand *AcquireDrawingWand(const DrawInfo *draw_info, 373 Image *image) 374{ 375 DrawingWand 376 *wand; 377 378 wand=NewDrawingWand(); 379 if (draw_info != (const DrawInfo *) NULL) 380 { 381 CurrentContext=DestroyDrawInfo(CurrentContext); 382 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,draw_info); 383 } 384 if (image != (Image *) NULL) 385 { 386 wand->image=DestroyImage(wand->image); 387 wand->destroy=MagickFalse; 388 } 389 wand->image=image; 390 return(wand); 391} 392 393/* 394%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 395% % 396% % 397% % 398% C l e a r D r a w i n g W a n d % 399% % 400% % 401% % 402%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 403% 404% ClearDrawingWand() clears resources associated with the drawing wand. 405% 406% The format of the ClearDrawingWand method is: 407% 408% void ClearDrawingWand(DrawingWand *wand) 409% 410% A description of each parameter follows: 411% 412% o wand: the drawing wand to clear. 413% 414*/ 415WandExport void ClearDrawingWand(DrawingWand *wand) 416{ 417 assert(wand != (DrawingWand *) NULL); 418 assert(wand->signature == MagickWandSignature); 419 if (wand->debug != MagickFalse) 420 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 421 for ( ; wand->index > 0; wand->index--) 422 CurrentContext=DestroyDrawInfo(CurrentContext); 423 CurrentContext=DestroyDrawInfo(CurrentContext); 424 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory( 425 wand->graphic_context); 426 if (wand->pattern_id != (char *) NULL) 427 wand->pattern_id=DestroyString(wand->pattern_id); 428 wand->mvg=DestroyString(wand->mvg); 429 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL)) 430 wand->image=DestroyImage(wand->image); 431 else 432 wand->image=(Image *) NULL; 433 wand->mvg=(char *) NULL; 434 wand->mvg_alloc=0; 435 wand->mvg_length=0; 436 wand->mvg_width=0; 437 wand->pattern_id=(char *) NULL; 438 wand->pattern_offset=0; 439 wand->pattern_bounds.x=0; 440 wand->pattern_bounds.y=0; 441 wand->pattern_bounds.width=0; 442 wand->pattern_bounds.height=0; 443 wand->index=0; 444 wand->graphic_context=(DrawInfo **) AcquireMagickMemory( 445 sizeof(*wand->graphic_context)); 446 if (wand->graphic_context == (DrawInfo **) NULL) 447 { 448 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed", 449 wand->name); 450 return; 451 } 452 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL); 453 wand->filter_off=MagickTrue; 454 wand->indent_depth=0; 455 wand->path_operation=PathDefaultOperation; 456 wand->path_mode=DefaultPathMode; 457 wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception); 458 ClearMagickException(wand->exception); 459 wand->destroy=MagickTrue; 460 wand->debug=IsEventLogging(); 461} 462 463/* 464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 465% % 466% % 467% % 468% C l o n e D r a w i n g W a n d % 469% % 470% % 471% % 472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 473% 474% CloneDrawingWand() makes an exact copy of the specified wand. 475% 476% The format of the CloneDrawingWand method is: 477% 478% DrawingWand *CloneDrawingWand(const DrawingWand *wand) 479% 480% A description of each parameter follows: 481% 482% o wand: the magick wand. 483% 484*/ 485WandExport DrawingWand *CloneDrawingWand(const DrawingWand *wand) 486{ 487 DrawingWand 488 *clone_wand; 489 490 register ssize_t 491 i; 492 493 assert(wand != (DrawingWand *) NULL); 494 assert(wand->signature == MagickWandSignature); 495 if (wand->debug != MagickFalse) 496 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 497 clone_wand=(DrawingWand *) AcquireMagickMemory(sizeof(*clone_wand)); 498 if (clone_wand == (DrawingWand *) NULL) 499 ThrowWandFatalException(ResourceLimitFatalError, 500 "MemoryAllocationFailed",GetExceptionMessage(errno)); 501 (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand)); 502 clone_wand->id=AcquireWandId(); 503 (void) FormatLocaleString(clone_wand->name,MagickPathExtent, 504 "DrawingWand-%.20g",(double) clone_wand->id); 505 clone_wand->exception=AcquireExceptionInfo(); 506 InheritException(clone_wand->exception,wand->exception); 507 clone_wand->mvg=AcquireString(wand->mvg); 508 clone_wand->mvg_length=strlen(clone_wand->mvg); 509 clone_wand->mvg_alloc=wand->mvg_length+1; 510 clone_wand->mvg_width=wand->mvg_width; 511 clone_wand->pattern_id=AcquireString(wand->pattern_id); 512 clone_wand->pattern_offset=wand->pattern_offset; 513 clone_wand->pattern_bounds=wand->pattern_bounds; 514 clone_wand->index=wand->index; 515 clone_wand->graphic_context=(DrawInfo **) AcquireQuantumMemory((size_t) 516 wand->index+1UL,sizeof(*wand->graphic_context)); 517 if (clone_wand->graphic_context == (DrawInfo **) NULL) 518 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 519 GetExceptionMessage(errno)); 520 for (i=0; i <= (ssize_t) wand->index; i++) 521 clone_wand->graphic_context[i]=CloneDrawInfo((ImageInfo *) NULL, 522 wand->graphic_context[i]); 523 clone_wand->filter_off=wand->filter_off; 524 clone_wand->indent_depth=wand->indent_depth; 525 clone_wand->path_operation=wand->path_operation; 526 clone_wand->path_mode=wand->path_mode; 527 clone_wand->image=wand->image; 528 if (wand->image != (Image *) NULL) 529 clone_wand->image=CloneImage(wand->image,0,0,MagickTrue, 530 clone_wand->exception); 531 clone_wand->destroy=MagickTrue; 532 clone_wand->debug=IsEventLogging(); 533 if (clone_wand->debug != MagickFalse) 534 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name); 535 clone_wand->signature=MagickWandSignature; 536 return(clone_wand); 537} 538 539/* 540%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 541% % 542% % 543% % 544% D e s t r o y D r a w i n g W a n d % 545% % 546% % 547% % 548%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 549% 550% DestroyDrawingWand() frees all resources associated with the drawing wand. 551% Once the drawing wand has been freed, it should not be used and further 552% unless it re-allocated. 553% 554% The format of the DestroyDrawingWand method is: 555% 556% DrawingWand *DestroyDrawingWand(DrawingWand *wand) 557% 558% A description of each parameter follows: 559% 560% o wand: the drawing wand to destroy. 561% 562*/ 563WandExport DrawingWand *DestroyDrawingWand(DrawingWand *wand) 564{ 565 assert(wand != (DrawingWand *) NULL); 566 assert(wand->signature == MagickWandSignature); 567 if (wand->debug != MagickFalse) 568 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 569 for ( ; wand->index > 0; wand->index--) 570 CurrentContext=DestroyDrawInfo(CurrentContext); 571 CurrentContext=DestroyDrawInfo(CurrentContext); 572 wand->graphic_context=(DrawInfo **) RelinquishMagickMemory( 573 wand->graphic_context); 574 if (wand->pattern_id != (char *) NULL) 575 wand->pattern_id=DestroyString(wand->pattern_id); 576 wand->mvg=DestroyString(wand->mvg); 577 if ((wand->destroy != MagickFalse) && (wand->image != (Image *) NULL)) 578 wand->image=DestroyImage(wand->image); 579 wand->image=(Image *) NULL; 580 wand->exception=DestroyExceptionInfo(wand->exception); 581 wand->signature=(~MagickWandSignature); 582 RelinquishWandId(wand->id); 583 wand=(DrawingWand *) RelinquishMagickMemory(wand); 584 return(wand); 585} 586 587/* 588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 589% % 590% % 591% % 592% D r a w A f f i n e % 593% % 594% % 595% % 596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 597% 598% DrawAffine() adjusts the current affine transformation matrix with 599% the specified affine transformation matrix. Note that the current affine 600% transform is adjusted rather than replaced. 601% 602% The format of the DrawAffine method is: 603% 604% void DrawAffine(DrawingWand *wand,const AffineMatrix *affine) 605% 606% A description of each parameter follows: 607% 608% o wand: Drawing wand 609% 610% o affine: Affine matrix parameters 611% 612*/ 613WandExport void DrawAffine(DrawingWand *wand,const AffineMatrix *affine) 614{ 615 assert(wand != (DrawingWand *) NULL); 616 assert(wand->signature == MagickWandSignature); 617 if (wand->debug != MagickFalse) 618 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 619 assert(affine != (const AffineMatrix *) NULL); 620 AdjustAffine(wand,affine); 621 (void) MVGPrintf(wand,"affine %.20g %.20g %.20g %.20g %.20g %.20g\n", 622 affine->sx,affine->rx,affine->ry,affine->sy,affine->tx,affine->ty); 623} 624 625/* 626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 627% % 628% % 629% % 630% D r a w A l p h a % 631% % 632% % 633% % 634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 635% 636% DrawAlpha() paints on the image's alpha channel in order to set effected 637% pixels to transparent. The available paint methods are: 638% 639% PointMethod: Select the target pixel 640% ReplaceMethod: Select any pixel that matches the target pixel. 641% FloodfillMethod: Select the target pixel and matching neighbors. 642% FillToBorderMethod: Select the target pixel and neighbors not matching 643% border color. 644% ResetMethod: Select all pixels. 645% 646% The format of the DrawAlpha method is: 647% 648% void DrawAlpha(DrawingWand *wand,const double x,const double y, 649% const PaintMethod paint_method) 650% 651% A description of each parameter follows: 652% 653% o wand: the drawing wand. 654% 655% o x: x ordinate 656% 657% o y: y ordinate 658% 659% o paint_method: paint method. 660% 661*/ 662WandExport void DrawAlpha(DrawingWand *wand,const double x,const double y, 663 const PaintMethod paint_method) 664{ 665 assert(wand != (DrawingWand *) NULL); 666 assert(wand->signature == MagickWandSignature); 667 if (wand->debug != MagickFalse) 668 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 669 (void) MVGPrintf(wand,"alpha %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic( 670 MagickMethodOptions,(ssize_t) paint_method)); 671} 672 673/* 674%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 675% % 676% % 677% % 678% D r a w A n n o t a t i o n % 679% % 680% % 681% % 682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 683% 684% DrawAnnotation() draws text on the image. 685% 686% The format of the DrawAnnotation method is: 687% 688% void DrawAnnotation(DrawingWand *wand,const double x, 689% const double y,const unsigned char *text) 690% 691% A description of each parameter follows: 692% 693% o wand: the drawing wand. 694% 695% o x: x ordinate to left of text 696% 697% o y: y ordinate to text baseline 698% 699% o text: text to draw 700% 701*/ 702WandExport void DrawAnnotation(DrawingWand *wand,const double x,const double y, 703 const unsigned char *text) 704{ 705 char 706 *escaped_text; 707 708 assert(wand != (DrawingWand *) NULL); 709 assert(wand->signature == MagickWandSignature); 710 if (wand->debug != MagickFalse) 711 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 712 assert(text != (const unsigned char *) NULL); 713 escaped_text=EscapeString((const char *) text,'\''); 714 if (escaped_text != (char *) NULL) 715 { 716 (void) MVGPrintf(wand,"text %.20g %.20g '%s'\n",x,y,escaped_text); 717 escaped_text=DestroyString(escaped_text); 718 } 719} 720 721/* 722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 723% % 724% % 725% % 726% D r a w A r c % 727% % 728% % 729% % 730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 731% 732% DrawArc() draws an arc falling within a specified bounding rectangle on the 733% image. 734% 735% The format of the DrawArc method is: 736% 737% void DrawArc(DrawingWand *wand,const double sx,const double sy, 738% const double ex,const double ey,const double sd,const double ed) 739% 740% A description of each parameter follows: 741% 742% o wand: the drawing wand. 743% 744% o sx: starting x ordinate of bounding rectangle 745% 746% o sy: starting y ordinate of bounding rectangle 747% 748% o ex: ending x ordinate of bounding rectangle 749% 750% o ey: ending y ordinate of bounding rectangle 751% 752% o sd: starting degrees of rotation 753% 754% o ed: ending degrees of rotation 755% 756*/ 757WandExport void DrawArc(DrawingWand *wand,const double sx,const double sy, 758 const double ex,const double ey,const double sd,const double ed) 759{ 760 assert(wand != (DrawingWand *) NULL); 761 assert(wand->signature == MagickWandSignature); 762 if (wand->debug != MagickFalse) 763 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 764 (void) MVGPrintf(wand,"arc %.20g %.20g %.20g %.20g %.20g %.20g\n",sx,sy,ex, 765 ey,sd,ed); 766} 767 768/* 769%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 770% % 771% % 772% % 773% D r a w B e z i e r % 774% % 775% % 776% % 777%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 778% 779% DrawBezier() draws a bezier curve through a set of points on the image. 780% 781% The format of the DrawBezier method is: 782% 783% void DrawBezier(DrawingWand *wand, 784% const size_t number_coordinates,const PointInfo *coordinates) 785% 786% A description of each parameter follows: 787% 788% o wand: the drawing wand. 789% 790% o number_coordinates: number of coordinates 791% 792% o coordinates: coordinates 793% 794*/ 795WandExport void DrawBezier(DrawingWand *wand, 796 const size_t number_coordinates,const PointInfo *coordinates) 797{ 798 assert(wand != (DrawingWand *) NULL); 799 assert(wand->signature == MagickWandSignature); 800 if (wand->debug != MagickFalse) 801 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 802 assert(coordinates != (const PointInfo *) NULL); 803 MVGAppendPointsCommand(wand,"bezier",number_coordinates,coordinates); 804} 805 806/* 807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 808% % 809% % 810% % 811% D r a w C i r c l e % 812% % 813% % 814% % 815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 816% 817% DrawCircle() draws a circle on the image. 818% 819% The format of the DrawCircle method is: 820% 821% void DrawCircle(DrawingWand *wand,const double ox, 822% const double oy,const double px, const double py) 823% 824% A description of each parameter follows: 825% 826% o wand: the drawing wand. 827% 828% o ox: origin x ordinate 829% 830% o oy: origin y ordinate 831% 832% o px: perimeter x ordinate 833% 834% o py: perimeter y ordinate 835% 836*/ 837WandExport void DrawCircle(DrawingWand *wand,const double ox,const double oy, 838 const double px,const double py) 839{ 840 assert(wand != (DrawingWand *) NULL); 841 assert(wand->signature == MagickWandSignature); 842 if (wand->debug != MagickFalse) 843 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 844 (void) MVGPrintf(wand,"circle %.20g %.20g %.20g %.20g\n",ox,oy,px,py); 845} 846 847/* 848%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 849% % 850% % 851% % 852% D r a w C l e a r E x c e p t i o n % 853% % 854% % 855% % 856%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 857% 858% DrawClearException() clear any exceptions associated with the wand. 859% 860% The format of the DrawClearException method is: 861% 862% MagickBooleanType DrawClearException(DrawWand *wand) 863% 864% A description of each parameter follows: 865% 866% o wand: the drawing wand. 867% 868*/ 869WandExport MagickBooleanType DrawClearException(DrawingWand *wand) 870{ 871 assert(wand != (DrawingWand *) NULL); 872 assert(wand->signature == MagickWandSignature); 873 if (wand->debug != MagickFalse) 874 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 875 ClearMagickException(wand->exception); 876 return(MagickTrue); 877} 878 879/* 880%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 881% % 882% % 883% % 884% D r a w C l o n e E x c e p t i o n I n f o % 885% % 886% % 887% % 888%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 889% 890% DrawCloneExceptionInfo() clones the ExceptionInfo structure within the wand. 891% 892% The format of the DrawCloneExceptionInfo method is: 893% 894% ExceptionInfo *DrawCloneExceptionInfo(DrawWand *wand) 895% 896% A description of each parameter follows: 897% 898% o wand: the drawing wand. 899% 900*/ 901WandExport ExceptionInfo *DrawCloneExceptionInfo(const DrawingWand *wand) 902{ 903 assert(wand != (DrawingWand *) NULL); 904 assert(wand->signature == MagickWandSignature); 905 if (wand->exception == (ExceptionInfo*) NULL) 906 return (ExceptionInfo*) NULL; 907 return CloneExceptionInfo(wand->exception); 908} 909 910/* 911%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 912% % 913% % 914% % 915% D r a w C o l o r % 916% % 917% % 918% % 919%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 920% 921% DrawColor() draws color on image using the current fill color, starting at 922% specified position, and using specified paint method. The available paint 923% methods are: 924% 925% PointMethod: Recolors the target pixel 926% ReplaceMethod: Recolor any pixel that matches the target pixel. 927% FloodfillMethod: Recolors target pixels and matching neighbors. 928% ResetMethod: Recolor all pixels. 929% 930% The format of the DrawColor method is: 931% 932% void DrawColor(DrawingWand *wand,const double x,const double y, 933% const PaintMethod paint_method) 934% 935% A description of each parameter follows: 936% 937% o wand: the drawing wand. 938% 939% o x: x ordinate. 940% 941% o y: y ordinate. 942% 943% o paint_method: paint method. 944% 945*/ 946WandExport void DrawColor(DrawingWand *wand, const double x, const double y, 947 const PaintMethod paint_method) 948{ 949 assert(wand != (DrawingWand *)NULL); 950 assert(wand->signature == MagickWandSignature); 951 if (wand->debug != MagickFalse) 952 (void) LogMagickEvent(WandEvent, GetMagickModule(), "%s", wand->name); 953 (void) MVGPrintf(wand, "color %.20g %.20g '%s'\n",x,y,CommandOptionToMnemonic( 954 MagickMethodOptions,(ssize_t) paint_method)); 955} 956 957/* 958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 959% % 960% % 961% % 962% D r a w C o m p o s i t e % 963% % 964% % 965% % 966%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 967% 968% DrawComposite() composites an image onto the current image, using the 969% specified composition operator, specified position, and at the specified 970% size. 971% 972% The format of the DrawComposite method is: 973% 974% MagickBooleanType DrawComposite(DrawingWand *wand, 975% const CompositeOperator compose,const double x, 976% const double y,const double width,const double height, 977% MagickWand *magick_wand) 978% 979% A description of each parameter follows: 980% 981% o wand: the drawing wand. 982% 983% o compose: composition operator 984% 985% o x: x ordinate of top left corner 986% 987% o y: y ordinate of top left corner 988% 989% o width: Width to resize image to prior to compositing. Specify zero to 990% use existing width. 991% 992% o height: Height to resize image to prior to compositing. Specify zero 993% to use existing height. 994% 995% o magick_wand: Image to composite is obtained from this wand. 996% 997*/ 998WandExport MagickBooleanType DrawComposite(DrawingWand *wand, 999 const CompositeOperator compose,const double x,const double y, 1000 const double width,const double height,MagickWand *magick_wand) 1001{ 1002 char 1003 *base64, 1004 *media_type; 1005 1006 const char 1007 *mode; 1008 1009 ImageInfo 1010 *image_info; 1011 1012 Image 1013 *clone_image, 1014 *image; 1015 1016 register char 1017 *p; 1018 1019 register ssize_t 1020 i; 1021 1022 size_t 1023 blob_length, 1024 encoded_length; 1025 1026 unsigned char 1027 *blob; 1028 1029 assert(wand != (DrawingWand *) NULL); 1030 assert(wand->signature == MagickWandSignature); 1031 if (wand->debug != MagickFalse) 1032 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1033 assert(magick_wand != (MagickWand *) NULL); 1034 image=GetImageFromMagickWand(magick_wand); 1035 if (image == (Image *) NULL) 1036 return(MagickFalse); 1037 clone_image=CloneImage(image,0,0,MagickTrue,wand->exception); 1038 if (clone_image == (Image *) NULL) 1039 return(MagickFalse); 1040 image_info=AcquireImageInfo(); 1041 (void) CopyMagickString(image_info->magick,"MIFF",MagickPathExtent); 1042 blob_length=2048; 1043 blob=(unsigned char *) ImageToBlob(image_info,clone_image,&blob_length, 1044 wand->exception); 1045 image_info=DestroyImageInfo(image_info); 1046 clone_image=DestroyImageList(clone_image); 1047 if (blob == (void *) NULL) 1048 return(MagickFalse); 1049 encoded_length=0; 1050 base64=Base64Encode(blob,blob_length,&encoded_length); 1051 blob=(unsigned char *) RelinquishMagickMemory(blob); 1052 if (base64 == (char *) NULL) 1053 { 1054 char 1055 buffer[MagickPathExtent]; 1056 1057 (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g bytes",(double) 1058 (4L*blob_length/3L+4L)); 1059 ThrowDrawException(ResourceLimitWarning,"MemoryAllocationFailed", 1060 wand->name); 1061 return(MagickFalse); 1062 } 1063 mode=CommandOptionToMnemonic(MagickComposeOptions,(ssize_t) compose); 1064 media_type=MagickToMime(image->magick); 1065 (void) MVGPrintf(wand,"image %s %.20g %.20g %.20g %.20g 'data:%s;base64,\n", 1066 mode,x,y,width,height,media_type); 1067 p=base64; 1068 for (i=(ssize_t) encoded_length; i > 0; i-=76) 1069 { 1070 (void) MVGPrintf(wand,"%.76s",p); 1071 p+=76; 1072 if (i > 76) 1073 (void) MVGPrintf(wand,"\n"); 1074 } 1075 (void) MVGPrintf(wand,"'\n"); 1076 media_type=DestroyString(media_type); 1077 base64=DestroyString(base64); 1078 return(MagickTrue); 1079} 1080 1081/* 1082%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1083% % 1084% % 1085% % 1086% D r a w C o m m e n t % 1087% % 1088% % 1089% % 1090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1091% 1092% DrawComment() adds a comment to a vector output stream. 1093% 1094% The format of the DrawComment method is: 1095% 1096% void DrawComment(DrawingWand *wand,const char *comment) 1097% 1098% A description of each parameter follows: 1099% 1100% o wand: the drawing wand. 1101% 1102% o comment: comment text 1103% 1104*/ 1105WandExport void DrawComment(DrawingWand *wand,const char *comment) 1106{ 1107 (void) MVGPrintf(wand,"#%s\n",comment); 1108} 1109 1110/* 1111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1112% % 1113% % 1114% % 1115% D r a w E l l i p s e % 1116% % 1117% % 1118% % 1119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1120% 1121% DrawEllipse() draws an ellipse on the image. 1122% 1123% The format of the DrawEllipse method is: 1124% 1125% void DrawEllipse(DrawingWand *wand,const double ox,const double oy, 1126% const double rx,const double ry,const double start,const double end) 1127% 1128% A description of each parameter follows: 1129% 1130% o wand: the drawing wand. 1131% 1132% o ox: origin x ordinate 1133% 1134% o oy: origin y ordinate 1135% 1136% o rx: radius in x 1137% 1138% o ry: radius in y 1139% 1140% o start: starting rotation in degrees 1141% 1142% o end: ending rotation in degrees 1143% 1144*/ 1145WandExport void DrawEllipse(DrawingWand *wand,const double ox,const double oy, 1146 const double rx,const double ry,const double start,const double end) 1147{ 1148 assert(wand != (DrawingWand *) NULL); 1149 assert(wand->signature == MagickWandSignature); 1150 if (wand->debug != MagickFalse) 1151 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1152 (void) MVGPrintf(wand,"ellipse %.20g %.20g %.20g %.20g %.20g %.20g\n",ox,oy, 1153 rx,ry,start,end); 1154} 1155 1156/* 1157%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1158% % 1159% % 1160% % 1161% D r a w G e t B o r d e r C o l o r % 1162% % 1163% % 1164% % 1165%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1166% 1167% DrawGetBorderColor() returns the border color used for drawing bordered 1168% objects. 1169% 1170% The format of the DrawGetBorderColor method is: 1171% 1172% void DrawGetBorderColor(const DrawingWand *wand, 1173% PixelWand *border_color) 1174% 1175% A description of each parameter follows: 1176% 1177% o wand: the drawing wand. 1178% 1179% o border_color: Return the border color. 1180% 1181*/ 1182WandExport void DrawGetBorderColor(const DrawingWand *wand, 1183 PixelWand *border_color) 1184{ 1185 assert(wand != (const DrawingWand *) NULL); 1186 assert(wand->signature == MagickWandSignature); 1187 assert(border_color != (PixelWand *) NULL); 1188 if (wand->debug != MagickFalse) 1189 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1190 PixelSetPixelColor(border_color,&CurrentContext->border_color); 1191} 1192 1193/* 1194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1195% % 1196% % 1197% % 1198% D r a w G e t C l i p P a t h % 1199% % 1200% % 1201% % 1202%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1203% 1204% DrawGetClipPath() obtains the current clipping path ID. The value returned 1205% must be deallocated by the user when it is no longer needed. 1206% 1207% The format of the DrawGetClipPath method is: 1208% 1209% char *DrawGetClipPath(const DrawingWand *wand) 1210% 1211% A description of each parameter follows: 1212% 1213% o wand: the drawing wand. 1214% 1215*/ 1216WandExport char *DrawGetClipPath(const DrawingWand *wand) 1217{ 1218 assert(wand != (const DrawingWand *) NULL); 1219 assert(wand->signature == MagickWandSignature); 1220 if (wand->debug != MagickFalse) 1221 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1222 if (CurrentContext->clip_mask != (char *) NULL) 1223 return((char *) AcquireString(CurrentContext->clip_mask)); 1224 return((char *) NULL); 1225} 1226 1227/* 1228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1229% % 1230% % 1231% % 1232% D r a w G e t C l i p R u l e % 1233% % 1234% % 1235% % 1236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1237% 1238% DrawGetClipRule() returns the current polygon fill rule to be used by the 1239% clipping path. 1240% 1241% The format of the DrawGetClipRule method is: 1242% 1243% FillRule DrawGetClipRule(const DrawingWand *wand) 1244% 1245% A description of each parameter follows: 1246% 1247% o wand: the drawing wand. 1248% 1249*/ 1250WandExport FillRule DrawGetClipRule(const DrawingWand *wand) 1251{ 1252 assert(wand != (const DrawingWand *) NULL); 1253 assert(wand->signature == MagickWandSignature); 1254 if (wand->debug != MagickFalse) 1255 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1256 return(CurrentContext->fill_rule); 1257} 1258 1259/* 1260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1261% % 1262% % 1263% % 1264% D r a w G e t C l i p U n i t s % 1265% % 1266% % 1267% % 1268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1269% 1270% DrawGetClipUnits() returns the interpretation of clip path units. 1271% 1272% The format of the DrawGetClipUnits method is: 1273% 1274% ClipPathUnits DrawGetClipUnits(const DrawingWand *wand) 1275% 1276% A description of each parameter follows: 1277% 1278% o wand: the drawing wand. 1279% 1280*/ 1281WandExport ClipPathUnits DrawGetClipUnits(const DrawingWand *wand) 1282{ 1283 assert(wand != (const DrawingWand *) NULL); 1284 assert(wand->signature == MagickWandSignature); 1285 if (wand->debug != MagickFalse) 1286 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1287 return(CurrentContext->clip_units); 1288} 1289 1290/* 1291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1292% % 1293% % 1294% % 1295% D r a w G e t D e n s i t y % 1296% % 1297% % 1298% % 1299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1300% 1301% DrawGetDensity() obtains the vertical and horizontal resolution. The value 1302% returned must be deallocated by the user when it is no longer needed. 1303% 1304% The format of the DrawGetDensity method is: 1305% 1306% char *DrawGetDensity(const DrawingWand *wand) 1307% 1308% A description of each parameter follows: 1309% 1310% o wand: the drawing wand. 1311% 1312*/ 1313WandExport char *DrawGetDensity(const DrawingWand *wand) 1314{ 1315 assert(wand != (const DrawingWand *) NULL); 1316 assert(wand->signature == MagickWandSignature); 1317 if (wand->debug != MagickFalse) 1318 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1319 if (CurrentContext->density != (char *) NULL) 1320 return((char *) AcquireString(CurrentContext->density)); 1321 return((char *) NULL); 1322} 1323 1324/* 1325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1326% % 1327% % 1328% % 1329% D r a w G e t E x c e p t i o n % 1330% % 1331% % 1332% % 1333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1334% 1335% DrawGetException() returns the severity, reason, and description of any 1336% error that occurs when using other methods in this API. 1337% 1338% The format of the DrawGetException method is: 1339% 1340% char *DrawGetException(const DrawWand *wand, 1341% ExceptionType *severity) 1342% 1343% A description of each parameter follows: 1344% 1345% o wand: the drawing wand. 1346% 1347% o severity: the severity of the error is returned here. 1348% 1349*/ 1350WandExport char *DrawGetException(const DrawingWand *wand, 1351 ExceptionType *severity) 1352{ 1353 char 1354 *description; 1355 1356 assert(wand != (const DrawingWand *) NULL); 1357 assert(wand->signature == MagickWandSignature); 1358 if (wand->debug != MagickFalse) 1359 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1360 assert(severity != (ExceptionType *) NULL); 1361 *severity=wand->exception->severity; 1362 description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent, 1363 sizeof(*description)); 1364 if (description == (char *) NULL) 1365 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 1366 wand->name); 1367 *description='\0'; 1368 if (wand->exception->reason != (char *) NULL) 1369 (void) CopyMagickString(description,GetLocaleExceptionMessage( 1370 wand->exception->severity,wand->exception->reason), 1371 MagickPathExtent); 1372 if (wand->exception->description != (char *) NULL) 1373 { 1374 (void) ConcatenateMagickString(description," (",MagickPathExtent); 1375 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage( 1376 wand->exception->severity,wand->exception->description), 1377 MagickPathExtent); 1378 (void) ConcatenateMagickString(description,")",MagickPathExtent); 1379 } 1380 return(description); 1381} 1382 1383/* 1384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1385% % 1386% % 1387% % 1388% P i x e l G e t E x c e p t i o n T y p e % 1389% % 1390% % 1391% % 1392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1393% 1394% DrawGetExceptionType() the exception type associated with the wand. If 1395% no exception has occurred, UndefinedExceptionType is returned. 1396% 1397% The format of the DrawGetExceptionType method is: 1398% 1399% ExceptionType DrawGetExceptionType(const DrawWand *wand) 1400% 1401% A description of each parameter follows: 1402% 1403% o wand: the magick wand. 1404% 1405*/ 1406WandExport ExceptionType DrawGetExceptionType(const DrawingWand *wand) 1407{ 1408 assert(wand != (const DrawingWand *) NULL); 1409 assert(wand->signature == MagickWandSignature); 1410 if (wand->debug != MagickFalse) 1411 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1412 return(wand->exception->severity); 1413} 1414 1415/* 1416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1417% % 1418% % 1419% % 1420% D r a w G e t F i l l C o l o r % 1421% % 1422% % 1423% % 1424%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1425% 1426% DrawGetFillColor() returns the fill color used for drawing filled objects. 1427% 1428% The format of the DrawGetFillColor method is: 1429% 1430% void DrawGetFillColor(const DrawingWand *wand, 1431% PixelWand *fill_color) 1432% 1433% A description of each parameter follows: 1434% 1435% o wand: the drawing wand. 1436% 1437% o fill_color: Return the fill color. 1438% 1439*/ 1440WandExport void DrawGetFillColor(const DrawingWand *wand,PixelWand *fill_color) 1441{ 1442 assert(wand != (const DrawingWand *) NULL); 1443 assert(wand->signature == MagickWandSignature); 1444 assert(fill_color != (PixelWand *) NULL); 1445 if (wand->debug != MagickFalse) 1446 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1447 PixelSetPixelColor(fill_color,&CurrentContext->fill); 1448} 1449 1450/* 1451%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1452% % 1453% % 1454% % 1455% D r a w G e t F i l l O p a c i t y % 1456% % 1457% % 1458% % 1459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1460% 1461% DrawGetFillOpacity() returns the alpha used when drawing using the fill 1462% color or fill texture. Fully opaque is 1.0. 1463% 1464% The format of the DrawGetFillOpacity method is: 1465% 1466% double DrawGetFillOpacity(const DrawingWand *wand) 1467% 1468% A description of each parameter follows: 1469% 1470% o wand: the drawing wand. 1471% 1472*/ 1473WandExport double DrawGetFillOpacity(const DrawingWand *wand) 1474{ 1475 double 1476 alpha; 1477 1478 assert(wand != (const DrawingWand *) NULL); 1479 assert(wand->signature == MagickWandSignature); 1480 if (wand->debug != MagickFalse) 1481 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1482 alpha=(double) QuantumScale*CurrentContext->fill.alpha; 1483 return(alpha); 1484} 1485 1486/* 1487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1488% % 1489% % 1490% % 1491% D r a w G e t F i l l R u l e % 1492% % 1493% % 1494% % 1495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1496% 1497% DrawGetFillRule() returns the fill rule used while drawing polygons. 1498% 1499% The format of the DrawGetFillRule method is: 1500% 1501% FillRule DrawGetFillRule(const DrawingWand *wand) 1502% 1503% A description of each parameter follows: 1504% 1505% o wand: the drawing wand. 1506% 1507*/ 1508WandExport FillRule DrawGetFillRule(const DrawingWand *wand) 1509{ 1510 assert(wand != (const DrawingWand *) NULL); 1511 assert(wand->signature == MagickWandSignature); 1512 if (wand->debug != MagickFalse) 1513 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1514 return(CurrentContext->fill_rule); 1515} 1516 1517/* 1518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1519% % 1520% % 1521% % 1522% D r a w G e t F o n t % 1523% % 1524% % 1525% % 1526%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1527% 1528% DrawGetFont() returns a null-terminaged string specifying the font used 1529% when annotating with text. The value returned must be freed by the user 1530% when no longer needed. 1531% 1532% The format of the DrawGetFont method is: 1533% 1534% char *DrawGetFont(const DrawingWand *wand) 1535% 1536% A description of each parameter follows: 1537% 1538% o wand: the drawing wand. 1539% 1540*/ 1541WandExport char *DrawGetFont(const DrawingWand *wand) 1542{ 1543 assert(wand != (const DrawingWand *) NULL); 1544 assert(wand->signature == MagickWandSignature); 1545 if (wand->debug != MagickFalse) 1546 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1547 if (CurrentContext->font != (char *) NULL) 1548 return(AcquireString(CurrentContext->font)); 1549 return((char *) NULL); 1550} 1551 1552/* 1553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1554% % 1555% % 1556% % 1557% D r a w G e t F o n t F a m i l y % 1558% % 1559% % 1560% % 1561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1562% 1563% DrawGetFontFamily() returns the font family to use when annotating with text. 1564% The value returned must be freed by the user when it is no longer needed. 1565% 1566% The format of the DrawGetFontFamily method is: 1567% 1568% char *DrawGetFontFamily(const DrawingWand *wand) 1569% 1570% A description of each parameter follows: 1571% 1572% o wand: the drawing wand. 1573% 1574*/ 1575WandExport char *DrawGetFontFamily(const DrawingWand *wand) 1576{ 1577 assert(wand != (const DrawingWand *) NULL); 1578 assert(wand->signature == MagickWandSignature); 1579 if (wand->debug != MagickFalse) 1580 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1581 if (CurrentContext->family != NULL) 1582 return(AcquireString(CurrentContext->family)); 1583 return((char *) NULL); 1584} 1585 1586/* 1587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1588% % 1589% % 1590% % 1591% D r a w G e t F o n t R e s o l u t i o n % 1592% % 1593% % 1594% % 1595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1596% 1597% DrawGetFontResolution() gets the image X and Y resolution. 1598% 1599% The format of the DrawGetFontResolution method is: 1600% 1601% MagickBooleanType DrawGetFontResolution(const DrawingWand *wand, 1602% double *x,double *y) 1603% 1604% A description of each parameter follows: 1605% 1606% o wand: the magick wand. 1607% 1608% o x: the x-resolution. 1609% 1610% o y: the y-resolution. 1611% 1612*/ 1613WandExport MagickBooleanType DrawGetFontResolution(const DrawingWand *wand, 1614 double *x,double *y) 1615{ 1616 assert(wand != (DrawingWand *) NULL); 1617 assert(wand->signature == MagickWandSignature); 1618 if (wand->debug != MagickFalse) 1619 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1620 *x=72.0; 1621 *y=72.0; 1622 if (CurrentContext->density != (char *) NULL) 1623 { 1624 GeometryInfo 1625 geometry_info; 1626 1627 MagickStatusType 1628 flags; 1629 1630 flags=ParseGeometry(CurrentContext->density,&geometry_info); 1631 *x=geometry_info.rho; 1632 *y=geometry_info.sigma; 1633 if ((flags & SigmaValue) == MagickFalse) 1634 *y=(*x); 1635 } 1636 return(MagickTrue); 1637} 1638 1639/* 1640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1641% % 1642% % 1643% % 1644% D r a w G e t F o n t S i z e % 1645% % 1646% % 1647% % 1648%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1649% 1650% DrawGetFontSize() returns the font pointsize used when annotating with text. 1651% 1652% The format of the DrawGetFontSize method is: 1653% 1654% double DrawGetFontSize(const DrawingWand *wand) 1655% 1656% A description of each parameter follows: 1657% 1658% o wand: the drawing wand. 1659% 1660*/ 1661WandExport double DrawGetFontSize(const DrawingWand *wand) 1662{ 1663 assert(wand != (const DrawingWand *) NULL); 1664 assert(wand->signature == MagickWandSignature); 1665 if (wand->debug != MagickFalse) 1666 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1667 return(CurrentContext->pointsize); 1668} 1669 1670/* 1671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1672% % 1673% % 1674% % 1675% D r a w G e t F o n t S t r e t c h % 1676% % 1677% % 1678% % 1679%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1680% 1681% DrawGetFontStretch() returns the font stretch used when annotating with text. 1682% 1683% The format of the DrawGetFontStretch method is: 1684% 1685% StretchType DrawGetFontStretch(const DrawingWand *wand) 1686% 1687% A description of each parameter follows: 1688% 1689% o wand: the drawing wand. 1690% 1691*/ 1692WandExport StretchType DrawGetFontStretch(const DrawingWand *wand) 1693{ 1694 assert(wand != (const DrawingWand *) NULL); 1695 assert(wand->signature == MagickWandSignature); 1696 if (wand->debug != MagickFalse) 1697 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1698 return(CurrentContext->stretch); 1699} 1700 1701/* 1702%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1703% % 1704% % 1705% % 1706% D r a w G e t F o n t S t y l e % 1707% % 1708% % 1709% % 1710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1711% 1712% DrawGetFontStyle() returns the font style used when annotating with text. 1713% 1714% The format of the DrawGetFontStyle method is: 1715% 1716% StyleType DrawGetFontStyle(const DrawingWand *wand) 1717% 1718% A description of each parameter follows: 1719% 1720% o wand: the drawing wand. 1721% 1722*/ 1723WandExport StyleType DrawGetFontStyle(const DrawingWand *wand) 1724{ 1725 assert(wand != (const DrawingWand *) NULL); 1726 assert(wand->signature == MagickWandSignature); 1727 if (wand->debug != MagickFalse) 1728 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1729 return(CurrentContext->style); 1730} 1731 1732/* 1733%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1734% % 1735% % 1736% % 1737% D r a w G e t F o n t W e i g h t % 1738% % 1739% % 1740% % 1741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1742% 1743% DrawGetFontWeight() returns the font weight used when annotating with text. 1744% 1745% The format of the DrawGetFontWeight method is: 1746% 1747% size_t DrawGetFontWeight(const DrawingWand *wand) 1748% 1749% A description of each parameter follows: 1750% 1751% o wand: the drawing wand. 1752% 1753*/ 1754WandExport size_t DrawGetFontWeight(const DrawingWand *wand) 1755{ 1756 assert(wand != (const DrawingWand *) NULL); 1757 assert(wand->signature == MagickWandSignature); 1758 if (wand->debug != MagickFalse) 1759 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1760 return(CurrentContext->weight); 1761} 1762 1763/* 1764%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1765% % 1766% % 1767% % 1768% D r a w G e t G r a v i t y % 1769% % 1770% % 1771% % 1772%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1773% 1774% DrawGetGravity() returns the text placement gravity used when annotating 1775% with text. 1776% 1777% The format of the DrawGetGravity method is: 1778% 1779% GravityType DrawGetGravity(const DrawingWand *wand) 1780% 1781% A description of each parameter follows: 1782% 1783% o wand: the drawing wand. 1784% 1785*/ 1786WandExport GravityType DrawGetGravity(const DrawingWand *wand) 1787{ 1788 assert(wand != (const DrawingWand *) NULL); 1789 assert(wand->signature == MagickWandSignature); 1790 if (wand->debug != MagickFalse) 1791 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1792 return(CurrentContext->gravity); 1793} 1794 1795/* 1796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1797% % 1798% % 1799% % 1800% D r a w G e t O p a c i t y % 1801% % 1802% % 1803% % 1804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1805% 1806% DrawGetOpacity() returns the alpha used when drawing with the fill 1807% or stroke color or texture. Fully opaque is 1.0. 1808% 1809% The format of the DrawGetOpacity method is: 1810% 1811% double DrawGetOpacity(const DrawingWand *wand) 1812% 1813% A description of each parameter follows: 1814% 1815% o wand: the drawing wand. 1816% 1817*/ 1818WandExport double DrawGetOpacity(const DrawingWand *wand) 1819{ 1820 double 1821 alpha; 1822 1823 assert(wand != (const DrawingWand *) NULL); 1824 assert(wand->signature == MagickWandSignature); 1825 if (wand->debug != MagickFalse) 1826 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1827 alpha=(double) QuantumScale*CurrentContext->alpha; 1828 return(alpha); 1829} 1830 1831/* 1832%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1833% % 1834% % 1835% % 1836% D r a w G e t S t r o k e A n t i a l i a s % 1837% % 1838% % 1839% % 1840%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1841% 1842% DrawGetStrokeAntialias() returns the current stroke antialias setting. 1843% Stroked outlines are antialiased by default. When antialiasing is disabled 1844% stroked pixels are thresholded to determine if the stroke color or 1845% underlying canvas color should be used. 1846% 1847% The format of the DrawGetStrokeAntialias method is: 1848% 1849% MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand) 1850% 1851% A description of each parameter follows: 1852% 1853% o wand: the drawing wand. 1854% 1855*/ 1856WandExport MagickBooleanType DrawGetStrokeAntialias(const DrawingWand *wand) 1857{ 1858 assert(wand != (const DrawingWand *) NULL); 1859 assert(wand->signature == MagickWandSignature); 1860 if (wand->debug != MagickFalse) 1861 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1862 return(CurrentContext->stroke_antialias); 1863} 1864 1865/* 1866%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1867% % 1868% % 1869% % 1870% D r a w G e t S t r o k e C o l o r % 1871% % 1872% % 1873% % 1874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1875% 1876% DrawGetStrokeColor() returns the color used for stroking object outlines. 1877% 1878% The format of the DrawGetStrokeColor method is: 1879% 1880% void DrawGetStrokeColor(const DrawingWand *wand, 1881% PixelWand *stroke_color) 1882% 1883% A description of each parameter follows: 1884% 1885% o wand: the drawing wand. 1886% 1887% o stroke_color: Return the stroke color. 1888% 1889*/ 1890WandExport void DrawGetStrokeColor(const DrawingWand *wand, 1891 PixelWand *stroke_color) 1892{ 1893 assert(wand != (const DrawingWand *) NULL); 1894 assert(wand->signature == MagickWandSignature); 1895 assert(stroke_color != (PixelWand *) NULL); 1896 if (wand->debug != MagickFalse) 1897 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1898 PixelSetPixelColor(stroke_color,&CurrentContext->stroke); 1899} 1900 1901/* 1902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1903% % 1904% % 1905% % 1906% D r a w G e t S t r o k e D a s h A r r a y % 1907% % 1908% % 1909% % 1910%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1911% 1912% DrawGetStrokeDashArray() returns an array representing the pattern of 1913% dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The 1914% array must be freed once it is no longer required by the user. 1915% 1916% The format of the DrawGetStrokeDashArray method is: 1917% 1918% double *DrawGetStrokeDashArray(const DrawingWand *wand, 1919% size_t *number_elements) 1920% 1921% A description of each parameter follows: 1922% 1923% o wand: the drawing wand. 1924% 1925% o number_elements: address to place number of elements in dash array 1926% 1927*/ 1928WandExport double *DrawGetStrokeDashArray(const DrawingWand *wand, 1929 size_t *number_elements) 1930{ 1931 double 1932 *dasharray; 1933 1934 register const double 1935 *p; 1936 1937 register double 1938 *q; 1939 1940 register ssize_t 1941 i; 1942 1943 size_t 1944 n; 1945 1946 assert(wand != (const DrawingWand *) NULL); 1947 assert(wand->signature == MagickWandSignature); 1948 if (wand->debug != MagickFalse) 1949 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 1950 assert(number_elements != (size_t *) NULL); 1951 n=0; 1952 p=CurrentContext->dash_pattern; 1953 if (p != (const double *) NULL) 1954 while (fabs(*p++) >= MagickEpsilon) 1955 n++; 1956 *number_elements=n; 1957 dasharray=(double *) NULL; 1958 if (n != 0) 1959 { 1960 dasharray=(double *) AcquireQuantumMemory((size_t) n+1UL, 1961 sizeof(*dasharray)); 1962 p=CurrentContext->dash_pattern; 1963 q=dasharray; 1964 for (i=0; i < (ssize_t) n; i++) 1965 *q++=(*p++); 1966 *q=0.0; 1967 } 1968 return(dasharray); 1969} 1970 1971/* 1972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1973% % 1974% % 1975% % 1976% D r a w G e t S t r o k e D a s h O f f s e t % 1977% % 1978% % 1979% % 1980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1981% 1982% DrawGetStrokeDashOffset() returns the offset into the dash pattern to 1983% start the dash. 1984% 1985% The format of the DrawGetStrokeDashOffset method is: 1986% 1987% double DrawGetStrokeDashOffset(const DrawingWand *wand) 1988% 1989% A description of each parameter follows: 1990% 1991% o wand: the drawing wand. 1992% 1993*/ 1994WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand) 1995{ 1996 assert(wand != (const DrawingWand *) NULL); 1997 assert(wand->signature == MagickWandSignature); 1998 if (wand->debug != MagickFalse) 1999 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2000 return(CurrentContext->dash_offset); 2001} 2002 2003/* 2004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2005% % 2006% % 2007% % 2008% D r a w G e t S t r o k e L i n e C a p % 2009% % 2010% % 2011% % 2012%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2013% 2014% DrawGetStrokeLineCap() returns the shape to be used at the end of 2015% open subpaths when they are stroked. Values of LineCap are 2016% UndefinedCap, ButtCap, RoundCap, and SquareCap. 2017% 2018% The format of the DrawGetStrokeLineCap method is: 2019% 2020% LineCap DrawGetStrokeLineCap(const DrawingWand *wand) 2021% 2022% A description of each parameter follows: 2023% 2024% o wand: the drawing wand. 2025% 2026*/ 2027WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand) 2028{ 2029 assert(wand != (const DrawingWand *) NULL); 2030 assert(wand->signature == MagickWandSignature); 2031 if (wand->debug != MagickFalse) 2032 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2033 return(CurrentContext->linecap); 2034} 2035 2036/* 2037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2038% % 2039% % 2040% % 2041% D r a w G e t S t r o k e L i n e J o i n % 2042% % 2043% % 2044% % 2045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2046% 2047% DrawGetStrokeLineJoin() returns the shape to be used at the 2048% corners of paths (or other vector shapes) when they are 2049% stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin, 2050% and BevelJoin. 2051% 2052% The format of the DrawGetStrokeLineJoin method is: 2053% 2054% LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand) 2055% 2056% A description of each parameter follows: 2057% 2058% o wand: the drawing wand. 2059% 2060*/ 2061WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand) 2062{ 2063 assert(wand != (const DrawingWand *) NULL); 2064 assert(wand->signature == MagickWandSignature); 2065 if (wand->debug != MagickFalse) 2066 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2067 return(CurrentContext->linejoin); 2068} 2069 2070/* 2071%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2072% % 2073% % 2074% % 2075% D r a w G e t S t r o k e M i t e r L i m i t % 2076% % 2077% % 2078% % 2079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2080% 2081% DrawGetStrokeMiterLimit() returns the miter limit. When two line 2082% segments meet at a sharp angle and miter joins have been specified for 2083% 'lineJoin', it is possible for the miter to extend far beyond the 2084% thickness of the line stroking the path. The miterLimit' imposes a 2085% limit on the ratio of the miter length to the 'lineWidth'. 2086% 2087% The format of the DrawGetStrokeMiterLimit method is: 2088% 2089% size_t DrawGetStrokeMiterLimit(const DrawingWand *wand) 2090% 2091% A description of each parameter follows: 2092% 2093% o wand: the drawing wand. 2094% 2095*/ 2096WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand) 2097{ 2098 assert(wand != (const DrawingWand *) NULL); 2099 assert(wand->signature == MagickWandSignature); 2100 if (wand->debug != MagickFalse) 2101 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2102 return CurrentContext->miterlimit; 2103} 2104 2105/* 2106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2107% % 2108% % 2109% % 2110% D r a w G e t S t r o k e O p a c i t y % 2111% % 2112% % 2113% % 2114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2115% 2116% DrawGetStrokeOpacity() returns the alpha of stroked object outlines. 2117% 2118% The format of the DrawGetStrokeOpacity method is: 2119% 2120% double DrawGetStrokeOpacity(const DrawingWand *wand) 2121% 2122% A description of each parameter follows: 2123% 2124% o wand: the drawing wand. 2125% 2126*/ 2127WandExport double DrawGetStrokeOpacity(const DrawingWand *wand) 2128{ 2129 double 2130 alpha; 2131 2132 assert(wand != (const DrawingWand *) NULL); 2133 assert(wand->signature == MagickWandSignature); 2134 if (wand->debug != MagickFalse) 2135 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2136 alpha=(double) QuantumScale*CurrentContext->stroke.alpha; 2137 return(alpha); 2138} 2139 2140/* 2141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2142% % 2143% % 2144% % 2145% D r a w G e t S t r o k e W i d t h % 2146% % 2147% % 2148% % 2149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2150% 2151% DrawGetStrokeWidth() returns the width of the stroke used to draw object 2152% outlines. 2153% 2154% The format of the DrawGetStrokeWidth method is: 2155% 2156% double DrawGetStrokeWidth(const DrawingWand *wand) 2157% 2158% A description of each parameter follows: 2159% 2160% o wand: the drawing wand. 2161% 2162*/ 2163WandExport double DrawGetStrokeWidth(const DrawingWand *wand) 2164{ 2165 assert(wand != (const DrawingWand *) NULL); 2166 assert(wand->signature == MagickWandSignature); 2167 if (wand->debug != MagickFalse) 2168 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2169 return(CurrentContext->stroke_width); 2170} 2171 2172/* 2173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2174% % 2175% % 2176% % 2177% D r a w G e t T e x t A l i g n m e n t % 2178% % 2179% % 2180% % 2181%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2182% 2183% DrawGetTextAlignment() returns the alignment applied when annotating with 2184% text. 2185% 2186% The format of the DrawGetTextAlignment method is: 2187% 2188% AlignType DrawGetTextAlignment(const DrawingWand *wand) 2189% 2190% A description of each parameter follows: 2191% 2192% o wand: the drawing wand. 2193% 2194*/ 2195WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand) 2196{ 2197 assert(wand != (const DrawingWand *) NULL); 2198 assert(wand->signature == MagickWandSignature); 2199 if (wand->debug != MagickFalse) 2200 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2201 return(CurrentContext->align); 2202} 2203 2204/* 2205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2206% % 2207% % 2208% % 2209% D r a w G e t T e x t A n t i a l i a s % 2210% % 2211% % 2212% % 2213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2214% 2215% DrawGetTextAntialias() returns the current text antialias setting, which 2216% determines whether text is antialiased. Text is antialiased by default. 2217% 2218% The format of the DrawGetTextAntialias method is: 2219% 2220% MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand) 2221% 2222% A description of each parameter follows: 2223% 2224% o wand: the drawing wand. 2225% 2226*/ 2227WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand) 2228{ 2229 assert(wand != (const DrawingWand *) NULL); 2230 assert(wand->signature == MagickWandSignature); 2231 if (wand->debug != MagickFalse) 2232 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2233 return(CurrentContext->text_antialias); 2234} 2235 2236/* 2237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2238% % 2239% % 2240% % 2241% D r a w G e t T e x t D e c o r a t i o n % 2242% % 2243% % 2244% % 2245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2246% 2247% DrawGetTextDecoration() returns the decoration applied when annotating with 2248% text. 2249% 2250% The format of the DrawGetTextDecoration method is: 2251% 2252% DecorationType DrawGetTextDecoration(const DrawingWand *wand) 2253% 2254% A description of each parameter follows: 2255% 2256% o wand: the drawing wand. 2257% 2258*/ 2259WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand) 2260{ 2261 assert(wand != (const DrawingWand *) NULL); 2262 assert(wand->signature == MagickWandSignature); 2263 if (wand->debug != MagickFalse) 2264 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2265 return(CurrentContext->decorate); 2266} 2267 2268/* 2269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2270% % 2271% % 2272% % 2273% D r a w G e t T e x t D i r e c t i o n % 2274% % 2275% % 2276% % 2277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2278% 2279% DrawGetTextDirection() returns the direction that will be used when 2280% annotating with text. 2281% 2282% The format of the DrawGetTextDirection method is: 2283% 2284% DirectionType DrawGetTextDirection(const DrawingWand *wand) 2285% 2286% A description of each parameter follows: 2287% 2288% o wand: the drawing wand. 2289% 2290*/ 2291WandExport DirectionType DrawGetTextDirection(const DrawingWand *wand) 2292{ 2293 assert(wand != (const DrawingWand *) NULL); 2294 assert(wand->signature == MagickWandSignature); 2295 if (wand->debug != MagickFalse) 2296 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2297 return(CurrentContext->direction); 2298} 2299 2300/* 2301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2302% % 2303% % 2304% % 2305% D r a w G e t T e x t E n c o d i n g % 2306% % 2307% % 2308% % 2309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2310% 2311% DrawGetTextEncoding() returns a null-terminated string which specifies the 2312% code set used for text annotations. The string must be freed by the user 2313% once it is no longer required. 2314% 2315% The format of the DrawGetTextEncoding method is: 2316% 2317% char *DrawGetTextEncoding(const DrawingWand *wand) 2318% 2319% A description of each parameter follows: 2320% 2321% o wand: the drawing wand. 2322% 2323*/ 2324WandExport char *DrawGetTextEncoding(const DrawingWand *wand) 2325{ 2326 assert(wand != (const DrawingWand *) NULL); 2327 assert(wand->signature == MagickWandSignature); 2328 if (wand->debug != MagickFalse) 2329 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2330 if (CurrentContext->encoding != (char *) NULL) 2331 return((char *) AcquireString(CurrentContext->encoding)); 2332 return((char *) NULL); 2333} 2334 2335/* 2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2337% % 2338% % 2339% % 2340% D r a w G e t T e x t K e r n i n g % 2341% % 2342% % 2343% % 2344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2345% 2346% DrawGetTextKerning() gets the spacing between characters in text. 2347% 2348% The format of the DrawSetFontKerning method is: 2349% 2350% double DrawGetTextKerning(DrawingWand *wand) 2351% 2352% A description of each parameter follows: 2353% 2354% o wand: the drawing wand. 2355% 2356*/ 2357WandExport double DrawGetTextKerning(DrawingWand *wand) 2358{ 2359 assert(wand != (DrawingWand *) NULL); 2360 assert(wand->signature == MagickWandSignature); 2361 2362 if (wand->debug != MagickFalse) 2363 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2364 return(CurrentContext->kerning); 2365} 2366 2367/* 2368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2369% % 2370% % 2371% % 2372% D r a w G e t T e x t I n t e r l i n e S p a c i n g % 2373% % 2374% % 2375% % 2376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2377% 2378% DrawGetTextInterlineSpacing() gets the spacing between lines in text. 2379% 2380% The format of the DrawGetTextInterlineSpacing method is: 2381% 2382% double DrawGetTextInterlineSpacing(DrawingWand *wand) 2383% 2384% A description of each parameter follows: 2385% 2386% o wand: the drawing wand. 2387% 2388*/ 2389WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand) 2390{ 2391 assert(wand != (DrawingWand *) NULL); 2392 assert(wand->signature == MagickWandSignature); 2393 if (wand->debug != MagickFalse) 2394 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2395 return(CurrentContext->interline_spacing); 2396} 2397 2398/* 2399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2400% % 2401% % 2402% % 2403% D r a w G e t T e x t I n t e r w o r d S p a c i n g % 2404% % 2405% % 2406% % 2407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2408% 2409% DrawGetTextInterwordSpacing() gets the spacing between words in text. 2410% 2411% The format of the DrawSetFontKerning method is: 2412% 2413% double DrawGetTextInterwordSpacing(DrawingWand *wand) 2414% 2415% A description of each parameter follows: 2416% 2417% o wand: the drawing wand. 2418% 2419*/ 2420WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand) 2421{ 2422 assert(wand != (DrawingWand *) NULL); 2423 assert(wand->signature == MagickWandSignature); 2424 if (wand->debug != MagickFalse) 2425 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2426 return(CurrentContext->interword_spacing); 2427} 2428 2429/* 2430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2431% % 2432% % 2433% % 2434% D r a w G e t V e c t o r G r a p h i c s % 2435% % 2436% % 2437% % 2438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2439% 2440% DrawGetVectorGraphics() returns a null-terminated string which specifies the 2441% vector graphics generated by any graphics calls made since the wand was 2442% instantiated. The string must be freed by the user once it is no longer 2443% required. 2444% 2445% The format of the DrawGetVectorGraphics method is: 2446% 2447% char *DrawGetVectorGraphics(DrawingWand *wand) 2448% 2449% A description of each parameter follows: 2450% 2451% o wand: the drawing wand. 2452% 2453*/ 2454WandExport char *DrawGetVectorGraphics(DrawingWand *wand) 2455{ 2456 char 2457 value[MagickPathExtent], 2458 *xml; 2459 2460 PixelInfo 2461 pixel; 2462 2463 register ssize_t 2464 i; 2465 2466 XMLTreeInfo 2467 *child, 2468 *xml_info; 2469 2470 assert(wand != (const DrawingWand *) NULL); 2471 assert(wand->signature == MagickWandSignature); 2472 if (wand->debug != MagickFalse) 2473 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2474 xml_info=NewXMLTreeTag("drawing-wand"); 2475 if (xml_info == (XMLTreeInfo *) NULL) 2476 return((char *) NULL); 2477 (void) SetXMLTreeContent(xml_info," "); 2478 GetPixelInfo(wand->image,&pixel); 2479 child=AddChildToXMLTree(xml_info,"clip-path",0); 2480 if (child != (XMLTreeInfo *) NULL) 2481 (void) SetXMLTreeContent(child,CurrentContext->clip_mask); 2482 child=AddChildToXMLTree(xml_info,"clip-units",0); 2483 if (child != (XMLTreeInfo *) NULL) 2484 { 2485 (void) CopyMagickString(value,CommandOptionToMnemonic( 2486 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units), 2487 MagickPathExtent); 2488 (void) SetXMLTreeContent(child,value); 2489 } 2490 child=AddChildToXMLTree(xml_info,"decorate",0); 2491 if (child != (XMLTreeInfo *) NULL) 2492 { 2493 (void) CopyMagickString(value,CommandOptionToMnemonic( 2494 MagickDecorateOptions,(ssize_t) CurrentContext->decorate), 2495 MagickPathExtent); 2496 (void) SetXMLTreeContent(child,value); 2497 } 2498 child=AddChildToXMLTree(xml_info,"encoding",0); 2499 if (child != (XMLTreeInfo *) NULL) 2500 (void) SetXMLTreeContent(child,CurrentContext->encoding); 2501 child=AddChildToXMLTree(xml_info,"fill",0); 2502 if (child != (XMLTreeInfo *) NULL) 2503 { 2504 if (CurrentContext->fill.alpha != OpaqueAlpha) 2505 pixel.alpha_trait=CurrentContext->fill.alpha != OpaqueAlpha ? 2506 BlendPixelTrait : UndefinedPixelTrait; 2507 pixel=CurrentContext->fill; 2508 GetColorTuple(&pixel,MagickTrue,value); 2509 (void) SetXMLTreeContent(child,value); 2510 } 2511 child=AddChildToXMLTree(xml_info,"fill-opacity",0); 2512 if (child != (XMLTreeInfo *) NULL) 2513 { 2514 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2515 (double) (QuantumScale*CurrentContext->fill.alpha)); 2516 (void) SetXMLTreeContent(child,value); 2517 } 2518 child=AddChildToXMLTree(xml_info,"fill-rule",0); 2519 if (child != (XMLTreeInfo *) NULL) 2520 { 2521 (void) CopyMagickString(value,CommandOptionToMnemonic( 2522 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule), 2523 MagickPathExtent); 2524 (void) SetXMLTreeContent(child,value); 2525 } 2526 child=AddChildToXMLTree(xml_info,"font",0); 2527 if (child != (XMLTreeInfo *) NULL) 2528 (void) SetXMLTreeContent(child,CurrentContext->font); 2529 child=AddChildToXMLTree(xml_info,"font-family",0); 2530 if (child != (XMLTreeInfo *) NULL) 2531 (void) SetXMLTreeContent(child,CurrentContext->family); 2532 child=AddChildToXMLTree(xml_info,"font-size",0); 2533 if (child != (XMLTreeInfo *) NULL) 2534 { 2535 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2536 CurrentContext->pointsize); 2537 (void) SetXMLTreeContent(child,value); 2538 } 2539 child=AddChildToXMLTree(xml_info,"font-stretch",0); 2540 if (child != (XMLTreeInfo *) NULL) 2541 { 2542 (void) CopyMagickString(value,CommandOptionToMnemonic( 2543 MagickStretchOptions,(ssize_t) CurrentContext->stretch), 2544 MagickPathExtent); 2545 (void) SetXMLTreeContent(child,value); 2546 } 2547 child=AddChildToXMLTree(xml_info,"font-style",0); 2548 if (child != (XMLTreeInfo *) NULL) 2549 { 2550 (void) CopyMagickString(value,CommandOptionToMnemonic( 2551 MagickStyleOptions,(ssize_t) CurrentContext->style),MagickPathExtent); 2552 (void) SetXMLTreeContent(child,value); 2553 } 2554 child=AddChildToXMLTree(xml_info,"font-weight",0); 2555 if (child != (XMLTreeInfo *) NULL) 2556 { 2557 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double) 2558 CurrentContext->weight); 2559 (void) SetXMLTreeContent(child,value); 2560 } 2561 child=AddChildToXMLTree(xml_info,"gravity",0); 2562 if (child != (XMLTreeInfo *) NULL) 2563 { 2564 (void) CopyMagickString(value,CommandOptionToMnemonic( 2565 MagickGravityOptions,(ssize_t) CurrentContext->gravity), 2566 MagickPathExtent); 2567 (void) SetXMLTreeContent(child,value); 2568 } 2569 child=AddChildToXMLTree(xml_info,"stroke",0); 2570 if (child != (XMLTreeInfo *) NULL) 2571 { 2572 if (CurrentContext->stroke.alpha != OpaqueAlpha) 2573 pixel.alpha_trait=CurrentContext->stroke.alpha != OpaqueAlpha ? 2574 BlendPixelTrait : UndefinedPixelTrait; 2575 pixel=CurrentContext->stroke; 2576 GetColorTuple(&pixel,MagickTrue,value); 2577 (void) SetXMLTreeContent(child,value); 2578 } 2579 child=AddChildToXMLTree(xml_info,"stroke-antialias",0); 2580 if (child != (XMLTreeInfo *) NULL) 2581 { 2582 (void) FormatLocaleString(value,MagickPathExtent,"%d", 2583 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0); 2584 (void) SetXMLTreeContent(child,value); 2585 } 2586 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0); 2587 if ((child != (XMLTreeInfo *) NULL) && 2588 (CurrentContext->dash_pattern != (double *) NULL)) 2589 { 2590 char 2591 *dash_pattern; 2592 2593 dash_pattern=AcquireString((char *) NULL); 2594 for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++) 2595 { 2596 if (i != 0) 2597 (void) ConcatenateString(&dash_pattern,","); 2598 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2599 CurrentContext->dash_pattern[i]); 2600 (void) ConcatenateString(&dash_pattern,value); 2601 } 2602 (void) SetXMLTreeContent(child,dash_pattern); 2603 dash_pattern=DestroyString(dash_pattern); 2604 } 2605 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0); 2606 if (child != (XMLTreeInfo *) NULL) 2607 { 2608 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2609 CurrentContext->dash_offset); 2610 (void) SetXMLTreeContent(child,value); 2611 } 2612 child=AddChildToXMLTree(xml_info,"stroke-linecap",0); 2613 if (child != (XMLTreeInfo *) NULL) 2614 { 2615 (void) CopyMagickString(value,CommandOptionToMnemonic( 2616 MagickLineCapOptions,(ssize_t) CurrentContext->linecap), 2617 MagickPathExtent); 2618 (void) SetXMLTreeContent(child,value); 2619 } 2620 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0); 2621 if (child != (XMLTreeInfo *) NULL) 2622 { 2623 (void) CopyMagickString(value,CommandOptionToMnemonic( 2624 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin), 2625 MagickPathExtent); 2626 (void) SetXMLTreeContent(child,value); 2627 } 2628 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0); 2629 if (child != (XMLTreeInfo *) NULL) 2630 { 2631 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double) 2632 CurrentContext->miterlimit); 2633 (void) SetXMLTreeContent(child,value); 2634 } 2635 child=AddChildToXMLTree(xml_info,"stroke-opacity",0); 2636 if (child != (XMLTreeInfo *) NULL) 2637 { 2638 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2639 (double) (QuantumScale*CurrentContext->stroke.alpha)); 2640 (void) SetXMLTreeContent(child,value); 2641 } 2642 child=AddChildToXMLTree(xml_info,"stroke-width",0); 2643 if (child != (XMLTreeInfo *) NULL) 2644 { 2645 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2646 CurrentContext->stroke_width); 2647 (void) SetXMLTreeContent(child,value); 2648 } 2649 child=AddChildToXMLTree(xml_info,"text-align",0); 2650 if (child != (XMLTreeInfo *) NULL) 2651 { 2652 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions, 2653 (ssize_t) CurrentContext->align),MagickPathExtent); 2654 (void) SetXMLTreeContent(child,value); 2655 } 2656 child=AddChildToXMLTree(xml_info,"text-antialias",0); 2657 if (child != (XMLTreeInfo *) NULL) 2658 { 2659 (void) FormatLocaleString(value,MagickPathExtent,"%d", 2660 CurrentContext->text_antialias != MagickFalse ? 1 : 0); 2661 (void) SetXMLTreeContent(child,value); 2662 } 2663 child=AddChildToXMLTree(xml_info,"text-undercolor",0); 2664 if (child != (XMLTreeInfo *) NULL) 2665 { 2666 if (CurrentContext->undercolor.alpha != OpaqueAlpha) 2667 pixel.alpha_trait=CurrentContext->undercolor.alpha != OpaqueAlpha ? 2668 BlendPixelTrait : UndefinedPixelTrait; 2669 pixel=CurrentContext->undercolor; 2670 GetColorTuple(&pixel,MagickTrue,value); 2671 (void) SetXMLTreeContent(child,value); 2672 } 2673 child=AddChildToXMLTree(xml_info,"vector-graphics",0); 2674 if (child != (XMLTreeInfo *) NULL) 2675 (void) SetXMLTreeContent(child,wand->mvg); 2676 xml=XMLTreeInfoToXML(xml_info); 2677 xml_info=DestroyXMLTree(xml_info); 2678 return(xml); 2679} 2680 2681/* 2682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2683% % 2684% % 2685% % 2686% D r a w G e t T e x t U n d e r C o l o r % 2687% % 2688% % 2689% % 2690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2691% 2692% DrawGetTextUnderColor() returns the color of a background rectangle 2693% to place under text annotations. 2694% 2695% The format of the DrawGetTextUnderColor method is: 2696% 2697% void DrawGetTextUnderColor(const DrawingWand *wand, 2698% PixelWand *under_color) 2699% 2700% A description of each parameter follows: 2701% 2702% o wand: the drawing wand. 2703% 2704% o under_color: Return the under color. 2705% 2706*/ 2707WandExport void DrawGetTextUnderColor(const DrawingWand *wand, 2708 PixelWand *under_color) 2709{ 2710 assert(wand != (const DrawingWand *) NULL); 2711 assert(wand->signature == MagickWandSignature); 2712 assert(under_color != (PixelWand *) NULL); 2713 if (wand->debug != MagickFalse) 2714 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2715 PixelSetPixelColor(under_color,&CurrentContext->undercolor); 2716} 2717 2718/* 2719%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2720% % 2721% % 2722% % 2723% D r a w L i n e % 2724% % 2725% % 2726% % 2727%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2728% 2729% DrawLine() draws a line on the image using the current stroke color, 2730% stroke alpha, and stroke width. 2731% 2732% The format of the DrawLine method is: 2733% 2734% void DrawLine(DrawingWand *wand,const double sx,const double sy, 2735% const double ex,const double ey) 2736% 2737% A description of each parameter follows: 2738% 2739% o wand: the drawing wand. 2740% 2741% o sx: starting x ordinate 2742% 2743% o sy: starting y ordinate 2744% 2745% o ex: ending x ordinate 2746% 2747% o ey: ending y ordinate 2748% 2749*/ 2750WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy, 2751 const double ex,const double ey) 2752{ 2753 assert(wand != (DrawingWand *) NULL); 2754 assert(wand->signature == MagickWandSignature); 2755 if (wand->debug != MagickFalse) 2756 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2757 (void) MVGPrintf(wand,"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey); 2758} 2759 2760/* 2761%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2762% % 2763% % 2764% % 2765% D r a w P a t h C l o s e % 2766% % 2767% % 2768% % 2769%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2770% 2771% DrawPathClose() adds a path element to the current path which closes the 2772% current subpath by drawing a straight line from the current point to the 2773% current subpath's most recent starting point (usually, the most recent 2774% moveto point). 2775% 2776% The format of the DrawPathClose method is: 2777% 2778% void DrawPathClose(DrawingWand *wand) 2779% 2780% A description of each parameter follows: 2781% 2782% o wand: the drawing wand. 2783% 2784*/ 2785WandExport void DrawPathClose(DrawingWand *wand) 2786{ 2787 assert(wand != (DrawingWand *) NULL); 2788 assert(wand->signature == MagickWandSignature); 2789 if (wand->debug != MagickFalse) 2790 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2791 (void) MVGAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ? 2792 "Z" : "z"); 2793} 2794 2795/* 2796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2797% % 2798% % 2799% % 2800% D r a w P a t h C u r v e T o A b s o l u t e % 2801% % 2802% % 2803% % 2804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2805% 2806% DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current 2807% point to (x,y) using (x1,y1) as the control point at the beginning of 2808% the curve and (x2,y2) as the control point at the end of the curve using 2809% absolute coordinates. At the end of the command, the new current point 2810% becomes the final (x,y) coordinate pair used in the polybezier. 2811% 2812% The format of the DrawPathCurveToAbsolute method is: 2813% 2814% void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1, 2815% const double y1,const double x2,const double y2,const double x, 2816% const double y) 2817% 2818% A description of each parameter follows: 2819% 2820% o wand: the drawing wand. 2821% 2822% o x1: x ordinate of control point for curve beginning 2823% 2824% o y1: y ordinate of control point for curve beginning 2825% 2826% o x2: x ordinate of control point for curve ending 2827% 2828% o y2: y ordinate of control point for curve ending 2829% 2830% o x: x ordinate of the end of the curve 2831% 2832% o y: y ordinate of the end of the curve 2833% 2834*/ 2835 2836static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode, 2837 const double x1,const double y1,const double x2,const double y2, 2838 const double x,const double y) 2839{ 2840 assert(wand != (DrawingWand *) NULL); 2841 assert(wand->signature == MagickWandSignature); 2842 if (wand->debug != MagickFalse) 2843 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2844 if ((wand->path_operation != PathCurveToOperation) || 2845 (wand->path_mode != mode)) 2846 { 2847 wand->path_operation=PathCurveToOperation; 2848 wand->path_mode=mode; 2849 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g %.20g %.20g", 2850 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y); 2851 } 2852 else 2853 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1, 2854 x2,y2,x,y); 2855} 2856 2857WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1, 2858 const double y1,const double x2,const double y2,const double x,const double y) 2859{ 2860 assert(wand != (DrawingWand *) NULL); 2861 assert(wand->signature == MagickWandSignature); 2862 if (wand->debug != MagickFalse) 2863 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2864 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y); 2865} 2866 2867/* 2868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2869% % 2870% % 2871% % 2872% D r a w P a t h C u r v e T o R e l a t i v e % 2873% % 2874% % 2875% % 2876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2877% 2878% DrawPathCurveToRelative() draws a cubic Bezier curve from the current 2879% point to (x,y) using (x1,y1) as the control point at the beginning of 2880% the curve and (x2,y2) as the control point at the end of the curve using 2881% relative coordinates. At the end of the command, the new current point 2882% becomes the final (x,y) coordinate pair used in the polybezier. 2883% 2884% The format of the DrawPathCurveToRelative method is: 2885% 2886% void DrawPathCurveToRelative(DrawingWand *wand,const double x1, 2887% const double y1,const double x2,const double y2,const double x, 2888% const double y) 2889% 2890% A description of each parameter follows: 2891% 2892% o wand: the drawing wand. 2893% 2894% o x1: x ordinate of control point for curve beginning 2895% 2896% o y1: y ordinate of control point for curve beginning 2897% 2898% o x2: x ordinate of control point for curve ending 2899% 2900% o y2: y ordinate of control point for curve ending 2901% 2902% o x: x ordinate of the end of the curve 2903% 2904% o y: y ordinate of the end of the curve 2905% 2906*/ 2907WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1, 2908 const double y1,const double x2,const double y2,const double x,const double y) 2909{ 2910 assert(wand != (DrawingWand *) NULL); 2911 assert(wand->signature == MagickWandSignature); 2912 if (wand->debug != MagickFalse) 2913 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2914 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y); 2915} 2916 2917/* 2918%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2919% % 2920% % 2921% % 2922% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r A b s o l u t e % 2923% % 2924% % 2925% % 2926%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2927% 2928% DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve 2929% from the current point to (x,y) using (x1,y1) as the control point using 2930% absolute coordinates. At the end of the command, the new current point 2931% becomes the final (x,y) coordinate pair used in the polybezier. 2932% 2933% The format of the DrawPathCurveToQuadraticBezierAbsolute method is: 2934% 2935% void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand, 2936% const double x1,const double y1,onst double x,const double y) 2937% 2938% A description of each parameter follows: 2939% 2940% o wand: the drawing wand. 2941% 2942% o x1: x ordinate of the control point 2943% 2944% o y1: y ordinate of the control point 2945% 2946% o x: x ordinate of final point 2947% 2948% o y: y ordinate of final point 2949% 2950*/ 2951 2952static void DrawPathCurveToQuadraticBezier(DrawingWand *wand, 2953 const PathMode mode,const double x1,double y1,const double x,const double y) 2954{ 2955 assert(wand != (DrawingWand *) NULL); 2956 assert(wand->signature == MagickWandSignature); 2957 if (wand->debug != MagickFalse) 2958 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2959 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) || 2960 (wand->path_mode != mode)) 2961 { 2962 wand->path_operation=PathCurveToQuadraticBezierOperation; 2963 wand->path_mode=mode; 2964 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g", 2965 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y); 2966 } 2967 else 2968 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x1,y1,x,y); 2969} 2970 2971WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand, 2972 const double x1,const double y1,const double x,const double y) 2973{ 2974 assert(wand != (DrawingWand *) NULL); 2975 assert(wand->signature == MagickWandSignature); 2976 if (wand->debug != MagickFalse) 2977 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2978 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y); 2979} 2980 2981/* 2982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2983% % 2984% % 2985% % 2986% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r R e l a t i v e % 2987% % 2988% % 2989% % 2990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2991% 2992% DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve 2993% from the current point to (x,y) using (x1,y1) as the control point using 2994% relative coordinates. At the end of the command, the new current point 2995% becomes the final (x,y) coordinate pair used in the polybezier. 2996% 2997% The format of the DrawPathCurveToQuadraticBezierRelative method is: 2998% 2999% void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand, 3000% const double x1,const double y1,const double x,const double y) 3001% 3002% A description of each parameter follows: 3003% 3004% o wand: the drawing wand. 3005% 3006% o x1: x ordinate of the control point 3007% 3008% o y1: y ordinate of the control point 3009% 3010% o x: x ordinate of final point 3011% 3012% o y: y ordinate of final point 3013% 3014*/ 3015WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand, 3016 const double x1,const double y1,const double x,const double y) 3017{ 3018 assert(wand != (DrawingWand *) NULL); 3019 assert(wand->signature == MagickWandSignature); 3020 if (wand->debug != MagickFalse) 3021 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3022 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y); 3023} 3024 3025/* 3026%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3027% % 3028% % 3029% % 3030% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h % 3031% % 3032% % 3033% % 3034%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3035% 3036% DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic 3037% Bezier curve (using absolute coordinates) from the current point to 3038% (x,y). The control point is assumed to be the reflection of the 3039% control point on the previous command relative to the current 3040% point. (If there is no previous command or if the previous command was 3041% not a DrawPathCurveToQuadraticBezierAbsolute, 3042% DrawPathCurveToQuadraticBezierRelative, 3043% DrawPathCurveToQuadraticBezierSmoothAbsolute or 3044% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point 3045% is coincident with the current point.). At the end of the command, the 3046% new current point becomes the final (x,y) coordinate pair used in the 3047% polybezier. 3048% 3049% The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is: 3050% 3051% void DrawPathCurveToQuadraticBezierSmoothAbsolute( 3052% DrawingWand *wand,const double x,const double y) 3053% 3054% A description of each parameter follows: 3055% 3056% o wand: the drawing wand. 3057% 3058% o x: x ordinate of final point 3059% 3060% o y: y ordinate of final point 3061% 3062*/ 3063 3064static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand, 3065 const PathMode mode,const double x,const double y) 3066{ 3067 assert(wand != (DrawingWand *) NULL); 3068 assert(wand->signature == MagickWandSignature); 3069 if (wand->debug != MagickFalse) 3070 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3071 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) || 3072 (wand->path_mode != mode)) 3073 { 3074 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation; 3075 wand->path_mode=mode; 3076 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ? 3077 'T' : 't',x,y); 3078 } 3079 else 3080 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y); 3081} 3082 3083WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand, 3084 const double x,const double y) 3085{ 3086 assert(wand != (DrawingWand *) NULL); 3087 assert(wand->signature == MagickWandSignature); 3088 if (wand->debug != MagickFalse) 3089 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3090 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y); 3091} 3092 3093/* 3094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3095% % 3096% % 3097% % 3098% D r a w P a t h C u r v e T o Q u a d r a t i c B e z i e r S m o o t h % 3099% % 3100% % 3101% % 3102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3103% 3104% DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic Bezier 3105% curve (using relative coordinates) from the current point to (x,y). The 3106% control point is assumed to be the reflection of the control point on the 3107% previous command relative to the current point. (If there is no previous 3108% command or if the previous command was not a 3109% DrawPathCurveToQuadraticBezierAbsolute, 3110% DrawPathCurveToQuadraticBezierRelative, 3111% DrawPathCurveToQuadraticBezierSmoothAbsolute or 3112% DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is 3113% coincident with the current point.). At the end of the command, the new 3114% current point becomes the final (x,y) coordinate pair used in the polybezier. 3115% 3116% The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is: 3117% 3118% void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand, 3119% const double x,const double y) 3120% 3121% A description of each parameter follows: 3122% 3123% o wand: the drawing wand. 3124% 3125% o x: x ordinate of final point 3126% 3127% o y: y ordinate of final point 3128% 3129*/ 3130WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand, 3131 const double x,const double y) 3132{ 3133 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y); 3134} 3135 3136/* 3137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3138% % 3139% % 3140% % 3141% D r a w P a t h C u r v e T o S m o o t h A b s o l u t e % 3142% % 3143% % 3144% % 3145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3146% 3147% DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the 3148% current point to (x,y) using absolute coordinates. The first control 3149% point is assumed to be the reflection of the second control point on 3150% the previous command relative to the current point. (If there is no 3151% previous command or if the previous command was not an 3152% DrawPathCurveToAbsolute, DrawPathCurveToRelative, 3153% DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume 3154% the first control point is coincident with the current point.) (x2,y2) 3155% is the second control point (i.e., the control point at the end of the 3156% curve). At the end of the command, the new current point becomes the 3157% final (x,y) coordinate pair used in the polybezier. 3158% 3159% The format of the DrawPathCurveToSmoothAbsolute method is: 3160% 3161% void DrawPathCurveToSmoothAbsolute(DrawingWand *wand, 3162% const double x2,const double y2,const double x,const double y) 3163% 3164% A description of each parameter follows: 3165% 3166% o wand: the drawing wand. 3167% 3168% o x2: x ordinate of second control point 3169% 3170% o y2: y ordinate of second control point 3171% 3172% o x: x ordinate of termination point 3173% 3174% o y: y ordinate of termination point 3175% 3176*/ 3177 3178static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode, 3179 const double x2,const double y2,const double x,const double y) 3180{ 3181 assert(wand != (DrawingWand *) NULL); 3182 assert(wand->signature == MagickWandSignature); 3183 if (wand->debug != MagickFalse) 3184 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3185 if ((wand->path_operation != PathCurveToSmoothOperation) || 3186 (wand->path_mode != mode)) 3187 { 3188 wand->path_operation=PathCurveToSmoothOperation; 3189 wand->path_mode=mode; 3190 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g %.20g %.20g", 3191 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y); 3192 } 3193 else 3194 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x2,y2,x,y); 3195} 3196 3197WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2, 3198 const double y2,const double x,const double y) 3199{ 3200 assert(wand != (DrawingWand *) NULL); 3201 assert(wand->signature == MagickWandSignature); 3202 if (wand->debug != MagickFalse) 3203 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3204 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y); 3205} 3206 3207/* 3208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3209% % 3210% % 3211% % 3212% D r a w P a t h C u r v e T o S m o o t h R e l a t i v e % 3213% % 3214% % 3215% % 3216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3217% 3218% DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current 3219% point to (x,y) using relative coordinates. The first control point is 3220% assumed to be the reflection of the second control point on the previous 3221% command relative to the current point. (If there is no previous command or 3222% if the previous command was not an DrawPathCurveToAbsolute, 3223% DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or 3224% DrawPathCurveToSmoothRelative, assume the first control point is coincident 3225% with the current point.) (x2,y2) is the second control point (i.e., the 3226% control point at the end of the curve). At the end of the command, the new 3227% current point becomes the final (x,y) coordinate pair used in the polybezier. 3228% 3229% The format of the DrawPathCurveToSmoothRelative method is: 3230% 3231% void DrawPathCurveToSmoothRelative(DrawingWand *wand, 3232% const double x2,const double y2,const double x,const double y) 3233% 3234% A description of each parameter follows: 3235% 3236% o wand: the drawing wand. 3237% 3238% o x2: x ordinate of second control point 3239% 3240% o y2: y ordinate of second control point 3241% 3242% o x: x ordinate of termination point 3243% 3244% o y: y ordinate of termination point 3245% 3246*/ 3247WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2, 3248 const double y2,const double x,const double y) 3249{ 3250 assert(wand != (DrawingWand *) NULL); 3251 assert(wand->signature == MagickWandSignature); 3252 if (wand->debug != MagickFalse) 3253 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3254 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y); 3255} 3256 3257/* 3258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3259% % 3260% % 3261% % 3262% D r a w P a t h E l l i p t i c A r c A b s o l u t e % 3263% % 3264% % 3265% % 3266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3267% 3268% DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point 3269% to (x, y) using absolute coordinates. The size and orientation of the 3270% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which 3271% indicates how the ellipse as a whole is rotated relative to the current 3272% coordinate system. The center (cx, cy) of the ellipse is calculated 3273% automagically to satisfy the constraints imposed by the other parameters. 3274% largeArcFlag and sweepFlag contribute to the automatic calculations and help 3275% determine how the arc is drawn. If largeArcFlag is true then draw the larger 3276% of the available arcs. If sweepFlag is true, then draw the arc matching a 3277% clock-wise rotation. 3278% 3279% The format of the DrawPathEllipticArcAbsolute method is: 3280% 3281% void DrawPathEllipticArcAbsolute(DrawingWand *wand, 3282% const double rx,const double ry,const double x_axis_rotation, 3283% const MagickBooleanType large_arc_flag, 3284% const MagickBooleanType sweep_flag,const double x,const double y) 3285% 3286% A description of each parameter follows: 3287% 3288% o wand: the drawing wand. 3289% 3290% o rx: x radius 3291% 3292% o ry: y radius 3293% 3294% o x_axis_rotation: indicates how the ellipse as a whole is rotated 3295% relative to the current coordinate system 3296% 3297% o large_arc_flag: If non-zero (true) then draw the larger of the 3298% available arcs 3299% 3300% o sweep_flag: If non-zero (true) then draw the arc matching a 3301% clock-wise rotation 3302% 3303% 3304*/ 3305 3306static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode, 3307 const double rx,const double ry,const double x_axis_rotation, 3308 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag, 3309 const double x,const double y) 3310{ 3311 assert(wand != (DrawingWand *) NULL); 3312 assert(wand->signature == MagickWandSignature); 3313 if (wand->debug != MagickFalse) 3314 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3315 if ((wand->path_operation != PathEllipticArcOperation) || 3316 (wand->path_mode != mode)) 3317 { 3318 wand->path_operation=PathEllipticArcOperation; 3319 wand->path_mode=mode; 3320 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %u %u %.20g %.20g", 3321 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation, 3322 large_arc_flag,sweep_flag,x,y); 3323 } 3324 else 3325 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry, 3326 x_axis_rotation,large_arc_flag,sweep_flag,x,y); 3327} 3328 3329WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx, 3330 const double ry,const double x_axis_rotation, 3331 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag, 3332 const double x,const double y) 3333{ 3334 assert(wand != (DrawingWand *) NULL); 3335 assert(wand->signature == MagickWandSignature); 3336 if (wand->debug != MagickFalse) 3337 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3338 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation, 3339 large_arc_flag,sweep_flag,x,y); 3340} 3341 3342/* 3343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3344% % 3345% % 3346% % 3347% D r a w P a t h E l l i p t i c A r c R e l a t i v e % 3348% % 3349% % 3350% % 3351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3352% 3353% DrawPathEllipticArcRelative() draws an elliptical arc from the current point 3354% to (x, y) using relative coordinates. The size and orientation of the 3355% ellipse are defined by two radii (rx, ry) and an xAxisRotation, which 3356% indicates how the ellipse as a whole is rotated relative to the current 3357% coordinate system. The center (cx, cy) of the ellipse is calculated 3358% automagically to satisfy the constraints imposed by the other parameters. 3359% largeArcFlag and sweepFlag contribute to the automatic calculations and help 3360% determine how the arc is drawn. If largeArcFlag is true then draw the larger 3361% of the available arcs. If sweepFlag is true, then draw the arc matching a 3362% clock-wise rotation. 3363% 3364% The format of the DrawPathEllipticArcRelative method is: 3365% 3366% void DrawPathEllipticArcRelative(DrawingWand *wand, 3367% const double rx,const double ry,const double x_axis_rotation, 3368% const MagickBooleanType large_arc_flag, 3369% const MagickBooleanType sweep_flag,const double x,const double y) 3370% 3371% A description of each parameter follows: 3372% 3373% o wand: the drawing wand. 3374% 3375% o rx: x radius 3376% 3377% o ry: y radius 3378% 3379% o x_axis_rotation: indicates how the ellipse as a whole is rotated 3380% relative to the current coordinate system 3381% 3382% o large_arc_flag: If non-zero (true) then draw the larger of the 3383% available arcs 3384% 3385% o sweep_flag: If non-zero (true) then draw the arc matching a 3386% clock-wise rotation 3387% 3388*/ 3389WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx, 3390 const double ry,const double x_axis_rotation, 3391 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag, 3392 const double x,const double y) 3393{ 3394 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation, 3395 large_arc_flag,sweep_flag,x,y); 3396} 3397 3398/* 3399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3400% % 3401% % 3402% % 3403% D r a w P a t h F i n i s h % 3404% % 3405% % 3406% % 3407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3408% 3409% DrawPathFinish() terminates the current path. 3410% 3411% The format of the DrawPathFinish method is: 3412% 3413% void DrawPathFinish(DrawingWand *wand) 3414% 3415% A description of each parameter follows: 3416% 3417% o wand: the drawing wand. 3418% 3419*/ 3420WandExport void DrawPathFinish(DrawingWand *wand) 3421{ 3422 assert(wand != (DrawingWand *) NULL); 3423 assert(wand->signature == MagickWandSignature); 3424 if (wand->debug != MagickFalse) 3425 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3426 (void) MVGPrintf(wand,"'\n"); 3427 wand->path_operation=PathDefaultOperation; 3428 wand->path_mode=DefaultPathMode; 3429} 3430 3431/* 3432%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3433% % 3434% % 3435% % 3436% D r a w P a t h L i n e T o A b s o l u t e % 3437% % 3438% % 3439% % 3440%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3441% 3442% DrawPathLineToAbsolute() draws a line path from the current point to the 3443% given coordinate using absolute coordinates. The coordinate then becomes 3444% the new current point. 3445% 3446% The format of the DrawPathLineToAbsolute method is: 3447% 3448% void DrawPathLineToAbsolute(DrawingWand *wand,const double x, 3449% const double y) 3450% 3451% A description of each parameter follows: 3452% 3453% o wand: the drawing wand. 3454% 3455% o x: target x ordinate 3456% 3457% o y: target y ordinate 3458% 3459*/ 3460static void DrawPathLineTo(DrawingWand *wand,const PathMode mode, 3461 const double x,const double y) 3462{ 3463 assert(wand != (DrawingWand *) NULL); 3464 assert(wand->signature == MagickWandSignature); 3465 if (wand->debug != MagickFalse) 3466 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3467 if ((wand->path_operation != PathLineToOperation) || 3468 (wand->path_mode != mode)) 3469 { 3470 wand->path_operation=PathLineToOperation; 3471 wand->path_mode=mode; 3472 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ? 3473 'L' : 'l',x,y); 3474 } 3475 else 3476 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y); 3477} 3478 3479WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x, 3480 const double y) 3481{ 3482 assert(wand != (DrawingWand *) NULL); 3483 assert(wand->signature == MagickWandSignature); 3484 if (wand->debug != MagickFalse) 3485 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3486 DrawPathLineTo(wand,AbsolutePathMode,x,y); 3487} 3488 3489/* 3490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3491% % 3492% % 3493% % 3494% D r a w P a t h L i n e T o R e l a t i v e % 3495% % 3496% % 3497% % 3498%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3499% 3500% DrawPathLineToRelative() draws a line path from the current point to the 3501% given coordinate using relative coordinates. The coordinate then becomes 3502% the new current point. 3503% 3504% The format of the DrawPathLineToRelative method is: 3505% 3506% void DrawPathLineToRelative(DrawingWand *wand,const double x, 3507% const double y) 3508% 3509% A description of each parameter follows: 3510% 3511% o wand: the drawing wand. 3512% 3513% o x: target x ordinate 3514% 3515% o y: target y ordinate 3516% 3517*/ 3518WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x, 3519 const double y) 3520{ 3521 assert(wand != (DrawingWand *) NULL); 3522 assert(wand->signature == MagickWandSignature); 3523 if (wand->debug != MagickFalse) 3524 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3525 DrawPathLineTo(wand,RelativePathMode,x,y); 3526} 3527 3528/* 3529%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3530% % 3531% % 3532% % 3533% D r a w P a t h L i n e T o H o r i z o n t a l A b s o l u t e % 3534% % 3535% % 3536% % 3537%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3538% 3539% DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the 3540% current point to the target point using absolute coordinates. The target 3541% point then becomes the new current point. 3542% 3543% The format of the DrawPathLineToHorizontalAbsolute method is: 3544% 3545% void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,const double x) 3546% 3547% A description of each parameter follows: 3548% 3549% o wand: the drawing wand. 3550% 3551% o x: target x ordinate 3552% 3553*/ 3554 3555static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode, 3556 const double x) 3557{ 3558 assert(wand != (DrawingWand *) NULL); 3559 assert(wand->signature == MagickWandSignature); 3560 if (wand->debug != MagickFalse) 3561 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3562 if ((wand->path_operation != PathLineToHorizontalOperation) || 3563 (wand->path_mode != mode)) 3564 { 3565 wand->path_operation=PathLineToHorizontalOperation; 3566 wand->path_mode=mode; 3567 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ? 3568 'H' : 'h',x); 3569 } 3570 else 3571 (void) MVGAutoWrapPrintf(wand," %.20g",x); 3572} 3573 3574WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand, 3575 const double x) 3576{ 3577 assert(wand != (DrawingWand *) NULL); 3578 assert(wand->signature == MagickWandSignature); 3579 if (wand->debug != MagickFalse) 3580 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3581 DrawPathLineToHorizontal(wand,AbsolutePathMode,x); 3582} 3583 3584/* 3585%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3586% % 3587% % 3588% % 3589% D r a w P a t h L i n e T o H o r i z o n t a l R e l a t i v e % 3590% % 3591% % 3592% % 3593%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3594% 3595% DrawPathLineToHorizontalRelative() draws a horizontal line path from the 3596% current point to the target point using relative coordinates. The target 3597% point then becomes the new current point. 3598% 3599% The format of the DrawPathLineToHorizontalRelative method is: 3600% 3601% void DrawPathLineToHorizontalRelative(DrawingWand *wand, 3602% const double x) 3603% 3604% A description of each parameter follows: 3605% 3606% o wand: the drawing wand. 3607% 3608% o x: target x ordinate 3609% 3610*/ 3611WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand, 3612 const double x) 3613{ 3614 DrawPathLineToHorizontal(wand,RelativePathMode,x); 3615} 3616 3617/* 3618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3619% % 3620% % 3621% % 3622% D r a w P a t h L i n e T o V e r t i c a l A b s o l u t e % 3623% % 3624% % 3625% % 3626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3627% 3628% DrawPathLineToVerticalAbsolute() draws a vertical line path from the 3629% current point to the target point using absolute coordinates. The target 3630% point then becomes the new current point. 3631% 3632% The format of the DrawPathLineToVerticalAbsolute method is: 3633% 3634% void DrawPathLineToVerticalAbsolute(DrawingWand *wand, 3635% const double y) 3636% 3637% A description of each parameter follows: 3638% 3639% o wand: the drawing wand. 3640% 3641% o y: target y ordinate 3642% 3643*/ 3644 3645static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode, 3646 const double y) 3647{ 3648 assert(wand != (DrawingWand *) NULL); 3649 assert(wand->signature == MagickWandSignature); 3650 if (wand->debug != MagickFalse) 3651 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3652 if ((wand->path_operation != PathLineToVerticalOperation) || 3653 (wand->path_mode != mode)) 3654 { 3655 wand->path_operation=PathLineToVerticalOperation; 3656 wand->path_mode=mode; 3657 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ? 3658 'V' : 'v',y); 3659 } 3660 else 3661 (void) MVGAutoWrapPrintf(wand," %.20g",y); 3662} 3663 3664WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y) 3665{ 3666 assert(wand != (DrawingWand *) NULL); 3667 assert(wand->signature == MagickWandSignature); 3668 if (wand->debug != MagickFalse) 3669 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3670 DrawPathLineToVertical(wand,AbsolutePathMode,y); 3671} 3672 3673/* 3674%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3675% % 3676% % 3677% % 3678% D r a w P a t h L i n e T o V e r t i c a l R e l a t i v e % 3679% % 3680% % 3681% % 3682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3683% 3684% DrawPathLineToVerticalRelative() draws a vertical line path from the 3685% current point to the target point using relative coordinates. The target 3686% point then becomes the new current point. 3687% 3688% The format of the DrawPathLineToVerticalRelative method is: 3689% 3690% void DrawPathLineToVerticalRelative(DrawingWand *wand, 3691% const double y) 3692% 3693% A description of each parameter follows: 3694% 3695% o wand: the drawing wand. 3696% 3697% o y: target y ordinate 3698% 3699*/ 3700WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y) 3701{ 3702 assert(wand != (DrawingWand *) NULL); 3703 assert(wand->signature == MagickWandSignature); 3704 if (wand->debug != MagickFalse) 3705 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3706 DrawPathLineToVertical(wand,RelativePathMode,y); 3707} 3708/* 3709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3710% % 3711% % 3712% % 3713% D r a w P a t h M o v e T o A b s o l u t e % 3714% % 3715% % 3716% % 3717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3718% 3719% DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate 3720% using absolute coordinates. The current point then becomes the 3721% specified coordinate. 3722% 3723% The format of the DrawPathMoveToAbsolute method is: 3724% 3725% void DrawPathMoveToAbsolute(DrawingWand *wand,const double x, 3726% const double y) 3727% 3728% A description of each parameter follows: 3729% 3730% o wand: the drawing wand. 3731% 3732% o x: target x ordinate 3733% 3734% o y: target y ordinate 3735% 3736*/ 3737 3738static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x, 3739 const double y) 3740{ 3741 assert(wand != (DrawingWand *) NULL); 3742 assert(wand->signature == MagickWandSignature); 3743 if (wand->debug != MagickFalse) 3744 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3745 if ((wand->path_operation != PathMoveToOperation) || 3746 (wand->path_mode != mode)) 3747 { 3748 wand->path_operation=PathMoveToOperation; 3749 wand->path_mode=mode; 3750 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ? 3751 'M' : 'm',x,y); 3752 } 3753 else 3754 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y); 3755} 3756 3757WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x, 3758 const double y) 3759{ 3760 assert(wand != (DrawingWand *) NULL); 3761 assert(wand->signature == MagickWandSignature); 3762 if (wand->debug != MagickFalse) 3763 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3764 DrawPathMoveTo(wand,AbsolutePathMode,x,y); 3765} 3766 3767/* 3768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3769% % 3770% % 3771% % 3772% D r a w P a t h M o v e T o R e l a t i v e % 3773% % 3774% % 3775% % 3776%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3777% 3778% DrawPathMoveToRelative() starts a new sub-path at the given coordinate using 3779% relative coordinates. The current point then becomes the specified 3780% coordinate. 3781% 3782% The format of the DrawPathMoveToRelative method is: 3783% 3784% void DrawPathMoveToRelative(DrawingWand *wand,const double x, 3785% const double y) 3786% 3787% A description of each parameter follows: 3788% 3789% o wand: the drawing wand. 3790% 3791% o x: target x ordinate 3792% 3793% o y: target y ordinate 3794% 3795*/ 3796WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x, 3797 const double y) 3798{ 3799 assert(wand != (DrawingWand *) NULL); 3800 assert(wand->signature == MagickWandSignature); 3801 if (wand->debug != MagickFalse) 3802 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3803 DrawPathMoveTo(wand,RelativePathMode,x,y); 3804} 3805 3806/* 3807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3808% % 3809% % 3810% % 3811% D r a w P a t h S t a r t % 3812% % 3813% % 3814% % 3815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3816% 3817% DrawPathStart() declares the start of a path drawing list which is terminated 3818% by a matching DrawPathFinish() command. All other DrawPath commands must 3819% be enclosed between a DrawPathStart() and a DrawPathFinish() command. This 3820% is because path drawing commands are subordinate commands and they do not 3821% function by themselves. 3822% 3823% The format of the DrawPathStart method is: 3824% 3825% void DrawPathStart(DrawingWand *wand) 3826% 3827% A description of each parameter follows: 3828% 3829% o wand: the drawing wand. 3830% 3831*/ 3832WandExport void DrawPathStart(DrawingWand *wand) 3833{ 3834 assert(wand != (DrawingWand *) NULL); 3835 assert(wand->signature == MagickWandSignature); 3836 if (wand->debug != MagickFalse) 3837 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3838 (void) MVGPrintf(wand,"path '"); 3839 wand->path_operation=PathDefaultOperation; 3840 wand->path_mode=DefaultPathMode; 3841} 3842 3843/* 3844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3845% % 3846% % 3847% % 3848% D r a w P o i n t % 3849% % 3850% % 3851% % 3852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3853% 3854% DrawPoint() draws a point using the current fill color. 3855% 3856% The format of the DrawPoint method is: 3857% 3858% void DrawPoint(DrawingWand *wand,const double x,const double y) 3859% 3860% A description of each parameter follows: 3861% 3862% o wand: the drawing wand. 3863% 3864% o x: target x coordinate 3865% 3866% o y: target y coordinate 3867% 3868*/ 3869WandExport void DrawPoint(DrawingWand *wand,const double x,const double y) 3870{ 3871 assert(wand != (DrawingWand *) NULL); 3872 assert(wand->signature == MagickWandSignature); 3873 if (wand->debug != MagickFalse) 3874 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3875 (void) MVGPrintf(wand,"point %.20g %.20g\n",x,y); 3876} 3877 3878/* 3879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3880% % 3881% % 3882% % 3883% D r a w P o l y g o n % 3884% % 3885% % 3886% % 3887%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3888% 3889% DrawPolygon() draws a polygon using the current stroke, stroke width, and 3890% fill color or texture, using the specified array of coordinates. 3891% 3892% The format of the DrawPolygon method is: 3893% 3894% void DrawPolygon(DrawingWand *wand, 3895% const size_t number_coordinates,const PointInfo *coordinates) 3896% 3897% A description of each parameter follows: 3898% 3899% o wand: the drawing wand. 3900% 3901% o number_coordinates: number of coordinates 3902% 3903% o coordinates: coordinate array 3904% 3905*/ 3906WandExport void DrawPolygon(DrawingWand *wand, 3907 const size_t number_coordinates,const PointInfo *coordinates) 3908{ 3909 assert(wand != (DrawingWand *) NULL); 3910 assert(wand->signature == MagickWandSignature); 3911 if (wand->debug != MagickFalse) 3912 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3913 MVGAppendPointsCommand(wand,"polygon",number_coordinates,coordinates); 3914} 3915 3916/* 3917%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3918% % 3919% % 3920% % 3921% D r a w P o l y l i n e % 3922% % 3923% % 3924% % 3925%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3926% 3927% DrawPolyline() draws a polyline using the current stroke, stroke width, and 3928% fill color or texture, using the specified array of coordinates. 3929% 3930% The format of the DrawPolyline method is: 3931% 3932% void DrawPolyline(DrawingWand *wand, 3933% const size_t number_coordinates,const PointInfo *coordinates) 3934% 3935% A description of each parameter follows: 3936% 3937% o wand: the drawing wand. 3938% 3939% o number_coordinates: number of coordinates 3940% 3941% o coordinates: coordinate array 3942% 3943*/ 3944WandExport void DrawPolyline(DrawingWand *wand, 3945 const size_t number_coordinates,const PointInfo *coordinates) 3946{ 3947 assert(wand != (DrawingWand *) NULL); 3948 assert(wand->signature == MagickWandSignature); 3949 if (wand->debug != MagickFalse) 3950 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3951 MVGAppendPointsCommand(wand,"polyline",number_coordinates,coordinates); 3952} 3953 3954/* 3955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3956% % 3957% % 3958% % 3959% D r a w P o p C l i p P a t h % 3960% % 3961% % 3962% % 3963%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3964% 3965% DrawPopClipPath() terminates a clip path definition. 3966% 3967% The format of the DrawPopClipPath method is: 3968% 3969% void DrawPopClipPath(DrawingWand *wand) 3970% 3971% A description of each parameter follows: 3972% 3973% o wand: the drawing wand. 3974% 3975*/ 3976WandExport void DrawPopClipPath(DrawingWand *wand) 3977{ 3978 assert(wand != (DrawingWand *) NULL); 3979 assert(wand->signature == MagickWandSignature); 3980 if (wand->debug != MagickFalse) 3981 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3982 if (wand->indent_depth > 0) 3983 wand->indent_depth--; 3984 (void) MVGPrintf(wand,"pop clip-path\n"); 3985} 3986 3987/* 3988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3989% % 3990% % 3991% % 3992% D r a w P o p D e f s % 3993% % 3994% % 3995% % 3996%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3997% 3998% DrawPopDefs() terminates a definition list. 3999% 4000% The format of the DrawPopDefs method is: 4001% 4002% void DrawPopDefs(DrawingWand *wand) 4003% 4004% A description of each parameter follows: 4005% 4006% o wand: the drawing wand. 4007% 4008*/ 4009WandExport void DrawPopDefs(DrawingWand *wand) 4010{ 4011 assert(wand != (DrawingWand *) NULL); 4012 assert(wand->signature == MagickWandSignature); 4013 if (wand->debug != MagickFalse) 4014 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4015 if (wand->indent_depth > 0) 4016 wand->indent_depth--; 4017 (void) MVGPrintf(wand,"pop defs\n"); 4018} 4019 4020/* 4021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4022% % 4023% % 4024% % 4025% D r a w P o p P a t t e r n % 4026% % 4027% % 4028% % 4029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4030% 4031% DrawPopPattern() terminates a pattern definition. 4032% 4033% The format of the DrawPopPattern method is: 4034% 4035% MagickBooleanType DrawPopPattern(DrawingWand *wand) 4036% 4037% A description of each parameter follows: 4038% 4039% o wand: the drawing wand. 4040% 4041*/ 4042WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand) 4043{ 4044 char 4045 geometry[MagickPathExtent], 4046 key[MagickPathExtent]; 4047 4048 assert(wand != (DrawingWand *) NULL); 4049 assert(wand->signature == MagickWandSignature); 4050 if (wand->debug != MagickFalse) 4051 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4052 if (wand->image == (Image *) NULL) 4053 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 4054 if (wand->pattern_id == (const char *) NULL) 4055 { 4056 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition", 4057 wand->name); 4058 return(MagickFalse); 4059 } 4060 (void) FormatLocaleString(key,MagickPathExtent,"%s",wand->pattern_id); 4061 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset); 4062 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g%+.20g%+.20g", 4063 (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height, 4064 (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y); 4065 (void) SetImageArtifact(wand->image,key,geometry); 4066 wand->pattern_id=DestroyString(wand->pattern_id); 4067 wand->pattern_offset=0; 4068 wand->pattern_bounds.x=0; 4069 wand->pattern_bounds.y=0; 4070 wand->pattern_bounds.width=0; 4071 wand->pattern_bounds.height=0; 4072 wand->filter_off=MagickTrue; 4073 if (wand->indent_depth > 0) 4074 wand->indent_depth--; 4075 (void) MVGPrintf(wand,"pop pattern\n"); 4076 return(MagickTrue); 4077} 4078 4079/* 4080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4081% % 4082% % 4083% % 4084% D r a w P u s h C l i p P a t h % 4085% % 4086% % 4087% % 4088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4089% 4090% DrawPushClipPath() starts a clip path definition which is comprized of any 4091% number of drawing commands and terminated by a DrawPopClipPath() command. 4092% 4093% The format of the DrawPushClipPath method is: 4094% 4095% void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id) 4096% 4097% A description of each parameter follows: 4098% 4099% o wand: the drawing wand. 4100% 4101% o clip_mask_id: string identifier to associate with the clip path for 4102% later use. 4103% 4104*/ 4105WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id) 4106{ 4107 assert(wand != (DrawingWand *) NULL); 4108 assert(wand->signature == MagickWandSignature); 4109 if (wand->debug != MagickFalse) 4110 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4111 assert(clip_mask_id != (const char *) NULL); 4112 (void) MVGPrintf(wand,"push clip-path %s\n",clip_mask_id); 4113 wand->indent_depth++; 4114} 4115 4116/* 4117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4118% % 4119% % 4120% % 4121% D r a w P u s h D e f s % 4122% % 4123% % 4124% % 4125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4126% 4127% DrawPushDefs() indicates that commands up to a terminating DrawPopDefs() 4128% command create named elements (e.g. clip-paths, textures, etc.) which 4129% may safely be processed earlier for the sake of efficiency. 4130% 4131% The format of the DrawPushDefs method is: 4132% 4133% void DrawPushDefs(DrawingWand *wand) 4134% 4135% A description of each parameter follows: 4136% 4137% o wand: the drawing wand. 4138% 4139*/ 4140WandExport void DrawPushDefs(DrawingWand *wand) 4141{ 4142 assert(wand != (DrawingWand *) NULL); 4143 assert(wand->signature == MagickWandSignature); 4144 if (wand->debug != MagickFalse) 4145 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4146 (void) MVGPrintf(wand,"push defs\n"); 4147 wand->indent_depth++; 4148} 4149 4150/* 4151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4152% % 4153% % 4154% % 4155% D r a w P u s h P a t t e r n % 4156% % 4157% % 4158% % 4159%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4160% 4161% DrawPushPattern() indicates that subsequent commands up to a 4162% DrawPopPattern() command comprise the definition of a named pattern. 4163% The pattern space is assigned top left corner coordinates, a width 4164% and height, and becomes its own drawing space. Anything which can 4165% be drawn may be used in a pattern definition. 4166% Named patterns may be used as stroke or brush definitions. 4167% 4168% The format of the DrawPushPattern method is: 4169% 4170% MagickBooleanType DrawPushPattern(DrawingWand *wand, 4171% const char *pattern_id,const double x,const double y, 4172% const double width,const double height) 4173% 4174% A description of each parameter follows: 4175% 4176% o wand: the drawing wand. 4177% 4178% o pattern_id: pattern identification for later reference 4179% 4180% o x: x ordinate of top left corner 4181% 4182% o y: y ordinate of top left corner 4183% 4184% o width: width of pattern space 4185% 4186% o height: height of pattern space 4187% 4188*/ 4189WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand, 4190 const char *pattern_id,const double x,const double y,const double width, 4191 const double height) 4192{ 4193 assert(wand != (DrawingWand *) NULL); 4194 assert(wand->signature == MagickWandSignature); 4195 if (wand->debug != MagickFalse) 4196 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4197 assert(pattern_id != (const char *) NULL); 4198 if (wand->pattern_id != NULL) 4199 { 4200 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition", 4201 wand->pattern_id); 4202 return(MagickFalse); 4203 } 4204 wand->filter_off=MagickTrue; 4205 (void) MVGPrintf(wand,"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id, 4206 x,y,width,height); 4207 wand->indent_depth++; 4208 wand->pattern_id=AcquireString(pattern_id); 4209 wand->pattern_bounds.x=(ssize_t) ceil(x-0.5); 4210 wand->pattern_bounds.y=(ssize_t) ceil(y-0.5); 4211 wand->pattern_bounds.width=(size_t) floor(width+0.5); 4212 wand->pattern_bounds.height=(size_t) floor(height+0.5); 4213 wand->pattern_offset=wand->mvg_length; 4214 return(MagickTrue); 4215} 4216 4217/* 4218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4219% % 4220% % 4221% % 4222% D r a w R e c t a n g l e % 4223% % 4224% % 4225% % 4226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4227% 4228% DrawRectangle() draws a rectangle given two coordinates and using the 4229% current stroke, stroke width, and fill settings. 4230% 4231% The format of the DrawRectangle method is: 4232% 4233% void DrawRectangle(DrawingWand *wand,const double x1, 4234% const double y1,const double x2,const double y2) 4235% 4236% A description of each parameter follows: 4237% 4238% o x1: x ordinate of first coordinate 4239% 4240% o y1: y ordinate of first coordinate 4241% 4242% o x2: x ordinate of second coordinate 4243% 4244% o y2: y ordinate of second coordinate 4245% 4246*/ 4247WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1, 4248 const double x2,const double y2) 4249{ 4250 assert(wand != (DrawingWand *) NULL); 4251 assert(wand->signature == MagickWandSignature); 4252 if (wand->debug != MagickFalse) 4253 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4254 (void) MVGPrintf(wand,"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2); 4255} 4256 4257/* 4258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4259% % 4260% % 4261% % 4262+ D r a w R e n d e r % 4263% % 4264% % 4265% % 4266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4267% 4268% DrawRender() renders all preceding drawing commands onto the image. 4269% 4270% The format of the DrawRender method is: 4271% 4272% MagickBooleanType DrawRender(DrawingWand *wand) 4273% 4274% A description of each parameter follows: 4275% 4276% o wand: the drawing wand. 4277% 4278*/ 4279WandExport MagickBooleanType DrawRender(DrawingWand *wand) 4280{ 4281 MagickBooleanType 4282 status; 4283 4284 assert(wand != (const DrawingWand *) NULL); 4285 assert(wand->signature == MagickWandSignature); 4286 if (wand->debug != MagickFalse) 4287 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4288 CurrentContext->primitive=wand->mvg; 4289 if (wand->debug != MagickFalse) 4290 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg); 4291 if (wand->image == (Image *) NULL) 4292 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 4293 status=DrawImage(wand->image,CurrentContext,wand->exception); 4294 CurrentContext->primitive=(char *) NULL; 4295 return(status); 4296} 4297 4298/* 4299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4300% % 4301% % 4302% % 4303% D r a w R e s e t V e c t o r G r a p h i c s % 4304% % 4305% % 4306% % 4307%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4308% 4309% DrawResetVectorGraphics() resets the vector graphics associated with the 4310% specified wand. 4311% 4312% The format of the DrawResetVectorGraphics method is: 4313% 4314% void DrawResetVectorGraphics(DrawingWand *wand) 4315% 4316% A description of each parameter follows: 4317% 4318% o wand: the drawing wand. 4319% 4320*/ 4321WandExport void DrawResetVectorGraphics(DrawingWand *wand) 4322{ 4323 assert(wand != (DrawingWand *) NULL); 4324 assert(wand->signature == MagickWandSignature); 4325 if (wand->debug != MagickFalse) 4326 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4327 if (wand->mvg != (char *) NULL) 4328 wand->mvg=DestroyString(wand->mvg); 4329 wand->mvg_alloc=0; 4330 wand->mvg_length=0; 4331 wand->mvg_width=0; 4332} 4333 4334/* 4335%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4336% % 4337% % 4338% % 4339% D r a w R o t a t e % 4340% % 4341% % 4342% % 4343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4344% 4345% DrawRotate() applies the specified rotation to the current coordinate space. 4346% 4347% The format of the DrawRotate method is: 4348% 4349% void DrawRotate(DrawingWand *wand,const double degrees) 4350% 4351% A description of each parameter follows: 4352% 4353% o wand: the drawing wand. 4354% 4355% o degrees: degrees of rotation 4356% 4357*/ 4358WandExport void DrawRotate(DrawingWand *wand,const double degrees) 4359{ 4360 assert(wand != (DrawingWand *) NULL); 4361 assert(wand->signature == MagickWandSignature); 4362 if (wand->debug != MagickFalse) 4363 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4364 (void) MVGPrintf(wand,"rotate %.20g\n",degrees); 4365} 4366 4367/* 4368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4369% % 4370% % 4371% % 4372% D r a w R o u n d R e c t a n g l e % 4373% % 4374% % 4375% % 4376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4377% 4378% DrawRoundRectangle() draws a rounted rectangle given two coordinates, 4379% x & y corner radiuses and using the current stroke, stroke width, 4380% and fill settings. 4381% 4382% The format of the DrawRoundRectangle method is: 4383% 4384% void DrawRoundRectangle(DrawingWand *wand,double x1,double y1, 4385% double x2,double y2,double rx,double ry) 4386% 4387% A description of each parameter follows: 4388% 4389% o wand: the drawing wand. 4390% 4391% o x1: x ordinate of first coordinate 4392% 4393% o y1: y ordinate of first coordinate 4394% 4395% o x2: x ordinate of second coordinate 4396% 4397% o y2: y ordinate of second coordinate 4398% 4399% o rx: radius of corner in horizontal direction 4400% 4401% o ry: radius of corner in vertical direction 4402% 4403*/ 4404WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1, 4405 double x2,double y2,double rx,double ry) 4406{ 4407 assert(wand != (DrawingWand *) NULL); 4408 assert(wand->signature == MagickWandSignature); 4409 if (wand->debug != MagickFalse) 4410 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4411 (void) MVGPrintf(wand,"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n", 4412 x1,y1,x2,y2,rx,ry); 4413} 4414 4415/* 4416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4417% % 4418% % 4419% % 4420% D r a w S c a l e % 4421% % 4422% % 4423% % 4424%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4425% 4426% DrawScale() adjusts the scaling factor to apply in the horizontal and 4427% vertical directions to the current coordinate space. 4428% 4429% The format of the DrawScale method is: 4430% 4431% void DrawScale(DrawingWand *wand,const double x,const double y) 4432% 4433% A description of each parameter follows: 4434% 4435% o wand: the drawing wand. 4436% 4437% o x: horizontal scale factor 4438% 4439% o y: vertical scale factor 4440% 4441*/ 4442WandExport void DrawScale(DrawingWand *wand,const double x,const double y) 4443{ 4444 assert(wand != (DrawingWand *) NULL); 4445 assert(wand->signature == MagickWandSignature); 4446 if (wand->debug != MagickFalse) 4447 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4448 (void) MVGPrintf(wand,"scale %.20g %.20g\n",x,y); 4449} 4450 4451/* 4452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4453% % 4454% % 4455% % 4456% D r a w S e t B o r d e r C o l o r % 4457% % 4458% % 4459% % 4460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4461% 4462% DrawSetBorderColor() sets the border color to be used for drawing bordered 4463% objects. 4464% 4465% The format of the DrawSetBorderColor method is: 4466% 4467% void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand) 4468% 4469% A description of each parameter follows: 4470% 4471% o wand: the drawing wand. 4472% 4473% o border_wand: border wand. 4474% 4475*/ 4476WandExport void DrawSetBorderColor(DrawingWand *wand, 4477 const PixelWand *border_wand) 4478{ 4479 PixelInfo 4480 *current_border, 4481 border_color, 4482 new_border; 4483 4484 assert(wand != (DrawingWand *) NULL); 4485 assert(wand->signature == MagickWandSignature); 4486 if (wand->debug != MagickFalse) 4487 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4488 assert(border_wand != (const PixelWand *) NULL); 4489 PixelGetQuantumPacket(border_wand,&border_color); 4490 new_border=border_color; 4491 current_border=(&CurrentContext->border_color); 4492 if ((wand->filter_off != MagickFalse) || 4493 (IsPixelInfoEquivalent(current_border,&new_border) == MagickFalse)) 4494 { 4495 CurrentContext->border_color=new_border; 4496 (void) MVGPrintf(wand,"border-color '"); 4497 MVGAppendColor(wand,&border_color); 4498 (void) MVGPrintf(wand,"'\n"); 4499 } 4500} 4501 4502/* 4503%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4504% % 4505% % 4506% % 4507% D r a w S e t C l i p P a t h % 4508% % 4509% % 4510% % 4511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4512% 4513% DrawSetClipPath() associates a named clipping path with the image. Only 4514% the areas drawn on by the clipping path will be modified as ssize_t as it 4515% remains in effect. 4516% 4517% The format of the DrawSetClipPath method is: 4518% 4519% MagickBooleanType DrawSetClipPath(DrawingWand *wand, 4520% const char *clip_mask) 4521% 4522% A description of each parameter follows: 4523% 4524% o wand: the drawing wand. 4525% 4526% o clip_mask: name of clipping path to associate with image 4527% 4528*/ 4529WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand, 4530 const char *clip_mask) 4531{ 4532 if (wand->debug != MagickFalse) 4533 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask); 4534 assert(wand != (DrawingWand *) NULL); 4535 assert(wand->signature == MagickWandSignature); 4536 assert(clip_mask != (const char *) NULL); 4537 if ((CurrentContext->clip_mask == (const char *) NULL) || 4538 (wand->filter_off != MagickFalse) || 4539 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0)) 4540 { 4541 (void) CloneString(&CurrentContext->clip_mask,clip_mask); 4542#if DRAW_BINARY_IMPLEMENTATION 4543 if (wand->image == (Image *) NULL) 4544 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 4545 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask); 4546#endif 4547 (void) MVGPrintf(wand,"clip-path url(#%s)\n",clip_mask); 4548 } 4549 return(MagickTrue); 4550} 4551 4552/* 4553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4554% % 4555% % 4556% % 4557% D r a w S e t C l i p R u l e % 4558% % 4559% % 4560% % 4561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4562% 4563% DrawSetClipRule() set the polygon fill rule to be used by the clipping path. 4564% 4565% The format of the DrawSetClipRule method is: 4566% 4567% void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule) 4568% 4569% A description of each parameter follows: 4570% 4571% o wand: the drawing wand. 4572% 4573% o fill_rule: fill rule (EvenOddRule or NonZeroRule) 4574% 4575*/ 4576WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule) 4577{ 4578 assert(wand != (DrawingWand *) NULL); 4579 assert(wand->signature == MagickWandSignature); 4580 if (wand->debug != MagickFalse) 4581 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4582 if ((wand->filter_off != MagickFalse) || 4583 (CurrentContext->fill_rule != fill_rule)) 4584 { 4585 CurrentContext->fill_rule=fill_rule; 4586 (void) MVGPrintf(wand, "clip-rule '%s'\n",CommandOptionToMnemonic( 4587 MagickFillRuleOptions,(ssize_t) fill_rule)); 4588 } 4589} 4590 4591/* 4592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4593% % 4594% % 4595% % 4596% D r a w S e t C l i p U n i t s % 4597% % 4598% % 4599% % 4600%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4601% 4602% DrawSetClipUnits() sets the interpretation of clip path units. 4603% 4604% The format of the DrawSetClipUnits method is: 4605% 4606% void DrawSetClipUnits(DrawingWand *wand, 4607% const ClipPathUnits clip_units) 4608% 4609% A description of each parameter follows: 4610% 4611% o wand: the drawing wand. 4612% 4613% o clip_units: units to use (UserSpace, UserSpaceOnUse, or 4614% ObjectBoundingBox) 4615% 4616*/ 4617WandExport void DrawSetClipUnits(DrawingWand *wand, 4618 const ClipPathUnits clip_units) 4619{ 4620 assert(wand != (DrawingWand *) NULL); 4621 assert(wand->signature == MagickWandSignature); 4622 if (wand->debug != MagickFalse) 4623 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4624 if ((wand->filter_off != MagickFalse) || 4625 (CurrentContext->clip_units != clip_units)) 4626 { 4627 CurrentContext->clip_units=clip_units; 4628 if (clip_units == ObjectBoundingBox) 4629 { 4630 AffineMatrix 4631 affine; 4632 4633 GetAffineMatrix(&affine); 4634 affine.sx=CurrentContext->bounds.x2; 4635 affine.sy=CurrentContext->bounds.y2; 4636 affine.tx=CurrentContext->bounds.x1; 4637 affine.ty=CurrentContext->bounds.y1; 4638 AdjustAffine(wand,&affine); 4639 } 4640 (void) MVGPrintf(wand, "clip-units '%s'\n",CommandOptionToMnemonic( 4641 MagickClipPathOptions,(ssize_t) clip_units)); 4642 } 4643} 4644 4645/* 4646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4647% % 4648% % 4649% % 4650% D r a w S e t D e n s i t y % 4651% % 4652% % 4653% % 4654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4655% 4656% DrawSetDensity() sets the vertical and horizontal resolution. 4657% 4658% The format of the DrawSetDensity method is: 4659% 4660% MagickBooleanType DrawSetDensity(DrawingWand *wand, 4661% const char *density) 4662% 4663% A description of each parameter follows: 4664% 4665% o wand: the drawing wand. 4666% 4667% o density: the vertical and horizontal resolution. 4668% 4669*/ 4670WandExport MagickBooleanType DrawSetDensity(DrawingWand *wand, 4671 const char *density) 4672{ 4673 if (wand->debug != MagickFalse) 4674 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",density); 4675 assert(wand != (DrawingWand *) NULL); 4676 assert(wand->signature == MagickWandSignature); 4677 assert(density != (const char *) NULL); 4678 if ((CurrentContext->density == (const char *) NULL) || 4679 (wand->filter_off != MagickFalse) || 4680 (LocaleCompare(CurrentContext->density,density) != 0)) 4681 { 4682 (void) CloneString(&CurrentContext->density,density); 4683 (void) MVGPrintf(wand,"density '%s'\n",density); 4684 } 4685 return(MagickTrue); 4686} 4687 4688/* 4689%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4690% % 4691% % 4692% % 4693% D r a w S e t F i l l C o l o r % 4694% % 4695% % 4696% % 4697%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4698% 4699% DrawSetFillColor() sets the fill color to be used for drawing filled objects. 4700% 4701% The format of the DrawSetFillColor method is: 4702% 4703% void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand) 4704% 4705% A description of each parameter follows: 4706% 4707% o wand: the drawing wand. 4708% 4709% o fill_wand: fill wand. 4710% 4711*/ 4712WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand) 4713{ 4714 PixelInfo 4715 *current_fill, 4716 fill_color, 4717 new_fill; 4718 4719 assert(wand != (DrawingWand *) NULL); 4720 assert(wand->signature == MagickWandSignature); 4721 if (wand->debug != MagickFalse) 4722 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4723 assert(fill_wand != (const PixelWand *) NULL); 4724 PixelGetQuantumPacket(fill_wand,&fill_color); 4725 new_fill=fill_color; 4726 current_fill=(&CurrentContext->fill); 4727 if ((wand->filter_off != MagickFalse) || 4728 (IsPixelInfoEquivalent(current_fill,&new_fill) == MagickFalse)) 4729 { 4730 CurrentContext->fill=new_fill; 4731 (void) MVGPrintf(wand,"fill '"); 4732 MVGAppendColor(wand,&fill_color); 4733 (void) MVGPrintf(wand,"'\n"); 4734 } 4735} 4736 4737/* 4738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4739% % 4740% % 4741% % 4742% D r a w S e t F i l l O p a c i t y % 4743% % 4744% % 4745% % 4746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4747% 4748% DrawSetFillOpacity() sets the alpha to use when drawing using the fill 4749% color or fill texture. Fully opaque is 1.0. 4750% 4751% The format of the DrawSetFillOpacity method is: 4752% 4753% void DrawSetFillOpacity(DrawingWand *wand,const double fill_alpha) 4754% 4755% A description of each parameter follows: 4756% 4757% o wand: the drawing wand. 4758% 4759% o fill_opacity: fill opacity 4760% 4761*/ 4762WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity) 4763{ 4764 double 4765 alpha; 4766 4767 assert(wand != (DrawingWand *) NULL); 4768 assert(wand->signature == MagickWandSignature); 4769 if (wand->debug != MagickFalse) 4770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4771 alpha=(double) ClampToQuantum(QuantumRange*fill_opacity); 4772 if ((wand->filter_off != MagickFalse) || 4773 (CurrentContext->fill.alpha != alpha)) 4774 { 4775 CurrentContext->fill.alpha=alpha; 4776 (void) MVGPrintf(wand,"fill-opacity %.20g\n",fill_opacity); 4777 } 4778} 4779 4780/* 4781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4782% % 4783% % 4784% % 4785% D r a w S e t F o n t R e s o l u t i o n % 4786% % 4787% % 4788% % 4789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4790% 4791% DrawSetFontResolution() sets the image resolution. 4792% 4793% The format of the DrawSetFontResolution method is: 4794% 4795% MagickBooleanType DrawSetFontResolution(DrawingWand *wand, 4796% const double x_resolution,const double y_resolution) 4797% 4798% A description of each parameter follows: 4799% 4800% o wand: the magick wand. 4801% 4802% o x_resolution: the image x resolution. 4803% 4804% o y_resolution: the image y resolution. 4805% 4806*/ 4807WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand, 4808 const double x_resolution,const double y_resolution) 4809{ 4810 char 4811 density[MagickPathExtent]; 4812 4813 assert(wand != (DrawingWand *) NULL); 4814 assert(wand->signature == MagickWandSignature); 4815 if (wand->debug != MagickFalse) 4816 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4817 (void) FormatLocaleString(density,MagickPathExtent,"%.20gx%.20g",x_resolution, 4818 y_resolution); 4819 (void) CloneString(&CurrentContext->density,density); 4820 return(MagickTrue); 4821} 4822 4823/* 4824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4825% % 4826% % 4827% % 4828% D r a w S e t O p a c i t y % 4829% % 4830% % 4831% % 4832%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4833% 4834% DrawSetOpacity() sets the alpha to use when drawing using the fill or 4835% stroke color or texture. Fully opaque is 1.0. 4836% 4837% The format of the DrawSetOpacity method is: 4838% 4839% void DrawSetOpacity(DrawingWand *wand,const double alpha) 4840% 4841% A description of each parameter follows: 4842% 4843% o wand: the drawing wand. 4844% 4845% o opacity: fill and stroke opacity. The value 1.0 is opaque. 4846% 4847*/ 4848WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity) 4849{ 4850 Quantum 4851 quantum_alpha; 4852 4853 assert(wand != (DrawingWand *) NULL); 4854 assert(wand->signature == MagickWandSignature); 4855 if (wand->debug != MagickFalse) 4856 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4857 quantum_alpha=ClampToQuantum(QuantumRange*opacity); 4858 if ((wand->filter_off != MagickFalse) || 4859 (CurrentContext->alpha != quantum_alpha)) 4860 { 4861 CurrentContext->alpha=quantum_alpha; 4862 (void) MVGPrintf(wand,"opacity %.20g\n",opacity); 4863 } 4864} 4865 4866/* 4867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4868% % 4869% % 4870% % 4871% D r a w S e t F i l l P a t t e r n U R L % 4872% % 4873% % 4874% % 4875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4876% 4877% DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling 4878% objects. Only local URLs ("#identifier") are supported at this time. These 4879% local URLs are normally created by defining a named fill pattern with 4880% DrawPushPattern/DrawPopPattern. 4881% 4882% The format of the DrawSetFillPatternURL method is: 4883% 4884% MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand, 4885% const char *fill_url) 4886% 4887% A description of each parameter follows: 4888% 4889% o wand: the drawing wand. 4890% 4891% o fill_url: URL to use to obtain fill pattern. 4892% 4893*/ 4894WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand, 4895 const char *fill_url) 4896{ 4897 char 4898 pattern[MagickPathExtent], 4899 pattern_spec[MagickPathExtent]; 4900 4901 assert(wand != (DrawingWand *) NULL); 4902 assert(wand->signature == MagickWandSignature); 4903 if (wand->debug != MagickFalse) 4904 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url); 4905 if (wand->image == (Image *) NULL) 4906 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 4907 assert(fill_url != (const char *) NULL); 4908 if (*fill_url != '#') 4909 { 4910 ThrowDrawException(DrawError,"NotARelativeURL",fill_url); 4911 return(MagickFalse); 4912 } 4913 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",fill_url+1); 4914 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL) 4915 { 4916 ThrowDrawException(DrawError,"URLNotFound",fill_url) 4917 return(MagickFalse); 4918 } 4919 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",fill_url); 4920#if DRAW_BINARY_IMPLEMENTATION 4921 DrawPatternPath(wand->image,CurrentContext,pattern_spec, 4922 &CurrentContext->fill_pattern); 4923#endif 4924 if (CurrentContext->fill.alpha != (Quantum) TransparentAlpha) 4925 CurrentContext->fill.alpha=(double) CurrentContext->alpha; 4926 (void) MVGPrintf(wand,"fill %s\n",pattern_spec); 4927 return(MagickTrue); 4928} 4929 4930/* 4931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4932% % 4933% % 4934% % 4935% D r a w S e t F i l l R u l e % 4936% % 4937% % 4938% % 4939%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4940% 4941% DrawSetFillRule() sets the fill rule to use while drawing polygons. 4942% 4943% The format of the DrawSetFillRule method is: 4944% 4945% void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule) 4946% 4947% A description of each parameter follows: 4948% 4949% o wand: the drawing wand. 4950% 4951% o fill_rule: fill rule (EvenOddRule or NonZeroRule) 4952% 4953*/ 4954WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule) 4955{ 4956 assert(wand != (DrawingWand *) NULL); 4957 assert(wand->signature == MagickWandSignature); 4958 if (wand->debug != MagickFalse) 4959 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4960 if ((wand->filter_off != MagickFalse) || 4961 (CurrentContext->fill_rule != fill_rule)) 4962 { 4963 CurrentContext->fill_rule=fill_rule; 4964 (void) MVGPrintf(wand, "fill-rule '%s'\n",CommandOptionToMnemonic( 4965 MagickFillRuleOptions,(ssize_t) fill_rule)); 4966 } 4967} 4968 4969/* 4970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4971% % 4972% % 4973% % 4974% D r a w S e t F o n t % 4975% % 4976% % 4977% % 4978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4979% 4980% DrawSetFont() sets the fully-sepecified font to use when annotating with 4981% text. 4982% 4983% The format of the DrawSetFont method is: 4984% 4985% MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name) 4986% 4987% A description of each parameter follows: 4988% 4989% o wand: the drawing wand. 4990% 4991% o font_name: font name 4992% 4993*/ 4994WandExport MagickBooleanType DrawSetFont(DrawingWand *wand, 4995 const char *font_name) 4996{ 4997 assert(wand != (DrawingWand *) NULL); 4998 assert(wand->signature == MagickWandSignature); 4999 if (wand->debug != MagickFalse) 5000 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5001 assert(font_name != (const char *) NULL); 5002 if ((wand->filter_off != MagickFalse) || 5003 (CurrentContext->font == (char *) NULL) || 5004 (LocaleCompare(CurrentContext->font,font_name) != 0)) 5005 { 5006 (void) CloneString(&CurrentContext->font,font_name); 5007 (void) MVGPrintf(wand,"font '%s'\n",font_name); 5008 } 5009 return(MagickTrue); 5010} 5011 5012/* 5013%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5014% % 5015% % 5016% % 5017% D r a w S e t F o n t F a m i l y % 5018% % 5019% % 5020% % 5021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5022% 5023% DrawSetFontFamily() sets the font family to use when annotating with text. 5024% 5025% The format of the DrawSetFontFamily method is: 5026% 5027% MagickBooleanType DrawSetFontFamily(DrawingWand *wand, 5028% const char *font_family) 5029% 5030% A description of each parameter follows: 5031% 5032% o wand: the drawing wand. 5033% 5034% o font_family: font family 5035% 5036*/ 5037WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand, 5038 const char *font_family) 5039{ 5040 assert(wand != (DrawingWand *) NULL); 5041 assert(wand->signature == MagickWandSignature); 5042 if (wand->debug != MagickFalse) 5043 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5044 assert(font_family != (const char *) NULL); 5045 if ((wand->filter_off != MagickFalse) || 5046 (CurrentContext->family == (const char *) NULL) || 5047 (LocaleCompare(CurrentContext->family,font_family) != 0)) 5048 { 5049 (void) CloneString(&CurrentContext->family,font_family); 5050 (void) MVGPrintf(wand,"font-family '%s'\n",font_family); 5051 } 5052 return(MagickTrue); 5053} 5054 5055/* 5056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5057% % 5058% % 5059% % 5060% D r a w S e t F o n t S i z e % 5061% % 5062% % 5063% % 5064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5065% 5066% DrawSetFontSize() sets the font pointsize to use when annotating with text. 5067% 5068% The format of the DrawSetFontSize method is: 5069% 5070% void DrawSetFontSize(DrawingWand *wand,const double pointsize) 5071% 5072% A description of each parameter follows: 5073% 5074% o wand: the drawing wand. 5075% 5076% o pointsize: text pointsize 5077% 5078*/ 5079WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize) 5080{ 5081 assert(wand != (DrawingWand *) NULL); 5082 assert(wand->signature == MagickWandSignature); 5083 if (wand->debug != MagickFalse) 5084 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5085 if ((wand->filter_off != MagickFalse) || 5086 (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon)) 5087 { 5088 CurrentContext->pointsize=pointsize; 5089 (void) MVGPrintf(wand,"font-size %.20g\n",pointsize); 5090 } 5091} 5092 5093/* 5094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5095% % 5096% % 5097% % 5098% D r a w S e t F o n t S t r e t c h % 5099% % 5100% % 5101% % 5102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5103% 5104% DrawSetFontStretch() sets the font stretch to use when annotating with text. 5105% The AnyStretch enumeration acts as a wild-card "don't care" option. 5106% 5107% The format of the DrawSetFontStretch method is: 5108% 5109% void DrawSetFontStretch(DrawingWand *wand, 5110% const StretchType font_stretch) 5111% 5112% A description of each parameter follows: 5113% 5114% o wand: the drawing wand. 5115% 5116% o font_stretch: font stretch (NormalStretch, UltraCondensedStretch, 5117% CondensedStretch, SemiCondensedStretch, 5118% SemiExpandedStretch, ExpandedStretch, 5119% ExtraExpandedStretch, UltraExpandedStretch, AnyStretch) 5120% 5121*/ 5122WandExport void DrawSetFontStretch(DrawingWand *wand, 5123 const StretchType font_stretch) 5124{ 5125 assert(wand != (DrawingWand *) NULL); 5126 assert(wand->signature == MagickWandSignature); 5127 if (wand->debug != MagickFalse) 5128 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5129 if ((wand->filter_off != MagickFalse) || 5130 (CurrentContext->stretch != font_stretch)) 5131 { 5132 CurrentContext->stretch=font_stretch; 5133 (void) MVGPrintf(wand, "font-stretch '%s'\n",CommandOptionToMnemonic( 5134 MagickStretchOptions,(ssize_t) font_stretch)); 5135 } 5136} 5137 5138/* 5139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5140% % 5141% % 5142% % 5143% D r a w S e t F o n t S t y l e % 5144% % 5145% % 5146% % 5147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5148% 5149% DrawSetFontStyle() sets the font style to use when annotating with text. 5150% The AnyStyle enumeration acts as a wild-card "don't care" option. 5151% 5152% The format of the DrawSetFontStyle method is: 5153% 5154% void DrawSetFontStyle(DrawingWand *wand,const StyleType style) 5155% 5156% A description of each parameter follows: 5157% 5158% o wand: the drawing wand. 5159% 5160% o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle) 5161% 5162*/ 5163WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style) 5164{ 5165 assert(wand != (DrawingWand *) NULL); 5166 assert(wand->signature == MagickWandSignature); 5167 if (wand->debug != MagickFalse) 5168 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5169 if ((wand->filter_off != MagickFalse) || 5170 (CurrentContext->style != style)) 5171 { 5172 CurrentContext->style=style; 5173 (void) MVGPrintf(wand, "font-style '%s'\n",CommandOptionToMnemonic( 5174 MagickStyleOptions,(ssize_t) style)); 5175 } 5176} 5177 5178/* 5179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5180% % 5181% % 5182% % 5183% D r a w S e t F o n t W e i g h t % 5184% % 5185% % 5186% % 5187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5188% 5189% DrawSetFontWeight() sets the font weight to use when annotating with text. 5190% 5191% The format of the DrawSetFontWeight method is: 5192% 5193% void DrawSetFontWeight(DrawingWand *wand, 5194% const size_t font_weight) 5195% 5196% A description of each parameter follows: 5197% 5198% o wand: the drawing wand. 5199% 5200% o font_weight: font weight (valid range 100-900) 5201% 5202*/ 5203WandExport void DrawSetFontWeight(DrawingWand *wand, 5204 const size_t font_weight) 5205{ 5206 assert(wand != (DrawingWand *) NULL); 5207 assert(wand->signature == MagickWandSignature); 5208 if (wand->debug != MagickFalse) 5209 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5210 if ((wand->filter_off != MagickFalse) || 5211 (CurrentContext->weight != font_weight)) 5212 { 5213 CurrentContext->weight=font_weight; 5214 (void) MVGPrintf(wand,"font-weight %.20g\n",(double) font_weight); 5215 } 5216} 5217 5218/* 5219%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5220% % 5221% % 5222% % 5223% D r a w S e t G r a v i t y % 5224% % 5225% % 5226% % 5227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5228% 5229% DrawSetGravity() sets the text placement gravity to use when annotating 5230% with text. 5231% 5232% The format of the DrawSetGravity method is: 5233% 5234% void DrawSetGravity(DrawingWand *wand,const GravityType gravity) 5235% 5236% A description of each parameter follows: 5237% 5238% o wand: the drawing wand. 5239% 5240% o gravity: positioning gravity (NorthWestGravity, NorthGravity, 5241% NorthEastGravity, WestGravity, CenterGravity, 5242% EastGravity, SouthWestGravity, SouthGravity, 5243% SouthEastGravity) 5244% 5245*/ 5246WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity) 5247{ 5248 assert(wand != (DrawingWand *) NULL); 5249 assert(wand->signature == MagickWandSignature); 5250 if (wand->debug != MagickFalse) 5251 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5252 if ((wand->filter_off != MagickFalse) || 5253 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity)) 5254 { 5255 CurrentContext->gravity=gravity; 5256 (void) MVGPrintf(wand,"gravity '%s'\n",CommandOptionToMnemonic( 5257 MagickGravityOptions,(ssize_t) gravity)); 5258 } 5259} 5260 5261/* 5262%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5263% % 5264% % 5265% % 5266% D r a w S e t S t r o k e C o l o r % 5267% % 5268% % 5269% % 5270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5271% 5272% DrawSetStrokeColor() sets the color used for stroking object outlines. 5273% 5274% The format of the DrawSetStrokeColor method is: 5275% 5276% void DrawSetStrokeColor(DrawingWand *wand, 5277% const PixelWand *stroke_wand) 5278% 5279% A description of each parameter follows: 5280% 5281% o wand: the drawing wand. 5282% 5283% o stroke_wand: stroke wand. 5284% 5285*/ 5286WandExport void DrawSetStrokeColor(DrawingWand *wand, 5287 const PixelWand *stroke_wand) 5288{ 5289 PixelInfo 5290 *current_stroke, 5291 new_stroke, 5292 stroke_color; 5293 5294 assert(wand != (DrawingWand *) NULL); 5295 assert(wand->signature == MagickWandSignature); 5296 if (wand->debug != MagickFalse) 5297 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5298 assert(stroke_wand != (const PixelWand *) NULL); 5299 PixelGetQuantumPacket(stroke_wand,&stroke_color); 5300 new_stroke=stroke_color; 5301 current_stroke=(&CurrentContext->stroke); 5302 if ((wand->filter_off != MagickFalse) || 5303 (IsPixelInfoEquivalent(current_stroke,&new_stroke) == MagickFalse)) 5304 { 5305 CurrentContext->stroke=new_stroke; 5306 (void) MVGPrintf(wand,"stroke '"); 5307 MVGAppendColor(wand,&stroke_color); 5308 (void) MVGPrintf(wand,"'\n"); 5309 } 5310} 5311 5312/* 5313%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5314% % 5315% % 5316% % 5317% D r a w S e t S t r o k e P a t t e r n U R L % 5318% % 5319% % 5320% % 5321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5322% 5323% DrawSetStrokePatternURL() sets the pattern used for stroking object outlines. 5324% 5325% The format of the DrawSetStrokePatternURL method is: 5326% 5327% MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand, 5328% const char *stroke_url) 5329% 5330% A description of each parameter follows: 5331% 5332% o wand: the drawing wand. 5333% 5334% o stroke_url: URL specifying pattern ID (e.g. "#pattern_id") 5335% 5336*/ 5337WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand, 5338 const char *stroke_url) 5339{ 5340 char 5341 pattern[MagickPathExtent], 5342 pattern_spec[MagickPathExtent]; 5343 5344 assert(wand != (DrawingWand *) NULL); 5345 assert(wand->signature == MagickWandSignature); 5346 if (wand->debug != MagickFalse) 5347 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5348 if (wand->image == (Image *) NULL) 5349 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 5350 assert(stroke_url != NULL); 5351 if (stroke_url[0] != '#') 5352 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url); 5353 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",stroke_url+1); 5354 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL) 5355 { 5356 ThrowDrawException(DrawError,"URLNotFound",stroke_url) 5357 return(MagickFalse); 5358 } 5359 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",stroke_url); 5360#if DRAW_BINARY_IMPLEMENTATION 5361 DrawPatternPath(wand->image,CurrentContext,pattern_spec, 5362 &CurrentContext->stroke_pattern); 5363#endif 5364 if (CurrentContext->stroke.alpha != (Quantum) TransparentAlpha) 5365 CurrentContext->stroke.alpha=(double) CurrentContext->alpha; 5366 (void) MVGPrintf(wand,"stroke %s\n",pattern_spec); 5367 return(MagickTrue); 5368} 5369 5370/* 5371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5372% % 5373% % 5374% % 5375% D r a w S e t S t r o k e A n t i a l i a s % 5376% % 5377% % 5378% % 5379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5380% 5381% DrawSetStrokeAntialias() controls whether stroked outlines are antialiased. 5382% Stroked outlines are antialiased by default. When antialiasing is disabled 5383% stroked pixels are thresholded to determine if the stroke color or 5384% underlying canvas color should be used. 5385% 5386% The format of the DrawSetStrokeAntialias method is: 5387% 5388% void DrawSetStrokeAntialias(DrawingWand *wand, 5389% const MagickBooleanType stroke_antialias) 5390% 5391% A description of each parameter follows: 5392% 5393% o wand: the drawing wand. 5394% 5395% o stroke_antialias: set to false (zero) to disable antialiasing 5396% 5397*/ 5398WandExport void DrawSetStrokeAntialias(DrawingWand *wand, 5399 const MagickBooleanType stroke_antialias) 5400{ 5401 assert(wand != (DrawingWand *) NULL); 5402 assert(wand->signature == MagickWandSignature); 5403 if (wand->debug != MagickFalse) 5404 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5405 if ((wand->filter_off != MagickFalse) || 5406 (CurrentContext->stroke_antialias != stroke_antialias)) 5407 { 5408 CurrentContext->stroke_antialias=stroke_antialias; 5409 (void) MVGPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ? 5410 1 : 0); 5411 } 5412} 5413 5414/* 5415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5416% % 5417% % 5418% % 5419% D r a w S e t S t r o k e D a s h A r r a y % 5420% % 5421% % 5422% % 5423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5424% 5425% DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to 5426% stroke paths. The stroke dash array represents an array of numbers that 5427% specify the lengths of alternating dashes and gaps in pixels. If an odd 5428% number of values is provided, then the list of values is repeated to yield 5429% an even number of values. To remove an existing dash array, pass a zero 5430% number_elements argument and null dasharray. A typical stroke dash array 5431% might contain the members 5 3 2. 5432% 5433% The format of the DrawSetStrokeDashArray method is: 5434% 5435% MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand, 5436% const size_t number_elements,const double *dasharray) 5437% 5438% A description of each parameter follows: 5439% 5440% o wand: the drawing wand. 5441% 5442% o number_elements: number of elements in dash array 5443% 5444% o dasharray: dash array values 5445% 5446*/ 5447WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand, 5448 const size_t number_elements,const double *dasharray) 5449{ 5450 MagickBooleanType 5451 update; 5452 5453 register const double 5454 *p; 5455 5456 register double 5457 *q; 5458 5459 register ssize_t 5460 i; 5461 5462 size_t 5463 n_new, 5464 n_old; 5465 5466 assert(wand != (DrawingWand *) NULL); 5467 assert(wand->signature == MagickWandSignature); 5468 if (wand->debug != MagickFalse) 5469 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5470 n_new=number_elements; 5471 if (dasharray == (const double *) NULL) 5472 n_new=0; 5473 n_old=0; 5474 update=MagickFalse; 5475 q=CurrentContext->dash_pattern; 5476 if (q != (const double *) NULL) 5477 while (fabs(*q++) < MagickEpsilon) 5478 n_old++; 5479 if ((n_old == 0) && (n_new == 0)) 5480 update=MagickFalse; 5481 else 5482 if (n_old != n_new) 5483 update=MagickTrue; 5484 else 5485 if ((CurrentContext->dash_pattern != (double *) NULL) && 5486 (dasharray != (double *) NULL)) 5487 { 5488 p=dasharray; 5489 q=CurrentContext->dash_pattern; 5490 for (i=0; i < (ssize_t) n_new; i++) 5491 { 5492 if (fabs((*p)-(*q)) >= MagickEpsilon) 5493 { 5494 update=MagickTrue; 5495 break; 5496 } 5497 p++; 5498 q++; 5499 } 5500 } 5501 if ((wand->filter_off != MagickFalse) || (update != MagickFalse)) 5502 { 5503 if (CurrentContext->dash_pattern != (double *) NULL) 5504 CurrentContext->dash_pattern=(double *) 5505 RelinquishMagickMemory(CurrentContext->dash_pattern); 5506 if (n_new != 0) 5507 { 5508 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t) 5509 n_new+1UL,sizeof(*CurrentContext->dash_pattern)); 5510 if (CurrentContext->dash_pattern == (double *) NULL) 5511 { 5512 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed", 5513 wand->name); 5514 return(MagickFalse); 5515 } 5516 for (i=0; i < (ssize_t) n_new; i++) 5517 { 5518 CurrentContext->dash_pattern[i]=0.0; 5519 if (dasharray != (double *) NULL) 5520 CurrentContext->dash_pattern[i]=dasharray[i]; 5521 } 5522 CurrentContext->dash_pattern[n_new]=0.0; 5523 } 5524 (void) MVGPrintf(wand,"stroke-dasharray "); 5525 if (n_new == 0) 5526 (void) MVGPrintf(wand,"none\n"); 5527 else 5528 if (dasharray != (double *) NULL) 5529 { 5530 for (i=0; i < (ssize_t) n_new; i++) 5531 { 5532 if (i != 0) 5533 (void) MVGPrintf(wand,","); 5534 (void) MVGPrintf(wand,"%.20g",dasharray[i]); 5535 } 5536 (void) MVGPrintf(wand,"\n"); 5537 } 5538 } 5539 return(MagickTrue); 5540} 5541 5542/* 5543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5544% % 5545% % 5546% % 5547% D r a w S e t S t r o k e D a s h O f f s e t % 5548% % 5549% % 5550% % 5551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5552% 5553% DrawSetStrokeDashOffset() specifies the offset into the dash pattern to 5554% start the dash. 5555% 5556% The format of the DrawSetStrokeDashOffset method is: 5557% 5558% void DrawSetStrokeDashOffset(DrawingWand *wand, 5559% const double dash_offset) 5560% 5561% A description of each parameter follows: 5562% 5563% o wand: the drawing wand. 5564% 5565% o dash_offset: dash offset 5566% 5567*/ 5568WandExport void DrawSetStrokeDashOffset(DrawingWand *wand, 5569 const double dash_offset) 5570{ 5571 assert(wand != (DrawingWand *) NULL); 5572 assert(wand->signature == MagickWandSignature); 5573 if (wand->debug != MagickFalse) 5574 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5575 if ((wand->filter_off != MagickFalse) || 5576 (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon)) 5577 { 5578 CurrentContext->dash_offset=dash_offset; 5579 (void) MVGPrintf(wand,"stroke-dashoffset %.20g\n",dash_offset); 5580 } 5581} 5582 5583/* 5584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5585% % 5586% % 5587% % 5588% D r a w S e t S t r o k e L i n e C a p % 5589% % 5590% % 5591% % 5592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5593% 5594% DrawSetStrokeLineCap() specifies the shape to be used at the end of 5595% open subpaths when they are stroked. Values of LineCap are 5596% UndefinedCap, ButtCap, RoundCap, and SquareCap. 5597% 5598% The format of the DrawSetStrokeLineCap method is: 5599% 5600% void DrawSetStrokeLineCap(DrawingWand *wand, 5601% const LineCap linecap) 5602% 5603% A description of each parameter follows: 5604% 5605% o wand: the drawing wand. 5606% 5607% o linecap: linecap style 5608% 5609*/ 5610WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap) 5611{ 5612 assert(wand != (DrawingWand *) NULL); 5613 assert(wand->signature == MagickWandSignature); 5614 if (wand->debug != MagickFalse) 5615 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5616 if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap)) 5617 { 5618 CurrentContext->linecap=linecap; 5619 (void) MVGPrintf(wand,"stroke-linecap '%s'\n",CommandOptionToMnemonic( 5620 MagickLineCapOptions,(ssize_t) linecap)); 5621 } 5622} 5623 5624/* 5625%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5626% % 5627% % 5628% % 5629% D r a w S e t S t r o k e L i n e J o i n % 5630% % 5631% % 5632% % 5633%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5634% 5635% DrawSetStrokeLineJoin() specifies the shape to be used at the corners of 5636% paths (or other vector shapes) when they are stroked. Values of LineJoin are 5637% UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin. 5638% 5639% The format of the DrawSetStrokeLineJoin method is: 5640% 5641% void DrawSetStrokeLineJoin(DrawingWand *wand, 5642% const LineJoin linejoin) 5643% 5644% A description of each parameter follows: 5645% 5646% o wand: the drawing wand. 5647% 5648% o linejoin: line join style 5649% 5650*/ 5651WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin) 5652{ 5653 assert(wand != (DrawingWand *) NULL); 5654 assert(wand->signature == MagickWandSignature); 5655 if (wand->debug != MagickFalse) 5656 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5657 if ((wand->filter_off != MagickFalse) || 5658 (CurrentContext->linejoin != linejoin)) 5659 { 5660 CurrentContext->linejoin=linejoin; 5661 (void) MVGPrintf(wand, "stroke-linejoin '%s'\n",CommandOptionToMnemonic( 5662 MagickLineJoinOptions,(ssize_t) linejoin)); 5663 } 5664} 5665 5666/* 5667%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5668% % 5669% % 5670% % 5671% D r a w S e t S t r o k e M i t e r L i m i t % 5672% % 5673% % 5674% % 5675%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5676% 5677% DrawSetStrokeMiterLimit() specifies the miter limit. When two line 5678% segments meet at a sharp angle and miter joins have been specified for 5679% 'lineJoin', it is possible for the miter to extend far beyond the 5680% thickness of the line stroking the path. The miterLimit' imposes a 5681% limit on the ratio of the miter length to the 'lineWidth'. 5682% 5683% The format of the DrawSetStrokeMiterLimit method is: 5684% 5685% void DrawSetStrokeMiterLimit(DrawingWand *wand, 5686% const size_t miterlimit) 5687% 5688% A description of each parameter follows: 5689% 5690% o wand: the drawing wand. 5691% 5692% o miterlimit: miter limit 5693% 5694*/ 5695WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand, 5696 const size_t miterlimit) 5697{ 5698 assert(wand != (DrawingWand *) NULL); 5699 assert(wand->signature == MagickWandSignature); 5700 if (wand->debug != MagickFalse) 5701 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5702 if (CurrentContext->miterlimit != miterlimit) 5703 { 5704 CurrentContext->miterlimit=miterlimit; 5705 (void) MVGPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit); 5706 } 5707} 5708 5709/* 5710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5711% % 5712% % 5713% % 5714% D r a w S e t S t r o k e O p a c i t y % 5715% % 5716% % 5717% % 5718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5719% 5720% DrawSetStrokeOpacity() specifies the alpha of stroked object outlines. 5721% 5722% The format of the DrawSetStrokeOpacity method is: 5723% 5724% void DrawSetStrokeOpacity(DrawingWand *wand, 5725% const double stroke_alpha) 5726% 5727% A description of each parameter follows: 5728% 5729% o wand: the drawing wand. 5730% 5731% o opacity: stroke opacity. The value 1.0 is opaque. 5732% 5733*/ 5734WandExport void DrawSetStrokeOpacity(DrawingWand *wand, 5735 const double opacity) 5736{ 5737 double 5738 alpha; 5739 5740 assert(wand != (DrawingWand *) NULL); 5741 assert(wand->signature == MagickWandSignature); 5742 if (wand->debug != MagickFalse) 5743 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5744 alpha=(double) ClampToQuantum(QuantumRange*opacity); 5745 if ((wand->filter_off != MagickFalse) || 5746 (CurrentContext->stroke.alpha != alpha)) 5747 { 5748 CurrentContext->stroke.alpha=alpha; 5749 (void) MVGPrintf(wand,"stroke-opacity %.20g\n",opacity); 5750 } 5751} 5752 5753/* 5754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5755% % 5756% % 5757% % 5758% D r a w S e t S t r o k e W i d t h % 5759% % 5760% % 5761% % 5762%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5763% 5764% DrawSetStrokeWidth() sets the width of the stroke used to draw object 5765% outlines. 5766% 5767% The format of the DrawSetStrokeWidth method is: 5768% 5769% void DrawSetStrokeWidth(DrawingWand *wand, 5770% const double stroke_width) 5771% 5772% A description of each parameter follows: 5773% 5774% o wand: the drawing wand. 5775% 5776% o stroke_width: stroke width 5777% 5778*/ 5779WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width) 5780{ 5781 assert(wand != (DrawingWand *) NULL); 5782 assert(wand->signature == MagickWandSignature); 5783 if (wand->debug != MagickFalse) 5784 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5785 if ((wand->filter_off != MagickFalse) || 5786 (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon)) 5787 { 5788 CurrentContext->stroke_width=stroke_width; 5789 (void) MVGPrintf(wand,"stroke-width %.20g\n",stroke_width); 5790 } 5791} 5792 5793/* 5794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5795% % 5796% % 5797% % 5798% D r a w S e t T e x t A l i g n m e n t % 5799% % 5800% % 5801% % 5802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5803% 5804% DrawSetTextAlignment() specifies a text alignment to be applied when 5805% annotating with text. 5806% 5807% The format of the DrawSetTextAlignment method is: 5808% 5809% void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment) 5810% 5811% A description of each parameter follows: 5812% 5813% o wand: the drawing wand. 5814% 5815% o alignment: text alignment. One of UndefinedAlign, LeftAlign, 5816% CenterAlign, or RightAlign. 5817% 5818*/ 5819WandExport void DrawSetTextAlignment(DrawingWand *wand, 5820 const AlignType alignment) 5821{ 5822 assert(wand != (DrawingWand *) NULL); 5823 assert(wand->signature == MagickWandSignature); 5824 if (wand->debug != MagickFalse) 5825 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5826 if ((wand->filter_off != MagickFalse) || 5827 (CurrentContext->align != alignment)) 5828 { 5829 CurrentContext->align=alignment; 5830 (void) MVGPrintf(wand,"text-align '%s'\n",CommandOptionToMnemonic( 5831 MagickAlignOptions,(ssize_t) alignment)); 5832 } 5833} 5834 5835/* 5836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5837% % 5838% % 5839% % 5840% D r a w S e t T e x t A n t i a l i a s % 5841% % 5842% % 5843% % 5844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5845% 5846% DrawSetTextAntialias() controls whether text is antialiased. Text is 5847% antialiased by default. 5848% 5849% The format of the DrawSetTextAntialias method is: 5850% 5851% void DrawSetTextAntialias(DrawingWand *wand, 5852% const MagickBooleanType text_antialias) 5853% 5854% A description of each parameter follows: 5855% 5856% o wand: the drawing wand. 5857% 5858% o text_antialias: antialias boolean. Set to false (0) to disable 5859% antialiasing. 5860% 5861*/ 5862WandExport void DrawSetTextAntialias(DrawingWand *wand, 5863 const MagickBooleanType text_antialias) 5864{ 5865 assert(wand != (DrawingWand *) NULL); 5866 assert(wand->signature == MagickWandSignature); 5867 if (wand->debug != MagickFalse) 5868 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5869 if ((wand->filter_off != MagickFalse) || 5870 (CurrentContext->text_antialias != text_antialias)) 5871 { 5872 CurrentContext->text_antialias=text_antialias; 5873 (void) MVGPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0); 5874 } 5875} 5876 5877/* 5878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5879% % 5880% % 5881% % 5882% D r a w S e t T e x t D e c o r a t i o n % 5883% % 5884% % 5885% % 5886%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5887% 5888% DrawSetTextDecoration() specifies a decoration to be applied when 5889% annotating with text. 5890% 5891% The format of the DrawSetTextDecoration method is: 5892% 5893% void DrawSetTextDecoration(DrawingWand *wand, 5894% const DecorationType decoration) 5895% 5896% A description of each parameter follows: 5897% 5898% o wand: the drawing wand. 5899% 5900% o decoration: text decoration. One of NoDecoration, UnderlineDecoration, 5901% OverlineDecoration, or LineThroughDecoration 5902% 5903*/ 5904WandExport void DrawSetTextDecoration(DrawingWand *wand, 5905 const DecorationType decoration) 5906{ 5907 assert(wand != (DrawingWand *) NULL); 5908 assert(wand->signature == MagickWandSignature); 5909 if (wand->debug != MagickFalse) 5910 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5911 if ((wand->filter_off != MagickFalse) || 5912 (CurrentContext->decorate != decoration)) 5913 { 5914 CurrentContext->decorate=decoration; 5915 (void) MVGPrintf(wand,"decorate '%s'\n",CommandOptionToMnemonic( 5916 MagickDecorateOptions,(ssize_t) decoration)); 5917 } 5918} 5919 5920/* 5921%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5922% % 5923% % 5924% % 5925% D r a w S e t T e x t D i r e c t i o n % 5926% % 5927% % 5928% % 5929%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5930% 5931% DrawSetTextDirection() specifies the direction to be used when 5932% annotating with text. 5933% 5934% The format of the DrawSetTextDirection method is: 5935% 5936% void DrawSetTextDirection(DrawingWand *wand, 5937% const DirectionType direction) 5938% 5939% A description of each parameter follows: 5940% 5941% o wand: the drawing wand. 5942% 5943% o direction: text direction. One of RightToLeftDirection, 5944% LeftToRightDirection 5945% 5946*/ 5947WandExport void DrawSetTextDirection(DrawingWand *wand, 5948 const DirectionType direction) 5949{ 5950 assert(wand != (DrawingWand *) NULL); 5951 assert(wand->signature == MagickWandSignature); 5952 5953 if (wand->debug != MagickFalse) 5954 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5955 if ((wand->filter_off != MagickFalse) || 5956 (CurrentContext->direction != direction)) 5957 { 5958 CurrentContext->direction=direction; 5959 (void) MVGPrintf(wand,"direction '%s'\n",CommandOptionToMnemonic( 5960 MagickDirectionOptions,(ssize_t) direction)); 5961 } 5962} 5963 5964/* 5965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5966% % 5967% % 5968% % 5969% D r a w S e t T e x t E n c o d i n g % 5970% % 5971% % 5972% % 5973%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5974% 5975% DrawSetTextEncoding() specifies the code set to use for text 5976% annotations. The only character encoding which may be specified 5977% at this time is "UTF-8" for representing Unicode as a sequence of 5978% bytes. Specify an empty string to set text encoding to the system's 5979% default. Successful text annotation using Unicode may require fonts 5980% designed to support Unicode. 5981% 5982% The format of the DrawSetTextEncoding method is: 5983% 5984% void DrawSetTextEncoding(DrawingWand *wand,const char *encoding) 5985% 5986% A description of each parameter follows: 5987% 5988% o wand: the drawing wand. 5989% 5990% o encoding: character string specifying text encoding 5991% 5992*/ 5993WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding) 5994{ 5995 assert(wand != (DrawingWand *) NULL); 5996 assert(wand->signature == MagickWandSignature); 5997 if (wand->debug != MagickFalse) 5998 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5999 assert(encoding != (char *) NULL); 6000 if ((wand->filter_off != MagickFalse) || 6001 (CurrentContext->encoding == (char *) NULL) || 6002 (LocaleCompare(CurrentContext->encoding,encoding) != 0)) 6003 { 6004 (void) CloneString(&CurrentContext->encoding,encoding); 6005 (void) MVGPrintf(wand,"encoding '%s'\n",encoding); 6006 } 6007} 6008 6009/* 6010%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6011% % 6012% % 6013% % 6014% D r a w S e t T e x t K e r n i n g % 6015% % 6016% % 6017% % 6018%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6019% 6020% DrawSetTextKerning() sets the spacing between characters in text. 6021% 6022% The format of the DrawSetTextKerning method is: 6023% 6024% void DrawSetTextKerning(DrawingWand *wand,const double kerning) 6025% 6026% A description of each parameter follows: 6027% 6028% o wand: the drawing wand. 6029% 6030% o kerning: text kerning 6031% 6032*/ 6033WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning) 6034{ 6035 assert(wand != (DrawingWand *) NULL); 6036 assert(wand->signature == MagickWandSignature); 6037 6038 if (wand->debug != MagickFalse) 6039 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6040 if ((wand->filter_off != MagickFalse) && 6041 ((CurrentContext->kerning-kerning) >= MagickEpsilon)) 6042 { 6043 CurrentContext->kerning=kerning; 6044 (void) MVGPrintf(wand,"kerning %lf\n",kerning); 6045 } 6046} 6047 6048/* 6049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6050% % 6051% % 6052% % 6053% D r a w S e t T e x t I n t e r L i n e S p a c i n g % 6054% % 6055% % 6056% % 6057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6058% 6059% DrawSetTextInterlineSpacing() sets the spacing between line in text. 6060% 6061% The format of the DrawSetInterlineSpacing method is: 6062% 6063% void DrawSetTextInterlineSpacing(DrawingWand *wand, 6064% const double interline_spacing) 6065% 6066% A description of each parameter follows: 6067% 6068% o wand: the drawing wand. 6069% 6070% o interline_spacing: text line spacing 6071% 6072*/ 6073WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand, 6074 const double interline_spacing) 6075{ 6076 assert(wand != (DrawingWand *) NULL); 6077 assert(wand->signature == MagickWandSignature); 6078 6079 if (wand->debug != MagickFalse) 6080 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6081 if ((wand->filter_off != MagickFalse) && 6082 ((CurrentContext->interline_spacing-interline_spacing) >= MagickEpsilon)) 6083 { 6084 CurrentContext->interline_spacing=interline_spacing; 6085 (void) MVGPrintf(wand,"interline-spacing %lf\n",interline_spacing); 6086 } 6087} 6088 6089/* 6090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6091% % 6092% % 6093% % 6094% D r a w S e t T e x t I n t e r w o r d S p a c i n g % 6095% % 6096% % 6097% % 6098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6099% 6100% DrawSetTextInterwordSpacing() sets the spacing between words in text. 6101% 6102% The format of the DrawSetInterwordSpacing method is: 6103% 6104% void DrawSetTextInterwordSpacing(DrawingWand *wand, 6105% const double interword_spacing) 6106% 6107% A description of each parameter follows: 6108% 6109% o wand: the drawing wand. 6110% 6111% o interword_spacing: text word spacing 6112% 6113*/ 6114WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand, 6115 const double interword_spacing) 6116{ 6117 assert(wand != (DrawingWand *) NULL); 6118 assert(wand->signature == MagickWandSignature); 6119 6120 if (wand->debug != MagickFalse) 6121 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6122 if ((wand->filter_off != MagickFalse) && 6123 ((CurrentContext->interword_spacing-interword_spacing) >= MagickEpsilon)) 6124 { 6125 CurrentContext->interword_spacing=interword_spacing; 6126 (void) MVGPrintf(wand,"interword-spacing %lf\n",interword_spacing); 6127 } 6128} 6129 6130/* 6131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6132% % 6133% % 6134% % 6135% D r a w S e t T e x t U n d e r C o l o r % 6136% % 6137% % 6138% % 6139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6140% 6141% DrawSetTextUnderColor() specifies the color of a background rectangle 6142% to place under text annotations. 6143% 6144% The format of the DrawSetTextUnderColor method is: 6145% 6146% void DrawSetTextUnderColor(DrawingWand *wand, 6147% const PixelWand *under_wand) 6148% 6149% A description of each parameter follows: 6150% 6151% o wand: the drawing wand. 6152% 6153% o under_wand: text under wand. 6154% 6155*/ 6156WandExport void DrawSetTextUnderColor(DrawingWand *wand, 6157 const PixelWand *under_wand) 6158{ 6159 PixelInfo 6160 under_color; 6161 6162 assert(wand != (DrawingWand *) NULL); 6163 assert(wand->signature == MagickWandSignature); 6164 if (wand->debug != MagickFalse) 6165 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6166 assert(under_wand != (const PixelWand *) NULL); 6167 PixelGetQuantumPacket(under_wand,&under_color); 6168 if ((wand->filter_off != MagickFalse) || 6169 (IsPixelInfoEquivalent(&CurrentContext->undercolor,&under_color) == MagickFalse)) 6170 { 6171 CurrentContext->undercolor=under_color; 6172 (void) MVGPrintf(wand,"text-undercolor '"); 6173 MVGAppendColor(wand,&under_color); 6174 (void) MVGPrintf(wand,"'\n"); 6175 } 6176} 6177 6178/* 6179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6180% % 6181% % 6182% % 6183% D r a w S e t V e c t o r G r a p h i c s % 6184% % 6185% % 6186% % 6187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6188% 6189% DrawSetVectorGraphics() sets the vector graphics associated with the 6190% specified wand. Use this method with DrawGetVectorGraphics() as a method 6191% to persist the vector graphics state. 6192% 6193% The format of the DrawSetVectorGraphics method is: 6194% 6195% MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand, 6196% const char *xml) 6197% 6198% A description of each parameter follows: 6199% 6200% o wand: the drawing wand. 6201% 6202% o xml: the drawing wand XML. 6203% 6204*/ 6205 6206static inline MagickBooleanType IsPoint(const char *point) 6207{ 6208 char 6209 *p; 6210 6211 long 6212 value; 6213 6214 value=strtol(point,&p,10); 6215 (void) value; 6216 return(p != point ? MagickTrue : MagickFalse); 6217} 6218 6219WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand, 6220 const char *xml) 6221{ 6222 const char 6223 *value; 6224 6225 XMLTreeInfo 6226 *child, 6227 *xml_info; 6228 6229 assert(wand != (DrawingWand *) NULL); 6230 assert(wand->signature == MagickWandSignature); 6231 if (wand->debug != MagickFalse) 6232 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6233 CurrentContext=DestroyDrawInfo(CurrentContext); 6234 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL); 6235 if (xml == (const char *) NULL) 6236 return(MagickFalse); 6237 xml_info=NewXMLTree(xml,wand->exception); 6238 if (xml_info == (XMLTreeInfo *) NULL) 6239 return(MagickFalse); 6240 child=GetXMLTreeChild(xml_info,"clip-path"); 6241 if (child != (XMLTreeInfo *) NULL) 6242 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child)); 6243 child=GetXMLTreeChild(xml_info,"clip-units"); 6244 if (child != (XMLTreeInfo *) NULL) 6245 { 6246 value=GetXMLTreeContent(child); 6247 if (value != (const char *) NULL) 6248 CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption( 6249 MagickClipPathOptions,MagickFalse,value); 6250 } 6251 child=GetXMLTreeChild(xml_info,"decorate"); 6252 if (child != (XMLTreeInfo *) NULL) 6253 { 6254 value=GetXMLTreeContent(child); 6255 if (value != (const char *) NULL) 6256 CurrentContext->decorate=(DecorationType) ParseCommandOption( 6257 MagickDecorateOptions,MagickFalse,value); 6258 } 6259 child=GetXMLTreeChild(xml_info,"encoding"); 6260 if (child != (XMLTreeInfo *) NULL) 6261 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child)); 6262 child=GetXMLTreeChild(xml_info,"fill"); 6263 if (child != (XMLTreeInfo *) NULL) 6264 { 6265 value=GetXMLTreeContent(child); 6266 if (value != (const char *) NULL) 6267 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->fill, 6268 wand->exception); 6269 } 6270 child=GetXMLTreeChild(xml_info,"fill-opacity"); 6271 if (child != (XMLTreeInfo *) NULL) 6272 { 6273 value=GetXMLTreeContent(child); 6274 if (value != (const char *) NULL) 6275 CurrentContext->fill.alpha=(double) ClampToQuantum(QuantumRange* 6276 (1.0-StringToDouble(value,(char **) NULL))); 6277 } 6278 child=GetXMLTreeChild(xml_info,"fill-rule"); 6279 if (child != (XMLTreeInfo *) NULL) 6280 { 6281 value=GetXMLTreeContent(child); 6282 if (value != (const char *) NULL) 6283 CurrentContext->fill_rule=(FillRule) ParseCommandOption( 6284 MagickFillRuleOptions,MagickFalse,value); 6285 } 6286 child=GetXMLTreeChild(xml_info,"font"); 6287 if (child != (XMLTreeInfo *) NULL) 6288 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child)); 6289 child=GetXMLTreeChild(xml_info,"font-family"); 6290 if (child != (XMLTreeInfo *) NULL) 6291 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child)); 6292 child=GetXMLTreeChild(xml_info,"font-size"); 6293 if (child != (XMLTreeInfo *) NULL) 6294 { 6295 value=GetXMLTreeContent(child); 6296 if (value != (const char *) NULL) 6297 CurrentContext->pointsize=StringToDouble(value,(char **) NULL); 6298 } 6299 child=GetXMLTreeChild(xml_info,"font-stretch"); 6300 if (child != (XMLTreeInfo *) NULL) 6301 { 6302 value=GetXMLTreeContent(child); 6303 if (value != (const char *) NULL) 6304 CurrentContext->stretch=(StretchType) ParseCommandOption( 6305 MagickStretchOptions,MagickFalse,value); 6306 } 6307 child=GetXMLTreeChild(xml_info,"font-style"); 6308 if (child != (XMLTreeInfo *) NULL) 6309 { 6310 value=GetXMLTreeContent(child); 6311 if (value != (const char *) NULL) 6312 CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions, 6313 MagickFalse,value); 6314 } 6315 child=GetXMLTreeChild(xml_info,"font-weight"); 6316 if (child != (XMLTreeInfo *) NULL) 6317 { 6318 value=GetXMLTreeContent(child); 6319 if (value != (const char *) NULL) 6320 { 6321 ssize_t 6322 weight; 6323 6324 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value); 6325 if (weight == -1) 6326 weight=StringToUnsignedLong(value); 6327 CurrentContext->weight=weight; 6328 } 6329 } 6330 child=GetXMLTreeChild(xml_info,"gravity"); 6331 if (child != (XMLTreeInfo *) NULL) 6332 { 6333 value=GetXMLTreeContent(child); 6334 if (value != (const char *) NULL) 6335 CurrentContext->gravity=(GravityType) ParseCommandOption( 6336 MagickGravityOptions,MagickFalse,value); 6337 } 6338 child=GetXMLTreeChild(xml_info,"stroke"); 6339 if (child != (XMLTreeInfo *) NULL) 6340 { 6341 value=GetXMLTreeContent(child); 6342 if (value != (const char *) NULL) 6343 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->stroke, 6344 wand->exception); 6345 } 6346 child=GetXMLTreeChild(xml_info,"stroke-antialias"); 6347 if (child != (XMLTreeInfo *) NULL) 6348 { 6349 value=GetXMLTreeContent(child); 6350 if (value != (const char *) NULL) 6351 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue : 6352 MagickFalse; 6353 } 6354 child=GetXMLTreeChild(xml_info,"stroke-dasharray"); 6355 if (child != (XMLTreeInfo *) NULL) 6356 { 6357 char 6358 token[MagickPathExtent]; 6359 6360 const char 6361 *q; 6362 6363 register ssize_t 6364 x; 6365 6366 ssize_t 6367 j; 6368 6369 value=GetXMLTreeContent(child); 6370 if (value != (const char *) NULL) 6371 { 6372 if (CurrentContext->dash_pattern != (double *) NULL) 6373 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory( 6374 CurrentContext->dash_pattern); 6375 q=(char *) value; 6376 if (IsPoint(q) != MagickFalse) 6377 { 6378 const char 6379 *p; 6380 6381 p=q; 6382 GetNextToken(p,&p,MagickPathExtent,token); 6383 if (*token == ',') 6384 GetNextToken(p,&p,MagickPathExtent,token); 6385 for (x=0; IsPoint(token) != MagickFalse; x++) 6386 { 6387 GetNextToken(p,&p,MagickPathExtent,token); 6388 if (*token == ',') 6389 GetNextToken(p,&p,MagickPathExtent,token); 6390 } 6391 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory( 6392 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern)); 6393 if (CurrentContext->dash_pattern == (double *) NULL) 6394 ThrowWandFatalException(ResourceLimitFatalError, 6395 "MemoryAllocationFailed",wand->name); 6396 for (j=0; j < x; j++) 6397 { 6398 GetNextToken(q,&q,MagickPathExtent,token); 6399 if (*token == ',') 6400 GetNextToken(q,&q,MagickPathExtent,token); 6401 CurrentContext->dash_pattern[j]=StringToDouble(token, 6402 (char **) NULL); 6403 } 6404 if ((x & 0x01) != 0) 6405 for ( ; j < (2*x); j++) 6406 CurrentContext->dash_pattern[j]= 6407 CurrentContext->dash_pattern[j-x]; 6408 CurrentContext->dash_pattern[j]=0.0; 6409 } 6410 } 6411 } 6412 child=GetXMLTreeChild(xml_info,"stroke-dashoffset"); 6413 if (child != (XMLTreeInfo *) NULL) 6414 { 6415 value=GetXMLTreeContent(child); 6416 if (value != (const char *) NULL) 6417 CurrentContext->dash_offset=StringToDouble(value,(char **) NULL); 6418 } 6419 child=GetXMLTreeChild(xml_info,"stroke-linecap"); 6420 if (child != (XMLTreeInfo *) NULL) 6421 { 6422 value=GetXMLTreeContent(child); 6423 if (value != (const char *) NULL) 6424 CurrentContext->linecap=(LineCap) ParseCommandOption( 6425 MagickLineCapOptions,MagickFalse,value); 6426 } 6427 child=GetXMLTreeChild(xml_info,"stroke-linejoin"); 6428 if (child != (XMLTreeInfo *) NULL) 6429 { 6430 value=GetXMLTreeContent(child); 6431 if (value != (const char *) NULL) 6432 CurrentContext->linejoin=(LineJoin) ParseCommandOption( 6433 MagickLineJoinOptions,MagickFalse,value); 6434 } 6435 child=GetXMLTreeChild(xml_info,"stroke-miterlimit"); 6436 if (child != (XMLTreeInfo *) NULL) 6437 { 6438 value=GetXMLTreeContent(child); 6439 if (value != (const char *) NULL) 6440 CurrentContext->miterlimit=StringToUnsignedLong(value); 6441 } 6442 child=GetXMLTreeChild(xml_info,"stroke-opacity"); 6443 if (child != (XMLTreeInfo *) NULL) 6444 { 6445 value=GetXMLTreeContent(child); 6446 if (value != (const char *) NULL) 6447 CurrentContext->stroke.alpha=(double) ClampToQuantum(QuantumRange* 6448 (1.0-StringToDouble(value,(char **) NULL))); 6449 } 6450 child=GetXMLTreeChild(xml_info,"stroke-width"); 6451 if (child != (XMLTreeInfo *) NULL) 6452 { 6453 value=GetXMLTreeContent(child); 6454 if (value != (const char *) NULL) 6455 CurrentContext->stroke_width=StringToDouble(value,(char **) NULL); 6456 } 6457 child=GetXMLTreeChild(xml_info,"text-align"); 6458 if (child != (XMLTreeInfo *) NULL) 6459 { 6460 value=GetXMLTreeContent(child); 6461 if (value != (const char *) NULL) 6462 CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions, 6463 MagickFalse,value); 6464 } 6465 child=GetXMLTreeChild(xml_info,"text-antialias"); 6466 if (child != (XMLTreeInfo *) NULL) 6467 { 6468 value=GetXMLTreeContent(child); 6469 if (value != (const char *) NULL) 6470 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue : 6471 MagickFalse; 6472 } 6473 child=GetXMLTreeChild(xml_info,"text-undercolor"); 6474 if (child != (XMLTreeInfo *) NULL) 6475 { 6476 value=GetXMLTreeContent(child); 6477 if (value != (const char *) NULL) 6478 (void) QueryColorCompliance(value,AllCompliance, 6479 &CurrentContext->undercolor,wand->exception); 6480 } 6481 child=GetXMLTreeChild(xml_info,"vector-graphics"); 6482 if (child != (XMLTreeInfo *) NULL) 6483 { 6484 (void) CloneString(&wand->mvg,GetXMLTreeContent(child)); 6485 wand->mvg_length=strlen(wand->mvg); 6486 wand->mvg_alloc=wand->mvg_length+1; 6487 } 6488 xml_info=DestroyXMLTree(xml_info); 6489 return(MagickTrue); 6490} 6491 6492/* 6493%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6494% % 6495% % 6496% % 6497% D r a w S k e w X % 6498% % 6499% % 6500% % 6501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6502% 6503% DrawSkewX() skews the current coordinate system in the horizontal 6504% direction. 6505% 6506% The format of the DrawSkewX method is: 6507% 6508% void DrawSkewX(DrawingWand *wand,const double degrees) 6509% 6510% A description of each parameter follows: 6511% 6512% o wand: the drawing wand. 6513% 6514% o degrees: number of degrees to skew the coordinates 6515% 6516*/ 6517WandExport void DrawSkewX(DrawingWand *wand,const double degrees) 6518{ 6519 assert(wand != (DrawingWand *) NULL); 6520 assert(wand->signature == MagickWandSignature); 6521 if (wand->debug != MagickFalse) 6522 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6523 (void) MVGPrintf(wand,"skewX %.20g\n",degrees); 6524} 6525 6526/* 6527%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6528% % 6529% % 6530% % 6531% D r a w S k e w Y % 6532% % 6533% % 6534% % 6535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6536% 6537% DrawSkewY() skews the current coordinate system in the vertical 6538% direction. 6539% 6540% The format of the DrawSkewY method is: 6541% 6542% void DrawSkewY(DrawingWand *wand,const double degrees) 6543% 6544% A description of each parameter follows: 6545% 6546% o wand: the drawing wand. 6547% 6548% o degrees: number of degrees to skew the coordinates 6549% 6550*/ 6551WandExport void DrawSkewY(DrawingWand *wand,const double degrees) 6552{ 6553 assert(wand != (DrawingWand *) NULL); 6554 assert(wand->signature == MagickWandSignature); 6555 if (wand->debug != MagickFalse) 6556 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6557 (void) MVGPrintf(wand,"skewY %.20g\n",degrees); 6558} 6559 6560/* 6561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6562% % 6563% % 6564% % 6565% D r a w T r a n s l a t e % 6566% % 6567% % 6568% % 6569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6570% 6571% DrawTranslate() applies a translation to the current coordinate 6572% system which moves the coordinate system origin to the specified 6573% coordinate. 6574% 6575% The format of the DrawTranslate method is: 6576% 6577% void DrawTranslate(DrawingWand *wand,const double x, 6578% const double y) 6579% 6580% A description of each parameter follows: 6581% 6582% o wand: the drawing wand. 6583% 6584% o x: new x ordinate for coordinate system origin 6585% 6586% o y: new y ordinate for coordinate system origin 6587% 6588*/ 6589WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y) 6590{ 6591 assert(wand != (DrawingWand *) NULL); 6592 assert(wand->signature == MagickWandSignature); 6593 if (wand->debug != MagickFalse) 6594 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6595 (void) MVGPrintf(wand,"translate %.20g %.20g\n",x,y); 6596} 6597 6598/* 6599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6600% % 6601% % 6602% % 6603% D r a w S e t V i e w b o x % 6604% % 6605% % 6606% % 6607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6608% 6609% DrawSetViewbox() sets the overall canvas size to be recorded with the 6610% drawing vector data. Usually this will be specified using the same 6611% size as the canvas image. When the vector data is saved to SVG or MVG 6612% formats, the viewbox is use to specify the size of the canvas image that 6613% a viewer will render the vector data on. 6614% 6615% The format of the DrawSetViewbox method is: 6616% 6617% void DrawSetViewbox(DrawingWand *wand,const double x1,const double y1, 6618% const double x2,const double y2) 6619% 6620% A description of each parameter follows: 6621% 6622% o wand: the drawing wand. 6623% 6624% o x1: left x ordinate 6625% 6626% o y1: top y ordinate 6627% 6628% o x2: right x ordinate 6629% 6630% o y2: bottom y ordinate 6631% 6632*/ 6633WandExport void DrawSetViewbox(DrawingWand *wand,const double x1, 6634 const double y1,const double x2,const double y2) 6635{ 6636 assert(wand != (DrawingWand *) NULL); 6637 assert(wand->signature == MagickWandSignature); 6638 if (wand->debug != MagickFalse) 6639 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6640 (void) MVGPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2); 6641} 6642 6643/* 6644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6645% % 6646% % 6647% % 6648% I s D r a w i n g W a n d % 6649% % 6650% % 6651% % 6652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6653% 6654% IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand. 6655% 6656% The format of the IsDrawingWand method is: 6657% 6658% MagickBooleanType IsDrawingWand(const DrawingWand *wand) 6659% 6660% A description of each parameter follows: 6661% 6662% o wand: the drawing wand. 6663% 6664*/ 6665WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand) 6666{ 6667 if (wand == (const DrawingWand *) NULL) 6668 return(MagickFalse); 6669 if (wand->signature != MagickWandSignature) 6670 return(MagickFalse); 6671 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0) 6672 return(MagickFalse); 6673 return(MagickTrue); 6674} 6675 6676/* 6677%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6678% % 6679% % 6680% % 6681% N e w D r a w i n g W a n d % 6682% % 6683% % 6684% % 6685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6686% 6687% NewDrawingWand() returns a drawing wand required for all other methods in 6688% the API. 6689% 6690% The format of the NewDrawingWand method is: 6691% 6692% DrawingWand *NewDrawingWand(void) 6693% 6694*/ 6695WandExport DrawingWand *NewDrawingWand(void) 6696{ 6697 const char 6698 *quantum; 6699 6700 DrawingWand 6701 *wand; 6702 6703 size_t 6704 depth; 6705 6706 quantum=GetMagickQuantumDepth(&depth); 6707 if (depth != MAGICKCORE_QUANTUM_DEPTH) 6708 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum); 6709 wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand)); 6710 if (wand == (DrawingWand *) NULL) 6711 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 6712 GetExceptionMessage(errno)); 6713 (void) ResetMagickMemory(wand,0,sizeof(*wand)); 6714 wand->id=AcquireWandId(); 6715 (void) FormatLocaleString(wand->name,MagickPathExtent,"%s-%.20g", 6716 DrawingWandId,(double) wand->id); 6717 if (wand->debug != MagickFalse) 6718 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6719 wand->mvg=(char *) NULL; 6720 wand->mvg_alloc=0; 6721 wand->mvg_length=0; 6722 wand->mvg_width=0; 6723 wand->pattern_id=(char *) NULL; 6724 wand->pattern_offset=0; 6725 wand->pattern_bounds.x=0; 6726 wand->pattern_bounds.y=0; 6727 wand->pattern_bounds.width=0; 6728 wand->pattern_bounds.height=0; 6729 wand->index=0; 6730 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof( 6731 *wand->graphic_context)); 6732 if (wand->graphic_context == (DrawInfo **) NULL) 6733 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 6734 GetExceptionMessage(errno)); 6735 wand->filter_off=MagickTrue; 6736 wand->indent_depth=0; 6737 wand->path_operation=PathDefaultOperation; 6738 wand->path_mode=DefaultPathMode; 6739 wand->exception=AcquireExceptionInfo(); 6740 wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception); 6741 wand->destroy=MagickTrue; 6742 wand->debug=IsEventLogging(); 6743 wand->signature=MagickWandSignature; 6744 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL); 6745 return(wand); 6746} 6747 6748/* 6749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6750% % 6751% % 6752% % 6753% P e e k D r a w i n g W a n d % 6754% % 6755% % 6756% % 6757%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6758% 6759% PeekDrawingWand() returns the current drawing wand. 6760% 6761% The format of the PeekDrawingWand method is: 6762% 6763% DrawInfo *PeekDrawingWand(const DrawingWand *wand) 6764% 6765% A description of each parameter follows: 6766% 6767% o wand: the drawing wand. 6768% 6769*/ 6770WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand) 6771{ 6772 DrawInfo 6773 *draw_info; 6774 6775 assert(wand != (const DrawingWand *) NULL); 6776 assert(wand->signature == MagickWandSignature); 6777 if (wand->debug != MagickFalse) 6778 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6779 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext); 6780 GetAffineMatrix(&draw_info->affine); 6781 (void) CloneString(&draw_info->primitive,wand->mvg); 6782 return(draw_info); 6783} 6784 6785/* 6786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6787% % 6788% % 6789% % 6790% P o p D r a w i n g W a n d % 6791% % 6792% % 6793% % 6794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6795% 6796% PopDrawingWand() destroys the current drawing wand and returns to the 6797% previously pushed drawing wand. Multiple drawing wands may exist. It is an 6798% error to attempt to pop more drawing wands than have been pushed, and it is 6799% proper form to pop all drawing wands which have been pushed. 6800% 6801% The format of the PopDrawingWand method is: 6802% 6803% MagickBooleanType PopDrawingWand(DrawingWand *wand) 6804% 6805% A description of each parameter follows: 6806% 6807% o wand: the drawing wand. 6808% 6809*/ 6810WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand) 6811{ 6812 assert(wand != (DrawingWand *) NULL); 6813 assert(wand->signature == MagickWandSignature); 6814 if (wand->debug != MagickFalse) 6815 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6816 if (wand->index == 0) 6817 { 6818 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name) 6819 return(MagickFalse); 6820 } 6821 /* 6822 Destroy clip path if not same in preceding wand. 6823 */ 6824#if DRAW_BINARY_IMPLEMENTATION 6825 if (wand->image == (Image *) NULL) 6826 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 6827 if (CurrentContext->clip_mask != (char *) NULL) 6828 if (LocaleCompare(CurrentContext->clip_mask, 6829 wand->graphic_context[wand->index-1]->clip_mask) != 0) 6830 (void) SetImageMask(wand->image,ReadPixelMask,(Image *) NULL, 6831 wand->exception); 6832#endif 6833 CurrentContext=DestroyDrawInfo(CurrentContext); 6834 wand->index--; 6835 if (wand->indent_depth > 0) 6836 wand->indent_depth--; 6837 (void) MVGPrintf(wand,"pop graphic-context\n"); 6838 return(MagickTrue); 6839} 6840 6841/* 6842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6843% % 6844% % 6845% % 6846% P u s h D r a w i n g W a n d % 6847% % 6848% % 6849% % 6850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6851% 6852% PushDrawingWand() clones the current drawing wand to create a new drawing 6853% wand. The original drawing wand(s) may be returned to by invoking 6854% PopDrawingWand(). The drawing wands are stored on a drawing wand stack. 6855% For every Pop there must have already been an equivalent Push. 6856% 6857% The format of the PushDrawingWand method is: 6858% 6859% MagickBooleanType PushDrawingWand(DrawingWand *wand) 6860% 6861% A description of each parameter follows: 6862% 6863% o wand: the drawing wand. 6864% 6865*/ 6866WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand) 6867{ 6868 assert(wand != (DrawingWand *) NULL); 6869 assert(wand->signature == MagickWandSignature); 6870 if (wand->debug != MagickFalse) 6871 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6872 wand->index++; 6873 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context, 6874 (size_t) wand->index+1UL,sizeof(*wand->graphic_context)); 6875 if (wand->graphic_context == (DrawInfo **) NULL) 6876 { 6877 wand->index--; 6878 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed", 6879 wand->name); 6880 return(MagickFalse); 6881 } 6882 CurrentContext=CloneDrawInfo((ImageInfo *) NULL, 6883 wand->graphic_context[wand->index-1]); 6884 (void) MVGPrintf(wand,"push graphic-context\n"); 6885 wand->indent_depth++; 6886 return(MagickTrue); 6887} 6888