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