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-2015
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 Magick::Options & options_)45 Magick::Options::Options(const Magick::Options& options_)
46   : _imageInfo(CloneImageInfo(options_._imageInfo)),
47     _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
48     _drawInfo(CloneDrawInfo(_imageInfo,options_._drawInfo)),
49     _quiet(false)
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 
antiAlias(bool flag_)65 void Magick::Options::antiAlias(bool flag_)
66 {
67   _drawInfo->text_antialias=static_cast<MagickBooleanType>(
68     flag_ ? MagickTrue : MagickFalse);
69 }
70 
antiAlias(void) const71 bool Magick::Options::antiAlias(void) const
72 {
73   return(static_cast<bool>(_drawInfo->text_antialias));
74 }
75 
adjoin(bool flag_)76 void Magick::Options::adjoin(bool flag_)
77 {
78   _imageInfo->adjoin=static_cast<MagickBooleanType>(
79     flag_ ? MagickTrue : MagickFalse);
80 }
81 
adjoin(void) const82 bool Magick::Options::adjoin(void) const
83 {
84   return(static_cast<bool>(_imageInfo->adjoin));
85 }
86 
backgroundColor(const Magick::Color & color_)87 void Magick::Options::backgroundColor(const Magick::Color &color_)
88 {
89   _imageInfo->background_color=color_;
90 }
91 
backgroundColor(void) const92 Magick::Color Magick::Options::backgroundColor(void) const
93 {
94   return(Magick::Color(_imageInfo->background_color));
95 }
96 
backgroundTexture(const std::string & backgroundTexture_)97 void Magick::Options::backgroundTexture(const std::string &backgroundTexture_)
98 {
99   if (backgroundTexture_.length() == 0)
100     _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture);
101   else
102     Magick::CloneString(&_imageInfo->texture,backgroundTexture_);
103 }
104 
backgroundTexture(void) const105 std::string Magick::Options::backgroundTexture(void) const
106 {
107   if (_imageInfo->texture)
108     return(std::string(_imageInfo->texture));
109   else
110     return(std::string());
111 }
112 
borderColor(const Color & color_)113 void Magick::Options::borderColor(const Color &color_)
114 {
115   _imageInfo->border_color=color_;
116   _drawInfo->border_color=color_;
117 }
118 
borderColor(void) const119 Magick::Color Magick::Options::borderColor(void) const
120 {
121   return(Magick::Color(_imageInfo->border_color));
122 }
123 
boxColor(const Magick::Color & boxColor_)124 void Magick::Options::boxColor(const Magick::Color &boxColor_)
125 {
126   _drawInfo->undercolor=boxColor_;
127 }
128 
boxColor(void) const129 Magick::Color Magick::Options::boxColor(void) const
130 {
131   return(Magick::Color(_drawInfo->undercolor));
132 }
133 
colorspaceType(Magick::ColorspaceType colorspace_)134 void Magick::Options::colorspaceType(Magick::ColorspaceType colorspace_)
135 {
136   _imageInfo->colorspace=colorspace_;
137 }
138 
colorspaceType(void) const139 Magick::ColorspaceType Magick::Options::colorspaceType(void) const
140 {
141   return(static_cast<Magick::ColorspaceType>(_imageInfo->colorspace));
142 }
143 
compressType(CompressionType compressType_)144 void Magick::Options::compressType(CompressionType compressType_)
145 {
146   _imageInfo->compression=compressType_;
147 }
148 
compressType(void) const149 Magick::CompressionType Magick::Options::compressType(void) const
150 {
151   return(static_cast<Magick::CompressionType>(_imageInfo->compression));
152 }
153 
colorFuzz(double fuzz_)154 void Magick::Options::colorFuzz(double fuzz_)
155 {
156   _imageInfo->fuzz=fuzz_;
157 }
158 
colorFuzz(void) const159 double Magick::Options::colorFuzz(void) const
160 {
161   return(_imageInfo->fuzz);
162 }
163 
debug(bool flag_)164 void Magick::Options::debug(bool flag_)
165 {
166   if (flag_)
167     SetLogEventMask("All");
168   else
169     SetLogEventMask("None");
170 }
171 
debug(void) const172 bool Magick::Options::debug(void) const
173 {
174   if (IsEventLogging())
175     return(true);
176 
177   return(false);
178 }
179 
density(const Magick::Geometry & density_)180 void Magick::Options::density(const Magick::Geometry &density_)
181 {
182   if (!density_.isValid())
183     _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density);
184   else
185     Magick::CloneString(&_imageInfo->density,density_);
186 }
187 
density(void) const188 Magick::Geometry Magick::Options::density(void) const
189 {
190   if (_imageInfo->density)
191     return(Geometry(_imageInfo->density));
192 
193   return(Geometry());
194 }
195 
depth(size_t depth_)196 void Magick::Options::depth(size_t depth_)
197 {
198   _imageInfo->depth=depth_;
199 }
200 
depth(void) const201 size_t Magick::Options::depth(void) const
202 {
203   return(_imageInfo->depth);
204 }
205 
endian(Magick::EndianType endian_)206 void Magick::Options::endian(Magick::EndianType endian_)
207 {
208   _imageInfo->endian=endian_;
209 }
210 
endian(void) const211 Magick::EndianType Magick::Options::endian(void) const
212 {
213   return(_imageInfo->endian);
214 }
215 
file(FILE * file_)216 void Magick::Options::file(FILE *file_)
217 {
218   SetImageInfoFile(_imageInfo,file_);
219 }
220 
file(void) const221 FILE *Magick::Options::file(void) const
222 {
223   return(GetImageInfoFile(_imageInfo));
224 }
225 
fileName(const std::string & fileName_)226 void Magick::Options::fileName(const std::string &fileName_)
227 {
228   ssize_t
229     max_length;
230 
231   max_length=sizeof(_imageInfo->filename)-1;
232   fileName_.copy(_imageInfo->filename,max_length);
233   if ((ssize_t) fileName_.length() > max_length)
234     _imageInfo->filename[max_length]=0;
235   else
236     _imageInfo->filename[fileName_.length()]=0;
237 }
238 
fileName(void) const239 std::string Magick::Options::fileName(void) const
240 {
241   return(std::string(_imageInfo->filename));
242 }
243 
fillColor(const Magick::Color & fillColor_)244 void Magick::Options::fillColor(const Magick::Color &fillColor_)
245 {
246   _drawInfo->fill=fillColor_;
247   if (fillColor_ == Magick::Color())
248     fillPattern((const MagickCore::Image*) NULL);
249   setOption("fill",fillColor_);
250 }
251 
fillColor(void) const252 Magick::Color Magick::Options::fillColor(void) const
253 {
254   return(_drawInfo->fill);
255 }
256 
fillPattern(const MagickCore::Image * fillPattern_)257 void Magick::Options::fillPattern(const MagickCore::Image *fillPattern_)
258 {
259   if (_drawInfo->fill_pattern)
260     {
261       DestroyImageList(_drawInfo->fill_pattern);
262       _drawInfo->fill_pattern=0;
263     }
264   if (fillPattern_)
265     {
266       GetPPException;
267       _drawInfo->fill_pattern=CloneImage(const_cast<MagickCore::Image*>(
268         fillPattern_),0,0,static_cast<MagickBooleanType>(MagickTrue),
269         exceptionInfo);
270       ThrowPPException(_quiet);
271     }
272 }
273 
fillPattern(void) const274 const MagickCore::Image *Magick::Options::fillPattern(void) const
275 {
276   return(_drawInfo->fill_pattern);
277 }
278 
fillRule(const Magick::FillRule & fillRule_)279 void Magick::Options::fillRule(const Magick::FillRule &fillRule_)
280 {
281   _drawInfo->fill_rule=fillRule_;
282 }
283 
fillRule(void) const284 Magick::FillRule Magick::Options::fillRule(void) const
285 {
286   return(_drawInfo->fill_rule);
287 }
288 
font(const std::string & font_)289 void Magick::Options::font(const std::string &font_)
290 {
291   if (font_.length() == 0)
292     {
293       _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font);
294       _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font);
295     }
296   else
297     {
298       Magick::CloneString(&_imageInfo->font,font_);
299       Magick::CloneString(&_drawInfo->font,font_);
300     }
301 }
302 
font(void) const303 std::string Magick::Options::font(void) const
304 {
305   if (_imageInfo->font)
306     return(std::string(_imageInfo->font));
307 
308   return(std::string());
309 }
310 
fontFamily(const std::string & family_)311 void Magick::Options::fontFamily(const std::string &family_)
312 {
313   if (family_.length() == 0)
314     {
315       _drawInfo->family=(char *) RelinquishMagickMemory(_drawInfo->font);
316       DestroyString(RemoveImageOption(imageInfo(),"family"));
317     }
318   else
319     {
320       Magick::CloneString(&_drawInfo->family,family_);
321       (void) SetImageOption(imageInfo(),"family",family_.c_str());
322     }
323 }
324 
fontFamily(void) const325 std::string Magick::Options::fontFamily(void) const
326 {
327   if (_drawInfo->family)
328     return(std::string(_drawInfo->family));
329 
330   return(std::string());
331 }
332 
fontPointsize(double pointSize_)333 void Magick::Options::fontPointsize(double pointSize_)
334 {
335   _imageInfo->pointsize=pointSize_;
336   _drawInfo->pointsize=pointSize_;
337 }
338 
fontPointsize(void) const339 double Magick::Options::fontPointsize(void) const
340 {
341   return(_imageInfo->pointsize);
342 }
343 
fontStyle(const StyleType style_)344 void Magick::Options::fontStyle(const StyleType style_)
345 {
346   _drawInfo->style=style_;
347   (void) SetImageOption(_imageInfo,"style",CommandOptionToMnemonic(
348     MagickStyleOptions,(ssize_t) style_));
349 }
350 
fontStyle(void) const351 Magick::StyleType Magick::Options::fontStyle(void) const
352 {
353   return(_drawInfo->style);
354 }
355 
fontWeight(const size_t weight_)356 void Magick::Options::fontWeight(const size_t weight_)
357 {
358   _drawInfo->weight=weight_;
359   setOption("weight",(double) weight_);
360 }
361 
fontWeight(void) const362 size_t Magick::Options::fontWeight(void) const
363 {
364   return(_drawInfo->weight);
365 }
366 
367 
format(void) const368 std::string Magick::Options::format(void) const
369 {
370   const MagickInfo
371     *magick_info=0;
372 
373   GetPPException;
374   if (*_imageInfo->magick != '\0')
375     magick_info=GetMagickInfo(_imageInfo->magick,exceptionInfo);
376   ThrowPPException(_quiet);
377 
378   if ((magick_info != 0) && (*magick_info->description != '\0'))
379     return(std::string(magick_info->description));
380 
381   return(std::string());
382 }
383 
interlaceType(Magick::InterlaceType interlace_)384 void Magick::Options::interlaceType(Magick::InterlaceType interlace_)
385 {
386   _imageInfo->interlace=interlace_;
387 }
388 
interlaceType(void) const389 Magick::InterlaceType Magick::Options::interlaceType(void) const
390 {
391   return(static_cast<Magick::InterlaceType>(_imageInfo->interlace));
392 }
393 
magick(const std::string & magick_)394 void Magick::Options::magick(const std::string &magick_)
395 {
396   if (magick_.empty())
397   {
398     _imageInfo->magick[0] = '\0';
399     return;
400   }
401 
402   FormatLocaleString(_imageInfo->filename,MaxTextExtent,"%.1024s:",
403     magick_.c_str());
404   GetPPException;
405   SetImageInfo(_imageInfo,1,exceptionInfo);
406   ThrowPPException(_quiet);
407   if ( _imageInfo->magick[0] == '\0' )
408     throwExceptionExplicit(OptionWarning,"Unrecognized image format",
409       magick_.c_str());
410 }
411 
magick(void) const412 std::string Magick::Options::magick(void) const
413 {
414   if ( _imageInfo->magick[0] != '\0' )
415     return(std::string(_imageInfo->magick));
416 
417   return(std::string());
418 }
419 
matteColor(const Magick::Color & matteColor_)420 void Magick::Options::matteColor(const Magick::Color &matteColor_)
421 {
422   _imageInfo->matte_color=matteColor_;
423 }
424 
matteColor(void) const425 Magick::Color Magick::Options::matteColor(void) const
426 {
427   return(Magick::Color(_imageInfo->matte_color));
428 }
429 
monochrome(bool monochromeFlag_)430 void Magick::Options::monochrome(bool monochromeFlag_)
431 {
432   _imageInfo->monochrome=(MagickBooleanType) monochromeFlag_;
433 }
434 
monochrome(void) const435 bool Magick::Options::monochrome(void) const
436 {
437   return(static_cast<bool>(_imageInfo->monochrome));
438 }
439 
page(const Magick::Geometry & pageSize_)440 void Magick::Options::page(const Magick::Geometry &pageSize_)
441 {
442   if (!pageSize_.isValid())
443     _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page);
444   else
445     Magick::CloneString(&_imageInfo->page,pageSize_);
446 }
447 
page(void) const448 Magick::Geometry Magick::Options::page(void) const
449 {
450   if (_imageInfo->page)
451     return(Geometry(_imageInfo->page));
452 
453   return(Geometry());
454 }
455 
quality(size_t quality_)456 void Magick::Options::quality(size_t quality_)
457 {
458   _imageInfo->quality=quality_;
459 }
460 
quality(void) const461 size_t Magick::Options::quality(void) const
462 {
463   return(_imageInfo->quality);
464 }
465 
quantizeColors(size_t colors_)466 void Magick::Options::quantizeColors(size_t colors_)
467 {
468   _quantizeInfo->number_colors=colors_;
469 }
470 
quantizeColors(void) const471 size_t Magick::Options::quantizeColors(void) const
472 {
473   return(_quantizeInfo->number_colors);
474 }
475 
quantizeColorSpace(Magick::ColorspaceType colorSpace_)476 void Magick::Options::quantizeColorSpace(Magick::ColorspaceType colorSpace_)
477 {
478   _quantizeInfo->colorspace=colorSpace_;
479 }
480 
quantizeColorSpace(void) const481 Magick::ColorspaceType Magick::Options::quantizeColorSpace(void) const
482 {
483   return(static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace));
484 }
485 
quantizeDither(bool ditherFlag_)486 void Magick::Options::quantizeDither(bool ditherFlag_)
487 {
488   _imageInfo->dither=(MagickBooleanType) ditherFlag_;
489   _quantizeInfo->dither=(MagickBooleanType) ditherFlag_;
490 }
491 
quantizeDither(void) const492 bool Magick::Options::quantizeDither(void) const
493 {
494   return(static_cast<bool>(_imageInfo->dither));
495 }
496 
quantizeDitherMethod(DitherMethod ditherMethod_)497 void Magick::Options::quantizeDitherMethod(DitherMethod ditherMethod_)
498 {
499   _quantizeInfo->dither_method=ditherMethod_;
500 }
501 
quantizeDitherMethod(void) const502 MagickCore::DitherMethod Magick::Options::quantizeDitherMethod(void) const
503 {
504   return(_quantizeInfo->dither_method);
505 }
506 
quantizeTreeDepth(size_t treeDepth_)507 void Magick::Options::quantizeTreeDepth(size_t treeDepth_)
508 {
509   _quantizeInfo->tree_depth=treeDepth_;
510 }
511 
quantizeTreeDepth(void) const512 size_t Magick::Options::quantizeTreeDepth(void) const
513 {
514   return(_quantizeInfo->tree_depth);
515 }
516 
quiet(const bool quiet_)517 void Magick::Options::quiet(const bool quiet_)
518 {
519   _quiet=quiet_;
520 }
521 
quiet(void) const522 bool Magick::Options::quiet(void) const
523 {
524    return(_quiet);
525 }
526 
resolutionUnits(Magick::ResolutionType resolutionUnits_)527 void Magick::Options::resolutionUnits(Magick::ResolutionType resolutionUnits_)
528 {
529   _imageInfo->units=resolutionUnits_;
530 }
531 
resolutionUnits(void) const532 Magick::ResolutionType Magick::Options::resolutionUnits(void) const
533 {
534   return(_imageInfo->units);
535 }
536 
samplingFactor(const std::string & samplingFactor_)537 void Magick::Options::samplingFactor(const std::string &samplingFactor_)
538 {
539   if (samplingFactor_.length() == 0)
540     _imageInfo->sampling_factor=(char *) RelinquishMagickMemory(
541       _imageInfo->sampling_factor);
542   else
543     Magick::CloneString(&_imageInfo->sampling_factor, samplingFactor_);
544 }
545 
samplingFactor(void) const546 std::string Magick::Options::samplingFactor(void) const
547 {
548   if (_imageInfo->sampling_factor)
549     return(std::string(_imageInfo->sampling_factor));
550 
551   return(std::string());
552 }
553 
size(const Geometry & geometry_)554 void Magick::Options::size(const Geometry &geometry_)
555 {
556   _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size);
557 
558   if ( geometry_.isValid() )
559     Magick::CloneString(&_imageInfo->size,geometry_);
560 }
561 
size(void) const562 Magick::Geometry Magick::Options::size(void) const
563 {
564   if (_imageInfo->size)
565     return(Geometry(_imageInfo->size));
566 
567   return(Geometry());
568 }
569 
strokeAntiAlias(bool flag_)570 void Magick::Options::strokeAntiAlias(bool flag_)
571 {
572   flag_ ? _drawInfo->stroke_antialias=MagickTrue :
573     _drawInfo->stroke_antialias=MagickFalse;
574 }
575 
strokeAntiAlias(void) const576 bool Magick::Options::strokeAntiAlias(void) const
577 {
578   return(_drawInfo->stroke_antialias != 0 ? true : false);
579 }
580 
strokeColor(const Magick::Color & strokeColor_)581 void Magick::Options::strokeColor(const Magick::Color &strokeColor_)
582 {
583   _drawInfo->stroke=strokeColor_;
584   if (strokeColor_ == Magick::Color())
585     strokePattern((const MagickCore::Image*) NULL);
586   setOption("stroke",strokeColor_);
587 }
588 
strokeColor(void) const589 Magick::Color Magick::Options::strokeColor(void) const
590 {
591   return(_drawInfo->stroke);
592 }
593 
strokeDashArray(const double * strokeDashArray_)594 void Magick::Options::strokeDashArray(const double *strokeDashArray_)
595 {
596   _drawInfo->dash_pattern=(double *) RelinquishMagickMemory(
597     _drawInfo->dash_pattern);
598 
599   if(strokeDashArray_)
600     {
601       size_t
602         x;
603 
604       // Count elements in dash array
605       for (x=0; strokeDashArray_[x]; x++) ;
606       // Allocate elements
607       _drawInfo->dash_pattern=static_cast<double*>(AcquireMagickMemory((x+1)*
608         sizeof(double)));
609       if (!_drawInfo->dash_pattern)
610         throwExceptionExplicit(MagickCore::ResourceLimitError,
611           "Unable to allocate dash-pattern memory");
612       // Copy elements
613       memcpy(_drawInfo->dash_pattern,strokeDashArray_,(x+1)*sizeof(double));
614       _drawInfo->dash_pattern[x]=0.0;
615     }
616 }
617 
strokeDashArray(void) const618 const double *Magick::Options::strokeDashArray(void) const
619 {
620   return(_drawInfo->dash_pattern);
621 }
622 
strokeDashOffset(double strokeDashOffset_)623 void Magick::Options::strokeDashOffset(double strokeDashOffset_)
624 {
625   _drawInfo->dash_offset=strokeDashOffset_;
626 }
627 
strokeDashOffset(void) const628 double Magick::Options::strokeDashOffset(void) const
629 {
630   return(_drawInfo->dash_offset);
631 }
632 
strokeLineCap(Magick::LineCap lineCap_)633 void Magick::Options::strokeLineCap(Magick::LineCap lineCap_)
634 {
635   _drawInfo->linecap=lineCap_;
636 }
637 
strokeLineCap(void) const638 Magick::LineCap Magick::Options::strokeLineCap(void) const
639 {
640   return(_drawInfo->linecap);
641 }
642 
strokeLineJoin(Magick::LineJoin lineJoin_)643 void Magick::Options::strokeLineJoin(Magick::LineJoin lineJoin_)
644 {
645   _drawInfo->linejoin=lineJoin_;
646 }
647 
strokeLineJoin(void) const648 Magick::LineJoin Magick::Options::strokeLineJoin(void) const
649 {
650   return(_drawInfo->linejoin);
651 }
652 
strokeMiterLimit(size_t miterLimit_)653 void Magick::Options::strokeMiterLimit(size_t miterLimit_)
654 {
655   _drawInfo->miterlimit=miterLimit_;
656 }
657 
strokeMiterLimit(void) const658 size_t Magick::Options::strokeMiterLimit(void) const
659 {
660   return(_drawInfo->miterlimit);
661 }
662 
strokePattern(const MagickCore::Image * strokePattern_)663 void Magick::Options::strokePattern(const MagickCore::Image *strokePattern_)
664 {
665   if (_drawInfo->stroke_pattern)
666     _drawInfo->stroke_pattern=DestroyImageList(_drawInfo->stroke_pattern);
667 
668   if (strokePattern_)
669     {
670       GetPPException;
671       _drawInfo->stroke_pattern=CloneImage(const_cast<MagickCore::Image*>(
672         strokePattern_),0,0,MagickTrue,exceptionInfo);
673       ThrowPPException(_quiet);
674     }
675 }
676 
strokePattern(void) const677 const MagickCore::Image *Magick::Options::strokePattern(void) const
678 {
679   return(_drawInfo->stroke_pattern);
680 }
681 
strokeWidth(double strokeWidth_)682 void Magick::Options::strokeWidth(double strokeWidth_)
683 {
684   _drawInfo->stroke_width=strokeWidth_;
685 }
686 
strokeWidth(void) const687 double Magick::Options::strokeWidth(void) const
688 {
689   return(_drawInfo->stroke_width);
690 }
691 
subImage(size_t subImage_)692 void Magick::Options::subImage(size_t subImage_)
693 {
694   _imageInfo->scene=subImage_;
695 }
696 
subImage(void) const697 size_t Magick::Options::subImage(void) const
698 {
699   return(_imageInfo->scene);
700 }
701 
subRange(size_t subRange_)702 void Magick::Options::subRange(size_t subRange_)
703 {
704   _imageInfo->number_scenes=subRange_;
705 }
706 
subRange(void) const707 size_t Magick::Options::subRange(void) const
708 {
709   return(_imageInfo->number_scenes);
710 }
711 
textDirection(DirectionType direction_)712 void Magick::Options::textDirection(DirectionType direction_)
713 {
714   _drawInfo->direction=direction_;
715   (void) SetImageOption(_imageInfo,"direction",CommandOptionToMnemonic(
716     MagickDirectionOptions,(ssize_t) direction_));
717 }
718 
textDirection() const719 Magick::DirectionType Magick::Options::textDirection() const
720 {
721   return(_drawInfo->direction);
722 }
723 
textEncoding(const std::string & encoding_)724 void Magick::Options::textEncoding(const std::string &encoding_)
725 {
726   CloneString(&_drawInfo->encoding,encoding_.c_str());
727   (void) SetImageOption(imageInfo(),"encoding",encoding_.c_str());
728 }
729 
textEncoding(void) const730 std::string Magick::Options::textEncoding(void) const
731 {
732   if (_drawInfo->encoding && *_drawInfo->encoding)
733     return(std::string(_drawInfo->encoding));
734 
735   return(std::string());
736 }
737 
textGravity(GravityType gravity_)738 void Magick::Options::textGravity(GravityType gravity_)
739 {
740   _drawInfo->gravity=gravity_;
741   (void) SetImageOption(_imageInfo,"gravity",CommandOptionToMnemonic(
742     MagickGravityOptions,(ssize_t) gravity_));
743 }
744 
textGravity() const745 Magick::GravityType Magick::Options::textGravity() const
746 {
747   return(_drawInfo->gravity);
748 }
749 
textInterlineSpacing(double spacing_)750 void Magick::Options::textInterlineSpacing(double spacing_)
751 {
752   _drawInfo->interline_spacing=spacing_;
753   setOption("interline-spacing",spacing_);
754 }
755 
textInterlineSpacing(void) const756 double Magick::Options::textInterlineSpacing(void) const
757 {
758   return(_drawInfo->interline_spacing);
759 }
760 
textInterwordSpacing(double spacing_)761 void Magick::Options::textInterwordSpacing(double spacing_)
762 {
763   _drawInfo->interword_spacing=spacing_;
764   setOption("interword-spacing",spacing_);
765 }
766 
textInterwordSpacing(void) const767 double Magick::Options::textInterwordSpacing(void) const
768 {
769   return(_drawInfo->interword_spacing);
770 }
771 
textKerning(double kerning_)772 void Magick::Options::textKerning(double kerning_)
773 {
774   _drawInfo->kerning=kerning_;
775   setOption("kerning",kerning_);
776 }
777 
textKerning(void) const778 double Magick::Options::textKerning(void) const
779 {
780   return(_drawInfo->kerning);
781 }
782 
textUnderColor(const Magick::Color & undercolor_)783 void Magick::Options::textUnderColor(const Magick::Color &undercolor_)
784 {
785   _drawInfo->undercolor=undercolor_;
786   setOption("undercolor",undercolor_);
787 }
788 
textUnderColor(void) const789 Magick::Color Magick::Options::textUnderColor(void) const
790 {
791   return(_drawInfo->undercolor);
792 }
793 
794 
tileName(const std::string & tileName_)795 void Magick::Options::tileName(const std::string &tileName_)
796 {
797   if (tileName_.length() == 0)
798     _imageInfo->tile=(char *) RelinquishMagickMemory(_imageInfo->tile);
799   else
800     Magick::CloneString(&_imageInfo->tile,tileName_);
801 }
802 
tileName(void) const803 std::string Magick::Options::tileName(void) const
804 {
805   if (_imageInfo->tile)
806     return(std::string(_imageInfo->tile));
807   return(std::string());
808 }
809 
transformOrigin(double tx_,double ty_)810 void Magick::Options::transformOrigin(double tx_,double ty_)
811 {
812   AffineMatrix
813     affine,
814     current=_drawInfo->affine;
815 
816   affine.sx=1.0;
817   affine.rx=0.0;
818   affine.ry=0.0;
819   affine.sy=1.0;
820   affine.tx=0.0;
821   affine.ty=0.0;
822 
823   affine.tx=tx_;
824   affine.ty=ty_;
825 
826   _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
827   _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
828   _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
829   _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
830   _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
831   _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
832 }
833 
transformReset(void)834 void Magick::Options::transformReset(void)
835 {
836   _drawInfo->affine.sx=1.0;
837   _drawInfo->affine.rx=0.0;
838   _drawInfo->affine.ry=0.0;
839   _drawInfo->affine.sy=1.0;
840   _drawInfo->affine.tx=0.0;
841   _drawInfo->affine.ty=0.0;
842 }
843 
transformRotation(double angle_)844 void Magick::Options::transformRotation(double angle_)
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=cos(DegreesToRadians(fmod(angle_,360.0)));
858   affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
859   affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
860   affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
861 
862   _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
863   _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
864   _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
865   _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
866   _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
867   _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
868 }
869 
transformScale(double sx_,double sy_)870 void Magick::Options::transformScale(double sx_,double sy_)
871 {
872   AffineMatrix
873     affine,
874     current=_drawInfo->affine;
875 
876   affine.sx=1.0;
877   affine.rx=0.0;
878   affine.ry=0.0;
879   affine.sy=1.0;
880   affine.tx=0.0;
881   affine.ty=0.0;
882 
883   affine.sx=sx_;
884   affine.sy=sy_;
885 
886   _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
887   _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
888   _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
889   _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
890   _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
891   _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
892 }
893 
transformSkewX(double skewx_)894 void Magick::Options::transformSkewX(double skewx_)
895 {
896   AffineMatrix
897     affine,
898     current=_drawInfo->affine;
899 
900   affine.sx=1.0;
901   affine.rx=0.0;
902   affine.ry=0.0;
903   affine.sy=1.0;
904   affine.tx=0.0;
905   affine.ty=0.0;
906 
907   affine.sx=1.0;
908   affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
909   affine.sy=1.0;
910 
911   _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
912   _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
913   _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
914   _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
915   _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
916   _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
917 }
918 
transformSkewY(double skewy_)919 void Magick::Options::transformSkewY(double skewy_)
920 {
921   AffineMatrix
922     affine,
923     current=_drawInfo->affine;
924 
925   affine.sx=1.0;
926   affine.rx=0.0;
927   affine.ry=0.0;
928   affine.sy=1.0;
929   affine.tx=0.0;
930   affine.ty=0.0;
931 
932   affine.sx=1.0;
933   affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
934   affine.sy=1.0;
935 
936   _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
937   _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
938   _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
939   _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
940   _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
941   _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
942 }
943 
type(const Magick::ImageType type_)944 void Magick::Options::type(const Magick::ImageType type_)
945 {
946   _imageInfo->type=type_;
947 }
948 
type(void) const949 Magick::ImageType Magick::Options::type(void) const
950 {
951   return(_imageInfo->type);
952 }
953 
verbose(bool verboseFlag_)954 void Magick::Options::verbose(bool verboseFlag_)
955 {
956   _imageInfo->verbose=(MagickBooleanType) verboseFlag_;
957 }
958 
verbose(void) const959 bool Magick::Options::verbose(void) const
960 {
961   return(static_cast<bool>(_imageInfo->verbose));
962 }
963 
virtualPixelMethod(VirtualPixelMethod virtual_pixel_method_)964 void Magick::Options::virtualPixelMethod(
965   VirtualPixelMethod virtual_pixel_method_)
966 {
967   _imageInfo->virtual_pixel_method=virtual_pixel_method_;
968 }
969 
virtualPixelMethod(void) const970 Magick::VirtualPixelMethod Magick::Options::virtualPixelMethod(void) const
971 {
972   return(static_cast<Magick::VirtualPixelMethod>(
973     _imageInfo->virtual_pixel_method));
974 }
975 
view(const std::string & view_)976 void Magick::Options::view(const std::string &view_)
977 {
978   if (view_.length() == 0)
979     _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
980   else
981     Magick::CloneString(&_imageInfo->view,view_);
982 }
983 
view(void) const984 std::string Magick::Options::view(void) const
985 {
986   if (_imageInfo->view)
987     return(std::string(_imageInfo->view));
988 
989   return(std::string());
990 }
991 
x11Display(const std::string & display_)992 void Magick::Options::x11Display(const std::string &display_)
993 {
994   if (display_.length() == 0)
995     _imageInfo->server_name=(char *) RelinquishMagickMemory(
996       _imageInfo->server_name);
997   else
998     Magick::CloneString(&_imageInfo->server_name,display_);
999 }
1000 
x11Display(void) const1001 std::string Magick::Options::x11Display(void) const
1002 {
1003   if (_imageInfo->server_name)
1004     return(std::string(_imageInfo->server_name));
1005 
1006   return(std::string());
1007 }
1008 
drawInfo(void)1009 MagickCore::DrawInfo *Magick::Options::drawInfo(void)
1010 {
1011   return(_drawInfo);
1012 }
1013 
imageInfo(void)1014 MagickCore::ImageInfo *Magick::Options::imageInfo(void)
1015 {
1016   return(_imageInfo);
1017 }
1018 
quantizeInfo(void)1019 MagickCore::QuantizeInfo *Magick::Options::quantizeInfo( void )
1020 {
1021   return(_quantizeInfo);
1022 }
1023 
Options(const MagickCore::ImageInfo * imageInfo_,const MagickCore::QuantizeInfo * quantizeInfo_,const MagickCore::DrawInfo * drawInfo_)1024 Magick::Options::Options(const MagickCore::ImageInfo *imageInfo_,
1025   const MagickCore::QuantizeInfo *quantizeInfo_,
1026   const MagickCore::DrawInfo *drawInfo_)
1027 : _imageInfo((MagickCore::ImageInfo* ) NULL),
1028   _quantizeInfo((MagickCore::QuantizeInfo* ) NULL),
1029   _drawInfo((MagickCore::DrawInfo* ) NULL),
1030   _quiet(false)
1031 {
1032   _imageInfo=CloneImageInfo(imageInfo_);
1033   _quantizeInfo=CloneQuantizeInfo(quantizeInfo_);
1034   _drawInfo=CloneDrawInfo(imageInfo_,drawInfo_);
1035 }
1036 
setOption(const char * name,const Color & value_)1037 void Magick::Options::setOption(const char *name,const Color &value_)
1038 {
1039   std::string
1040     option;
1041 
1042   option=value_;
1043   (void) SetImageOption(imageInfo(),name,option.c_str());
1044 }
1045 
setOption(const char * name,const double value_)1046 void Magick::Options::setOption(const char *name,const double value_)
1047 {
1048   char
1049     option[MaxTextExtent];
1050 
1051   (void) FormatLocaleString(option,MaxTextExtent,"%.20g",value_);
1052   (void) SetImageOption(_imageInfo,name,option);
1053 }
1054