1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % DDDD RRRR AAA W W IIIII N N GGGG % 7 % D D R R A A W W I NN N G % 8 % D D RRRR AAAAA W W I N N N G GG % 9 % D D R R A A W W W I N NN G G % 10 % DDDD R R A A W W IIIII N N GGG % 11 % % 12 % W W AAA N N DDDD % 13 % W W A A NN N D D % 14 % W W W AAAAA N N N D D % 15 % WW WW A A N NN D D % 16 % W W A A N N DDDD % 17 % % 18 % % 19 % MagickWand Image Vector Drawing Methods % 20 % % 21 % Software Design % 22 % Bob Friesenhahn % 23 % March 2002 % 24 % % 25 % % 26 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 27 % dedicated to making software imaging solutions freely available. % 28 % % 29 % You may not use this file except in compliance with the License. You may % 30 % obtain a copy of the License at % 31 % % 32 % http://www.imagemagick.org/script/license.php % 33 % % 34 % Unless required by applicable law or agreed to in writing, software % 35 % distributed under the License is distributed on an "AS IS" BASIS, % 36 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 37 % See the License for the specific language governing permissions and % 38 % limitations under the License. % 39 % % 40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 41 % 42 % 43 % 44 */ 45 46 /* 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 if (wand->debug != MagickFalse) 180 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",format); 181 assert(wand != (DrawingWand *) NULL); 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) ResetMagickMemory(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 p=CurrentContext->dash_pattern; 2003 q=dasharray; 2004 for (i=0; i < (ssize_t) n; i++) 2005 *q++=(*p++); 2006 *q=0.0; 2007 } 2008 return(dasharray); 2009 } 2010 2011 /* 2013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2014 % % 2015 % % 2016 % % 2017 % D r a w G e t S t r o k e D a s h O f f s e t % 2018 % % 2019 % % 2020 % % 2021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2022 % 2023 % DrawGetStrokeDashOffset() returns the offset into the dash pattern to 2024 % start the dash. 2025 % 2026 % The format of the DrawGetStrokeDashOffset method is: 2027 % 2028 % double DrawGetStrokeDashOffset(const DrawingWand *wand) 2029 % 2030 % A description of each parameter follows: 2031 % 2032 % o wand: the drawing wand. 2033 % 2034 */ 2035 WandExport double DrawGetStrokeDashOffset(const DrawingWand *wand) 2036 { 2037 assert(wand != (const DrawingWand *) NULL); 2038 assert(wand->signature == MagickWandSignature); 2039 if (wand->debug != MagickFalse) 2040 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2041 return(CurrentContext->dash_offset); 2042 } 2043 2044 /* 2046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2047 % % 2048 % % 2049 % % 2050 % D r a w G e t S t r o k e L i n e C a p % 2051 % % 2052 % % 2053 % % 2054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2055 % 2056 % DrawGetStrokeLineCap() returns the shape to be used at the end of 2057 % open subpaths when they are stroked. Values of LineCap are 2058 % UndefinedCap, ButtCap, RoundCap, and SquareCap. 2059 % 2060 % The format of the DrawGetStrokeLineCap method is: 2061 % 2062 % LineCap DrawGetStrokeLineCap(const DrawingWand *wand) 2063 % 2064 % A description of each parameter follows: 2065 % 2066 % o wand: the drawing wand. 2067 % 2068 */ 2069 WandExport LineCap DrawGetStrokeLineCap(const DrawingWand *wand) 2070 { 2071 assert(wand != (const DrawingWand *) NULL); 2072 assert(wand->signature == MagickWandSignature); 2073 if (wand->debug != MagickFalse) 2074 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2075 return(CurrentContext->linecap); 2076 } 2077 2078 /* 2080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2081 % % 2082 % % 2083 % % 2084 % D r a w G e t S t r o k e L i n e J o i n % 2085 % % 2086 % % 2087 % % 2088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2089 % 2090 % DrawGetStrokeLineJoin() returns the shape to be used at the 2091 % corners of paths (or other vector shapes) when they are 2092 % stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin, 2093 % and BevelJoin. 2094 % 2095 % The format of the DrawGetStrokeLineJoin method is: 2096 % 2097 % LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand) 2098 % 2099 % A description of each parameter follows: 2100 % 2101 % o wand: the drawing wand. 2102 % 2103 */ 2104 WandExport LineJoin DrawGetStrokeLineJoin(const DrawingWand *wand) 2105 { 2106 assert(wand != (const DrawingWand *) NULL); 2107 assert(wand->signature == MagickWandSignature); 2108 if (wand->debug != MagickFalse) 2109 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2110 return(CurrentContext->linejoin); 2111 } 2112 2113 /* 2115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2116 % % 2117 % % 2118 % % 2119 % D r a w G e t S t r o k e M i t e r L i m i t % 2120 % % 2121 % % 2122 % % 2123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2124 % 2125 % DrawGetStrokeMiterLimit() returns the miter limit. When two line 2126 % segments meet at a sharp angle and miter joins have been specified for 2127 % 'lineJoin', it is possible for the miter to extend far beyond the 2128 % thickness of the line stroking the path. The miterLimit' imposes a 2129 % limit on the ratio of the miter length to the 'lineWidth'. 2130 % 2131 % The format of the DrawGetStrokeMiterLimit method is: 2132 % 2133 % size_t DrawGetStrokeMiterLimit(const DrawingWand *wand) 2134 % 2135 % A description of each parameter follows: 2136 % 2137 % o wand: the drawing wand. 2138 % 2139 */ 2140 WandExport size_t DrawGetStrokeMiterLimit(const DrawingWand *wand) 2141 { 2142 assert(wand != (const DrawingWand *) NULL); 2143 assert(wand->signature == MagickWandSignature); 2144 if (wand->debug != MagickFalse) 2145 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2146 return CurrentContext->miterlimit; 2147 } 2148 2149 /* 2151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2152 % % 2153 % % 2154 % % 2155 % D r a w G e t S t r o k e O p a c i t y % 2156 % % 2157 % % 2158 % % 2159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2160 % 2161 % DrawGetStrokeOpacity() returns the alpha of stroked object outlines. 2162 % 2163 % The format of the DrawGetStrokeOpacity method is: 2164 % 2165 % double DrawGetStrokeOpacity(const DrawingWand *wand) 2166 % 2167 % A description of each parameter follows: 2168 % 2169 % o wand: the drawing wand. 2170 % 2171 */ 2172 WandExport double DrawGetStrokeOpacity(const DrawingWand *wand) 2173 { 2174 double 2175 alpha; 2176 2177 assert(wand != (const DrawingWand *) NULL); 2178 assert(wand->signature == MagickWandSignature); 2179 if (wand->debug != MagickFalse) 2180 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2181 alpha=(double) QuantumScale*CurrentContext->stroke.alpha; 2182 return(alpha); 2183 } 2184 2185 /* 2187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2188 % % 2189 % % 2190 % % 2191 % D r a w G e t S t r o k e W i d t h % 2192 % % 2193 % % 2194 % % 2195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2196 % 2197 % DrawGetStrokeWidth() returns the width of the stroke used to draw object 2198 % outlines. 2199 % 2200 % The format of the DrawGetStrokeWidth method is: 2201 % 2202 % double DrawGetStrokeWidth(const DrawingWand *wand) 2203 % 2204 % A description of each parameter follows: 2205 % 2206 % o wand: the drawing wand. 2207 % 2208 */ 2209 WandExport double DrawGetStrokeWidth(const DrawingWand *wand) 2210 { 2211 assert(wand != (const DrawingWand *) NULL); 2212 assert(wand->signature == MagickWandSignature); 2213 if (wand->debug != MagickFalse) 2214 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2215 return(CurrentContext->stroke_width); 2216 } 2217 2218 /* 2220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2221 % % 2222 % % 2223 % % 2224 % D r a w G e t T e x t A l i g n m e n t % 2225 % % 2226 % % 2227 % % 2228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2229 % 2230 % DrawGetTextAlignment() returns the alignment applied when annotating with 2231 % text. 2232 % 2233 % The format of the DrawGetTextAlignment method is: 2234 % 2235 % AlignType DrawGetTextAlignment(const DrawingWand *wand) 2236 % 2237 % A description of each parameter follows: 2238 % 2239 % o wand: the drawing wand. 2240 % 2241 */ 2242 WandExport AlignType DrawGetTextAlignment(const DrawingWand *wand) 2243 { 2244 assert(wand != (const DrawingWand *) NULL); 2245 assert(wand->signature == MagickWandSignature); 2246 if (wand->debug != MagickFalse) 2247 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2248 return(CurrentContext->align); 2249 } 2250 2251 /* 2253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2254 % % 2255 % % 2256 % % 2257 % D r a w G e t T e x t A n t i a l i a s % 2258 % % 2259 % % 2260 % % 2261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2262 % 2263 % DrawGetTextAntialias() returns the current text antialias setting, which 2264 % determines whether text is antialiased. Text is antialiased by default. 2265 % 2266 % The format of the DrawGetTextAntialias method is: 2267 % 2268 % MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand) 2269 % 2270 % A description of each parameter follows: 2271 % 2272 % o wand: the drawing wand. 2273 % 2274 */ 2275 WandExport MagickBooleanType DrawGetTextAntialias(const DrawingWand *wand) 2276 { 2277 assert(wand != (const DrawingWand *) NULL); 2278 assert(wand->signature == MagickWandSignature); 2279 if (wand->debug != MagickFalse) 2280 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2281 return(CurrentContext->text_antialias); 2282 } 2283 2284 /* 2286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2287 % % 2288 % % 2289 % % 2290 % D r a w G e t T e x t D e c o r a t i o n % 2291 % % 2292 % % 2293 % % 2294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2295 % 2296 % DrawGetTextDecoration() returns the decoration applied when annotating with 2297 % text. 2298 % 2299 % The format of the DrawGetTextDecoration method is: 2300 % 2301 % DecorationType DrawGetTextDecoration(const DrawingWand *wand) 2302 % 2303 % A description of each parameter follows: 2304 % 2305 % o wand: the drawing wand. 2306 % 2307 */ 2308 WandExport DecorationType DrawGetTextDecoration(const DrawingWand *wand) 2309 { 2310 assert(wand != (const DrawingWand *) NULL); 2311 assert(wand->signature == MagickWandSignature); 2312 if (wand->debug != MagickFalse) 2313 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2314 return(CurrentContext->decorate); 2315 } 2316 2317 /* 2319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2320 % % 2321 % % 2322 % % 2323 % D r a w G e t T e x t D i r e c t i o n % 2324 % % 2325 % % 2326 % % 2327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2328 % 2329 % DrawGetTextDirection() returns the direction that will be used when 2330 % annotating with text. 2331 % 2332 % The format of the DrawGetTextDirection method is: 2333 % 2334 % DirectionType DrawGetTextDirection(const DrawingWand *wand) 2335 % 2336 % A description of each parameter follows: 2337 % 2338 % o wand: the drawing wand. 2339 % 2340 */ 2341 WandExport DirectionType DrawGetTextDirection(const DrawingWand *wand) 2342 { 2343 assert(wand != (const DrawingWand *) NULL); 2344 assert(wand->signature == MagickWandSignature); 2345 if (wand->debug != MagickFalse) 2346 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2347 return(CurrentContext->direction); 2348 } 2349 2350 /* 2352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2353 % % 2354 % % 2355 % % 2356 % D r a w G e t T e x t E n c o d i n g % 2357 % % 2358 % % 2359 % % 2360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2361 % 2362 % DrawGetTextEncoding() returns a null-terminated string which specifies the 2363 % code set used for text annotations. The string must be freed by the user 2364 % once it is no longer required. 2365 % 2366 % The format of the DrawGetTextEncoding method is: 2367 % 2368 % char *DrawGetTextEncoding(const DrawingWand *wand) 2369 % 2370 % A description of each parameter follows: 2371 % 2372 % o wand: the drawing wand. 2373 % 2374 */ 2375 WandExport char *DrawGetTextEncoding(const DrawingWand *wand) 2376 { 2377 assert(wand != (const DrawingWand *) NULL); 2378 assert(wand->signature == MagickWandSignature); 2379 if (wand->debug != MagickFalse) 2380 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2381 if (CurrentContext->encoding != (char *) NULL) 2382 return((char *) AcquireString(CurrentContext->encoding)); 2383 return((char *) NULL); 2384 } 2385 2386 /* 2388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2389 % % 2390 % % 2391 % % 2392 % D r a w G e t T e x t K e r n i n g % 2393 % % 2394 % % 2395 % % 2396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2397 % 2398 % DrawGetTextKerning() gets the spacing between characters in text. 2399 % 2400 % The format of the DrawSetFontKerning method is: 2401 % 2402 % double DrawGetTextKerning(DrawingWand *wand) 2403 % 2404 % A description of each parameter follows: 2405 % 2406 % o wand: the drawing wand. 2407 % 2408 */ 2409 WandExport double DrawGetTextKerning(DrawingWand *wand) 2410 { 2411 assert(wand != (DrawingWand *) NULL); 2412 assert(wand->signature == MagickWandSignature); 2413 2414 if (wand->debug != MagickFalse) 2415 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2416 return(CurrentContext->kerning); 2417 } 2418 2419 /* 2421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2422 % % 2423 % % 2424 % % 2425 % 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 % 2426 % % 2427 % % 2428 % % 2429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2430 % 2431 % DrawGetTextInterlineSpacing() gets the spacing between lines in text. 2432 % 2433 % The format of the DrawGetTextInterlineSpacing method is: 2434 % 2435 % double DrawGetTextInterlineSpacing(DrawingWand *wand) 2436 % 2437 % A description of each parameter follows: 2438 % 2439 % o wand: the drawing wand. 2440 % 2441 */ 2442 WandExport double DrawGetTextInterlineSpacing(DrawingWand *wand) 2443 { 2444 assert(wand != (DrawingWand *) NULL); 2445 assert(wand->signature == MagickWandSignature); 2446 if (wand->debug != MagickFalse) 2447 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2448 return(CurrentContext->interline_spacing); 2449 } 2450 2451 /* 2453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2454 % % 2455 % % 2456 % % 2457 % 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 % 2458 % % 2459 % % 2460 % % 2461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2462 % 2463 % DrawGetTextInterwordSpacing() gets the spacing between words in text. 2464 % 2465 % The format of the DrawSetFontKerning method is: 2466 % 2467 % double DrawGetTextInterwordSpacing(DrawingWand *wand) 2468 % 2469 % A description of each parameter follows: 2470 % 2471 % o wand: the drawing wand. 2472 % 2473 */ 2474 WandExport double DrawGetTextInterwordSpacing(DrawingWand *wand) 2475 { 2476 assert(wand != (DrawingWand *) NULL); 2477 assert(wand->signature == MagickWandSignature); 2478 if (wand->debug != MagickFalse) 2479 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2480 return(CurrentContext->interword_spacing); 2481 } 2482 2483 /* 2485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2486 % % 2487 % % 2488 % % 2489 % D r a w G e t V e c t o r G r a p h i c s % 2490 % % 2491 % % 2492 % % 2493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2494 % 2495 % DrawGetVectorGraphics() returns a null-terminated string which specifies the 2496 % vector graphics generated by any graphics calls made since the wand was 2497 % instantiated. The string must be freed by the user once it is no longer 2498 % required. 2499 % 2500 % The format of the DrawGetVectorGraphics method is: 2501 % 2502 % char *DrawGetVectorGraphics(DrawingWand *wand) 2503 % 2504 % A description of each parameter follows: 2505 % 2506 % o wand: the drawing wand. 2507 % 2508 */ 2509 WandExport char *DrawGetVectorGraphics(DrawingWand *wand) 2510 { 2511 char 2512 value[MagickPathExtent], 2513 *xml; 2514 2515 PixelInfo 2516 pixel; 2517 2518 register ssize_t 2519 i; 2520 2521 XMLTreeInfo 2522 *child, 2523 *xml_info; 2524 2525 assert(wand != (const DrawingWand *) NULL); 2526 assert(wand->signature == MagickWandSignature); 2527 if (wand->debug != MagickFalse) 2528 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2529 xml_info=NewXMLTreeTag("drawing-wand"); 2530 if (xml_info == (XMLTreeInfo *) NULL) 2531 return((char *) NULL); 2532 (void) SetXMLTreeContent(xml_info," "); 2533 GetPixelInfo(wand->image,&pixel); 2534 child=AddChildToXMLTree(xml_info,"clip-path",0); 2535 if (child != (XMLTreeInfo *) NULL) 2536 (void) SetXMLTreeContent(child,CurrentContext->clip_mask); 2537 child=AddChildToXMLTree(xml_info,"clip-units",0); 2538 if (child != (XMLTreeInfo *) NULL) 2539 { 2540 (void) CopyMagickString(value,CommandOptionToMnemonic( 2541 MagickClipPathOptions,(ssize_t) CurrentContext->clip_units), 2542 MagickPathExtent); 2543 (void) SetXMLTreeContent(child,value); 2544 } 2545 child=AddChildToXMLTree(xml_info,"decorate",0); 2546 if (child != (XMLTreeInfo *) NULL) 2547 { 2548 (void) CopyMagickString(value,CommandOptionToMnemonic( 2549 MagickDecorateOptions,(ssize_t) CurrentContext->decorate), 2550 MagickPathExtent); 2551 (void) SetXMLTreeContent(child,value); 2552 } 2553 child=AddChildToXMLTree(xml_info,"encoding",0); 2554 if (child != (XMLTreeInfo *) NULL) 2555 (void) SetXMLTreeContent(child,CurrentContext->encoding); 2556 child=AddChildToXMLTree(xml_info,"fill",0); 2557 if (child != (XMLTreeInfo *) NULL) 2558 { 2559 if (CurrentContext->fill.alpha != OpaqueAlpha) 2560 pixel.alpha_trait=CurrentContext->fill.alpha != OpaqueAlpha ? 2561 BlendPixelTrait : UndefinedPixelTrait; 2562 pixel=CurrentContext->fill; 2563 GetColorTuple(&pixel,MagickTrue,value); 2564 (void) SetXMLTreeContent(child,value); 2565 } 2566 child=AddChildToXMLTree(xml_info,"fill-opacity",0); 2567 if (child != (XMLTreeInfo *) NULL) 2568 { 2569 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2570 (double) (QuantumScale*CurrentContext->fill.alpha)); 2571 (void) SetXMLTreeContent(child,value); 2572 } 2573 child=AddChildToXMLTree(xml_info,"fill-rule",0); 2574 if (child != (XMLTreeInfo *) NULL) 2575 { 2576 (void) CopyMagickString(value,CommandOptionToMnemonic( 2577 MagickFillRuleOptions,(ssize_t) CurrentContext->fill_rule), 2578 MagickPathExtent); 2579 (void) SetXMLTreeContent(child,value); 2580 } 2581 child=AddChildToXMLTree(xml_info,"font",0); 2582 if (child != (XMLTreeInfo *) NULL) 2583 (void) SetXMLTreeContent(child,CurrentContext->font); 2584 child=AddChildToXMLTree(xml_info,"font-family",0); 2585 if (child != (XMLTreeInfo *) NULL) 2586 (void) SetXMLTreeContent(child,CurrentContext->family); 2587 child=AddChildToXMLTree(xml_info,"font-size",0); 2588 if (child != (XMLTreeInfo *) NULL) 2589 { 2590 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2591 CurrentContext->pointsize); 2592 (void) SetXMLTreeContent(child,value); 2593 } 2594 child=AddChildToXMLTree(xml_info,"font-stretch",0); 2595 if (child != (XMLTreeInfo *) NULL) 2596 { 2597 (void) CopyMagickString(value,CommandOptionToMnemonic( 2598 MagickStretchOptions,(ssize_t) CurrentContext->stretch), 2599 MagickPathExtent); 2600 (void) SetXMLTreeContent(child,value); 2601 } 2602 child=AddChildToXMLTree(xml_info,"font-style",0); 2603 if (child != (XMLTreeInfo *) NULL) 2604 { 2605 (void) CopyMagickString(value,CommandOptionToMnemonic( 2606 MagickStyleOptions,(ssize_t) CurrentContext->style),MagickPathExtent); 2607 (void) SetXMLTreeContent(child,value); 2608 } 2609 child=AddChildToXMLTree(xml_info,"font-weight",0); 2610 if (child != (XMLTreeInfo *) NULL) 2611 { 2612 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double) 2613 CurrentContext->weight); 2614 (void) SetXMLTreeContent(child,value); 2615 } 2616 child=AddChildToXMLTree(xml_info,"gravity",0); 2617 if (child != (XMLTreeInfo *) NULL) 2618 { 2619 (void) CopyMagickString(value,CommandOptionToMnemonic( 2620 MagickGravityOptions,(ssize_t) CurrentContext->gravity), 2621 MagickPathExtent); 2622 (void) SetXMLTreeContent(child,value); 2623 } 2624 child=AddChildToXMLTree(xml_info,"stroke",0); 2625 if (child != (XMLTreeInfo *) NULL) 2626 { 2627 if (CurrentContext->stroke.alpha != OpaqueAlpha) 2628 pixel.alpha_trait=CurrentContext->stroke.alpha != OpaqueAlpha ? 2629 BlendPixelTrait : UndefinedPixelTrait; 2630 pixel=CurrentContext->stroke; 2631 GetColorTuple(&pixel,MagickTrue,value); 2632 (void) SetXMLTreeContent(child,value); 2633 } 2634 child=AddChildToXMLTree(xml_info,"stroke-antialias",0); 2635 if (child != (XMLTreeInfo *) NULL) 2636 { 2637 (void) FormatLocaleString(value,MagickPathExtent,"%d", 2638 CurrentContext->stroke_antialias != MagickFalse ? 1 : 0); 2639 (void) SetXMLTreeContent(child,value); 2640 } 2641 child=AddChildToXMLTree(xml_info,"stroke-dasharray",0); 2642 if ((child != (XMLTreeInfo *) NULL) && 2643 (CurrentContext->dash_pattern != (double *) NULL)) 2644 { 2645 char 2646 *dash_pattern; 2647 2648 dash_pattern=AcquireString((char *) NULL); 2649 for (i=0; fabs(CurrentContext->dash_pattern[i]) >= MagickEpsilon; i++) 2650 { 2651 if (i != 0) 2652 (void) ConcatenateString(&dash_pattern,","); 2653 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2654 CurrentContext->dash_pattern[i]); 2655 (void) ConcatenateString(&dash_pattern,value); 2656 } 2657 (void) SetXMLTreeContent(child,dash_pattern); 2658 dash_pattern=DestroyString(dash_pattern); 2659 } 2660 child=AddChildToXMLTree(xml_info,"stroke-dashoffset",0); 2661 if (child != (XMLTreeInfo *) NULL) 2662 { 2663 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2664 CurrentContext->dash_offset); 2665 (void) SetXMLTreeContent(child,value); 2666 } 2667 child=AddChildToXMLTree(xml_info,"stroke-linecap",0); 2668 if (child != (XMLTreeInfo *) NULL) 2669 { 2670 (void) CopyMagickString(value,CommandOptionToMnemonic( 2671 MagickLineCapOptions,(ssize_t) CurrentContext->linecap), 2672 MagickPathExtent); 2673 (void) SetXMLTreeContent(child,value); 2674 } 2675 child=AddChildToXMLTree(xml_info,"stroke-linejoin",0); 2676 if (child != (XMLTreeInfo *) NULL) 2677 { 2678 (void) CopyMagickString(value,CommandOptionToMnemonic( 2679 MagickLineJoinOptions,(ssize_t) CurrentContext->linejoin), 2680 MagickPathExtent); 2681 (void) SetXMLTreeContent(child,value); 2682 } 2683 child=AddChildToXMLTree(xml_info,"stroke-miterlimit",0); 2684 if (child != (XMLTreeInfo *) NULL) 2685 { 2686 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",(double) 2687 CurrentContext->miterlimit); 2688 (void) SetXMLTreeContent(child,value); 2689 } 2690 child=AddChildToXMLTree(xml_info,"stroke-opacity",0); 2691 if (child != (XMLTreeInfo *) NULL) 2692 { 2693 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2694 (double) (QuantumScale*CurrentContext->stroke.alpha)); 2695 (void) SetXMLTreeContent(child,value); 2696 } 2697 child=AddChildToXMLTree(xml_info,"stroke-width",0); 2698 if (child != (XMLTreeInfo *) NULL) 2699 { 2700 (void) FormatLocaleString(value,MagickPathExtent,"%.20g", 2701 CurrentContext->stroke_width); 2702 (void) SetXMLTreeContent(child,value); 2703 } 2704 child=AddChildToXMLTree(xml_info,"text-align",0); 2705 if (child != (XMLTreeInfo *) NULL) 2706 { 2707 (void) CopyMagickString(value,CommandOptionToMnemonic(MagickAlignOptions, 2708 (ssize_t) CurrentContext->align),MagickPathExtent); 2709 (void) SetXMLTreeContent(child,value); 2710 } 2711 child=AddChildToXMLTree(xml_info,"text-antialias",0); 2712 if (child != (XMLTreeInfo *) NULL) 2713 { 2714 (void) FormatLocaleString(value,MagickPathExtent,"%d", 2715 CurrentContext->text_antialias != MagickFalse ? 1 : 0); 2716 (void) SetXMLTreeContent(child,value); 2717 } 2718 child=AddChildToXMLTree(xml_info,"text-undercolor",0); 2719 if (child != (XMLTreeInfo *) NULL) 2720 { 2721 if (CurrentContext->undercolor.alpha != OpaqueAlpha) 2722 pixel.alpha_trait=CurrentContext->undercolor.alpha != OpaqueAlpha ? 2723 BlendPixelTrait : UndefinedPixelTrait; 2724 pixel=CurrentContext->undercolor; 2725 GetColorTuple(&pixel,MagickTrue,value); 2726 (void) SetXMLTreeContent(child,value); 2727 } 2728 child=AddChildToXMLTree(xml_info,"vector-graphics",0); 2729 if (child != (XMLTreeInfo *) NULL) 2730 (void) SetXMLTreeContent(child,wand->mvg); 2731 xml=XMLTreeInfoToXML(xml_info); 2732 xml_info=DestroyXMLTree(xml_info); 2733 return(xml); 2734 } 2735 2736 /* 2738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2739 % % 2740 % % 2741 % % 2742 % D r a w G e t T e x t U n d e r C o l o r % 2743 % % 2744 % % 2745 % % 2746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2747 % 2748 % DrawGetTextUnderColor() returns the color of a background rectangle 2749 % to place under text annotations. 2750 % 2751 % The format of the DrawGetTextUnderColor method is: 2752 % 2753 % void DrawGetTextUnderColor(const DrawingWand *wand, 2754 % PixelWand *under_color) 2755 % 2756 % A description of each parameter follows: 2757 % 2758 % o wand: the drawing wand. 2759 % 2760 % o under_color: Return the under color. 2761 % 2762 */ 2763 WandExport void DrawGetTextUnderColor(const DrawingWand *wand, 2764 PixelWand *under_color) 2765 { 2766 assert(wand != (const DrawingWand *) NULL); 2767 assert(wand->signature == MagickWandSignature); 2768 assert(under_color != (PixelWand *) NULL); 2769 if (wand->debug != MagickFalse) 2770 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2771 PixelSetPixelColor(under_color,&CurrentContext->undercolor); 2772 } 2773 2774 /* 2776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2777 % % 2778 % % 2779 % % 2780 % D r a w L i n e % 2781 % % 2782 % % 2783 % % 2784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2785 % 2786 % DrawLine() draws a line on the image using the current stroke color, 2787 % stroke alpha, and stroke width. 2788 % 2789 % The format of the DrawLine method is: 2790 % 2791 % void DrawLine(DrawingWand *wand,const double sx,const double sy, 2792 % const double ex,const double ey) 2793 % 2794 % A description of each parameter follows: 2795 % 2796 % o wand: the drawing wand. 2797 % 2798 % o sx: starting x ordinate 2799 % 2800 % o sy: starting y ordinate 2801 % 2802 % o ex: ending x ordinate 2803 % 2804 % o ey: ending y ordinate 2805 % 2806 */ 2807 WandExport void DrawLine(DrawingWand *wand,const double sx,const double sy, 2808 const double ex,const double ey) 2809 { 2810 assert(wand != (DrawingWand *) NULL); 2811 assert(wand->signature == MagickWandSignature); 2812 if (wand->debug != MagickFalse) 2813 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2814 (void) MVGPrintf(wand,"line %.20g %.20g %.20g %.20g\n",sx,sy,ex,ey); 2815 } 2816 2817 /* 2819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2820 % % 2821 % % 2822 % % 2823 % D r a w P a t h C l o s e % 2824 % % 2825 % % 2826 % % 2827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2828 % 2829 % DrawPathClose() adds a path element to the current path which closes the 2830 % current subpath by drawing a straight line from the current point to the 2831 % current subpath's most recent starting point (usually, the most recent 2832 % moveto point). 2833 % 2834 % The format of the DrawPathClose method is: 2835 % 2836 % void DrawPathClose(DrawingWand *wand) 2837 % 2838 % A description of each parameter follows: 2839 % 2840 % o wand: the drawing wand. 2841 % 2842 */ 2843 WandExport void DrawPathClose(DrawingWand *wand) 2844 { 2845 assert(wand != (DrawingWand *) NULL); 2846 assert(wand->signature == MagickWandSignature); 2847 if (wand->debug != MagickFalse) 2848 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2849 (void) MVGAutoWrapPrintf(wand,"%s",wand->path_mode == AbsolutePathMode ? 2850 "Z" : "z"); 2851 } 2852 2853 /* 2855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2856 % % 2857 % % 2858 % % 2859 % D r a w P a t h C u r v e T o A b s o l u t e % 2860 % % 2861 % % 2862 % % 2863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2864 % 2865 % DrawPathCurveToAbsolute() draws a cubic Bezier curve from the current 2866 % point to (x,y) using (x1,y1) as the control point at the beginning of 2867 % the curve and (x2,y2) as the control point at the end of the curve using 2868 % absolute coordinates. At the end of the command, the new current point 2869 % becomes the final (x,y) coordinate pair used in the polybezier. 2870 % 2871 % The format of the DrawPathCurveToAbsolute method is: 2872 % 2873 % void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1, 2874 % const double y1,const double x2,const double y2,const double x, 2875 % const double y) 2876 % 2877 % A description of each parameter follows: 2878 % 2879 % o wand: the drawing wand. 2880 % 2881 % o x1: x ordinate of control point for curve beginning 2882 % 2883 % o y1: y ordinate of control point for curve beginning 2884 % 2885 % o x2: x ordinate of control point for curve ending 2886 % 2887 % o y2: y ordinate of control point for curve ending 2888 % 2889 % o x: x ordinate of the end of the curve 2890 % 2891 % o y: y ordinate of the end of the curve 2892 % 2893 */ 2894 2895 static void DrawPathCurveTo(DrawingWand *wand,const PathMode mode, 2896 const double x1,const double y1,const double x2,const double y2, 2897 const double x,const double y) 2898 { 2899 assert(wand != (DrawingWand *) NULL); 2900 assert(wand->signature == MagickWandSignature); 2901 if (wand->debug != MagickFalse) 2902 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2903 if ((wand->path_operation != PathCurveToOperation) || 2904 (wand->path_mode != mode)) 2905 { 2906 wand->path_operation=PathCurveToOperation; 2907 wand->path_mode=mode; 2908 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g %.20g %.20g", 2909 mode == AbsolutePathMode ? 'C' : 'c',x1,y1,x2,y2,x,y); 2910 } 2911 else 2912 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g %.20g %.20g",x1,y1, 2913 x2,y2,x,y); 2914 } 2915 2916 WandExport void DrawPathCurveToAbsolute(DrawingWand *wand,const double x1, 2917 const double y1,const double x2,const double y2,const double x,const double y) 2918 { 2919 assert(wand != (DrawingWand *) NULL); 2920 assert(wand->signature == MagickWandSignature); 2921 if (wand->debug != MagickFalse) 2922 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2923 DrawPathCurveTo(wand,AbsolutePathMode,x1,y1,x2,y2,x,y); 2924 } 2925 2926 /* 2928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2929 % % 2930 % % 2931 % % 2932 % D r a w P a t h C u r v e T o R e l a t i v e % 2933 % % 2934 % % 2935 % % 2936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2937 % 2938 % DrawPathCurveToRelative() draws a cubic Bezier curve from the current 2939 % point to (x,y) using (x1,y1) as the control point at the beginning of 2940 % the curve and (x2,y2) as the control point at the end of the curve using 2941 % relative coordinates. At the end of the command, the new current point 2942 % becomes the final (x,y) coordinate pair used in the polybezier. 2943 % 2944 % The format of the DrawPathCurveToRelative method is: 2945 % 2946 % void DrawPathCurveToRelative(DrawingWand *wand,const double x1, 2947 % const double y1,const double x2,const double y2,const double x, 2948 % const double y) 2949 % 2950 % A description of each parameter follows: 2951 % 2952 % o wand: the drawing wand. 2953 % 2954 % o x1: x ordinate of control point for curve beginning 2955 % 2956 % o y1: y ordinate of control point for curve beginning 2957 % 2958 % o x2: x ordinate of control point for curve ending 2959 % 2960 % o y2: y ordinate of control point for curve ending 2961 % 2962 % o x: x ordinate of the end of the curve 2963 % 2964 % o y: y ordinate of the end of the curve 2965 % 2966 */ 2967 WandExport void DrawPathCurveToRelative(DrawingWand *wand,const double x1, 2968 const double y1,const double x2,const double y2,const double x,const double y) 2969 { 2970 assert(wand != (DrawingWand *) NULL); 2971 assert(wand->signature == MagickWandSignature); 2972 if (wand->debug != MagickFalse) 2973 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 2974 DrawPathCurveTo(wand,RelativePathMode,x1,y1,x2,y2,x,y); 2975 } 2976 2977 /* 2979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2980 % % 2981 % % 2982 % % 2983 % 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 % 2984 % % 2985 % % 2986 % % 2987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2988 % 2989 % DrawPathCurveToQuadraticBezierAbsolute() draws a quadratic Bezier curve 2990 % from the current point to (x,y) using (x1,y1) as the control point using 2991 % absolute coordinates. At the end of the command, the new current point 2992 % becomes the final (x,y) coordinate pair used in the polybezier. 2993 % 2994 % The format of the DrawPathCurveToQuadraticBezierAbsolute method is: 2995 % 2996 % void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand, 2997 % const double x1,const double y1,onst double x,const double y) 2998 % 2999 % A description of each parameter follows: 3000 % 3001 % o wand: the drawing wand. 3002 % 3003 % o x1: x ordinate of the control point 3004 % 3005 % o y1: y ordinate of the control point 3006 % 3007 % o x: x ordinate of final point 3008 % 3009 % o y: y ordinate of final point 3010 % 3011 */ 3012 3013 static void DrawPathCurveToQuadraticBezier(DrawingWand *wand, 3014 const PathMode mode,const double x1,double y1,const double x,const double y) 3015 { 3016 assert(wand != (DrawingWand *) NULL); 3017 assert(wand->signature == MagickWandSignature); 3018 if (wand->debug != MagickFalse) 3019 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3020 if ((wand->path_operation != PathCurveToQuadraticBezierOperation) || 3021 (wand->path_mode != mode)) 3022 { 3023 wand->path_operation=PathCurveToQuadraticBezierOperation; 3024 wand->path_mode=mode; 3025 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %.20g", 3026 mode == AbsolutePathMode ? 'Q' : 'q',x1,y1,x,y); 3027 } 3028 else 3029 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x1,y1,x,y); 3030 } 3031 3032 WandExport void DrawPathCurveToQuadraticBezierAbsolute(DrawingWand *wand, 3033 const double x1,const double y1,const double x,const double y) 3034 { 3035 assert(wand != (DrawingWand *) NULL); 3036 assert(wand->signature == MagickWandSignature); 3037 if (wand->debug != MagickFalse) 3038 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3039 DrawPathCurveToQuadraticBezier(wand,AbsolutePathMode,x1,y1,x,y); 3040 } 3041 3042 /* 3044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3045 % % 3046 % % 3047 % % 3048 % 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 % 3049 % % 3050 % % 3051 % % 3052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3053 % 3054 % DrawPathCurveToQuadraticBezierRelative() draws a quadratic Bezier curve 3055 % from the current point to (x,y) using (x1,y1) as the control point using 3056 % relative coordinates. At the end of the command, the new current point 3057 % becomes the final (x,y) coordinate pair used in the polybezier. 3058 % 3059 % The format of the DrawPathCurveToQuadraticBezierRelative method is: 3060 % 3061 % void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand, 3062 % const double x1,const double y1,const double x,const double y) 3063 % 3064 % A description of each parameter follows: 3065 % 3066 % o wand: the drawing wand. 3067 % 3068 % o x1: x ordinate of the control point 3069 % 3070 % o y1: y ordinate of the control point 3071 % 3072 % o x: x ordinate of final point 3073 % 3074 % o y: y ordinate of final point 3075 % 3076 */ 3077 WandExport void DrawPathCurveToQuadraticBezierRelative(DrawingWand *wand, 3078 const double x1,const double y1,const double x,const double y) 3079 { 3080 assert(wand != (DrawingWand *) NULL); 3081 assert(wand->signature == MagickWandSignature); 3082 if (wand->debug != MagickFalse) 3083 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3084 DrawPathCurveToQuadraticBezier(wand,RelativePathMode,x1,y1,x,y); 3085 } 3086 3087 /* 3089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3090 % % 3091 % % 3092 % % 3093 % 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 % 3094 % % 3095 % % 3096 % % 3097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3098 % 3099 % DrawPathCurveToQuadraticBezierSmoothAbsolute() draws a quadratic 3100 % Bezier curve (using absolute coordinates) from the current point to 3101 % (x,y). The control point is assumed to be the reflection of the 3102 % control point on the previous command relative to the current 3103 % point. (If there is no previous command or if the previous command was 3104 % not a DrawPathCurveToQuadraticBezierAbsolute, 3105 % DrawPathCurveToQuadraticBezierRelative, 3106 % DrawPathCurveToQuadraticBezierSmoothAbsolute or 3107 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point 3108 % is coincident with the current point.). At the end of the command, the 3109 % new current point becomes the final (x,y) coordinate pair used in the 3110 % polybezier. 3111 % 3112 % The format of the DrawPathCurveToQuadraticBezierSmoothAbsolute method is: 3113 % 3114 % void DrawPathCurveToQuadraticBezierSmoothAbsolute( 3115 % DrawingWand *wand,const double x,const double y) 3116 % 3117 % A description of each parameter follows: 3118 % 3119 % o wand: the drawing wand. 3120 % 3121 % o x: x ordinate of final point 3122 % 3123 % o y: y ordinate of final point 3124 % 3125 */ 3126 3127 static void DrawPathCurveToQuadraticBezierSmooth(DrawingWand *wand, 3128 const PathMode mode,const double x,const double y) 3129 { 3130 assert(wand != (DrawingWand *) NULL); 3131 assert(wand->signature == MagickWandSignature); 3132 if (wand->debug != MagickFalse) 3133 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3134 if ((wand->path_operation != PathCurveToQuadraticBezierSmoothOperation) || 3135 (wand->path_mode != mode)) 3136 { 3137 wand->path_operation=PathCurveToQuadraticBezierSmoothOperation; 3138 wand->path_mode=mode; 3139 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ? 3140 'T' : 't',x,y); 3141 } 3142 else 3143 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y); 3144 } 3145 3146 WandExport void DrawPathCurveToQuadraticBezierSmoothAbsolute(DrawingWand *wand, 3147 const double x,const double y) 3148 { 3149 assert(wand != (DrawingWand *) NULL); 3150 assert(wand->signature == MagickWandSignature); 3151 if (wand->debug != MagickFalse) 3152 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3153 DrawPathCurveToQuadraticBezierSmooth(wand,AbsolutePathMode,x,y); 3154 } 3155 3156 /* 3158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3159 % % 3160 % % 3161 % % 3162 % 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 % 3163 % % 3164 % % 3165 % % 3166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3167 % 3168 % DrawPathCurveToQuadraticBezierSmoothRelative() draws a quadratic Bezier 3169 % curve (using relative coordinates) from the current point to (x,y). The 3170 % control point is assumed to be the reflection of the control point on the 3171 % previous command relative to the current point. (If there is no previous 3172 % command or if the previous command was not a 3173 % DrawPathCurveToQuadraticBezierAbsolute, 3174 % DrawPathCurveToQuadraticBezierRelative, 3175 % DrawPathCurveToQuadraticBezierSmoothAbsolute or 3176 % DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is 3177 % coincident with the current point.). At the end of the command, the new 3178 % current point becomes the final (x,y) coordinate pair used in the polybezier. 3179 % 3180 % The format of the DrawPathCurveToQuadraticBezierSmoothRelative method is: 3181 % 3182 % void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand, 3183 % const double x,const double y) 3184 % 3185 % A description of each parameter follows: 3186 % 3187 % o wand: the drawing wand. 3188 % 3189 % o x: x ordinate of final point 3190 % 3191 % o y: y ordinate of final point 3192 % 3193 */ 3194 WandExport void DrawPathCurveToQuadraticBezierSmoothRelative(DrawingWand *wand, 3195 const double x,const double y) 3196 { 3197 DrawPathCurveToQuadraticBezierSmooth(wand,RelativePathMode,x,y); 3198 } 3199 3200 /* 3202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3203 % % 3204 % % 3205 % % 3206 % 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 % 3207 % % 3208 % % 3209 % % 3210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3211 % 3212 % DrawPathCurveToSmoothAbsolute() draws a cubic Bezier curve from the 3213 % current point to (x,y) using absolute coordinates. The first control 3214 % point is assumed to be the reflection of the second control point on 3215 % the previous command relative to the current point. (If there is no 3216 % previous command or if the previous command was not an 3217 % DrawPathCurveToAbsolute, DrawPathCurveToRelative, 3218 % DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume 3219 % the first control point is coincident with the current point.) (x2,y2) 3220 % is the second control point (i.e., the control point at the end of the 3221 % curve). At the end of the command, the new current point becomes the 3222 % final (x,y) coordinate pair used in the polybezier. 3223 % 3224 % The format of the DrawPathCurveToSmoothAbsolute method is: 3225 % 3226 % void DrawPathCurveToSmoothAbsolute(DrawingWand *wand, 3227 % const double x2,const double y2,const double x,const double y) 3228 % 3229 % A description of each parameter follows: 3230 % 3231 % o wand: the drawing wand. 3232 % 3233 % o x2: x ordinate of second control point 3234 % 3235 % o y2: y ordinate of second control point 3236 % 3237 % o x: x ordinate of termination point 3238 % 3239 % o y: y ordinate of termination point 3240 % 3241 */ 3242 3243 static void DrawPathCurveToSmooth(DrawingWand *wand,const PathMode mode, 3244 const double x2,const double y2,const double x,const double y) 3245 { 3246 assert(wand != (DrawingWand *) NULL); 3247 assert(wand->signature == MagickWandSignature); 3248 if (wand->debug != MagickFalse) 3249 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3250 if ((wand->path_operation != PathCurveToSmoothOperation) || 3251 (wand->path_mode != mode)) 3252 { 3253 wand->path_operation=PathCurveToSmoothOperation; 3254 wand->path_mode=mode; 3255 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g %.20g %.20g", 3256 mode == AbsolutePathMode ? 'S' : 's',x2,y2,x,y); 3257 } 3258 else 3259 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %.20g",x2,y2,x,y); 3260 } 3261 3262 WandExport void DrawPathCurveToSmoothAbsolute(DrawingWand *wand,const double x2, 3263 const double y2,const double x,const double y) 3264 { 3265 assert(wand != (DrawingWand *) NULL); 3266 assert(wand->signature == MagickWandSignature); 3267 if (wand->debug != MagickFalse) 3268 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3269 DrawPathCurveToSmooth(wand,AbsolutePathMode,x2,y2,x,y); 3270 } 3271 3272 /* 3274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3275 % % 3276 % % 3277 % % 3278 % 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 % 3279 % % 3280 % % 3281 % % 3282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3283 % 3284 % DrawPathCurveToSmoothRelative() draws a cubic Bezier curve from the current 3285 % point to (x,y) using relative coordinates. The first control point is 3286 % assumed to be the reflection of the second control point on the previous 3287 % command relative to the current point. (If there is no previous command or 3288 % if the previous command was not an DrawPathCurveToAbsolute, 3289 % DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or 3290 % DrawPathCurveToSmoothRelative, assume the first control point is coincident 3291 % with the current point.) (x2,y2) is the second control point (i.e., the 3292 % control point at the end of the curve). At the end of the command, the new 3293 % current point becomes the final (x,y) coordinate pair used in the polybezier. 3294 % 3295 % The format of the DrawPathCurveToSmoothRelative method is: 3296 % 3297 % void DrawPathCurveToSmoothRelative(DrawingWand *wand, 3298 % const double x2,const double y2,const double x,const double y) 3299 % 3300 % A description of each parameter follows: 3301 % 3302 % o wand: the drawing wand. 3303 % 3304 % o x2: x ordinate of second control point 3305 % 3306 % o y2: y ordinate of second control point 3307 % 3308 % o x: x ordinate of termination point 3309 % 3310 % o y: y ordinate of termination point 3311 % 3312 */ 3313 WandExport void DrawPathCurveToSmoothRelative(DrawingWand *wand,const double x2, 3314 const double y2,const double x,const double y) 3315 { 3316 assert(wand != (DrawingWand *) NULL); 3317 assert(wand->signature == MagickWandSignature); 3318 if (wand->debug != MagickFalse) 3319 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3320 DrawPathCurveToSmooth(wand,RelativePathMode,x2,y2,x,y); 3321 } 3322 3323 /* 3325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3326 % % 3327 % % 3328 % % 3329 % 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 % 3330 % % 3331 % % 3332 % % 3333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3334 % 3335 % DrawPathEllipticArcAbsolute() draws an elliptical arc from the current point 3336 % to (x, y) using absolute coordinates. The size and orientation of the 3337 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which 3338 % indicates how the ellipse as a whole is rotated relative to the current 3339 % coordinate system. The center (cx, cy) of the ellipse is calculated 3340 % automagically to satisfy the constraints imposed by the other parameters. 3341 % largeArcFlag and sweepFlag contribute to the automatic calculations and help 3342 % determine how the arc is drawn. If largeArcFlag is true then draw the larger 3343 % of the available arcs. If sweepFlag is true, then draw the arc matching a 3344 % clock-wise rotation. 3345 % 3346 % The format of the DrawPathEllipticArcAbsolute method is: 3347 % 3348 % void DrawPathEllipticArcAbsolute(DrawingWand *wand, 3349 % const double rx,const double ry,const double x_axis_rotation, 3350 % const MagickBooleanType large_arc_flag, 3351 % const MagickBooleanType sweep_flag,const double x,const double y) 3352 % 3353 % A description of each parameter follows: 3354 % 3355 % o wand: the drawing wand. 3356 % 3357 % o rx: x radius 3358 % 3359 % o ry: y radius 3360 % 3361 % o x_axis_rotation: indicates how the ellipse as a whole is rotated 3362 % relative to the current coordinate system 3363 % 3364 % o large_arc_flag: If non-zero (true) then draw the larger of the 3365 % available arcs 3366 % 3367 % o sweep_flag: If non-zero (true) then draw the arc matching a 3368 % clock-wise rotation 3369 % 3370 % 3371 */ 3372 3373 static void DrawPathEllipticArc(DrawingWand *wand, const PathMode mode, 3374 const double rx,const double ry,const double x_axis_rotation, 3375 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag, 3376 const double x,const double y) 3377 { 3378 assert(wand != (DrawingWand *) NULL); 3379 assert(wand->signature == MagickWandSignature); 3380 if (wand->debug != MagickFalse) 3381 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3382 if ((wand->path_operation != PathEllipticArcOperation) || 3383 (wand->path_mode != mode)) 3384 { 3385 wand->path_operation=PathEllipticArcOperation; 3386 wand->path_mode=mode; 3387 (void) MVGAutoWrapPrintf(wand, "%c%.20g %.20g %.20g %u %u %.20g %.20g", 3388 mode == AbsolutePathMode ? 'A' : 'a',rx,ry,x_axis_rotation, 3389 large_arc_flag,sweep_flag,x,y); 3390 } 3391 else 3392 (void) MVGAutoWrapPrintf(wand," %.20g %.20g %.20g %u %u %.20g %.20g",rx,ry, 3393 x_axis_rotation,large_arc_flag,sweep_flag,x,y); 3394 } 3395 3396 WandExport void DrawPathEllipticArcAbsolute(DrawingWand *wand,const double rx, 3397 const double ry,const double x_axis_rotation, 3398 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag, 3399 const double x,const double y) 3400 { 3401 assert(wand != (DrawingWand *) NULL); 3402 assert(wand->signature == MagickWandSignature); 3403 if (wand->debug != MagickFalse) 3404 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3405 DrawPathEllipticArc(wand,AbsolutePathMode,rx,ry,x_axis_rotation, 3406 large_arc_flag,sweep_flag,x,y); 3407 } 3408 3409 /* 3411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3412 % % 3413 % % 3414 % % 3415 % 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 % 3416 % % 3417 % % 3418 % % 3419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3420 % 3421 % DrawPathEllipticArcRelative() draws an elliptical arc from the current point 3422 % to (x, y) using relative coordinates. The size and orientation of the 3423 % ellipse are defined by two radii (rx, ry) and an xAxisRotation, which 3424 % indicates how the ellipse as a whole is rotated relative to the current 3425 % coordinate system. The center (cx, cy) of the ellipse is calculated 3426 % automagically to satisfy the constraints imposed by the other parameters. 3427 % largeArcFlag and sweepFlag contribute to the automatic calculations and help 3428 % determine how the arc is drawn. If largeArcFlag is true then draw the larger 3429 % of the available arcs. If sweepFlag is true, then draw the arc matching a 3430 % clock-wise rotation. 3431 % 3432 % The format of the DrawPathEllipticArcRelative method is: 3433 % 3434 % void DrawPathEllipticArcRelative(DrawingWand *wand, 3435 % const double rx,const double ry,const double x_axis_rotation, 3436 % const MagickBooleanType large_arc_flag, 3437 % const MagickBooleanType sweep_flag,const double x,const double y) 3438 % 3439 % A description of each parameter follows: 3440 % 3441 % o wand: the drawing wand. 3442 % 3443 % o rx: x radius 3444 % 3445 % o ry: y radius 3446 % 3447 % o x_axis_rotation: indicates how the ellipse as a whole is rotated 3448 % relative to the current coordinate system 3449 % 3450 % o large_arc_flag: If non-zero (true) then draw the larger of the 3451 % available arcs 3452 % 3453 % o sweep_flag: If non-zero (true) then draw the arc matching a 3454 % clock-wise rotation 3455 % 3456 */ 3457 WandExport void DrawPathEllipticArcRelative(DrawingWand *wand,const double rx, 3458 const double ry,const double x_axis_rotation, 3459 const MagickBooleanType large_arc_flag,const MagickBooleanType sweep_flag, 3460 const double x,const double y) 3461 { 3462 DrawPathEllipticArc(wand,RelativePathMode,rx,ry,x_axis_rotation, 3463 large_arc_flag,sweep_flag,x,y); 3464 } 3465 3466 /* 3468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3469 % % 3470 % % 3471 % % 3472 % D r a w P a t h F i n i s h % 3473 % % 3474 % % 3475 % % 3476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3477 % 3478 % DrawPathFinish() terminates the current path. 3479 % 3480 % The format of the DrawPathFinish method is: 3481 % 3482 % void DrawPathFinish(DrawingWand *wand) 3483 % 3484 % A description of each parameter follows: 3485 % 3486 % o wand: the drawing wand. 3487 % 3488 */ 3489 WandExport void DrawPathFinish(DrawingWand *wand) 3490 { 3491 assert(wand != (DrawingWand *) NULL); 3492 assert(wand->signature == MagickWandSignature); 3493 if (wand->debug != MagickFalse) 3494 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3495 (void) MVGPrintf(wand,"'\n"); 3496 wand->path_operation=PathDefaultOperation; 3497 wand->path_mode=DefaultPathMode; 3498 } 3499 3500 /* 3502 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3503 % % 3504 % % 3505 % % 3506 % D r a w P a t h L i n e T o A b s o l u t e % 3507 % % 3508 % % 3509 % % 3510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3511 % 3512 % DrawPathLineToAbsolute() draws a line path from the current point to the 3513 % given coordinate using absolute coordinates. The coordinate then becomes 3514 % the new current point. 3515 % 3516 % The format of the DrawPathLineToAbsolute method is: 3517 % 3518 % void DrawPathLineToAbsolute(DrawingWand *wand,const double x, 3519 % const double y) 3520 % 3521 % A description of each parameter follows: 3522 % 3523 % o wand: the drawing wand. 3524 % 3525 % o x: target x ordinate 3526 % 3527 % o y: target y ordinate 3528 % 3529 */ 3530 static void DrawPathLineTo(DrawingWand *wand,const PathMode mode, 3531 const double x,const double y) 3532 { 3533 assert(wand != (DrawingWand *) NULL); 3534 assert(wand->signature == MagickWandSignature); 3535 if (wand->debug != MagickFalse) 3536 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3537 if ((wand->path_operation != PathLineToOperation) || 3538 (wand->path_mode != mode)) 3539 { 3540 wand->path_operation=PathLineToOperation; 3541 wand->path_mode=mode; 3542 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ? 3543 'L' : 'l',x,y); 3544 } 3545 else 3546 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y); 3547 } 3548 3549 WandExport void DrawPathLineToAbsolute(DrawingWand *wand,const double x, 3550 const double y) 3551 { 3552 assert(wand != (DrawingWand *) NULL); 3553 assert(wand->signature == MagickWandSignature); 3554 if (wand->debug != MagickFalse) 3555 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3556 DrawPathLineTo(wand,AbsolutePathMode,x,y); 3557 } 3558 3559 /* 3561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3562 % % 3563 % % 3564 % % 3565 % D r a w P a t h L i n e T o R e l a t i v e % 3566 % % 3567 % % 3568 % % 3569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3570 % 3571 % DrawPathLineToRelative() draws a line path from the current point to the 3572 % given coordinate using relative coordinates. The coordinate then becomes 3573 % the new current point. 3574 % 3575 % The format of the DrawPathLineToRelative method is: 3576 % 3577 % void DrawPathLineToRelative(DrawingWand *wand,const double x, 3578 % const double y) 3579 % 3580 % A description of each parameter follows: 3581 % 3582 % o wand: the drawing wand. 3583 % 3584 % o x: target x ordinate 3585 % 3586 % o y: target y ordinate 3587 % 3588 */ 3589 WandExport void DrawPathLineToRelative(DrawingWand *wand,const double x, 3590 const double y) 3591 { 3592 assert(wand != (DrawingWand *) NULL); 3593 assert(wand->signature == MagickWandSignature); 3594 if (wand->debug != MagickFalse) 3595 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3596 DrawPathLineTo(wand,RelativePathMode,x,y); 3597 } 3598 3599 /* 3601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3602 % % 3603 % % 3604 % % 3605 % 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 % 3606 % % 3607 % % 3608 % % 3609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3610 % 3611 % DrawPathLineToHorizontalAbsolute() draws a horizontal line path from the 3612 % current point to the target point using absolute coordinates. The target 3613 % point then becomes the new current point. 3614 % 3615 % The format of the DrawPathLineToHorizontalAbsolute method is: 3616 % 3617 % void DrawPathLineToHorizontalAbsolute(DrawingWand *wand,const double x) 3618 % 3619 % A description of each parameter follows: 3620 % 3621 % o wand: the drawing wand. 3622 % 3623 % o x: target x ordinate 3624 % 3625 */ 3626 3627 static void DrawPathLineToHorizontal(DrawingWand *wand,const PathMode mode, 3628 const double x) 3629 { 3630 assert(wand != (DrawingWand *) NULL); 3631 assert(wand->signature == MagickWandSignature); 3632 if (wand->debug != MagickFalse) 3633 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3634 if ((wand->path_operation != PathLineToHorizontalOperation) || 3635 (wand->path_mode != mode)) 3636 { 3637 wand->path_operation=PathLineToHorizontalOperation; 3638 wand->path_mode=mode; 3639 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ? 3640 'H' : 'h',x); 3641 } 3642 else 3643 (void) MVGAutoWrapPrintf(wand," %.20g",x); 3644 } 3645 3646 WandExport void DrawPathLineToHorizontalAbsolute(DrawingWand *wand, 3647 const double x) 3648 { 3649 assert(wand != (DrawingWand *) NULL); 3650 assert(wand->signature == MagickWandSignature); 3651 if (wand->debug != MagickFalse) 3652 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3653 DrawPathLineToHorizontal(wand,AbsolutePathMode,x); 3654 } 3655 3656 /* 3658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3659 % % 3660 % % 3661 % % 3662 % 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 % 3663 % % 3664 % % 3665 % % 3666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3667 % 3668 % DrawPathLineToHorizontalRelative() draws a horizontal line path from the 3669 % current point to the target point using relative coordinates. The target 3670 % point then becomes the new current point. 3671 % 3672 % The format of the DrawPathLineToHorizontalRelative method is: 3673 % 3674 % void DrawPathLineToHorizontalRelative(DrawingWand *wand, 3675 % const double x) 3676 % 3677 % A description of each parameter follows: 3678 % 3679 % o wand: the drawing wand. 3680 % 3681 % o x: target x ordinate 3682 % 3683 */ 3684 WandExport void DrawPathLineToHorizontalRelative(DrawingWand *wand, 3685 const double x) 3686 { 3687 DrawPathLineToHorizontal(wand,RelativePathMode,x); 3688 } 3689 3690 /* 3692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3693 % % 3694 % % 3695 % % 3696 % 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 % 3697 % % 3698 % % 3699 % % 3700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3701 % 3702 % DrawPathLineToVerticalAbsolute() draws a vertical line path from the 3703 % current point to the target point using absolute coordinates. The target 3704 % point then becomes the new current point. 3705 % 3706 % The format of the DrawPathLineToVerticalAbsolute method is: 3707 % 3708 % void DrawPathLineToVerticalAbsolute(DrawingWand *wand, 3709 % const double y) 3710 % 3711 % A description of each parameter follows: 3712 % 3713 % o wand: the drawing wand. 3714 % 3715 % o y: target y ordinate 3716 % 3717 */ 3718 3719 static void DrawPathLineToVertical(DrawingWand *wand,const PathMode mode, 3720 const double y) 3721 { 3722 assert(wand != (DrawingWand *) NULL); 3723 assert(wand->signature == MagickWandSignature); 3724 if (wand->debug != MagickFalse) 3725 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3726 if ((wand->path_operation != PathLineToVerticalOperation) || 3727 (wand->path_mode != mode)) 3728 { 3729 wand->path_operation=PathLineToVerticalOperation; 3730 wand->path_mode=mode; 3731 (void) MVGAutoWrapPrintf(wand,"%c%.20g",mode == AbsolutePathMode ? 3732 'V' : 'v',y); 3733 } 3734 else 3735 (void) MVGAutoWrapPrintf(wand," %.20g",y); 3736 } 3737 3738 WandExport void DrawPathLineToVerticalAbsolute(DrawingWand *wand,const double y) 3739 { 3740 assert(wand != (DrawingWand *) NULL); 3741 assert(wand->signature == MagickWandSignature); 3742 if (wand->debug != MagickFalse) 3743 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3744 DrawPathLineToVertical(wand,AbsolutePathMode,y); 3745 } 3746 3747 /* 3749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3750 % % 3751 % % 3752 % % 3753 % 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 % 3754 % % 3755 % % 3756 % % 3757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3758 % 3759 % DrawPathLineToVerticalRelative() draws a vertical line path from the 3760 % current point to the target point using relative coordinates. The target 3761 % point then becomes the new current point. 3762 % 3763 % The format of the DrawPathLineToVerticalRelative method is: 3764 % 3765 % void DrawPathLineToVerticalRelative(DrawingWand *wand, 3766 % const double y) 3767 % 3768 % A description of each parameter follows: 3769 % 3770 % o wand: the drawing wand. 3771 % 3772 % o y: target y ordinate 3773 % 3774 */ 3775 WandExport void DrawPathLineToVerticalRelative(DrawingWand *wand,const double y) 3776 { 3777 assert(wand != (DrawingWand *) NULL); 3778 assert(wand->signature == MagickWandSignature); 3779 if (wand->debug != MagickFalse) 3780 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3781 DrawPathLineToVertical(wand,RelativePathMode,y); 3782 } 3783 /* 3784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3785 % % 3786 % % 3787 % % 3788 % D r a w P a t h M o v e T o A b s o l u t e % 3789 % % 3790 % % 3791 % % 3792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3793 % 3794 % DrawPathMoveToAbsolute() starts a new sub-path at the given coordinate 3795 % using absolute coordinates. The current point then becomes the 3796 % specified coordinate. 3797 % 3798 % The format of the DrawPathMoveToAbsolute method is: 3799 % 3800 % void DrawPathMoveToAbsolute(DrawingWand *wand,const double x, 3801 % const double y) 3802 % 3803 % A description of each parameter follows: 3804 % 3805 % o wand: the drawing wand. 3806 % 3807 % o x: target x ordinate 3808 % 3809 % o y: target y ordinate 3810 % 3811 */ 3812 3813 static void DrawPathMoveTo(DrawingWand *wand,const PathMode mode,const double x, 3814 const double y) 3815 { 3816 assert(wand != (DrawingWand *) NULL); 3817 assert(wand->signature == MagickWandSignature); 3818 if (wand->debug != MagickFalse) 3819 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3820 if ((wand->path_operation != PathMoveToOperation) || 3821 (wand->path_mode != mode)) 3822 { 3823 wand->path_operation=PathMoveToOperation; 3824 wand->path_mode=mode; 3825 (void) MVGAutoWrapPrintf(wand,"%c%.20g %.20g",mode == AbsolutePathMode ? 3826 'M' : 'm',x,y); 3827 } 3828 else 3829 (void) MVGAutoWrapPrintf(wand," %.20g %.20g",x,y); 3830 } 3831 3832 WandExport void DrawPathMoveToAbsolute(DrawingWand *wand,const double x, 3833 const double y) 3834 { 3835 assert(wand != (DrawingWand *) NULL); 3836 assert(wand->signature == MagickWandSignature); 3837 if (wand->debug != MagickFalse) 3838 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3839 DrawPathMoveTo(wand,AbsolutePathMode,x,y); 3840 } 3841 3842 /* 3844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3845 % % 3846 % % 3847 % % 3848 % D r a w P a t h M o v e T o R e l a t i v e % 3849 % % 3850 % % 3851 % % 3852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3853 % 3854 % DrawPathMoveToRelative() starts a new sub-path at the given coordinate using 3855 % relative coordinates. The current point then becomes the specified 3856 % coordinate. 3857 % 3858 % The format of the DrawPathMoveToRelative method is: 3859 % 3860 % void DrawPathMoveToRelative(DrawingWand *wand,const double x, 3861 % const double y) 3862 % 3863 % A description of each parameter follows: 3864 % 3865 % o wand: the drawing wand. 3866 % 3867 % o x: target x ordinate 3868 % 3869 % o y: target y ordinate 3870 % 3871 */ 3872 WandExport void DrawPathMoveToRelative(DrawingWand *wand,const double x, 3873 const double y) 3874 { 3875 assert(wand != (DrawingWand *) NULL); 3876 assert(wand->signature == MagickWandSignature); 3877 if (wand->debug != MagickFalse) 3878 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3879 DrawPathMoveTo(wand,RelativePathMode,x,y); 3880 } 3881 3882 /* 3884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3885 % % 3886 % % 3887 % % 3888 % D r a w P a t h S t a r t % 3889 % % 3890 % % 3891 % % 3892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3893 % 3894 % DrawPathStart() declares the start of a path drawing list which is terminated 3895 % by a matching DrawPathFinish() command. All other DrawPath commands must 3896 % be enclosed between a DrawPathStart() and a DrawPathFinish() command. This 3897 % is because path drawing commands are subordinate commands and they do not 3898 % function by themselves. 3899 % 3900 % The format of the DrawPathStart method is: 3901 % 3902 % void DrawPathStart(DrawingWand *wand) 3903 % 3904 % A description of each parameter follows: 3905 % 3906 % o wand: the drawing wand. 3907 % 3908 */ 3909 WandExport void DrawPathStart(DrawingWand *wand) 3910 { 3911 assert(wand != (DrawingWand *) NULL); 3912 assert(wand->signature == MagickWandSignature); 3913 if (wand->debug != MagickFalse) 3914 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3915 (void) MVGPrintf(wand,"path '"); 3916 wand->path_operation=PathDefaultOperation; 3917 wand->path_mode=DefaultPathMode; 3918 } 3919 3920 /* 3922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3923 % % 3924 % % 3925 % % 3926 % D r a w P o i n t % 3927 % % 3928 % % 3929 % % 3930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3931 % 3932 % DrawPoint() draws a point using the current fill color. 3933 % 3934 % The format of the DrawPoint method is: 3935 % 3936 % void DrawPoint(DrawingWand *wand,const double x,const double y) 3937 % 3938 % A description of each parameter follows: 3939 % 3940 % o wand: the drawing wand. 3941 % 3942 % o x: target x coordinate 3943 % 3944 % o y: target y coordinate 3945 % 3946 */ 3947 WandExport void DrawPoint(DrawingWand *wand,const double x,const double y) 3948 { 3949 assert(wand != (DrawingWand *) NULL); 3950 assert(wand->signature == MagickWandSignature); 3951 if (wand->debug != MagickFalse) 3952 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3953 (void) MVGPrintf(wand,"point %.20g %.20g\n",x,y); 3954 } 3955 3956 /* 3958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3959 % % 3960 % % 3961 % % 3962 % D r a w P o l y g o n % 3963 % % 3964 % % 3965 % % 3966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3967 % 3968 % DrawPolygon() draws a polygon using the current stroke, stroke width, and 3969 % fill color or texture, using the specified array of coordinates. 3970 % 3971 % The format of the DrawPolygon method is: 3972 % 3973 % void DrawPolygon(DrawingWand *wand, 3974 % const size_t number_coordinates,const PointInfo *coordinates) 3975 % 3976 % A description of each parameter follows: 3977 % 3978 % o wand: the drawing wand. 3979 % 3980 % o number_coordinates: number of coordinates 3981 % 3982 % o coordinates: coordinate array 3983 % 3984 */ 3985 WandExport void DrawPolygon(DrawingWand *wand, 3986 const size_t number_coordinates,const PointInfo *coordinates) 3987 { 3988 assert(wand != (DrawingWand *) NULL); 3989 assert(wand->signature == MagickWandSignature); 3990 if (wand->debug != MagickFalse) 3991 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 3992 MVGAppendPointsCommand(wand,"polygon",number_coordinates,coordinates); 3993 } 3994 3995 /* 3997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3998 % % 3999 % % 4000 % % 4001 % D r a w P o l y l i n e % 4002 % % 4003 % % 4004 % % 4005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4006 % 4007 % DrawPolyline() draws a polyline using the current stroke, stroke width, and 4008 % fill color or texture, using the specified array of coordinates. 4009 % 4010 % The format of the DrawPolyline method is: 4011 % 4012 % void DrawPolyline(DrawingWand *wand, 4013 % const size_t number_coordinates,const PointInfo *coordinates) 4014 % 4015 % A description of each parameter follows: 4016 % 4017 % o wand: the drawing wand. 4018 % 4019 % o number_coordinates: number of coordinates 4020 % 4021 % o coordinates: coordinate array 4022 % 4023 */ 4024 WandExport void DrawPolyline(DrawingWand *wand, 4025 const size_t number_coordinates,const PointInfo *coordinates) 4026 { 4027 assert(wand != (DrawingWand *) NULL); 4028 assert(wand->signature == MagickWandSignature); 4029 if (wand->debug != MagickFalse) 4030 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4031 MVGAppendPointsCommand(wand,"polyline",number_coordinates,coordinates); 4032 } 4033 4034 /* 4036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4037 % % 4038 % % 4039 % % 4040 % D r a w P o p C l i p P a t h % 4041 % % 4042 % % 4043 % % 4044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4045 % 4046 % DrawPopClipPath() terminates a clip path definition. 4047 % 4048 % The format of the DrawPopClipPath method is: 4049 % 4050 % void DrawPopClipPath(DrawingWand *wand) 4051 % 4052 % A description of each parameter follows: 4053 % 4054 % o wand: the drawing wand. 4055 % 4056 */ 4057 WandExport void DrawPopClipPath(DrawingWand *wand) 4058 { 4059 assert(wand != (DrawingWand *) NULL); 4060 assert(wand->signature == MagickWandSignature); 4061 if (wand->debug != MagickFalse) 4062 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4063 if (wand->indent_depth > 0) 4064 wand->indent_depth--; 4065 (void) MVGPrintf(wand,"pop clip-path\n"); 4066 } 4067 4068 /* 4070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4071 % % 4072 % % 4073 % % 4074 % D r a w P o p D e f s % 4075 % % 4076 % % 4077 % % 4078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4079 % 4080 % DrawPopDefs() terminates a definition list. 4081 % 4082 % The format of the DrawPopDefs method is: 4083 % 4084 % void DrawPopDefs(DrawingWand *wand) 4085 % 4086 % A description of each parameter follows: 4087 % 4088 % o wand: the drawing wand. 4089 % 4090 */ 4091 WandExport void DrawPopDefs(DrawingWand *wand) 4092 { 4093 assert(wand != (DrawingWand *) NULL); 4094 assert(wand->signature == MagickWandSignature); 4095 if (wand->debug != MagickFalse) 4096 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4097 if (wand->indent_depth > 0) 4098 wand->indent_depth--; 4099 (void) MVGPrintf(wand,"pop defs\n"); 4100 } 4101 4102 /* 4104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4105 % % 4106 % % 4107 % % 4108 % D r a w P o p P a t t e r n % 4109 % % 4110 % % 4111 % % 4112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4113 % 4114 % DrawPopPattern() terminates a pattern definition. 4115 % 4116 % The format of the DrawPopPattern method is: 4117 % 4118 % MagickBooleanType DrawPopPattern(DrawingWand *wand) 4119 % 4120 % A description of each parameter follows: 4121 % 4122 % o wand: the drawing wand. 4123 % 4124 */ 4125 WandExport MagickBooleanType DrawPopPattern(DrawingWand *wand) 4126 { 4127 char 4128 geometry[MagickPathExtent], 4129 key[MagickPathExtent]; 4130 4131 assert(wand != (DrawingWand *) NULL); 4132 assert(wand->signature == MagickWandSignature); 4133 if (wand->debug != MagickFalse) 4134 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4135 if (wand->image == (Image *) NULL) 4136 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 4137 if (wand->pattern_id == (const char *) NULL) 4138 { 4139 ThrowDrawException(DrawWarning,"NotCurrentlyPushingPatternDefinition", 4140 wand->name); 4141 return(MagickFalse); 4142 } 4143 (void) FormatLocaleString(key,MagickPathExtent,"%s",wand->pattern_id); 4144 (void) SetImageArtifact(wand->image,key,wand->mvg+wand->pattern_offset); 4145 (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g%+.20g%+.20g", 4146 (double) wand->pattern_bounds.width,(double) wand->pattern_bounds.height, 4147 (double) wand->pattern_bounds.x,(double) wand->pattern_bounds.y); 4148 (void) SetImageArtifact(wand->image,key,geometry); 4149 wand->pattern_id=DestroyString(wand->pattern_id); 4150 wand->pattern_offset=0; 4151 wand->pattern_bounds.x=0; 4152 wand->pattern_bounds.y=0; 4153 wand->pattern_bounds.width=0; 4154 wand->pattern_bounds.height=0; 4155 wand->filter_off=MagickTrue; 4156 if (wand->indent_depth > 0) 4157 wand->indent_depth--; 4158 (void) MVGPrintf(wand,"pop pattern\n"); 4159 return(MagickTrue); 4160 } 4161 4162 /* 4164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4165 % % 4166 % % 4167 % % 4168 % D r a w P u s h C l i p P a t h % 4169 % % 4170 % % 4171 % % 4172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4173 % 4174 % DrawPushClipPath() starts a clip path definition which is comprized of any 4175 % number of drawing commands and terminated by a DrawPopClipPath() command. 4176 % 4177 % The format of the DrawPushClipPath method is: 4178 % 4179 % void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id) 4180 % 4181 % A description of each parameter follows: 4182 % 4183 % o wand: the drawing wand. 4184 % 4185 % o clip_mask_id: string identifier to associate with the clip path for 4186 % later use. 4187 % 4188 */ 4189 WandExport void DrawPushClipPath(DrawingWand *wand,const char *clip_mask_id) 4190 { 4191 assert(wand != (DrawingWand *) NULL); 4192 assert(wand->signature == MagickWandSignature); 4193 if (wand->debug != MagickFalse) 4194 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4195 assert(clip_mask_id != (const char *) NULL); 4196 (void) MVGPrintf(wand,"push clip-path %s\n",clip_mask_id); 4197 wand->indent_depth++; 4198 } 4199 4200 /* 4202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4203 % % 4204 % % 4205 % % 4206 % D r a w P u s h D e f s % 4207 % % 4208 % % 4209 % % 4210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4211 % 4212 % DrawPushDefs() indicates that commands up to a terminating DrawPopDefs() 4213 % command create named elements (e.g. clip-paths, textures, etc.) which 4214 % may safely be processed earlier for the sake of efficiency. 4215 % 4216 % The format of the DrawPushDefs method is: 4217 % 4218 % void DrawPushDefs(DrawingWand *wand) 4219 % 4220 % A description of each parameter follows: 4221 % 4222 % o wand: the drawing wand. 4223 % 4224 */ 4225 WandExport void DrawPushDefs(DrawingWand *wand) 4226 { 4227 assert(wand != (DrawingWand *) NULL); 4228 assert(wand->signature == MagickWandSignature); 4229 if (wand->debug != MagickFalse) 4230 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4231 (void) MVGPrintf(wand,"push defs\n"); 4232 wand->indent_depth++; 4233 } 4234 4235 /* 4237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4238 % % 4239 % % 4240 % % 4241 % D r a w P u s h P a t t e r n % 4242 % % 4243 % % 4244 % % 4245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4246 % 4247 % DrawPushPattern() indicates that subsequent commands up to a 4248 % DrawPopPattern() command comprise the definition of a named pattern. 4249 % The pattern space is assigned top left corner coordinates, a width 4250 % and height, and becomes its own drawing space. Anything which can 4251 % be drawn may be used in a pattern definition. 4252 % Named patterns may be used as stroke or brush definitions. 4253 % 4254 % The format of the DrawPushPattern method is: 4255 % 4256 % MagickBooleanType DrawPushPattern(DrawingWand *wand, 4257 % const char *pattern_id,const double x,const double y, 4258 % const double width,const double height) 4259 % 4260 % A description of each parameter follows: 4261 % 4262 % o wand: the drawing wand. 4263 % 4264 % o pattern_id: pattern identification for later reference 4265 % 4266 % o x: x ordinate of top left corner 4267 % 4268 % o y: y ordinate of top left corner 4269 % 4270 % o width: width of pattern space 4271 % 4272 % o height: height of pattern space 4273 % 4274 */ 4275 WandExport MagickBooleanType DrawPushPattern(DrawingWand *wand, 4276 const char *pattern_id,const double x,const double y,const double width, 4277 const double height) 4278 { 4279 assert(wand != (DrawingWand *) NULL); 4280 assert(wand->signature == MagickWandSignature); 4281 if (wand->debug != MagickFalse) 4282 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4283 assert(pattern_id != (const char *) NULL); 4284 if (wand->pattern_id != NULL) 4285 { 4286 ThrowDrawException(DrawError,"AlreadyPushingPatternDefinition", 4287 wand->pattern_id); 4288 return(MagickFalse); 4289 } 4290 wand->filter_off=MagickTrue; 4291 (void) MVGPrintf(wand,"push pattern %s %.20g %.20g %.20g %.20g\n",pattern_id, 4292 x,y,width,height); 4293 wand->indent_depth++; 4294 wand->pattern_id=AcquireString(pattern_id); 4295 wand->pattern_bounds.x=(ssize_t) ceil(x-0.5); 4296 wand->pattern_bounds.y=(ssize_t) ceil(y-0.5); 4297 wand->pattern_bounds.width=(size_t) floor(width+0.5); 4298 wand->pattern_bounds.height=(size_t) floor(height+0.5); 4299 wand->pattern_offset=wand->mvg_length; 4300 return(MagickTrue); 4301 } 4302 4303 /* 4305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4306 % % 4307 % % 4308 % % 4309 % D r a w R e c t a n g l e % 4310 % % 4311 % % 4312 % % 4313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4314 % 4315 % DrawRectangle() draws a rectangle given two coordinates and using the 4316 % current stroke, stroke width, and fill settings. 4317 % 4318 % The format of the DrawRectangle method is: 4319 % 4320 % void DrawRectangle(DrawingWand *wand,const double x1, 4321 % const double y1,const double x2,const double y2) 4322 % 4323 % A description of each parameter follows: 4324 % 4325 % o x1: x ordinate of first coordinate 4326 % 4327 % o y1: y ordinate of first coordinate 4328 % 4329 % o x2: x ordinate of second coordinate 4330 % 4331 % o y2: y ordinate of second coordinate 4332 % 4333 */ 4334 WandExport void DrawRectangle(DrawingWand *wand,const double x1,const double y1, 4335 const double x2,const double y2) 4336 { 4337 assert(wand != (DrawingWand *) NULL); 4338 assert(wand->signature == MagickWandSignature); 4339 if (wand->debug != MagickFalse) 4340 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4341 (void) MVGPrintf(wand,"rectangle %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2); 4342 } 4343 4344 /* 4346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4347 % % 4348 % % 4349 % % 4350 + D r a w R e n d e r % 4351 % % 4352 % % 4353 % % 4354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4355 % 4356 % DrawRender() renders all preceding drawing commands onto the image. 4357 % 4358 % The format of the DrawRender method is: 4359 % 4360 % MagickBooleanType DrawRender(DrawingWand *wand) 4361 % 4362 % A description of each parameter follows: 4363 % 4364 % o wand: the drawing wand. 4365 % 4366 */ 4367 WandExport MagickBooleanType DrawRender(DrawingWand *wand) 4368 { 4369 MagickBooleanType 4370 status; 4371 4372 assert(wand != (const DrawingWand *) NULL); 4373 assert(wand->signature == MagickWandSignature); 4374 if (wand->debug != MagickFalse) 4375 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4376 CurrentContext->primitive=wand->mvg; 4377 if (wand->debug != MagickFalse) 4378 (void) LogMagickEvent(DrawEvent,GetMagickModule(),"MVG:\n'%s'\n",wand->mvg); 4379 if (wand->image == (Image *) NULL) 4380 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 4381 status=DrawImage(wand->image,CurrentContext,wand->exception); 4382 CurrentContext->primitive=(char *) NULL; 4383 return(status); 4384 } 4385 4386 /* 4388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4389 % % 4390 % % 4391 % % 4392 % D r a w R e s e t V e c t o r G r a p h i c s % 4393 % % 4394 % % 4395 % % 4396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4397 % 4398 % DrawResetVectorGraphics() resets the vector graphics associated with the 4399 % specified wand. 4400 % 4401 % The format of the DrawResetVectorGraphics method is: 4402 % 4403 % void DrawResetVectorGraphics(DrawingWand *wand) 4404 % 4405 % A description of each parameter follows: 4406 % 4407 % o wand: the drawing wand. 4408 % 4409 */ 4410 WandExport void DrawResetVectorGraphics(DrawingWand *wand) 4411 { 4412 assert(wand != (DrawingWand *) NULL); 4413 assert(wand->signature == MagickWandSignature); 4414 if (wand->debug != MagickFalse) 4415 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4416 if (wand->mvg != (char *) NULL) 4417 wand->mvg=DestroyString(wand->mvg); 4418 wand->mvg_alloc=0; 4419 wand->mvg_length=0; 4420 wand->mvg_width=0; 4421 } 4422 4423 /* 4425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4426 % % 4427 % % 4428 % % 4429 % D r a w R o t a t e % 4430 % % 4431 % % 4432 % % 4433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4434 % 4435 % DrawRotate() applies the specified rotation to the current coordinate space. 4436 % 4437 % The format of the DrawRotate method is: 4438 % 4439 % void DrawRotate(DrawingWand *wand,const double degrees) 4440 % 4441 % A description of each parameter follows: 4442 % 4443 % o wand: the drawing wand. 4444 % 4445 % o degrees: degrees of rotation 4446 % 4447 */ 4448 WandExport void DrawRotate(DrawingWand *wand,const double degrees) 4449 { 4450 assert(wand != (DrawingWand *) NULL); 4451 assert(wand->signature == MagickWandSignature); 4452 if (wand->debug != MagickFalse) 4453 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4454 (void) MVGPrintf(wand,"rotate %.20g\n",degrees); 4455 } 4456 4457 /* 4459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4460 % % 4461 % % 4462 % % 4463 % D r a w R o u n d R e c t a n g l e % 4464 % % 4465 % % 4466 % % 4467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4468 % 4469 % DrawRoundRectangle() draws a rounted rectangle given two coordinates, 4470 % x & y corner radiuses and using the current stroke, stroke width, 4471 % and fill settings. 4472 % 4473 % The format of the DrawRoundRectangle method is: 4474 % 4475 % void DrawRoundRectangle(DrawingWand *wand,double x1,double y1, 4476 % double x2,double y2,double rx,double ry) 4477 % 4478 % A description of each parameter follows: 4479 % 4480 % o wand: the drawing wand. 4481 % 4482 % o x1: x ordinate of first coordinate 4483 % 4484 % o y1: y ordinate of first coordinate 4485 % 4486 % o x2: x ordinate of second coordinate 4487 % 4488 % o y2: y ordinate of second coordinate 4489 % 4490 % o rx: radius of corner in horizontal direction 4491 % 4492 % o ry: radius of corner in vertical direction 4493 % 4494 */ 4495 WandExport void DrawRoundRectangle(DrawingWand *wand,double x1,double y1, 4496 double x2,double y2,double rx,double ry) 4497 { 4498 assert(wand != (DrawingWand *) NULL); 4499 assert(wand->signature == MagickWandSignature); 4500 if (wand->debug != MagickFalse) 4501 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4502 (void) MVGPrintf(wand,"roundrectangle %.20g %.20g %.20g %.20g %.20g %.20g\n", 4503 x1,y1,x2,y2,rx,ry); 4504 } 4505 4506 /* 4508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4509 % % 4510 % % 4511 % % 4512 % D r a w S c a l e % 4513 % % 4514 % % 4515 % % 4516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4517 % 4518 % DrawScale() adjusts the scaling factor to apply in the horizontal and 4519 % vertical directions to the current coordinate space. 4520 % 4521 % The format of the DrawScale method is: 4522 % 4523 % void DrawScale(DrawingWand *wand,const double x,const double y) 4524 % 4525 % A description of each parameter follows: 4526 % 4527 % o wand: the drawing wand. 4528 % 4529 % o x: horizontal scale factor 4530 % 4531 % o y: vertical scale factor 4532 % 4533 */ 4534 WandExport void DrawScale(DrawingWand *wand,const double x,const double y) 4535 { 4536 assert(wand != (DrawingWand *) NULL); 4537 assert(wand->signature == MagickWandSignature); 4538 if (wand->debug != MagickFalse) 4539 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4540 (void) MVGPrintf(wand,"scale %.20g %.20g\n",x,y); 4541 } 4542 4543 /* 4545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4546 % % 4547 % % 4548 % % 4549 % D r a w S e t B o r d e r C o l o r % 4550 % % 4551 % % 4552 % % 4553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4554 % 4555 % DrawSetBorderColor() sets the border color to be used for drawing bordered 4556 % objects. 4557 % 4558 % The format of the DrawSetBorderColor method is: 4559 % 4560 % void DrawSetBorderColor(DrawingWand *wand,const PixelWand *border_wand) 4561 % 4562 % A description of each parameter follows: 4563 % 4564 % o wand: the drawing wand. 4565 % 4566 % o border_wand: border wand. 4567 % 4568 */ 4569 WandExport void DrawSetBorderColor(DrawingWand *wand, 4570 const PixelWand *border_wand) 4571 { 4572 PixelInfo 4573 *current_border, 4574 border_color, 4575 new_border; 4576 4577 assert(wand != (DrawingWand *) NULL); 4578 assert(wand->signature == MagickWandSignature); 4579 if (wand->debug != MagickFalse) 4580 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4581 assert(border_wand != (const PixelWand *) NULL); 4582 PixelGetQuantumPacket(border_wand,&border_color); 4583 new_border=border_color; 4584 current_border=(&CurrentContext->border_color); 4585 if ((wand->filter_off != MagickFalse) || 4586 (IsPixelInfoEquivalent(current_border,&new_border) == MagickFalse)) 4587 { 4588 CurrentContext->border_color=new_border; 4589 (void) MVGPrintf(wand,"border-color '"); 4590 MVGAppendColor(wand,&border_color); 4591 (void) MVGPrintf(wand,"'\n"); 4592 } 4593 } 4594 4595 /* 4597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4598 % % 4599 % % 4600 % % 4601 % D r a w S e t C l i p P a t h % 4602 % % 4603 % % 4604 % % 4605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4606 % 4607 % DrawSetClipPath() associates a named clipping path with the image. Only 4608 % the areas drawn on by the clipping path will be modified as ssize_t as it 4609 % remains in effect. 4610 % 4611 % The format of the DrawSetClipPath method is: 4612 % 4613 % MagickBooleanType DrawSetClipPath(DrawingWand *wand, 4614 % const char *clip_mask) 4615 % 4616 % A description of each parameter follows: 4617 % 4618 % o wand: the drawing wand. 4619 % 4620 % o clip_mask: name of clipping path to associate with image 4621 % 4622 */ 4623 WandExport MagickBooleanType DrawSetClipPath(DrawingWand *wand, 4624 const char *clip_mask) 4625 { 4626 if (wand->debug != MagickFalse) 4627 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clip_mask); 4628 assert(wand != (DrawingWand *) NULL); 4629 assert(wand->signature == MagickWandSignature); 4630 assert(clip_mask != (const char *) NULL); 4631 if ((CurrentContext->clip_mask == (const char *) NULL) || 4632 (wand->filter_off != MagickFalse) || 4633 (LocaleCompare(CurrentContext->clip_mask,clip_mask) != 0)) 4634 { 4635 (void) CloneString(&CurrentContext->clip_mask,clip_mask); 4636 #if DRAW_BINARY_IMPLEMENTATION 4637 if (wand->image == (Image *) NULL) 4638 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 4639 (void) DrawClipPath(wand->image,CurrentContext,CurrentContext->clip_mask); 4640 #endif 4641 (void) MVGPrintf(wand,"clip-path url(#%s)\n",clip_mask); 4642 } 4643 return(MagickTrue); 4644 } 4645 4646 /* 4648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4649 % % 4650 % % 4651 % % 4652 % D r a w S e t C l i p R u l e % 4653 % % 4654 % % 4655 % % 4656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4657 % 4658 % DrawSetClipRule() set the polygon fill rule to be used by the clipping path. 4659 % 4660 % The format of the DrawSetClipRule method is: 4661 % 4662 % void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule) 4663 % 4664 % A description of each parameter follows: 4665 % 4666 % o wand: the drawing wand. 4667 % 4668 % o fill_rule: fill rule (EvenOddRule or NonZeroRule) 4669 % 4670 */ 4671 WandExport void DrawSetClipRule(DrawingWand *wand,const FillRule fill_rule) 4672 { 4673 assert(wand != (DrawingWand *) NULL); 4674 assert(wand->signature == MagickWandSignature); 4675 if (wand->debug != MagickFalse) 4676 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4677 if ((wand->filter_off != MagickFalse) || 4678 (CurrentContext->fill_rule != fill_rule)) 4679 { 4680 CurrentContext->fill_rule=fill_rule; 4681 (void) MVGPrintf(wand, "clip-rule '%s'\n",CommandOptionToMnemonic( 4682 MagickFillRuleOptions,(ssize_t) fill_rule)); 4683 } 4684 } 4685 4686 /* 4688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4689 % % 4690 % % 4691 % % 4692 % D r a w S e t C l i p U n i t s % 4693 % % 4694 % % 4695 % % 4696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4697 % 4698 % DrawSetClipUnits() sets the interpretation of clip path units. 4699 % 4700 % The format of the DrawSetClipUnits method is: 4701 % 4702 % void DrawSetClipUnits(DrawingWand *wand, 4703 % const ClipPathUnits clip_units) 4704 % 4705 % A description of each parameter follows: 4706 % 4707 % o wand: the drawing wand. 4708 % 4709 % o clip_units: units to use (UserSpace, UserSpaceOnUse, or 4710 % ObjectBoundingBox) 4711 % 4712 */ 4713 WandExport void DrawSetClipUnits(DrawingWand *wand, 4714 const ClipPathUnits clip_units) 4715 { 4716 assert(wand != (DrawingWand *) NULL); 4717 assert(wand->signature == MagickWandSignature); 4718 if (wand->debug != MagickFalse) 4719 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4720 if ((wand->filter_off != MagickFalse) || 4721 (CurrentContext->clip_units != clip_units)) 4722 { 4723 CurrentContext->clip_units=clip_units; 4724 if (clip_units == ObjectBoundingBox) 4725 { 4726 AffineMatrix 4727 affine; 4728 4729 GetAffineMatrix(&affine); 4730 affine.sx=CurrentContext->bounds.x2; 4731 affine.sy=CurrentContext->bounds.y2; 4732 affine.tx=CurrentContext->bounds.x1; 4733 affine.ty=CurrentContext->bounds.y1; 4734 AdjustAffine(wand,&affine); 4735 } 4736 (void) MVGPrintf(wand, "clip-units '%s'\n",CommandOptionToMnemonic( 4737 MagickClipPathOptions,(ssize_t) clip_units)); 4738 } 4739 } 4740 4741 /* 4743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4744 % % 4745 % % 4746 % % 4747 % D r a w S e t D e n s i t y % 4748 % % 4749 % % 4750 % % 4751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4752 % 4753 % DrawSetDensity() sets the vertical and horizontal resolution. 4754 % 4755 % The format of the DrawSetDensity method is: 4756 % 4757 % MagickBooleanType DrawSetDensity(DrawingWand *wand, 4758 % const char *density) 4759 % 4760 % A description of each parameter follows: 4761 % 4762 % o wand: the drawing wand. 4763 % 4764 % o density: the vertical and horizontal resolution. 4765 % 4766 */ 4767 WandExport MagickBooleanType DrawSetDensity(DrawingWand *wand, 4768 const char *density) 4769 { 4770 if (wand->debug != MagickFalse) 4771 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",density); 4772 assert(wand != (DrawingWand *) NULL); 4773 assert(wand->signature == MagickWandSignature); 4774 assert(density != (const char *) NULL); 4775 if ((CurrentContext->density == (const char *) NULL) || 4776 (wand->filter_off != MagickFalse) || 4777 (LocaleCompare(CurrentContext->density,density) != 0)) 4778 { 4779 (void) CloneString(&CurrentContext->density,density); 4780 (void) MVGPrintf(wand,"density '%s'\n",density); 4781 } 4782 return(MagickTrue); 4783 } 4784 4785 /* 4786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4787 % % 4788 % % 4789 % % 4790 % D r a w S e t F i l l C o l o r % 4791 % % 4792 % % 4793 % % 4794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4795 % 4796 % DrawSetFillColor() sets the fill color to be used for drawing filled objects. 4797 % 4798 % The format of the DrawSetFillColor method is: 4799 % 4800 % void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand) 4801 % 4802 % A description of each parameter follows: 4803 % 4804 % o wand: the drawing wand. 4805 % 4806 % o fill_wand: fill wand. 4807 % 4808 */ 4809 WandExport void DrawSetFillColor(DrawingWand *wand,const PixelWand *fill_wand) 4810 { 4811 PixelInfo 4812 *current_fill, 4813 fill_color, 4814 new_fill; 4815 4816 assert(wand != (DrawingWand *) NULL); 4817 assert(wand->signature == MagickWandSignature); 4818 if (wand->debug != MagickFalse) 4819 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4820 assert(fill_wand != (const PixelWand *) NULL); 4821 PixelGetQuantumPacket(fill_wand,&fill_color); 4822 new_fill=fill_color; 4823 current_fill=(&CurrentContext->fill); 4824 if ((wand->filter_off != MagickFalse) || 4825 (IsPixelInfoEquivalent(current_fill,&new_fill) == MagickFalse)) 4826 { 4827 CurrentContext->fill=new_fill; 4828 (void) MVGPrintf(wand,"fill '"); 4829 MVGAppendColor(wand,&fill_color); 4830 (void) MVGPrintf(wand,"'\n"); 4831 } 4832 } 4833 4834 /* 4836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4837 % % 4838 % % 4839 % % 4840 % D r a w S e t F i l l O p a c i t y % 4841 % % 4842 % % 4843 % % 4844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4845 % 4846 % DrawSetFillOpacity() sets the alpha to use when drawing using the fill 4847 % color or fill texture. Fully opaque is 1.0. 4848 % 4849 % The format of the DrawSetFillOpacity method is: 4850 % 4851 % void DrawSetFillOpacity(DrawingWand *wand,const double fill_alpha) 4852 % 4853 % A description of each parameter follows: 4854 % 4855 % o wand: the drawing wand. 4856 % 4857 % o fill_opacity: fill opacity 4858 % 4859 */ 4860 WandExport void DrawSetFillOpacity(DrawingWand *wand,const double fill_opacity) 4861 { 4862 double 4863 alpha; 4864 4865 assert(wand != (DrawingWand *) NULL); 4866 assert(wand->signature == MagickWandSignature); 4867 if (wand->debug != MagickFalse) 4868 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4869 alpha=(double) ClampToQuantum(QuantumRange*fill_opacity); 4870 if ((wand->filter_off != MagickFalse) || 4871 (CurrentContext->fill.alpha != alpha)) 4872 { 4873 CurrentContext->fill.alpha=alpha; 4874 (void) MVGPrintf(wand,"fill-opacity %.20g\n",fill_opacity); 4875 } 4876 } 4877 4878 /* 4880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4881 % % 4882 % % 4883 % % 4884 % D r a w S e t F o n t R e s o l u t i o n % 4885 % % 4886 % % 4887 % % 4888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4889 % 4890 % DrawSetFontResolution() sets the image resolution. 4891 % 4892 % The format of the DrawSetFontResolution method is: 4893 % 4894 % MagickBooleanType DrawSetFontResolution(DrawingWand *wand, 4895 % const double x_resolution,const double y_resolution) 4896 % 4897 % A description of each parameter follows: 4898 % 4899 % o wand: the magick wand. 4900 % 4901 % o x_resolution: the image x resolution. 4902 % 4903 % o y_resolution: the image y resolution. 4904 % 4905 */ 4906 WandExport MagickBooleanType DrawSetFontResolution(DrawingWand *wand, 4907 const double x_resolution,const double y_resolution) 4908 { 4909 char 4910 density[MagickPathExtent]; 4911 4912 assert(wand != (DrawingWand *) NULL); 4913 assert(wand->signature == MagickWandSignature); 4914 if (wand->debug != MagickFalse) 4915 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4916 (void) FormatLocaleString(density,MagickPathExtent,"%.20gx%.20g",x_resolution, 4917 y_resolution); 4918 (void) CloneString(&CurrentContext->density,density); 4919 return(MagickTrue); 4920 } 4921 4922 /* 4924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4925 % % 4926 % % 4927 % % 4928 % D r a w S e t O p a c i t y % 4929 % % 4930 % % 4931 % % 4932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4933 % 4934 % DrawSetOpacity() sets the alpha to use when drawing using the fill or 4935 % stroke color or texture. Fully opaque is 1.0. 4936 % 4937 % The format of the DrawSetOpacity method is: 4938 % 4939 % void DrawSetOpacity(DrawingWand *wand,const double alpha) 4940 % 4941 % A description of each parameter follows: 4942 % 4943 % o wand: the drawing wand. 4944 % 4945 % o opacity: fill and stroke opacity. The value 1.0 is opaque. 4946 % 4947 */ 4948 WandExport void DrawSetOpacity(DrawingWand *wand,const double opacity) 4949 { 4950 Quantum 4951 quantum_alpha; 4952 4953 assert(wand != (DrawingWand *) NULL); 4954 assert(wand->signature == MagickWandSignature); 4955 if (wand->debug != MagickFalse) 4956 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 4957 quantum_alpha=ClampToQuantum(QuantumRange*opacity); 4958 if ((wand->filter_off != MagickFalse) || 4959 (CurrentContext->alpha != quantum_alpha)) 4960 { 4961 CurrentContext->alpha=quantum_alpha; 4962 (void) MVGPrintf(wand,"opacity %.20g\n",opacity); 4963 } 4964 } 4965 4966 /* 4968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4969 % % 4970 % % 4971 % % 4972 % D r a w S e t F i l l P a t t e r n U R L % 4973 % % 4974 % % 4975 % % 4976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4977 % 4978 % DrawSetFillPatternURL() sets the URL to use as a fill pattern for filling 4979 % objects. Only local URLs ("#identifier") are supported at this time. These 4980 % local URLs are normally created by defining a named fill pattern with 4981 % DrawPushPattern/DrawPopPattern. 4982 % 4983 % The format of the DrawSetFillPatternURL method is: 4984 % 4985 % MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand, 4986 % const char *fill_url) 4987 % 4988 % A description of each parameter follows: 4989 % 4990 % o wand: the drawing wand. 4991 % 4992 % o fill_url: URL to use to obtain fill pattern. 4993 % 4994 */ 4995 WandExport MagickBooleanType DrawSetFillPatternURL(DrawingWand *wand, 4996 const char *fill_url) 4997 { 4998 char 4999 pattern[MagickPathExtent], 5000 pattern_spec[MagickPathExtent]; 5001 5002 assert(wand != (DrawingWand *) NULL); 5003 assert(wand->signature == MagickWandSignature); 5004 if (wand->debug != MagickFalse) 5005 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",fill_url); 5006 if (wand->image == (Image *) NULL) 5007 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 5008 assert(fill_url != (const char *) NULL); 5009 if (*fill_url != '#') 5010 { 5011 ThrowDrawException(DrawError,"NotARelativeURL",fill_url); 5012 return(MagickFalse); 5013 } 5014 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",fill_url+1); 5015 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL) 5016 { 5017 ThrowDrawException(DrawError,"URLNotFound",fill_url) 5018 return(MagickFalse); 5019 } 5020 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",fill_url); 5021 #if DRAW_BINARY_IMPLEMENTATION 5022 DrawPatternPath(wand->image,CurrentContext,pattern_spec, 5023 &CurrentContext->fill_pattern); 5024 #endif 5025 if (CurrentContext->fill.alpha != (Quantum) TransparentAlpha) 5026 CurrentContext->fill.alpha=(double) CurrentContext->alpha; 5027 (void) MVGPrintf(wand,"fill %s\n",pattern_spec); 5028 return(MagickTrue); 5029 } 5030 5031 /* 5033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5034 % % 5035 % % 5036 % % 5037 % D r a w S e t F i l l R u l e % 5038 % % 5039 % % 5040 % % 5041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5042 % 5043 % DrawSetFillRule() sets the fill rule to use while drawing polygons. 5044 % 5045 % The format of the DrawSetFillRule method is: 5046 % 5047 % void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule) 5048 % 5049 % A description of each parameter follows: 5050 % 5051 % o wand: the drawing wand. 5052 % 5053 % o fill_rule: fill rule (EvenOddRule or NonZeroRule) 5054 % 5055 */ 5056 WandExport void DrawSetFillRule(DrawingWand *wand,const FillRule fill_rule) 5057 { 5058 assert(wand != (DrawingWand *) NULL); 5059 assert(wand->signature == MagickWandSignature); 5060 if (wand->debug != MagickFalse) 5061 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5062 if ((wand->filter_off != MagickFalse) || 5063 (CurrentContext->fill_rule != fill_rule)) 5064 { 5065 CurrentContext->fill_rule=fill_rule; 5066 (void) MVGPrintf(wand, "fill-rule '%s'\n",CommandOptionToMnemonic( 5067 MagickFillRuleOptions,(ssize_t) fill_rule)); 5068 } 5069 } 5070 5071 /* 5073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5074 % % 5075 % % 5076 % % 5077 % D r a w S e t F o n t % 5078 % % 5079 % % 5080 % % 5081 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5082 % 5083 % DrawSetFont() sets the fully-sepecified font to use when annotating with 5084 % text. 5085 % 5086 % The format of the DrawSetFont method is: 5087 % 5088 % MagickBooleanType DrawSetFont(DrawingWand *wand,const char *font_name) 5089 % 5090 % A description of each parameter follows: 5091 % 5092 % o wand: the drawing wand. 5093 % 5094 % o font_name: font name 5095 % 5096 */ 5097 WandExport MagickBooleanType DrawSetFont(DrawingWand *wand, 5098 const char *font_name) 5099 { 5100 assert(wand != (DrawingWand *) NULL); 5101 assert(wand->signature == MagickWandSignature); 5102 if (wand->debug != MagickFalse) 5103 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5104 assert(font_name != (const char *) NULL); 5105 if ((wand->filter_off != MagickFalse) || 5106 (CurrentContext->font == (char *) NULL) || 5107 (LocaleCompare(CurrentContext->font,font_name) != 0)) 5108 { 5109 (void) CloneString(&CurrentContext->font,font_name); 5110 (void) MVGPrintf(wand,"font '%s'\n",font_name); 5111 } 5112 return(MagickTrue); 5113 } 5114 5115 /* 5117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5118 % % 5119 % % 5120 % % 5121 % D r a w S e t F o n t F a m i l y % 5122 % % 5123 % % 5124 % % 5125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5126 % 5127 % DrawSetFontFamily() sets the font family to use when annotating with text. 5128 % 5129 % The format of the DrawSetFontFamily method is: 5130 % 5131 % MagickBooleanType DrawSetFontFamily(DrawingWand *wand, 5132 % const char *font_family) 5133 % 5134 % A description of each parameter follows: 5135 % 5136 % o wand: the drawing wand. 5137 % 5138 % o font_family: font family 5139 % 5140 */ 5141 WandExport MagickBooleanType DrawSetFontFamily(DrawingWand *wand, 5142 const char *font_family) 5143 { 5144 assert(wand != (DrawingWand *) NULL); 5145 assert(wand->signature == MagickWandSignature); 5146 if (wand->debug != MagickFalse) 5147 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5148 assert(font_family != (const char *) NULL); 5149 if ((wand->filter_off != MagickFalse) || 5150 (CurrentContext->family == (const char *) NULL) || 5151 (LocaleCompare(CurrentContext->family,font_family) != 0)) 5152 { 5153 (void) CloneString(&CurrentContext->family,font_family); 5154 (void) MVGPrintf(wand,"font-family '%s'\n",font_family); 5155 } 5156 return(MagickTrue); 5157 } 5158 5159 /* 5161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5162 % % 5163 % % 5164 % % 5165 % D r a w S e t F o n t S i z e % 5166 % % 5167 % % 5168 % % 5169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5170 % 5171 % DrawSetFontSize() sets the font pointsize to use when annotating with text. 5172 % 5173 % The format of the DrawSetFontSize method is: 5174 % 5175 % void DrawSetFontSize(DrawingWand *wand,const double pointsize) 5176 % 5177 % A description of each parameter follows: 5178 % 5179 % o wand: the drawing wand. 5180 % 5181 % o pointsize: text pointsize 5182 % 5183 */ 5184 WandExport void DrawSetFontSize(DrawingWand *wand,const double pointsize) 5185 { 5186 assert(wand != (DrawingWand *) NULL); 5187 assert(wand->signature == MagickWandSignature); 5188 if (wand->debug != MagickFalse) 5189 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5190 if ((wand->filter_off != MagickFalse) || 5191 (fabs(CurrentContext->pointsize-pointsize) >= MagickEpsilon)) 5192 { 5193 CurrentContext->pointsize=pointsize; 5194 (void) MVGPrintf(wand,"font-size %.20g\n",pointsize); 5195 } 5196 } 5197 5198 /* 5200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5201 % % 5202 % % 5203 % % 5204 % D r a w S e t F o n t S t r e t c h % 5205 % % 5206 % % 5207 % % 5208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5209 % 5210 % DrawSetFontStretch() sets the font stretch to use when annotating with text. 5211 % The AnyStretch enumeration acts as a wild-card "don't care" option. 5212 % 5213 % The format of the DrawSetFontStretch method is: 5214 % 5215 % void DrawSetFontStretch(DrawingWand *wand, 5216 % const StretchType font_stretch) 5217 % 5218 % A description of each parameter follows: 5219 % 5220 % o wand: the drawing wand. 5221 % 5222 % o font_stretch: font stretch (NormalStretch, UltraCondensedStretch, 5223 % CondensedStretch, SemiCondensedStretch, 5224 % SemiExpandedStretch, ExpandedStretch, 5225 % ExtraExpandedStretch, UltraExpandedStretch, AnyStretch) 5226 % 5227 */ 5228 WandExport void DrawSetFontStretch(DrawingWand *wand, 5229 const StretchType font_stretch) 5230 { 5231 assert(wand != (DrawingWand *) NULL); 5232 assert(wand->signature == MagickWandSignature); 5233 if (wand->debug != MagickFalse) 5234 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5235 if ((wand->filter_off != MagickFalse) || 5236 (CurrentContext->stretch != font_stretch)) 5237 { 5238 CurrentContext->stretch=font_stretch; 5239 (void) MVGPrintf(wand, "font-stretch '%s'\n",CommandOptionToMnemonic( 5240 MagickStretchOptions,(ssize_t) font_stretch)); 5241 } 5242 } 5243 5244 /* 5246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5247 % % 5248 % % 5249 % % 5250 % D r a w S e t F o n t S t y l e % 5251 % % 5252 % % 5253 % % 5254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5255 % 5256 % DrawSetFontStyle() sets the font style to use when annotating with text. 5257 % The AnyStyle enumeration acts as a wild-card "don't care" option. 5258 % 5259 % The format of the DrawSetFontStyle method is: 5260 % 5261 % void DrawSetFontStyle(DrawingWand *wand,const StyleType style) 5262 % 5263 % A description of each parameter follows: 5264 % 5265 % o wand: the drawing wand. 5266 % 5267 % o style: font style (NormalStyle, ItalicStyle, ObliqueStyle, AnyStyle) 5268 % 5269 */ 5270 WandExport void DrawSetFontStyle(DrawingWand *wand,const StyleType style) 5271 { 5272 assert(wand != (DrawingWand *) NULL); 5273 assert(wand->signature == MagickWandSignature); 5274 if (wand->debug != MagickFalse) 5275 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5276 if ((wand->filter_off != MagickFalse) || 5277 (CurrentContext->style != style)) 5278 { 5279 CurrentContext->style=style; 5280 (void) MVGPrintf(wand, "font-style '%s'\n",CommandOptionToMnemonic( 5281 MagickStyleOptions,(ssize_t) style)); 5282 } 5283 } 5284 5285 /* 5287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5288 % % 5289 % % 5290 % % 5291 % D r a w S e t F o n t W e i g h t % 5292 % % 5293 % % 5294 % % 5295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5296 % 5297 % DrawSetFontWeight() sets the font weight to use when annotating with text. 5298 % 5299 % The format of the DrawSetFontWeight method is: 5300 % 5301 % void DrawSetFontWeight(DrawingWand *wand, 5302 % const size_t font_weight) 5303 % 5304 % A description of each parameter follows: 5305 % 5306 % o wand: the drawing wand. 5307 % 5308 % o font_weight: font weight (valid range 100-900) 5309 % 5310 */ 5311 WandExport void DrawSetFontWeight(DrawingWand *wand, 5312 const size_t font_weight) 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->weight != font_weight)) 5320 { 5321 CurrentContext->weight=font_weight; 5322 (void) MVGPrintf(wand,"font-weight %.20g\n",(double) font_weight); 5323 } 5324 } 5325 5326 /* 5328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5329 % % 5330 % % 5331 % % 5332 % D r a w S e t G r a v i t y % 5333 % % 5334 % % 5335 % % 5336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5337 % 5338 % DrawSetGravity() sets the text placement gravity to use when annotating 5339 % with text. 5340 % 5341 % The format of the DrawSetGravity method is: 5342 % 5343 % void DrawSetGravity(DrawingWand *wand,const GravityType gravity) 5344 % 5345 % A description of each parameter follows: 5346 % 5347 % o wand: the drawing wand. 5348 % 5349 % o gravity: positioning gravity (NorthWestGravity, NorthGravity, 5350 % NorthEastGravity, WestGravity, CenterGravity, 5351 % EastGravity, SouthWestGravity, SouthGravity, 5352 % SouthEastGravity) 5353 % 5354 */ 5355 WandExport void DrawSetGravity(DrawingWand *wand,const GravityType gravity) 5356 { 5357 assert(wand != (DrawingWand *) NULL); 5358 assert(wand->signature == MagickWandSignature); 5359 if (wand->debug != MagickFalse) 5360 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5361 if ((wand->filter_off != MagickFalse) || 5362 (CurrentContext->gravity != gravity) || (gravity != ForgetGravity)) 5363 { 5364 CurrentContext->gravity=gravity; 5365 (void) MVGPrintf(wand,"gravity '%s'\n",CommandOptionToMnemonic( 5366 MagickGravityOptions,(ssize_t) gravity)); 5367 } 5368 } 5369 5370 /* 5372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5373 % % 5374 % % 5375 % % 5376 % D r a w S e t S t r o k e C o l o r % 5377 % % 5378 % % 5379 % % 5380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5381 % 5382 % DrawSetStrokeColor() sets the color used for stroking object outlines. 5383 % 5384 % The format of the DrawSetStrokeColor method is: 5385 % 5386 % void DrawSetStrokeColor(DrawingWand *wand, 5387 % const PixelWand *stroke_wand) 5388 % 5389 % A description of each parameter follows: 5390 % 5391 % o wand: the drawing wand. 5392 % 5393 % o stroke_wand: stroke wand. 5394 % 5395 */ 5396 WandExport void DrawSetStrokeColor(DrawingWand *wand, 5397 const PixelWand *stroke_wand) 5398 { 5399 PixelInfo 5400 *current_stroke, 5401 new_stroke, 5402 stroke_color; 5403 5404 assert(wand != (DrawingWand *) NULL); 5405 assert(wand->signature == MagickWandSignature); 5406 if (wand->debug != MagickFalse) 5407 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5408 assert(stroke_wand != (const PixelWand *) NULL); 5409 PixelGetQuantumPacket(stroke_wand,&stroke_color); 5410 new_stroke=stroke_color; 5411 current_stroke=(&CurrentContext->stroke); 5412 if ((wand->filter_off != MagickFalse) || 5413 (IsPixelInfoEquivalent(current_stroke,&new_stroke) == MagickFalse)) 5414 { 5415 CurrentContext->stroke=new_stroke; 5416 (void) MVGPrintf(wand,"stroke '"); 5417 MVGAppendColor(wand,&stroke_color); 5418 (void) MVGPrintf(wand,"'\n"); 5419 } 5420 } 5421 5422 /* 5424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5425 % % 5426 % % 5427 % % 5428 % D r a w S e t S t r o k e P a t t e r n U R L % 5429 % % 5430 % % 5431 % % 5432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5433 % 5434 % DrawSetStrokePatternURL() sets the pattern used for stroking object outlines. 5435 % 5436 % The format of the DrawSetStrokePatternURL method is: 5437 % 5438 % MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand, 5439 % const char *stroke_url) 5440 % 5441 % A description of each parameter follows: 5442 % 5443 % o wand: the drawing wand. 5444 % 5445 % o stroke_url: URL specifying pattern ID (e.g. "#pattern_id") 5446 % 5447 */ 5448 WandExport MagickBooleanType DrawSetStrokePatternURL(DrawingWand *wand, 5449 const char *stroke_url) 5450 { 5451 char 5452 pattern[MagickPathExtent], 5453 pattern_spec[MagickPathExtent]; 5454 5455 assert(wand != (DrawingWand *) NULL); 5456 assert(wand->signature == MagickWandSignature); 5457 if (wand->debug != MagickFalse) 5458 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5459 if (wand->image == (Image *) NULL) 5460 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 5461 assert(stroke_url != NULL); 5462 if (stroke_url[0] != '#') 5463 ThrowDrawException(DrawError,"NotARelativeURL",stroke_url); 5464 (void) FormatLocaleString(pattern,MagickPathExtent,"%s",stroke_url+1); 5465 if (GetImageArtifact(wand->image,pattern) == (const char *) NULL) 5466 { 5467 ThrowDrawException(DrawError,"URLNotFound",stroke_url) 5468 return(MagickFalse); 5469 } 5470 (void) FormatLocaleString(pattern_spec,MagickPathExtent,"url(%s)",stroke_url); 5471 #if DRAW_BINARY_IMPLEMENTATION 5472 DrawPatternPath(wand->image,CurrentContext,pattern_spec, 5473 &CurrentContext->stroke_pattern); 5474 #endif 5475 if (CurrentContext->stroke.alpha != (Quantum) TransparentAlpha) 5476 CurrentContext->stroke.alpha=(double) CurrentContext->alpha; 5477 (void) MVGPrintf(wand,"stroke %s\n",pattern_spec); 5478 return(MagickTrue); 5479 } 5480 5481 /* 5483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5484 % % 5485 % % 5486 % % 5487 % D r a w S e t S t r o k e A n t i a l i a s % 5488 % % 5489 % % 5490 % % 5491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5492 % 5493 % DrawSetStrokeAntialias() controls whether stroked outlines are antialiased. 5494 % Stroked outlines are antialiased by default. When antialiasing is disabled 5495 % stroked pixels are thresholded to determine if the stroke color or 5496 % underlying canvas color should be used. 5497 % 5498 % The format of the DrawSetStrokeAntialias method is: 5499 % 5500 % void DrawSetStrokeAntialias(DrawingWand *wand, 5501 % const MagickBooleanType stroke_antialias) 5502 % 5503 % A description of each parameter follows: 5504 % 5505 % o wand: the drawing wand. 5506 % 5507 % o stroke_antialias: set to false (zero) to disable antialiasing 5508 % 5509 */ 5510 WandExport void DrawSetStrokeAntialias(DrawingWand *wand, 5511 const MagickBooleanType stroke_antialias) 5512 { 5513 assert(wand != (DrawingWand *) NULL); 5514 assert(wand->signature == MagickWandSignature); 5515 if (wand->debug != MagickFalse) 5516 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5517 if ((wand->filter_off != MagickFalse) || 5518 (CurrentContext->stroke_antialias != stroke_antialias)) 5519 { 5520 CurrentContext->stroke_antialias=stroke_antialias; 5521 (void) MVGPrintf(wand,"stroke-antialias %i\n",stroke_antialias != 0 ? 5522 1 : 0); 5523 } 5524 } 5525 5526 /* 5528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5529 % % 5530 % % 5531 % % 5532 % D r a w S e t S t r o k e D a s h A r r a y % 5533 % % 5534 % % 5535 % % 5536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5537 % 5538 % DrawSetStrokeDashArray() specifies the pattern of dashes and gaps used to 5539 % stroke paths. The stroke dash array represents an array of numbers that 5540 % specify the lengths of alternating dashes and gaps in pixels. If an odd 5541 % number of values is provided, then the list of values is repeated to yield 5542 % an even number of values. To remove an existing dash array, pass a zero 5543 % number_elements argument and null dasharray. A typical stroke dash array 5544 % might contain the members 5 3 2. 5545 % 5546 % The format of the DrawSetStrokeDashArray method is: 5547 % 5548 % MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand, 5549 % const size_t number_elements,const double *dasharray) 5550 % 5551 % A description of each parameter follows: 5552 % 5553 % o wand: the drawing wand. 5554 % 5555 % o number_elements: number of elements in dash array 5556 % 5557 % o dasharray: dash array values 5558 % 5559 */ 5560 WandExport MagickBooleanType DrawSetStrokeDashArray(DrawingWand *wand, 5561 const size_t number_elements,const double *dasharray) 5562 { 5563 MagickBooleanType 5564 update; 5565 5566 register const double 5567 *p; 5568 5569 register double 5570 *q; 5571 5572 register ssize_t 5573 i; 5574 5575 size_t 5576 n_new, 5577 n_old; 5578 5579 assert(wand != (DrawingWand *) NULL); 5580 assert(wand->signature == MagickWandSignature); 5581 if (wand->debug != MagickFalse) 5582 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5583 n_new=number_elements; 5584 if (dasharray == (const double *) NULL) 5585 n_new=0; 5586 n_old=0; 5587 update=MagickFalse; 5588 q=CurrentContext->dash_pattern; 5589 if (q != (const double *) NULL) 5590 while (fabs(*q++) < MagickEpsilon) 5591 n_old++; 5592 if ((n_old == 0) && (n_new == 0)) 5593 update=MagickFalse; 5594 else 5595 if (n_old != n_new) 5596 update=MagickTrue; 5597 else 5598 if ((CurrentContext->dash_pattern != (double *) NULL) && 5599 (dasharray != (double *) NULL)) 5600 { 5601 p=dasharray; 5602 q=CurrentContext->dash_pattern; 5603 for (i=0; i < (ssize_t) n_new; i++) 5604 { 5605 if (fabs((*p)-(*q)) >= MagickEpsilon) 5606 { 5607 update=MagickTrue; 5608 break; 5609 } 5610 p++; 5611 q++; 5612 } 5613 } 5614 if ((wand->filter_off != MagickFalse) || (update != MagickFalse)) 5615 { 5616 if (CurrentContext->dash_pattern != (double *) NULL) 5617 CurrentContext->dash_pattern=(double *) 5618 RelinquishMagickMemory(CurrentContext->dash_pattern); 5619 if (n_new != 0) 5620 { 5621 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory((size_t) 5622 n_new+1UL,sizeof(*CurrentContext->dash_pattern)); 5623 if (CurrentContext->dash_pattern == (double *) NULL) 5624 { 5625 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed", 5626 wand->name); 5627 return(MagickFalse); 5628 } 5629 for (i=0; i < (ssize_t) n_new; i++) 5630 { 5631 CurrentContext->dash_pattern[i]=0.0; 5632 if (dasharray != (double *) NULL) 5633 CurrentContext->dash_pattern[i]=dasharray[i]; 5634 } 5635 CurrentContext->dash_pattern[n_new]=0.0; 5636 } 5637 (void) MVGPrintf(wand,"stroke-dasharray "); 5638 if (n_new == 0) 5639 (void) MVGPrintf(wand,"none\n"); 5640 else 5641 if (dasharray != (double *) NULL) 5642 { 5643 for (i=0; i < (ssize_t) n_new; i++) 5644 { 5645 if (i != 0) 5646 (void) MVGPrintf(wand,","); 5647 (void) MVGPrintf(wand,"%.20g",dasharray[i]); 5648 } 5649 (void) MVGPrintf(wand,"\n"); 5650 } 5651 } 5652 return(MagickTrue); 5653 } 5654 5655 /* 5657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5658 % % 5659 % % 5660 % % 5661 % D r a w S e t S t r o k e D a s h O f f s e t % 5662 % % 5663 % % 5664 % % 5665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5666 % 5667 % DrawSetStrokeDashOffset() specifies the offset into the dash pattern to 5668 % start the dash. 5669 % 5670 % The format of the DrawSetStrokeDashOffset method is: 5671 % 5672 % void DrawSetStrokeDashOffset(DrawingWand *wand, 5673 % const double dash_offset) 5674 % 5675 % A description of each parameter follows: 5676 % 5677 % o wand: the drawing wand. 5678 % 5679 % o dash_offset: dash offset 5680 % 5681 */ 5682 WandExport void DrawSetStrokeDashOffset(DrawingWand *wand, 5683 const double dash_offset) 5684 { 5685 assert(wand != (DrawingWand *) NULL); 5686 assert(wand->signature == MagickWandSignature); 5687 if (wand->debug != MagickFalse) 5688 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5689 if ((wand->filter_off != MagickFalse) || 5690 (fabs(CurrentContext->dash_offset-dash_offset) >= MagickEpsilon)) 5691 { 5692 CurrentContext->dash_offset=dash_offset; 5693 (void) MVGPrintf(wand,"stroke-dashoffset %.20g\n",dash_offset); 5694 } 5695 } 5696 5697 /* 5699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5700 % % 5701 % % 5702 % % 5703 % D r a w S e t S t r o k e L i n e C a p % 5704 % % 5705 % % 5706 % % 5707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5708 % 5709 % DrawSetStrokeLineCap() specifies the shape to be used at the end of 5710 % open subpaths when they are stroked. Values of LineCap are 5711 % UndefinedCap, ButtCap, RoundCap, and SquareCap. 5712 % 5713 % The format of the DrawSetStrokeLineCap method is: 5714 % 5715 % void DrawSetStrokeLineCap(DrawingWand *wand, 5716 % const LineCap linecap) 5717 % 5718 % A description of each parameter follows: 5719 % 5720 % o wand: the drawing wand. 5721 % 5722 % o linecap: linecap style 5723 % 5724 */ 5725 WandExport void DrawSetStrokeLineCap(DrawingWand *wand,const LineCap linecap) 5726 { 5727 assert(wand != (DrawingWand *) NULL); 5728 assert(wand->signature == MagickWandSignature); 5729 if (wand->debug != MagickFalse) 5730 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5731 if ((wand->filter_off != MagickFalse) || (CurrentContext->linecap != linecap)) 5732 { 5733 CurrentContext->linecap=linecap; 5734 (void) MVGPrintf(wand,"stroke-linecap '%s'\n",CommandOptionToMnemonic( 5735 MagickLineCapOptions,(ssize_t) linecap)); 5736 } 5737 } 5738 5739 /* 5741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5742 % % 5743 % % 5744 % % 5745 % D r a w S e t S t r o k e L i n e J o i n % 5746 % % 5747 % % 5748 % % 5749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5750 % 5751 % DrawSetStrokeLineJoin() specifies the shape to be used at the corners of 5752 % paths (or other vector shapes) when they are stroked. Values of LineJoin are 5753 % UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin. 5754 % 5755 % The format of the DrawSetStrokeLineJoin method is: 5756 % 5757 % void DrawSetStrokeLineJoin(DrawingWand *wand, 5758 % const LineJoin linejoin) 5759 % 5760 % A description of each parameter follows: 5761 % 5762 % o wand: the drawing wand. 5763 % 5764 % o linejoin: line join style 5765 % 5766 */ 5767 WandExport void DrawSetStrokeLineJoin(DrawingWand *wand,const LineJoin linejoin) 5768 { 5769 assert(wand != (DrawingWand *) NULL); 5770 assert(wand->signature == MagickWandSignature); 5771 if (wand->debug != MagickFalse) 5772 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5773 if ((wand->filter_off != MagickFalse) || 5774 (CurrentContext->linejoin != linejoin)) 5775 { 5776 CurrentContext->linejoin=linejoin; 5777 (void) MVGPrintf(wand, "stroke-linejoin '%s'\n",CommandOptionToMnemonic( 5778 MagickLineJoinOptions,(ssize_t) linejoin)); 5779 } 5780 } 5781 5782 /* 5784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5785 % % 5786 % % 5787 % % 5788 % D r a w S e t S t r o k e M i t e r L i m i t % 5789 % % 5790 % % 5791 % % 5792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5793 % 5794 % DrawSetStrokeMiterLimit() specifies the miter limit. When two line 5795 % segments meet at a sharp angle and miter joins have been specified for 5796 % 'lineJoin', it is possible for the miter to extend far beyond the 5797 % thickness of the line stroking the path. The miterLimit' imposes a 5798 % limit on the ratio of the miter length to the 'lineWidth'. 5799 % 5800 % The format of the DrawSetStrokeMiterLimit method is: 5801 % 5802 % void DrawSetStrokeMiterLimit(DrawingWand *wand, 5803 % const size_t miterlimit) 5804 % 5805 % A description of each parameter follows: 5806 % 5807 % o wand: the drawing wand. 5808 % 5809 % o miterlimit: miter limit 5810 % 5811 */ 5812 WandExport void DrawSetStrokeMiterLimit(DrawingWand *wand, 5813 const size_t miterlimit) 5814 { 5815 assert(wand != (DrawingWand *) NULL); 5816 assert(wand->signature == MagickWandSignature); 5817 if (wand->debug != MagickFalse) 5818 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5819 if (CurrentContext->miterlimit != miterlimit) 5820 { 5821 CurrentContext->miterlimit=miterlimit; 5822 (void) MVGPrintf(wand,"stroke-miterlimit %.20g\n",(double) miterlimit); 5823 } 5824 } 5825 5826 /* 5828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5829 % % 5830 % % 5831 % % 5832 % D r a w S e t S t r o k e O p a c i t y % 5833 % % 5834 % % 5835 % % 5836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5837 % 5838 % DrawSetStrokeOpacity() specifies the alpha of stroked object outlines. 5839 % 5840 % The format of the DrawSetStrokeOpacity method is: 5841 % 5842 % void DrawSetStrokeOpacity(DrawingWand *wand, 5843 % const double stroke_alpha) 5844 % 5845 % A description of each parameter follows: 5846 % 5847 % o wand: the drawing wand. 5848 % 5849 % o opacity: stroke opacity. The value 1.0 is opaque. 5850 % 5851 */ 5852 WandExport void DrawSetStrokeOpacity(DrawingWand *wand, 5853 const double opacity) 5854 { 5855 double 5856 alpha; 5857 5858 assert(wand != (DrawingWand *) NULL); 5859 assert(wand->signature == MagickWandSignature); 5860 if (wand->debug != MagickFalse) 5861 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5862 alpha=(double) ClampToQuantum(QuantumRange*opacity); 5863 if ((wand->filter_off != MagickFalse) || 5864 (CurrentContext->stroke.alpha != alpha)) 5865 { 5866 CurrentContext->stroke.alpha=alpha; 5867 (void) MVGPrintf(wand,"stroke-opacity %.20g\n",opacity); 5868 } 5869 } 5870 5871 /* 5873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5874 % % 5875 % % 5876 % % 5877 % D r a w S e t S t r o k e W i d t h % 5878 % % 5879 % % 5880 % % 5881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5882 % 5883 % DrawSetStrokeWidth() sets the width of the stroke used to draw object 5884 % outlines. 5885 % 5886 % The format of the DrawSetStrokeWidth method is: 5887 % 5888 % void DrawSetStrokeWidth(DrawingWand *wand, 5889 % const double stroke_width) 5890 % 5891 % A description of each parameter follows: 5892 % 5893 % o wand: the drawing wand. 5894 % 5895 % o stroke_width: stroke width 5896 % 5897 */ 5898 WandExport void DrawSetStrokeWidth(DrawingWand *wand,const double stroke_width) 5899 { 5900 assert(wand != (DrawingWand *) NULL); 5901 assert(wand->signature == MagickWandSignature); 5902 if (wand->debug != MagickFalse) 5903 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5904 if ((wand->filter_off != MagickFalse) || 5905 (fabs(CurrentContext->stroke_width-stroke_width) >= MagickEpsilon)) 5906 { 5907 CurrentContext->stroke_width=stroke_width; 5908 (void) MVGPrintf(wand,"stroke-width %.20g\n",stroke_width); 5909 } 5910 } 5911 5912 /* 5914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5915 % % 5916 % % 5917 % % 5918 % D r a w S e t T e x t A l i g n m e n t % 5919 % % 5920 % % 5921 % % 5922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5923 % 5924 % DrawSetTextAlignment() specifies a text alignment to be applied when 5925 % annotating with text. 5926 % 5927 % The format of the DrawSetTextAlignment method is: 5928 % 5929 % void DrawSetTextAlignment(DrawingWand *wand,const AlignType alignment) 5930 % 5931 % A description of each parameter follows: 5932 % 5933 % o wand: the drawing wand. 5934 % 5935 % o alignment: text alignment. One of UndefinedAlign, LeftAlign, 5936 % CenterAlign, or RightAlign. 5937 % 5938 */ 5939 WandExport void DrawSetTextAlignment(DrawingWand *wand, 5940 const AlignType alignment) 5941 { 5942 assert(wand != (DrawingWand *) NULL); 5943 assert(wand->signature == MagickWandSignature); 5944 if (wand->debug != MagickFalse) 5945 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5946 if ((wand->filter_off != MagickFalse) || 5947 (CurrentContext->align != alignment)) 5948 { 5949 CurrentContext->align=alignment; 5950 (void) MVGPrintf(wand,"text-align '%s'\n",CommandOptionToMnemonic( 5951 MagickAlignOptions,(ssize_t) alignment)); 5952 } 5953 } 5954 5955 /* 5957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5958 % % 5959 % % 5960 % % 5961 % D r a w S e t T e x t A n t i a l i a s % 5962 % % 5963 % % 5964 % % 5965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5966 % 5967 % DrawSetTextAntialias() controls whether text is antialiased. Text is 5968 % antialiased by default. 5969 % 5970 % The format of the DrawSetTextAntialias method is: 5971 % 5972 % void DrawSetTextAntialias(DrawingWand *wand, 5973 % const MagickBooleanType text_antialias) 5974 % 5975 % A description of each parameter follows: 5976 % 5977 % o wand: the drawing wand. 5978 % 5979 % o text_antialias: antialias boolean. Set to false (0) to disable 5980 % antialiasing. 5981 % 5982 */ 5983 WandExport void DrawSetTextAntialias(DrawingWand *wand, 5984 const MagickBooleanType text_antialias) 5985 { 5986 assert(wand != (DrawingWand *) NULL); 5987 assert(wand->signature == MagickWandSignature); 5988 if (wand->debug != MagickFalse) 5989 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 5990 if ((wand->filter_off != MagickFalse) || 5991 (CurrentContext->text_antialias != text_antialias)) 5992 { 5993 CurrentContext->text_antialias=text_antialias; 5994 (void) MVGPrintf(wand,"text-antialias %i\n",text_antialias != 0 ? 1 : 0); 5995 } 5996 } 5997 5998 /* 6000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6001 % % 6002 % % 6003 % % 6004 % D r a w S e t T e x t D e c o r a t i o n % 6005 % % 6006 % % 6007 % % 6008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6009 % 6010 % DrawSetTextDecoration() specifies a decoration to be applied when 6011 % annotating with text. 6012 % 6013 % The format of the DrawSetTextDecoration method is: 6014 % 6015 % void DrawSetTextDecoration(DrawingWand *wand, 6016 % const DecorationType decoration) 6017 % 6018 % A description of each parameter follows: 6019 % 6020 % o wand: the drawing wand. 6021 % 6022 % o decoration: text decoration. One of NoDecoration, UnderlineDecoration, 6023 % OverlineDecoration, or LineThroughDecoration 6024 % 6025 */ 6026 WandExport void DrawSetTextDecoration(DrawingWand *wand, 6027 const DecorationType decoration) 6028 { 6029 assert(wand != (DrawingWand *) NULL); 6030 assert(wand->signature == MagickWandSignature); 6031 if (wand->debug != MagickFalse) 6032 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6033 if ((wand->filter_off != MagickFalse) || 6034 (CurrentContext->decorate != decoration)) 6035 { 6036 CurrentContext->decorate=decoration; 6037 (void) MVGPrintf(wand,"decorate '%s'\n",CommandOptionToMnemonic( 6038 MagickDecorateOptions,(ssize_t) decoration)); 6039 } 6040 } 6041 6042 /* 6044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6045 % % 6046 % % 6047 % % 6048 % D r a w S e t T e x t D i r e c t i o n % 6049 % % 6050 % % 6051 % % 6052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6053 % 6054 % DrawSetTextDirection() specifies the direction to be used when 6055 % annotating with text. 6056 % 6057 % The format of the DrawSetTextDirection method is: 6058 % 6059 % void DrawSetTextDirection(DrawingWand *wand, 6060 % const DirectionType direction) 6061 % 6062 % A description of each parameter follows: 6063 % 6064 % o wand: the drawing wand. 6065 % 6066 % o direction: text direction. One of RightToLeftDirection, 6067 % LeftToRightDirection 6068 % 6069 */ 6070 WandExport void DrawSetTextDirection(DrawingWand *wand, 6071 const DirectionType direction) 6072 { 6073 assert(wand != (DrawingWand *) NULL); 6074 assert(wand->signature == MagickWandSignature); 6075 6076 if (wand->debug != MagickFalse) 6077 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6078 if ((wand->filter_off != MagickFalse) || 6079 (CurrentContext->direction != direction)) 6080 { 6081 CurrentContext->direction=direction; 6082 (void) MVGPrintf(wand,"direction '%s'\n",CommandOptionToMnemonic( 6083 MagickDirectionOptions,(ssize_t) direction)); 6084 } 6085 } 6086 6087 /* 6088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6089 % % 6090 % % 6091 % % 6092 % D r a w S e t T e x t E n c o d i n g % 6093 % % 6094 % % 6095 % % 6096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6097 % 6098 % DrawSetTextEncoding() specifies the code set to use for text 6099 % annotations. The only character encoding which may be specified 6100 % at this time is "UTF-8" for representing Unicode as a sequence of 6101 % bytes. Specify an empty string to set text encoding to the system's 6102 % default. Successful text annotation using Unicode may require fonts 6103 % designed to support Unicode. 6104 % 6105 % The format of the DrawSetTextEncoding method is: 6106 % 6107 % void DrawSetTextEncoding(DrawingWand *wand,const char *encoding) 6108 % 6109 % A description of each parameter follows: 6110 % 6111 % o wand: the drawing wand. 6112 % 6113 % o encoding: character string specifying text encoding 6114 % 6115 */ 6116 WandExport void DrawSetTextEncoding(DrawingWand *wand,const char *encoding) 6117 { 6118 assert(wand != (DrawingWand *) NULL); 6119 assert(wand->signature == MagickWandSignature); 6120 if (wand->debug != MagickFalse) 6121 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6122 assert(encoding != (char *) NULL); 6123 if ((wand->filter_off != MagickFalse) || 6124 (CurrentContext->encoding == (char *) NULL) || 6125 (LocaleCompare(CurrentContext->encoding,encoding) != 0)) 6126 { 6127 (void) CloneString(&CurrentContext->encoding,encoding); 6128 (void) MVGPrintf(wand,"encoding '%s'\n",encoding); 6129 } 6130 } 6131 6132 /* 6134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6135 % % 6136 % % 6137 % % 6138 % D r a w S e t T e x t K e r n i n g % 6139 % % 6140 % % 6141 % % 6142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6143 % 6144 % DrawSetTextKerning() sets the spacing between characters in text. 6145 % 6146 % The format of the DrawSetTextKerning method is: 6147 % 6148 % void DrawSetTextKerning(DrawingWand *wand,const double kerning) 6149 % 6150 % A description of each parameter follows: 6151 % 6152 % o wand: the drawing wand. 6153 % 6154 % o kerning: text kerning 6155 % 6156 */ 6157 WandExport void DrawSetTextKerning(DrawingWand *wand,const double kerning) 6158 { 6159 assert(wand != (DrawingWand *) NULL); 6160 assert(wand->signature == MagickWandSignature); 6161 6162 if (wand->debug != MagickFalse) 6163 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6164 if ((wand->filter_off != MagickFalse) && 6165 ((CurrentContext->kerning-kerning) >= MagickEpsilon)) 6166 { 6167 CurrentContext->kerning=kerning; 6168 (void) MVGPrintf(wand,"kerning %lf\n",kerning); 6169 } 6170 } 6171 6172 /* 6174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6175 % % 6176 % % 6177 % % 6178 % 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 % 6179 % % 6180 % % 6181 % % 6182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6183 % 6184 % DrawSetTextInterlineSpacing() sets the spacing between line in text. 6185 % 6186 % The format of the DrawSetInterlineSpacing method is: 6187 % 6188 % void DrawSetTextInterlineSpacing(DrawingWand *wand, 6189 % const double interline_spacing) 6190 % 6191 % A description of each parameter follows: 6192 % 6193 % o wand: the drawing wand. 6194 % 6195 % o interline_spacing: text line spacing 6196 % 6197 */ 6198 WandExport void DrawSetTextInterlineSpacing(DrawingWand *wand, 6199 const double interline_spacing) 6200 { 6201 assert(wand != (DrawingWand *) NULL); 6202 assert(wand->signature == MagickWandSignature); 6203 6204 if (wand->debug != MagickFalse) 6205 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6206 if ((wand->filter_off != MagickFalse) && 6207 ((CurrentContext->interline_spacing-interline_spacing) >= MagickEpsilon)) 6208 { 6209 CurrentContext->interline_spacing=interline_spacing; 6210 (void) MVGPrintf(wand,"interline-spacing %lf\n",interline_spacing); 6211 } 6212 } 6213 6214 /* 6216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6217 % % 6218 % % 6219 % % 6220 % 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 % 6221 % % 6222 % % 6223 % % 6224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6225 % 6226 % DrawSetTextInterwordSpacing() sets the spacing between words in text. 6227 % 6228 % The format of the DrawSetInterwordSpacing method is: 6229 % 6230 % void DrawSetTextInterwordSpacing(DrawingWand *wand, 6231 % const double interword_spacing) 6232 % 6233 % A description of each parameter follows: 6234 % 6235 % o wand: the drawing wand. 6236 % 6237 % o interword_spacing: text word spacing 6238 % 6239 */ 6240 WandExport void DrawSetTextInterwordSpacing(DrawingWand *wand, 6241 const double interword_spacing) 6242 { 6243 assert(wand != (DrawingWand *) NULL); 6244 assert(wand->signature == MagickWandSignature); 6245 6246 if (wand->debug != MagickFalse) 6247 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6248 if ((wand->filter_off != MagickFalse) && 6249 ((CurrentContext->interword_spacing-interword_spacing) >= MagickEpsilon)) 6250 { 6251 CurrentContext->interword_spacing=interword_spacing; 6252 (void) MVGPrintf(wand,"interword-spacing %lf\n",interword_spacing); 6253 } 6254 } 6255 6256 /* 6258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6259 % % 6260 % % 6261 % % 6262 % D r a w S e t T e x t U n d e r C o l o r % 6263 % % 6264 % % 6265 % % 6266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6267 % 6268 % DrawSetTextUnderColor() specifies the color of a background rectangle 6269 % to place under text annotations. 6270 % 6271 % The format of the DrawSetTextUnderColor method is: 6272 % 6273 % void DrawSetTextUnderColor(DrawingWand *wand, 6274 % const PixelWand *under_wand) 6275 % 6276 % A description of each parameter follows: 6277 % 6278 % o wand: the drawing wand. 6279 % 6280 % o under_wand: text under wand. 6281 % 6282 */ 6283 WandExport void DrawSetTextUnderColor(DrawingWand *wand, 6284 const PixelWand *under_wand) 6285 { 6286 PixelInfo 6287 under_color; 6288 6289 assert(wand != (DrawingWand *) NULL); 6290 assert(wand->signature == MagickWandSignature); 6291 if (wand->debug != MagickFalse) 6292 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6293 assert(under_wand != (const PixelWand *) NULL); 6294 PixelGetQuantumPacket(under_wand,&under_color); 6295 if ((wand->filter_off != MagickFalse) || 6296 (IsPixelInfoEquivalent(&CurrentContext->undercolor,&under_color) == MagickFalse)) 6297 { 6298 CurrentContext->undercolor=under_color; 6299 (void) MVGPrintf(wand,"text-undercolor '"); 6300 MVGAppendColor(wand,&under_color); 6301 (void) MVGPrintf(wand,"'\n"); 6302 } 6303 } 6304 6305 /* 6307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6308 % % 6309 % % 6310 % % 6311 % D r a w S e t V e c t o r G r a p h i c s % 6312 % % 6313 % % 6314 % % 6315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6316 % 6317 % DrawSetVectorGraphics() sets the vector graphics associated with the 6318 % specified wand. Use this method with DrawGetVectorGraphics() as a method 6319 % to persist the vector graphics state. 6320 % 6321 % The format of the DrawSetVectorGraphics method is: 6322 % 6323 % MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand, 6324 % const char *xml) 6325 % 6326 % A description of each parameter follows: 6327 % 6328 % o wand: the drawing wand. 6329 % 6330 % o xml: the drawing wand XML. 6331 % 6332 */ 6333 6334 static inline MagickBooleanType IsPoint(const char *point) 6335 { 6336 char 6337 *p; 6338 6339 long 6340 value; 6341 6342 value=strtol(point,&p,10); 6343 (void) value; 6344 return(p != point ? MagickTrue : MagickFalse); 6345 } 6346 6347 WandExport MagickBooleanType DrawSetVectorGraphics(DrawingWand *wand, 6348 const char *xml) 6349 { 6350 const char 6351 *value; 6352 6353 XMLTreeInfo 6354 *child, 6355 *xml_info; 6356 6357 assert(wand != (DrawingWand *) NULL); 6358 assert(wand->signature == MagickWandSignature); 6359 if (wand->debug != MagickFalse) 6360 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6361 CurrentContext=DestroyDrawInfo(CurrentContext); 6362 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL); 6363 if (xml == (const char *) NULL) 6364 return(MagickFalse); 6365 xml_info=NewXMLTree(xml,wand->exception); 6366 if (xml_info == (XMLTreeInfo *) NULL) 6367 return(MagickFalse); 6368 child=GetXMLTreeChild(xml_info,"clip-path"); 6369 if (child != (XMLTreeInfo *) NULL) 6370 (void) CloneString(&CurrentContext->clip_mask,GetXMLTreeContent(child)); 6371 child=GetXMLTreeChild(xml_info,"clip-units"); 6372 if (child != (XMLTreeInfo *) NULL) 6373 { 6374 value=GetXMLTreeContent(child); 6375 if (value != (const char *) NULL) 6376 CurrentContext->clip_units=(ClipPathUnits) ParseCommandOption( 6377 MagickClipPathOptions,MagickFalse,value); 6378 } 6379 child=GetXMLTreeChild(xml_info,"decorate"); 6380 if (child != (XMLTreeInfo *) NULL) 6381 { 6382 value=GetXMLTreeContent(child); 6383 if (value != (const char *) NULL) 6384 CurrentContext->decorate=(DecorationType) ParseCommandOption( 6385 MagickDecorateOptions,MagickFalse,value); 6386 } 6387 child=GetXMLTreeChild(xml_info,"encoding"); 6388 if (child != (XMLTreeInfo *) NULL) 6389 (void) CloneString(&CurrentContext->encoding,GetXMLTreeContent(child)); 6390 child=GetXMLTreeChild(xml_info,"fill"); 6391 if (child != (XMLTreeInfo *) NULL) 6392 { 6393 value=GetXMLTreeContent(child); 6394 if (value != (const char *) NULL) 6395 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->fill, 6396 wand->exception); 6397 } 6398 child=GetXMLTreeChild(xml_info,"fill-opacity"); 6399 if (child != (XMLTreeInfo *) NULL) 6400 { 6401 value=GetXMLTreeContent(child); 6402 if (value != (const char *) NULL) 6403 CurrentContext->fill.alpha=(double) ClampToQuantum(QuantumRange* 6404 (1.0-StringToDouble(value,(char **) NULL))); 6405 } 6406 child=GetXMLTreeChild(xml_info,"fill-rule"); 6407 if (child != (XMLTreeInfo *) NULL) 6408 { 6409 value=GetXMLTreeContent(child); 6410 if (value != (const char *) NULL) 6411 CurrentContext->fill_rule=(FillRule) ParseCommandOption( 6412 MagickFillRuleOptions,MagickFalse,value); 6413 } 6414 child=GetXMLTreeChild(xml_info,"font"); 6415 if (child != (XMLTreeInfo *) NULL) 6416 (void) CloneString(&CurrentContext->font,GetXMLTreeContent(child)); 6417 child=GetXMLTreeChild(xml_info,"font-family"); 6418 if (child != (XMLTreeInfo *) NULL) 6419 (void) CloneString(&CurrentContext->family,GetXMLTreeContent(child)); 6420 child=GetXMLTreeChild(xml_info,"font-size"); 6421 if (child != (XMLTreeInfo *) NULL) 6422 { 6423 value=GetXMLTreeContent(child); 6424 if (value != (const char *) NULL) 6425 CurrentContext->pointsize=StringToDouble(value,(char **) NULL); 6426 } 6427 child=GetXMLTreeChild(xml_info,"font-stretch"); 6428 if (child != (XMLTreeInfo *) NULL) 6429 { 6430 value=GetXMLTreeContent(child); 6431 if (value != (const char *) NULL) 6432 CurrentContext->stretch=(StretchType) ParseCommandOption( 6433 MagickStretchOptions,MagickFalse,value); 6434 } 6435 child=GetXMLTreeChild(xml_info,"font-style"); 6436 if (child != (XMLTreeInfo *) NULL) 6437 { 6438 value=GetXMLTreeContent(child); 6439 if (value != (const char *) NULL) 6440 CurrentContext->style=(StyleType) ParseCommandOption(MagickStyleOptions, 6441 MagickFalse,value); 6442 } 6443 child=GetXMLTreeChild(xml_info,"font-weight"); 6444 if (child != (XMLTreeInfo *) NULL) 6445 { 6446 value=GetXMLTreeContent(child); 6447 if (value != (const char *) NULL) 6448 { 6449 ssize_t 6450 weight; 6451 6452 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,value); 6453 if (weight == -1) 6454 weight=StringToUnsignedLong(value); 6455 CurrentContext->weight=weight; 6456 } 6457 } 6458 child=GetXMLTreeChild(xml_info,"gravity"); 6459 if (child != (XMLTreeInfo *) NULL) 6460 { 6461 value=GetXMLTreeContent(child); 6462 if (value != (const char *) NULL) 6463 CurrentContext->gravity=(GravityType) ParseCommandOption( 6464 MagickGravityOptions,MagickFalse,value); 6465 } 6466 child=GetXMLTreeChild(xml_info,"stroke"); 6467 if (child != (XMLTreeInfo *) NULL) 6468 { 6469 value=GetXMLTreeContent(child); 6470 if (value != (const char *) NULL) 6471 (void) QueryColorCompliance(value,AllCompliance,&CurrentContext->stroke, 6472 wand->exception); 6473 } 6474 child=GetXMLTreeChild(xml_info,"stroke-antialias"); 6475 if (child != (XMLTreeInfo *) NULL) 6476 { 6477 value=GetXMLTreeContent(child); 6478 if (value != (const char *) NULL) 6479 CurrentContext->stroke_antialias=StringToLong(value) != 0 ? MagickTrue : 6480 MagickFalse; 6481 } 6482 child=GetXMLTreeChild(xml_info,"stroke-dasharray"); 6483 if (child != (XMLTreeInfo *) NULL) 6484 { 6485 char 6486 token[MagickPathExtent]; 6487 6488 const char 6489 *q; 6490 6491 register ssize_t 6492 x; 6493 6494 ssize_t 6495 j; 6496 6497 value=GetXMLTreeContent(child); 6498 if (value != (const char *) NULL) 6499 { 6500 if (CurrentContext->dash_pattern != (double *) NULL) 6501 CurrentContext->dash_pattern=(double *) RelinquishMagickMemory( 6502 CurrentContext->dash_pattern); 6503 q=(char *) value; 6504 if (IsPoint(q) != MagickFalse) 6505 { 6506 const char 6507 *p; 6508 6509 p=q; 6510 GetNextToken(p,&p,MagickPathExtent,token); 6511 if (*token == ',') 6512 GetNextToken(p,&p,MagickPathExtent,token); 6513 for (x=0; IsPoint(token) != MagickFalse; x++) 6514 { 6515 GetNextToken(p,&p,MagickPathExtent,token); 6516 if (*token == ',') 6517 GetNextToken(p,&p,MagickPathExtent,token); 6518 } 6519 CurrentContext->dash_pattern=(double *) AcquireQuantumMemory( 6520 (size_t) (2UL*x)+1UL,sizeof(*CurrentContext->dash_pattern)); 6521 if (CurrentContext->dash_pattern == (double *) NULL) 6522 ThrowWandFatalException(ResourceLimitFatalError, 6523 "MemoryAllocationFailed",wand->name); 6524 for (j=0; j < x; j++) 6525 { 6526 GetNextToken(q,&q,MagickPathExtent,token); 6527 if (*token == ',') 6528 GetNextToken(q,&q,MagickPathExtent,token); 6529 CurrentContext->dash_pattern[j]=StringToDouble(token, 6530 (char **) NULL); 6531 } 6532 if ((x & 0x01) != 0) 6533 for ( ; j < (2*x); j++) 6534 CurrentContext->dash_pattern[j]= 6535 CurrentContext->dash_pattern[j-x]; 6536 CurrentContext->dash_pattern[j]=0.0; 6537 } 6538 } 6539 } 6540 child=GetXMLTreeChild(xml_info,"stroke-dashoffset"); 6541 if (child != (XMLTreeInfo *) NULL) 6542 { 6543 value=GetXMLTreeContent(child); 6544 if (value != (const char *) NULL) 6545 CurrentContext->dash_offset=StringToDouble(value,(char **) NULL); 6546 } 6547 child=GetXMLTreeChild(xml_info,"stroke-linecap"); 6548 if (child != (XMLTreeInfo *) NULL) 6549 { 6550 value=GetXMLTreeContent(child); 6551 if (value != (const char *) NULL) 6552 CurrentContext->linecap=(LineCap) ParseCommandOption( 6553 MagickLineCapOptions,MagickFalse,value); 6554 } 6555 child=GetXMLTreeChild(xml_info,"stroke-linejoin"); 6556 if (child != (XMLTreeInfo *) NULL) 6557 { 6558 value=GetXMLTreeContent(child); 6559 if (value != (const char *) NULL) 6560 CurrentContext->linejoin=(LineJoin) ParseCommandOption( 6561 MagickLineJoinOptions,MagickFalse,value); 6562 } 6563 child=GetXMLTreeChild(xml_info,"stroke-miterlimit"); 6564 if (child != (XMLTreeInfo *) NULL) 6565 { 6566 value=GetXMLTreeContent(child); 6567 if (value != (const char *) NULL) 6568 CurrentContext->miterlimit=StringToUnsignedLong(value); 6569 } 6570 child=GetXMLTreeChild(xml_info,"stroke-opacity"); 6571 if (child != (XMLTreeInfo *) NULL) 6572 { 6573 value=GetXMLTreeContent(child); 6574 if (value != (const char *) NULL) 6575 CurrentContext->stroke.alpha=(double) ClampToQuantum(QuantumRange* 6576 (1.0-StringToDouble(value,(char **) NULL))); 6577 } 6578 child=GetXMLTreeChild(xml_info,"stroke-width"); 6579 if (child != (XMLTreeInfo *) NULL) 6580 { 6581 value=GetXMLTreeContent(child); 6582 if (value != (const char *) NULL) 6583 CurrentContext->stroke_width=StringToDouble(value,(char **) NULL); 6584 } 6585 child=GetXMLTreeChild(xml_info,"text-align"); 6586 if (child != (XMLTreeInfo *) NULL) 6587 { 6588 value=GetXMLTreeContent(child); 6589 if (value != (const char *) NULL) 6590 CurrentContext->align=(AlignType) ParseCommandOption(MagickAlignOptions, 6591 MagickFalse,value); 6592 } 6593 child=GetXMLTreeChild(xml_info,"text-antialias"); 6594 if (child != (XMLTreeInfo *) NULL) 6595 { 6596 value=GetXMLTreeContent(child); 6597 if (value != (const char *) NULL) 6598 CurrentContext->text_antialias=StringToLong(value) != 0 ? MagickTrue : 6599 MagickFalse; 6600 } 6601 child=GetXMLTreeChild(xml_info,"text-undercolor"); 6602 if (child != (XMLTreeInfo *) NULL) 6603 { 6604 value=GetXMLTreeContent(child); 6605 if (value != (const char *) NULL) 6606 (void) QueryColorCompliance(value,AllCompliance, 6607 &CurrentContext->undercolor,wand->exception); 6608 } 6609 child=GetXMLTreeChild(xml_info,"vector-graphics"); 6610 if (child != (XMLTreeInfo *) NULL) 6611 { 6612 (void) CloneString(&wand->mvg,GetXMLTreeContent(child)); 6613 wand->mvg_length=strlen(wand->mvg); 6614 wand->mvg_alloc=wand->mvg_length+1; 6615 } 6616 xml_info=DestroyXMLTree(xml_info); 6617 return(MagickTrue); 6618 } 6619 6620 /* 6622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6623 % % 6624 % % 6625 % % 6626 % D r a w S k e w X % 6627 % % 6628 % % 6629 % % 6630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6631 % 6632 % DrawSkewX() skews the current coordinate system in the horizontal 6633 % direction. 6634 % 6635 % The format of the DrawSkewX method is: 6636 % 6637 % void DrawSkewX(DrawingWand *wand,const double degrees) 6638 % 6639 % A description of each parameter follows: 6640 % 6641 % o wand: the drawing wand. 6642 % 6643 % o degrees: number of degrees to skew the coordinates 6644 % 6645 */ 6646 WandExport void DrawSkewX(DrawingWand *wand,const double degrees) 6647 { 6648 assert(wand != (DrawingWand *) NULL); 6649 assert(wand->signature == MagickWandSignature); 6650 if (wand->debug != MagickFalse) 6651 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6652 (void) MVGPrintf(wand,"skewX %.20g\n",degrees); 6653 } 6654 6655 /* 6657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6658 % % 6659 % % 6660 % % 6661 % D r a w S k e w Y % 6662 % % 6663 % % 6664 % % 6665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6666 % 6667 % DrawSkewY() skews the current coordinate system in the vertical 6668 % direction. 6669 % 6670 % The format of the DrawSkewY method is: 6671 % 6672 % void DrawSkewY(DrawingWand *wand,const double degrees) 6673 % 6674 % A description of each parameter follows: 6675 % 6676 % o wand: the drawing wand. 6677 % 6678 % o degrees: number of degrees to skew the coordinates 6679 % 6680 */ 6681 WandExport void DrawSkewY(DrawingWand *wand,const double degrees) 6682 { 6683 assert(wand != (DrawingWand *) NULL); 6684 assert(wand->signature == MagickWandSignature); 6685 if (wand->debug != MagickFalse) 6686 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6687 (void) MVGPrintf(wand,"skewY %.20g\n",degrees); 6688 } 6689 6690 /* 6692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6693 % % 6694 % % 6695 % % 6696 % D r a w T r a n s l a t e % 6697 % % 6698 % % 6699 % % 6700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6701 % 6702 % DrawTranslate() applies a translation to the current coordinate 6703 % system which moves the coordinate system origin to the specified 6704 % coordinate. 6705 % 6706 % The format of the DrawTranslate method is: 6707 % 6708 % void DrawTranslate(DrawingWand *wand,const double x, 6709 % const double y) 6710 % 6711 % A description of each parameter follows: 6712 % 6713 % o wand: the drawing wand. 6714 % 6715 % o x: new x ordinate for coordinate system origin 6716 % 6717 % o y: new y ordinate for coordinate system origin 6718 % 6719 */ 6720 WandExport void DrawTranslate(DrawingWand *wand,const double x,const double y) 6721 { 6722 assert(wand != (DrawingWand *) NULL); 6723 assert(wand->signature == MagickWandSignature); 6724 if (wand->debug != MagickFalse) 6725 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6726 (void) MVGPrintf(wand,"translate %.20g %.20g\n",x,y); 6727 } 6728 6729 /* 6731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6732 % % 6733 % % 6734 % % 6735 % D r a w S e t V i e w b o x % 6736 % % 6737 % % 6738 % % 6739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6740 % 6741 % DrawSetViewbox() sets the overall canvas size to be recorded with the 6742 % drawing vector data. Usually this will be specified using the same 6743 % size as the canvas image. When the vector data is saved to SVG or MVG 6744 % formats, the viewbox is use to specify the size of the canvas image that 6745 % a viewer will render the vector data on. 6746 % 6747 % The format of the DrawSetViewbox method is: 6748 % 6749 % void DrawSetViewbox(DrawingWand *wand,const double x1,const double y1, 6750 % const double x2,const double y2) 6751 % 6752 % A description of each parameter follows: 6753 % 6754 % o wand: the drawing wand. 6755 % 6756 % o x1: left x ordinate 6757 % 6758 % o y1: top y ordinate 6759 % 6760 % o x2: right x ordinate 6761 % 6762 % o y2: bottom y ordinate 6763 % 6764 */ 6765 WandExport void DrawSetViewbox(DrawingWand *wand,const double x1, 6766 const double y1,const double x2,const double y2) 6767 { 6768 assert(wand != (DrawingWand *) NULL); 6769 assert(wand->signature == MagickWandSignature); 6770 if (wand->debug != MagickFalse) 6771 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6772 (void) MVGPrintf(wand,"viewbox %.20g %.20g %.20g %.20g\n",x1,y1,x2,y2); 6773 } 6774 6775 /* 6777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6778 % % 6779 % % 6780 % % 6781 % I s D r a w i n g W a n d % 6782 % % 6783 % % 6784 % % 6785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6786 % 6787 % IsDrawingWand() returns MagickTrue if the wand is verified as a drawing wand. 6788 % 6789 % The format of the IsDrawingWand method is: 6790 % 6791 % MagickBooleanType IsDrawingWand(const DrawingWand *wand) 6792 % 6793 % A description of each parameter follows: 6794 % 6795 % o wand: the drawing wand. 6796 % 6797 */ 6798 WandExport MagickBooleanType IsDrawingWand(const DrawingWand *wand) 6799 { 6800 if (wand == (const DrawingWand *) NULL) 6801 return(MagickFalse); 6802 if (wand->signature != MagickWandSignature) 6803 return(MagickFalse); 6804 if (LocaleNCompare(wand->name,DrawingWandId,strlen(DrawingWandId)) != 0) 6805 return(MagickFalse); 6806 return(MagickTrue); 6807 } 6808 6809 /* 6811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6812 % % 6813 % % 6814 % % 6815 % N e w D r a w i n g W a n d % 6816 % % 6817 % % 6818 % % 6819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6820 % 6821 % NewDrawingWand() returns a drawing wand required for all other methods in 6822 % the API. 6823 % 6824 % The format of the NewDrawingWand method is: 6825 % 6826 % DrawingWand *NewDrawingWand(void) 6827 % 6828 */ 6829 WandExport DrawingWand *NewDrawingWand(void) 6830 { 6831 const char 6832 *quantum; 6833 6834 DrawingWand 6835 *wand; 6836 6837 size_t 6838 depth; 6839 6840 quantum=GetMagickQuantumDepth(&depth); 6841 if (depth != MAGICKCORE_QUANTUM_DEPTH) 6842 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum); 6843 wand=(DrawingWand *) AcquireMagickMemory(sizeof(*wand)); 6844 if (wand == (DrawingWand *) NULL) 6845 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 6846 GetExceptionMessage(errno)); 6847 (void) ResetMagickMemory(wand,0,sizeof(*wand)); 6848 wand->id=AcquireWandId(); 6849 (void) FormatLocaleString(wand->name,MagickPathExtent,"%s-%.20g", 6850 DrawingWandId,(double) wand->id); 6851 if (wand->debug != MagickFalse) 6852 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6853 wand->mvg=(char *) NULL; 6854 wand->mvg_alloc=0; 6855 wand->mvg_length=0; 6856 wand->mvg_width=0; 6857 wand->pattern_id=(char *) NULL; 6858 wand->pattern_offset=0; 6859 wand->pattern_bounds.x=0; 6860 wand->pattern_bounds.y=0; 6861 wand->pattern_bounds.width=0; 6862 wand->pattern_bounds.height=0; 6863 wand->index=0; 6864 wand->graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof( 6865 *wand->graphic_context)); 6866 if (wand->graphic_context == (DrawInfo **) NULL) 6867 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", 6868 GetExceptionMessage(errno)); 6869 wand->filter_off=MagickTrue; 6870 wand->indent_depth=0; 6871 wand->path_operation=PathDefaultOperation; 6872 wand->path_mode=DefaultPathMode; 6873 wand->exception=AcquireExceptionInfo(); 6874 wand->image=AcquireImage((const ImageInfo *) NULL,wand->exception); 6875 wand->destroy=MagickTrue; 6876 wand->debug=IsEventLogging(); 6877 wand->signature=MagickWandSignature; 6878 CurrentContext=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL); 6879 return(wand); 6880 } 6881 6882 /* 6884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6885 % % 6886 % % 6887 % % 6888 % P e e k D r a w i n g W a n d % 6889 % % 6890 % % 6891 % % 6892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6893 % 6894 % PeekDrawingWand() returns the current drawing wand. 6895 % 6896 % The format of the PeekDrawingWand method is: 6897 % 6898 % DrawInfo *PeekDrawingWand(const DrawingWand *wand) 6899 % 6900 % A description of each parameter follows: 6901 % 6902 % o wand: the drawing wand. 6903 % 6904 */ 6905 WandExport DrawInfo *PeekDrawingWand(const DrawingWand *wand) 6906 { 6907 DrawInfo 6908 *draw_info; 6909 6910 assert(wand != (const DrawingWand *) NULL); 6911 assert(wand->signature == MagickWandSignature); 6912 if (wand->debug != MagickFalse) 6913 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6914 draw_info=CloneDrawInfo((ImageInfo *) NULL,CurrentContext); 6915 GetAffineMatrix(&draw_info->affine); 6916 (void) CloneString(&draw_info->primitive,wand->mvg); 6917 return(draw_info); 6918 } 6919 6920 /* 6922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6923 % % 6924 % % 6925 % % 6926 % P o p D r a w i n g W a n d % 6927 % % 6928 % % 6929 % % 6930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6931 % 6932 % PopDrawingWand() destroys the current drawing wand and returns to the 6933 % previously pushed drawing wand. Multiple drawing wands may exist. It is an 6934 % error to attempt to pop more drawing wands than have been pushed, and it is 6935 % proper form to pop all drawing wands which have been pushed. 6936 % 6937 % The format of the PopDrawingWand method is: 6938 % 6939 % MagickBooleanType PopDrawingWand(DrawingWand *wand) 6940 % 6941 % A description of each parameter follows: 6942 % 6943 % o wand: the drawing wand. 6944 % 6945 */ 6946 WandExport MagickBooleanType PopDrawingWand(DrawingWand *wand) 6947 { 6948 assert(wand != (DrawingWand *) NULL); 6949 assert(wand->signature == MagickWandSignature); 6950 if (wand->debug != MagickFalse) 6951 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 6952 if (wand->index == 0) 6953 { 6954 ThrowDrawException(DrawError,"UnbalancedGraphicContextPushPop",wand->name) 6955 return(MagickFalse); 6956 } 6957 /* 6958 Destroy clip path if not same in preceding wand. 6959 */ 6960 #if DRAW_BINARY_IMPLEMENTATION 6961 if (wand->image == (Image *) NULL) 6962 ThrowDrawException(WandError,"ContainsNoImages",wand->name); 6963 if (CurrentContext->clip_mask != (char *) NULL) 6964 if (LocaleCompare(CurrentContext->clip_mask, 6965 wand->graphic_context[wand->index-1]->clip_mask) != 0) 6966 (void) SetImageMask(wand->image,ReadPixelMask,(Image *) NULL, 6967 wand->exception); 6968 #endif 6969 CurrentContext=DestroyDrawInfo(CurrentContext); 6970 wand->index--; 6971 if (wand->indent_depth > 0) 6972 wand->indent_depth--; 6973 (void) MVGPrintf(wand,"pop graphic-context\n"); 6974 return(MagickTrue); 6975 } 6976 6977 /* 6979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6980 % % 6981 % % 6982 % % 6983 % P u s h D r a w i n g W a n d % 6984 % % 6985 % % 6986 % % 6987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6988 % 6989 % PushDrawingWand() clones the current drawing wand to create a new drawing 6990 % wand. The original drawing wand(s) may be returned to by invoking 6991 % PopDrawingWand(). The drawing wands are stored on a drawing wand stack. 6992 % For every Pop there must have already been an equivalent Push. 6993 % 6994 % The format of the PushDrawingWand method is: 6995 % 6996 % MagickBooleanType PushDrawingWand(DrawingWand *wand) 6997 % 6998 % A description of each parameter follows: 6999 % 7000 % o wand: the drawing wand. 7001 % 7002 */ 7003 WandExport MagickBooleanType PushDrawingWand(DrawingWand *wand) 7004 { 7005 assert(wand != (DrawingWand *) NULL); 7006 assert(wand->signature == MagickWandSignature); 7007 if (wand->debug != MagickFalse) 7008 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name); 7009 wand->index++; 7010 wand->graphic_context=(DrawInfo **) ResizeQuantumMemory(wand->graphic_context, 7011 (size_t) wand->index+1UL,sizeof(*wand->graphic_context)); 7012 if (wand->graphic_context == (DrawInfo **) NULL) 7013 { 7014 wand->index--; 7015 ThrowDrawException(ResourceLimitError,"MemoryAllocationFailed", 7016 wand->name); 7017 return(MagickFalse); 7018 } 7019 CurrentContext=CloneDrawInfo((ImageInfo *) NULL, 7020 wand->graphic_context[wand->index-1]); 7021 (void) MVGPrintf(wand,"push graphic-context\n"); 7022 wand->indent_depth++; 7023 return(MagickTrue); 7024 } 7025