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