1 // This may look like C code, but it is really -*- C++ -*- 2 // 3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003 4 // Copyright Dirk Lemstra 2014-2016 5 // 6 // Implementation of Options 7 // 8 // A wrapper around DrawInfo, ImageInfo, and QuantizeInfo 9 // 10 11 #define MAGICKCORE_IMPLEMENTATION 1 12 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1 13 14 #include "Magick++/Include.h" 15 #include <string> 16 #include <string.h> 17 #include <stdlib.h> 18 #include <math.h> 19 20 #include "Magick++/Options.h" 21 #include "Magick++/Functions.h" 22 #include "Magick++/Exception.h" 23 24 #define MagickPI 3.14159265358979323846264338327950288419716939937510 25 #define DegreesToRadians(x) (MagickPI*(x)/180.0) 26 27 Magick::Options::Options(void) 28 : _imageInfo(static_cast<ImageInfo*>(AcquireMagickMemory( 29 sizeof(ImageInfo)))), 30 _quantizeInfo(static_cast<QuantizeInfo*>(AcquireMagickMemory( 31 sizeof(QuantizeInfo)))), 32 _drawInfo(static_cast<DrawInfo*>(AcquireMagickMemory(sizeof(DrawInfo)))), 33 _quiet(false) 34 { 35 // Initialize image info with defaults 36 GetImageInfo(_imageInfo); 37 38 // Initialize quantization info 39 GetQuantizeInfo(_quantizeInfo); 40 41 // Initialize drawing info 42 GetDrawInfo(_imageInfo,_drawInfo); 43 } 44 45 Magick::Options::Options(const Options& options_) 46 : _imageInfo(CloneImageInfo(options_._imageInfo)), 47 _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)), 48 _drawInfo(CloneDrawInfo(_imageInfo,options_._drawInfo)), 49 _quiet(options_._quiet) 50 { 51 } 52 53 Magick::Options::~Options() 54 { 55 // Destroy image info 56 _imageInfo=DestroyImageInfo(_imageInfo); 57 58 // Destroy quantization info 59 _quantizeInfo=DestroyQuantizeInfo(_quantizeInfo); 60 61 // Destroy drawing info 62 _drawInfo=DestroyDrawInfo(_drawInfo); 63 } 64 65 void Magick::Options::adjoin(const bool flag_) 66 { 67 _imageInfo->adjoin=static_cast<MagickBooleanType>( 68 flag_ ? MagickTrue : MagickFalse); 69 } 70 71 bool Magick::Options::adjoin(void) const 72 { 73 return(static_cast<bool>(_imageInfo->adjoin)); 74 } 75 76 void Magick::Options::alphaColor(const Color &alphaColor_) 77 { 78 _imageInfo->alpha_color=alphaColor_; 79 } 80 81 Magick::Color Magick::Options::alphaColor(void) const 82 { 83 return(Magick::Color(_imageInfo->alpha_color)); 84 } 85 86 void Magick::Options::backgroundColor(const Color &color_) 87 { 88 _imageInfo->background_color=color_; 89 } 90 91 Magick::Color Magick::Options::backgroundColor(void) const 92 { 93 return(Color(_imageInfo->background_color)); 94 } 95 96 void Magick::Options::backgroundTexture(const std::string &backgroundTexture_) 97 { 98 if (backgroundTexture_.length() == 0) 99 _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture); 100 else 101 Magick::CloneString(&_imageInfo->texture,backgroundTexture_); 102 } 103 104 std::string Magick::Options::backgroundTexture(void) const 105 { 106 if (_imageInfo->texture) 107 return(std::string(_imageInfo->texture)); 108 else 109 return(std::string()); 110 } 111 112 void Magick::Options::borderColor(const Color &color_) 113 { 114 _imageInfo->border_color=color_; 115 _drawInfo->border_color=color_; 116 } 117 118 Magick::Color Magick::Options::borderColor(void) const 119 { 120 return(Color(_imageInfo->border_color)); 121 } 122 123 void Magick::Options::boxColor(const Color &boxColor_) 124 { 125 _drawInfo->undercolor=boxColor_; 126 } 127 128 Magick::Color Magick::Options::boxColor(void) const 129 { 130 return(Color(_drawInfo->undercolor)); 131 } 132 133 void Magick::Options::colorspaceType(const ColorspaceType colorspace_) 134 { 135 _imageInfo->colorspace=colorspace_; 136 } 137 138 Magick::ColorspaceType Magick::Options::colorspaceType(void) const 139 { 140 return(static_cast<Magick::ColorspaceType>(_imageInfo->colorspace)); 141 } 142 143 void Magick::Options::compressType(const CompressionType compressType_) 144 { 145 _imageInfo->compression=compressType_; 146 } 147 148 Magick::CompressionType Magick::Options::compressType(void) const 149 { 150 return(static_cast<Magick::CompressionType>(_imageInfo->compression)); 151 } 152 153 void Magick::Options::colorFuzz(const double fuzz_) 154 { 155 _imageInfo->fuzz=fuzz_; 156 } 157 158 double Magick::Options::colorFuzz(void) const 159 { 160 return(_imageInfo->fuzz); 161 } 162 163 void Magick::Options::debug(const bool flag_) 164 { 165 if (flag_) 166 SetLogEventMask("All"); 167 else 168 SetLogEventMask("None"); 169 } 170 171 bool Magick::Options::debug(void) const 172 { 173 if (IsEventLogging()) 174 return(true); 175 return(false); 176 } 177 178 void Magick::Options::density(const Point &density_) 179 { 180 if (!density_.isValid()) 181 _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density); 182 else 183 CloneString(&_imageInfo->density,density_); 184 } 185 186 Magick::Point Magick::Options::density(void) const 187 { 188 if (_imageInfo->density) 189 return(Point(_imageInfo->density)); 190 191 return(Point()); 192 } 193 194 void Magick::Options::depth(const size_t depth_) 195 { 196 _imageInfo->depth=depth_; 197 } 198 199 size_t Magick::Options::depth(void) const 200 { 201 return(_imageInfo->depth); 202 } 203 204 void Magick::Options::endian(const Magick::EndianType endian_) 205 { 206 _imageInfo->endian=endian_; 207 } 208 209 Magick::EndianType Magick::Options::endian(void) const 210 { 211 return(_imageInfo->endian); 212 } 213 214 void Magick::Options::file(FILE *file_) 215 { 216 SetImageInfoFile(_imageInfo,file_); 217 } 218 219 FILE *Magick::Options::file(void) const 220 { 221 return(GetImageInfoFile(_imageInfo)); 222 } 223 224 void Magick::Options::fileName(const std::string &fileName_) 225 { 226 fileName_.copy(_imageInfo->filename,MagickPathExtent-1); 227 if (fileName_.length() > MagickPathExtent-1) 228 _imageInfo->filename[MagickPathExtent-1]=0; 229 else 230 _imageInfo->filename[fileName_.length()]=0; 231 } 232 233 std::string Magick::Options::fileName(void) const 234 { 235 return(std::string(_imageInfo->filename)); 236 } 237 238 void Magick::Options::fillColor(const Color &fillColor_) 239 { 240 _drawInfo->fill=fillColor_; 241 if (fillColor_ == Color()) 242 fillPattern((const MagickCore::Image*) NULL); 243 setOption("fill",fillColor_); 244 } 245 246 Magick::Color Magick::Options::fillColor(void) const 247 { 248 return(_drawInfo->fill); 249 } 250 251 void Magick::Options::fillPattern(const MagickCore::Image *fillPattern_) 252 { 253 if (_drawInfo->fill_pattern) 254 _drawInfo->fill_pattern=DestroyImageList(_drawInfo->fill_pattern); 255 256 if (fillPattern_) 257 { 258 GetPPException; 259 _drawInfo->fill_pattern=CloneImage(const_cast<MagickCore::Image*>( 260 fillPattern_),0,0,static_cast<MagickBooleanType>(MagickTrue), 261 exceptionInfo); 262 ThrowPPException(_quiet); 263 } 264 } 265 266 const MagickCore::Image *Magick::Options::fillPattern(void) const 267 { 268 return(_drawInfo->fill_pattern); 269 } 270 271 void Magick::Options::fillRule(const FillRule &fillRule_) 272 { 273 _drawInfo->fill_rule=fillRule_; 274 } 275 276 Magick::FillRule Magick::Options::fillRule(void) const 277 { 278 return(_drawInfo->fill_rule); 279 } 280 281 void Magick::Options::font(const std::string &font_) 282 { 283 if (font_.length() == 0) 284 { 285 _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font); 286 _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font); 287 } 288 else 289 { 290 Magick::CloneString(&_imageInfo->font,font_); 291 Magick::CloneString(&_drawInfo->font,font_); 292 } 293 } 294 295 std::string Magick::Options::font(void) const 296 { 297 if (_imageInfo->font) 298 return(std::string(_imageInfo->font)); 299 300 return(std::string()); 301 } 302 303 void Magick::Options::fontFamily(const std::string &family_) 304 { 305 if (family_.length() == 0) 306 { 307 _drawInfo->family=(char *) RelinquishMagickMemory(_drawInfo->font); 308 DestroyString(RemoveImageOption(imageInfo(),"family")); 309 } 310 else 311 { 312 Magick::CloneString(&_drawInfo->family,family_); 313 (void) SetImageOption(imageInfo(),"family",family_.c_str()); 314 } 315 } 316 317 std::string Magick::Options::fontFamily(void) const 318 { 319 if (_drawInfo->family) 320 return(std::string(_drawInfo->family)); 321 322 return(std::string()); 323 } 324 325 void Magick::Options::fontPointsize(const double pointSize_) 326 { 327 _imageInfo->pointsize=pointSize_; 328 _drawInfo->pointsize=pointSize_; 329 } 330 331 double Magick::Options::fontPointsize(void) const 332 { 333 return(_imageInfo->pointsize); 334 } 335 336 void Magick::Options::fontStyle(const StyleType style_) 337 { 338 _drawInfo->style=style_; 339 (void) SetImageOption(_imageInfo,"style",CommandOptionToMnemonic( 340 MagickStyleOptions,(ssize_t) style_)); 341 } 342 343 Magick::StyleType Magick::Options::fontStyle(void) const 344 { 345 return(_drawInfo->style); 346 } 347 348 void Magick::Options::fontWeight(const size_t weight_) 349 { 350 _drawInfo->weight=weight_; 351 setOption("weight",(double) weight_); 352 } 353 354 size_t Magick::Options::fontWeight(void) const 355 { 356 return(_drawInfo->weight); 357 } 358 359 std::string Magick::Options::format(void) const 360 { 361 const MagickInfo 362 *magick_info=0; 363 364 GetPPException; 365 if (*_imageInfo->magick != '\0' ) 366 magick_info = GetMagickInfo(_imageInfo->magick,exceptionInfo); 367 ThrowPPException(_quiet); 368 369 if ((magick_info != 0) && (*magick_info->description != '\0')) 370 return(std::string( magick_info->description)); 371 372 return(std::string()); 373 } 374 375 void Magick::Options::interlaceType(const InterlaceType interlace_) 376 { 377 _imageInfo->interlace=interlace_; 378 } 379 380 Magick::InterlaceType Magick::Options::interlaceType(void) const 381 { 382 return(static_cast<Magick::InterlaceType>(_imageInfo->interlace)); 383 } 384 385 void Magick::Options::magick(const std::string &magick_) 386 { 387 if (magick_.empty()) 388 { 389 _imageInfo->magick[0] = '\0'; 390 return; 391 } 392 393 FormatLocaleString(_imageInfo->filename,MagickPathExtent,"%.1024s:", 394 magick_.c_str()); 395 GetPPException; 396 SetImageInfo(_imageInfo,1,exceptionInfo); 397 if ( _imageInfo->magick[0] == '\0' ) 398 throwExceptionExplicit(MagickCore::OptionError,"Unrecognized image format", 399 magick_.c_str()); 400 ThrowPPException(_quiet); 401 } 402 403 std::string Magick::Options::magick(void) const 404 { 405 if ( _imageInfo->magick[0] != '\0' ) 406 return(std::string(_imageInfo->magick)); 407 408 return(std::string()); 409 } 410 411 void Magick::Options::monochrome(const bool monochromeFlag_) 412 { 413 _imageInfo->monochrome=(MagickBooleanType) monochromeFlag_; 414 } 415 416 bool Magick::Options::monochrome(void) const 417 { 418 return(static_cast<bool>(_imageInfo->monochrome)); 419 } 420 421 void Magick::Options::page(const Geometry &pageSize_) 422 { 423 if (!pageSize_.isValid()) 424 _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page); 425 else 426 Magick::CloneString(&_imageInfo->page,pageSize_); 427 } 428 429 Magick::Geometry Magick::Options::page(void) const 430 { 431 if (_imageInfo->page) 432 return(Geometry(_imageInfo->page)); 433 434 return(Geometry()); 435 } 436 437 void Magick::Options::quality(const size_t quality_) 438 { 439 _imageInfo->quality=quality_; 440 } 441 442 size_t Magick::Options::quality(void) const 443 { 444 return(_imageInfo->quality); 445 } 446 447 void Magick::Options::quantizeColors(const size_t colors_) 448 { 449 _quantizeInfo->number_colors=colors_; 450 } 451 452 size_t Magick::Options::quantizeColors(void) const 453 { 454 return(_quantizeInfo->number_colors); 455 } 456 457 void Magick::Options::quantizeColorSpace(const ColorspaceType colorSpace_) 458 { 459 _quantizeInfo->colorspace=colorSpace_; 460 } 461 462 Magick::ColorspaceType Magick::Options::quantizeColorSpace(void) const 463 { 464 return(static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace)); 465 } 466 467 void Magick::Options::quantizeDither(const bool ditherFlag_) 468 { 469 _imageInfo->dither=(MagickBooleanType) ditherFlag_; 470 _quantizeInfo->dither_method=ditherFlag_ ? RiemersmaDitherMethod : 471 NoDitherMethod; 472 } 473 474 bool Magick::Options::quantizeDither(void) const 475 { 476 return(static_cast<bool>(_imageInfo->dither)); 477 } 478 479 void Magick::Options::quantizeDitherMethod(const DitherMethod ditherMethod_) 480 { 481 _quantizeInfo->dither_method=ditherMethod_; 482 } 483 484 MagickCore::DitherMethod Magick::Options::quantizeDitherMethod(void) const 485 { 486 return(_quantizeInfo->dither_method); 487 } 488 489 void Magick::Options::quantizeTreeDepth(const size_t treeDepth_) 490 { 491 _quantizeInfo->tree_depth=treeDepth_; 492 } 493 494 size_t Magick::Options::quantizeTreeDepth(void) const 495 { 496 return(_quantizeInfo->tree_depth); 497 } 498 499 void Magick::Options::quiet(const bool quiet_) 500 { 501 _quiet=quiet_; 502 } 503 504 bool Magick::Options::quiet(void) const 505 { 506 return(_quiet); 507 } 508 509 void Magick::Options::resolutionUnits(const ResolutionType resolutionUnits_) 510 { 511 _imageInfo->units=resolutionUnits_; 512 } 513 514 Magick::ResolutionType Magick::Options::resolutionUnits(void) const 515 { 516 return(_imageInfo->units); 517 } 518 519 void Magick::Options::samplingFactor(const std::string &samplingFactor_) 520 { 521 if (samplingFactor_.length() == 0) 522 _imageInfo->sampling_factor=(char *) RelinquishMagickMemory( 523 _imageInfo->sampling_factor); 524 else 525 Magick::CloneString(&_imageInfo->sampling_factor,samplingFactor_); 526 } 527 528 std::string Magick::Options::samplingFactor(void) const 529 { 530 if (_imageInfo->sampling_factor) 531 return(std::string(_imageInfo->sampling_factor)); 532 533 return(std::string()); 534 } 535 536 void Magick::Options::size(const Geometry &geometry_) 537 { 538 _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size); 539 540 if (geometry_.isValid()) 541 Magick::CloneString(&_imageInfo->size,geometry_); 542 } 543 544 Magick::Geometry Magick::Options::size(void) const 545 { 546 if (_imageInfo->size) 547 return(Geometry(_imageInfo->size)); 548 549 return(Geometry()); 550 } 551 552 void Magick::Options::strokeAntiAlias(const bool flag_) 553 { 554 flag_ ? _drawInfo->stroke_antialias=MagickTrue : 555 _drawInfo->stroke_antialias=MagickFalse; 556 } 557 558 bool Magick::Options::strokeAntiAlias(void) const 559 { 560 return(_drawInfo->stroke_antialias != 0 ? true : false); 561 } 562 563 void Magick::Options::strokeColor(const Color &strokeColor_) 564 { 565 _drawInfo->stroke=strokeColor_; 566 if (strokeColor_ == Color()) 567 strokePattern((const MagickCore::Image*) NULL); 568 setOption("stroke",strokeColor_); 569 } 570 571 Magick::Color Magick::Options::strokeColor(void) const 572 { 573 return(_drawInfo->stroke); 574 } 575 576 void Magick::Options::strokeDashArray(const double *strokeDashArray_) 577 { 578 _drawInfo->dash_pattern=(double *) RelinquishMagickMemory( 579 _drawInfo->dash_pattern); 580 581 if(strokeDashArray_) 582 { 583 size_t 584 x; 585 // Count elements in dash array 586 for (x=0; strokeDashArray_[x]; x++) ; 587 // Allocate elements 588 _drawInfo->dash_pattern=static_cast<double*>(AcquireMagickMemory((x+1)* 589 sizeof(double))); 590 // Copy elements 591 memcpy(_drawInfo->dash_pattern,strokeDashArray_,(x+1)*sizeof(double)); 592 _drawInfo->dash_pattern[x]=0.0; 593 } 594 } 595 596 const double *Magick::Options::strokeDashArray(void) const 597 { 598 return(_drawInfo->dash_pattern); 599 } 600 601 void Magick::Options::strokeDashOffset(const double strokeDashOffset_) 602 { 603 _drawInfo->dash_offset=strokeDashOffset_; 604 } 605 606 double Magick::Options::strokeDashOffset(void) const 607 { 608 return(_drawInfo->dash_offset); 609 } 610 611 void Magick::Options::strokeLineCap(const LineCap lineCap_) 612 { 613 _drawInfo->linecap=lineCap_; 614 } 615 616 Magick::LineCap Magick::Options::strokeLineCap(void) const 617 { 618 return(_drawInfo->linecap); 619 } 620 621 void Magick::Options::strokeLineJoin(const LineJoin lineJoin_) 622 { 623 _drawInfo->linejoin=lineJoin_; 624 } 625 626 Magick::LineJoin Magick::Options::strokeLineJoin(void) const 627 { 628 return(_drawInfo->linejoin); 629 } 630 631 void Magick::Options::strokeMiterLimit(const size_t miterLimit_) 632 { 633 _drawInfo->miterlimit=miterLimit_; 634 } 635 636 size_t Magick::Options::strokeMiterLimit(void) const 637 { 638 return(_drawInfo->miterlimit); 639 } 640 641 void Magick::Options::strokePattern(const MagickCore::Image *strokePattern_) 642 { 643 if (_drawInfo->stroke_pattern) 644 _drawInfo->stroke_pattern=DestroyImageList(_drawInfo->stroke_pattern); 645 646 if (strokePattern_) 647 { 648 GetPPException; 649 _drawInfo->stroke_pattern=CloneImage(const_cast<MagickCore::Image*>( 650 strokePattern_),0,0,MagickTrue,exceptionInfo); 651 ThrowPPException(_quiet); 652 } 653 } 654 655 const MagickCore::Image *Magick::Options::strokePattern(void) const 656 { 657 return(_drawInfo->stroke_pattern); 658 } 659 660 void Magick::Options::strokeWidth(const double strokeWidth_) 661 { 662 _drawInfo->stroke_width=strokeWidth_; 663 setOption("strokewidth",strokeWidth_); 664 } 665 666 double Magick::Options::strokeWidth(void) const 667 { 668 return(_drawInfo->stroke_width); 669 } 670 671 void Magick::Options::subImage(const size_t subImage_) 672 { 673 _imageInfo->scene=subImage_; 674 } 675 676 size_t Magick::Options::subImage(void) const 677 { 678 return(_imageInfo->scene); 679 } 680 681 void Magick::Options::subRange(const size_t subRange_) 682 { 683 _imageInfo->number_scenes=subRange_; 684 } 685 686 size_t Magick::Options::subRange(void) const 687 { 688 return(_imageInfo->number_scenes); 689 } 690 691 void Magick::Options::textAntiAlias(const bool flag_) 692 { 693 _drawInfo->text_antialias=static_cast<MagickBooleanType>( 694 flag_ ? MagickTrue : MagickFalse); 695 } 696 697 bool Magick::Options::textAntiAlias(void) const 698 { 699 return(static_cast<bool>(_drawInfo->text_antialias)); 700 } 701 702 void Magick::Options::textDirection(const DirectionType direction_) 703 { 704 _drawInfo->direction=direction_; 705 (void) SetImageOption(_imageInfo,"direction",CommandOptionToMnemonic( 706 MagickDirectionOptions,(ssize_t) direction_)); 707 } 708 709 Magick::DirectionType Magick::Options::textDirection() const 710 { 711 return(_drawInfo->direction); 712 } 713 714 void Magick::Options::textEncoding(const std::string &encoding_) 715 { 716 CloneString(&_drawInfo->encoding,encoding_.c_str()); 717 (void) SetImageOption(imageInfo(),"encoding",encoding_.c_str()); 718 } 719 720 std::string Magick::Options::textEncoding(void) const 721 { 722 if (_drawInfo->encoding && *_drawInfo->encoding) 723 return(std::string(_drawInfo->encoding)); 724 725 return(std::string()); 726 } 727 728 void Magick::Options::textGravity(const GravityType gravity_) 729 { 730 _drawInfo->gravity=gravity_; 731 (void) SetImageOption(_imageInfo,"gravity",CommandOptionToMnemonic( 732 MagickGravityOptions,(ssize_t) gravity_)); 733 } 734 735 Magick::GravityType Magick::Options::textGravity() const 736 { 737 return(_drawInfo->gravity); 738 } 739 740 void Magick::Options::textInterlineSpacing(const double spacing_) 741 { 742 _drawInfo->interline_spacing=spacing_; 743 setOption("interline-spacing",spacing_); 744 } 745 746 double Magick::Options::textInterlineSpacing(void) const 747 { 748 return(_drawInfo->interline_spacing); 749 } 750 751 void Magick::Options::textInterwordSpacing(const double spacing_) 752 { 753 _drawInfo->interword_spacing=spacing_; 754 setOption("interword-spacing",spacing_); 755 } 756 757 double Magick::Options::textInterwordSpacing(void) const 758 { 759 return(_drawInfo->interword_spacing); 760 } 761 762 void Magick::Options::textKerning(const double kerning_) 763 { 764 _drawInfo->kerning=kerning_; 765 setOption("kerning",kerning_); 766 } 767 768 double Magick::Options::textKerning(void) const 769 { 770 return(_drawInfo->kerning); 771 } 772 773 void Magick::Options::textUnderColor(const Color &undercolor_) 774 { 775 _drawInfo->undercolor=undercolor_; 776 setOption("undercolor",undercolor_); 777 } 778 779 Magick::Color Magick::Options::textUnderColor(void) const 780 { 781 return(_drawInfo->undercolor); 782 } 783 784 void Magick::Options::transformOrigin(const double tx_,const double ty_) 785 { 786 AffineMatrix 787 affine, 788 current=_drawInfo->affine; 789 790 affine.sx=1.0; 791 affine.rx=0.0; 792 affine.ry=0.0; 793 affine.sy=1.0; 794 affine.tx=0.0; 795 affine.ty=0.0; 796 797 affine.tx=tx_; 798 affine.ty=ty_; 799 800 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx; 801 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx; 802 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy; 803 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy; 804 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx; 805 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty; 806 } 807 808 void Magick::Options::transformReset(void) 809 { 810 _drawInfo->affine.sx=1.0; 811 _drawInfo->affine.rx=0.0; 812 _drawInfo->affine.ry=0.0; 813 _drawInfo->affine.sy=1.0; 814 _drawInfo->affine.tx=0.0; 815 _drawInfo->affine.ty=0.0; 816 } 817 818 void Magick::Options::transformRotation(const double angle_) 819 { 820 AffineMatrix 821 affine, 822 current=_drawInfo->affine; 823 824 affine.sx=1.0; 825 affine.rx=0.0; 826 affine.ry=0.0; 827 affine.sy=1.0; 828 affine.tx=0.0; 829 affine.ty=0.0; 830 831 affine.sx=cos(DegreesToRadians(fmod(angle_,360.0))); 832 affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0)))); 833 affine.ry=sin(DegreesToRadians(fmod(angle_,360.0))); 834 affine.sy=cos(DegreesToRadians(fmod(angle_,360.0))); 835 836 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx; 837 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx; 838 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy; 839 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy; 840 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx; 841 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty; 842 } 843 844 void Magick::Options::transformScale(const double sx_,const double sy_) 845 { 846 AffineMatrix 847 affine, 848 current=_drawInfo->affine; 849 850 affine.sx=1.0; 851 affine.rx=0.0; 852 affine.ry=0.0; 853 affine.sy=1.0; 854 affine.tx=0.0; 855 affine.ty=0.0; 856 857 affine.sx=sx_; 858 affine.sy=sy_; 859 860 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx; 861 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx; 862 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy; 863 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy; 864 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx; 865 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty; 866 } 867 868 void Magick::Options::transformSkewX(const double skewx_) 869 { 870 AffineMatrix 871 affine, 872 current=_drawInfo->affine; 873 874 affine.sx=1.0; 875 affine.rx=0.0; 876 affine.ry=0.0; 877 affine.sy=1.0; 878 affine.tx=0.0; 879 affine.ty=0.0; 880 881 affine.sx=1.0; 882 affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0))); 883 affine.sy=1.0; 884 885 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx; 886 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx; 887 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy; 888 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy; 889 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx; 890 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty; 891 } 892 893 void Magick::Options::transformSkewY(const double skewy_) 894 { 895 AffineMatrix 896 affine, 897 current=_drawInfo->affine; 898 899 affine.sx=1.0; 900 affine.rx=0.0; 901 affine.ry=0.0; 902 affine.sy=1.0; 903 affine.tx=0.0; 904 affine.ty=0.0; 905 906 affine.sx=1.0; 907 affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0))); 908 affine.sy=1.0; 909 910 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx; 911 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx; 912 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy; 913 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy; 914 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx; 915 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty; 916 } 917 918 void Magick::Options::type(const ImageType type_) 919 { 920 _imageInfo->type=type_; 921 } 922 923 Magick::ImageType Magick::Options::type(void) const 924 { 925 return(_imageInfo->type); 926 } 927 928 void Magick::Options::verbose(const bool verboseFlag_) 929 { 930 _imageInfo->verbose=(MagickBooleanType) verboseFlag_; 931 } 932 933 bool Magick::Options::verbose(void) const 934 { 935 return(static_cast<bool>(_imageInfo->verbose)); 936 } 937 938 void Magick::Options::x11Display(const std::string &display_) 939 { 940 if (display_.length() == 0) 941 _imageInfo->server_name=(char *) RelinquishMagickMemory( 942 _imageInfo->server_name); 943 else 944 Magick::CloneString(&_imageInfo->server_name,display_); 945 } 946 947 std::string Magick::Options::x11Display(void) const 948 { 949 if (_imageInfo->server_name) 950 return(std::string( _imageInfo->server_name)); 951 952 return(std::string()); 953 } 954 955 MagickCore::DrawInfo *Magick::Options::drawInfo(void) 956 { 957 return(_drawInfo); 958 } 959 960 MagickCore::ImageInfo *Magick::Options::imageInfo(void) 961 { 962 return(_imageInfo); 963 } 964 965 MagickCore::QuantizeInfo *Magick::Options::quantizeInfo(void) 966 { 967 return(_quantizeInfo); 968 } 969 970 Magick::Options::Options(const MagickCore::ImageInfo* imageInfo_, 971 const MagickCore::QuantizeInfo* quantizeInfo_, 972 const MagickCore::DrawInfo* drawInfo_) 973 : _imageInfo((MagickCore::ImageInfo* ) NULL), 974 _quantizeInfo((MagickCore::QuantizeInfo* ) NULL), 975 _drawInfo((MagickCore::DrawInfo* ) NULL), 976 _quiet(false) 977 { 978 _imageInfo=CloneImageInfo(imageInfo_); 979 _quantizeInfo=CloneQuantizeInfo(quantizeInfo_); 980 _drawInfo=CloneDrawInfo(imageInfo_,drawInfo_); 981 } 982 983 void Magick::Options::setOption(const char *name,const Color &value_) 984 { 985 std::string 986 option; 987 988 option=value_; 989 (void) SetImageOption(imageInfo(),name,option.c_str()); 990 } 991 992 void Magick::Options::setOption(const char *name,const double value_) 993 { 994 char 995 option[MagickPathExtent]; 996 997 (void) FormatLocaleString(option,MagickPathExtent,"%.20g",value_); 998 (void) SetImageOption(_imageInfo,name,option); 999 } 1000 1001