Options.cpp revision cbda611068350bf4459f2dda1951f8823702e129
1// This may look like C code, but it is really -*- C++ -*-
2//
3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
4//
5// Implementation of Options
6//
7// A wrapper around DrawInfo, ImageInfo, and QuantizeInfo
8//
9
10#define MAGICKCORE_IMPLEMENTATION  1
11#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
12
13#include <string>
14#include <string.h>
15#include <stdlib.h>
16#include <math.h>
17#include "Magick++/Include.h"
18#include "Magick++/Options.h"
19#include "Magick++/Functions.h"
20#include "Magick++/Exception.h"
21
22#define DegreesToRadians(x)  (MagickPI*(x)/180.0)
23
24// Constructor
25Magick::Options::Options( void )
26  : _imageInfo(static_cast<ImageInfo*>(AcquireMagickMemory(sizeof(ImageInfo)))),
27    _quantizeInfo(static_cast<QuantizeInfo*>(AcquireMagickMemory(sizeof(QuantizeInfo)))),
28    _drawInfo(static_cast<DrawInfo*>(AcquireMagickMemory( sizeof(DrawInfo))))
29{
30  // Initialize image info with defaults
31  GetImageInfo( _imageInfo );
32
33  // Initialize quantization info
34  GetQuantizeInfo( _quantizeInfo );
35
36  // Initialize drawing info
37  GetDrawInfo( _imageInfo, _drawInfo );
38}
39
40// Copy constructor
41Magick::Options::Options( const Magick::Options& options_ )
42  : _imageInfo(CloneImageInfo( options_._imageInfo )),
43    _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
44    _drawInfo(CloneDrawInfo(_imageInfo, options_._drawInfo))
45{
46}
47
48// Construct using raw structures
49Magick::Options::Options( const MagickCore::ImageInfo* imageInfo_,
50                          const MagickCore::QuantizeInfo* quantizeInfo_,
51                          const MagickCore::DrawInfo* drawInfo_ )
52: _imageInfo(0),
53  _quantizeInfo(0),
54  _drawInfo(0)
55{
56  _imageInfo = CloneImageInfo(imageInfo_);
57  _quantizeInfo = CloneQuantizeInfo(quantizeInfo_);
58  _drawInfo = CloneDrawInfo(imageInfo_,drawInfo_);
59}
60
61// Destructor
62Magick::Options::~Options()
63{
64  // Destroy image info
65   _imageInfo =DestroyImageInfo( _imageInfo );
66  _imageInfo=0;
67
68  // Destroy quantization info
69   _quantizeInfo =DestroyQuantizeInfo( _quantizeInfo );
70  _quantizeInfo=0;
71
72  // Destroy drawing info
73   _drawInfo =DestroyDrawInfo( _drawInfo );
74  _drawInfo=0;
75}
76
77/*
78 * Methods for setting image attributes
79 *
80 */
81
82// Anti-alias Postscript and TrueType fonts (default true)
83void Magick::Options::antiAlias( bool flag_ )
84{
85  _drawInfo->text_antialias = static_cast<MagickBooleanType>
86    (flag_ ? MagickTrue : MagickFalse);
87}
88bool Magick::Options::antiAlias( void ) const
89{
90  return static_cast<bool>(_drawInfo->text_antialias);
91}
92
93void Magick::Options::adjoin ( bool flag_ )
94{
95  _imageInfo->adjoin = static_cast<MagickBooleanType>
96    (flag_ ? MagickTrue : MagickFalse);
97}
98bool Magick::Options::adjoin ( void ) const
99{
100  return static_cast<bool>(_imageInfo->adjoin);
101}
102
103void Magick::Options::backgroundColor ( const Magick::Color &color_ )
104{
105  _imageInfo->background_color = color_;
106}
107Magick::Color Magick::Options::backgroundColor ( void ) const
108{
109  return Magick::Color( _imageInfo->background_color );
110}
111
112void Magick::Options::backgroundTexture ( const std::string &backgroundTexture_ )
113{
114  if ( backgroundTexture_.length() == 0 )
115    _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture);
116  else
117    Magick::CloneString( &_imageInfo->texture, backgroundTexture_ );
118}
119std::string Magick::Options::backgroundTexture ( void ) const
120{
121  if ( _imageInfo->texture )
122    return std::string( _imageInfo->texture );
123  else
124    return std::string();
125}
126
127void Magick::Options::borderColor ( const Color &color_ )
128{
129  _imageInfo->border_color = color_;
130  _drawInfo->border_color = color_;
131}
132Magick::Color Magick::Options::borderColor ( void ) const
133{
134  return Magick::Color( _imageInfo->border_color );
135}
136
137// Text bounding-box base color
138void Magick::Options::boxColor ( const Magick::Color &boxColor_ )
139{
140  _drawInfo->undercolor = boxColor_;
141}
142Magick::Color Magick::Options::boxColor ( void ) const
143{
144  return Magick::Color( _drawInfo->undercolor );
145}
146
147void Magick::Options::colorspaceType ( Magick::ColorspaceType colorspace_ )
148{
149  _imageInfo->colorspace = colorspace_;
150}
151Magick::ColorspaceType Magick::Options::colorspaceType ( void ) const
152{
153  return static_cast<Magick::ColorspaceType>(_imageInfo->colorspace);
154}
155
156void Magick::Options::compressType ( CompressionType compressType_ )
157{
158  _imageInfo->compression = compressType_;
159}
160Magick::CompressionType Magick::Options::compressType ( void ) const
161{
162  return static_cast<Magick::CompressionType>(_imageInfo->compression);
163}
164
165void Magick::Options::colorFuzz ( double fuzz_ )
166{
167  _imageInfo->fuzz = fuzz_;
168}
169double Magick::Options::colorFuzz ( void ) const
170{
171  return _imageInfo->fuzz;
172}
173
174// Enable printing of debug messages from ImageMagick
175void Magick::Options::debug ( bool flag_ )
176{
177  if(flag_)
178    {
179      SetLogEventMask("All");
180    }
181  else
182    {
183      SetLogEventMask("None");
184    }
185}
186bool Magick::Options::debug ( void ) const
187{
188  if( IsEventLogging() )
189    {
190      return true;
191    }
192  return false;
193}
194
195void Magick::Options::density ( const Magick::Geometry &density_ )
196{
197  if ( !density_.isValid() )
198    _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density);
199  else
200    Magick::CloneString( &_imageInfo->density, density_ );
201}
202Magick::Geometry Magick::Options::density ( void ) const
203{
204  if ( _imageInfo->density )
205    return Geometry( _imageInfo->density );
206
207  return Geometry();
208}
209
210void Magick::Options::depth ( size_t depth_ )
211{
212  _imageInfo->depth = depth_;
213}
214size_t Magick::Options::depth ( void ) const
215{
216  return _imageInfo->depth;
217}
218
219// Endianness (little like Intel or big like SPARC) for image
220// formats which support endian-specific options.
221void Magick::Options::endian ( Magick::EndianType endian_ )
222{
223  _imageInfo->endian = endian_;
224}
225Magick::EndianType Magick::Options::endian ( void ) const
226{
227  return _imageInfo->endian;
228}
229
230void Magick::Options::file ( FILE *file_ )
231{
232  SetImageInfoFile( _imageInfo, file_ );
233}
234FILE *Magick::Options::file ( void ) const
235{
236  return GetImageInfoFile( _imageInfo );
237}
238
239void Magick::Options::fileName ( const std::string &fileName_ )
240{
241  fileName_.copy( _imageInfo->filename, MaxTextExtent-1 );
242  _imageInfo->filename[ fileName_.length() ] = 0;
243}
244std::string Magick::Options::fileName ( void ) const
245{
246  return std::string( _imageInfo->filename );
247}
248
249// Color to use when drawing inside an object
250void Magick::Options::fillColor ( const Magick::Color &fillColor_ )
251{
252  _drawInfo->fill = fillColor_;
253  if (fillColor_ == Magick::Color())
254    fillPattern((const MagickCore::Image*) NULL);
255}
256Magick::Color Magick::Options::fillColor ( void ) const
257{
258  return _drawInfo->fill;
259}
260// Pattern image to use when filling objects
261void Magick::Options::fillPattern ( const MagickCore::Image *fillPattern_ )
262{
263  if ( _drawInfo->fill_pattern )
264    {
265      DestroyImageList( _drawInfo->fill_pattern );
266      _drawInfo->fill_pattern = 0;
267    }
268  if ( fillPattern_ )
269    {
270      ExceptionInfo exceptionInfo;
271      GetExceptionInfo( &exceptionInfo );
272      _drawInfo->fill_pattern =
273	CloneImage( const_cast<MagickCore::Image*>(fillPattern_),
274		    0,
275		    0,
276		    static_cast<MagickBooleanType>(MagickTrue),
277		    &exceptionInfo );
278      throwException( exceptionInfo );
279      (void) DestroyExceptionInfo( &exceptionInfo );
280    }
281}
282const MagickCore::Image* Magick::Options::fillPattern ( void  ) const
283{
284  return _drawInfo->fill_pattern;
285}
286
287// Rule to use when filling drawn objects
288void Magick::Options::fillRule ( const Magick::FillRule &fillRule_ )
289{
290  _drawInfo->fill_rule = fillRule_;
291}
292Magick::FillRule Magick::Options::fillRule ( void ) const
293{
294  return _drawInfo->fill_rule;
295}
296
297void Magick::Options::font ( const std::string &font_ )
298{
299  if ( font_.length() == 0 )
300    {
301      _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font);
302      _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font);
303    }
304  else
305    {
306      Magick::CloneString( &_imageInfo->font, font_ );
307      Magick::CloneString( &_drawInfo->font, font_ );
308    }
309}
310std::string Magick::Options::font ( void ) const
311{
312  if ( _imageInfo->font )
313    return std::string( _imageInfo->font );
314
315  return std::string();
316}
317
318void Magick::Options::fontPointsize ( double pointSize_ )
319{
320  _imageInfo->pointsize = pointSize_;
321  _drawInfo->pointsize = pointSize_;
322}
323double Magick::Options::fontPointsize ( void ) const
324{
325  return _imageInfo->pointsize;
326}
327
328std::string Magick::Options::format ( void ) const
329{
330  ExceptionInfo exception;
331
332  const MagickInfo * magick_info = 0;
333  GetExceptionInfo(&exception);
334  if ( *_imageInfo->magick != '\0' )
335    magick_info = GetMagickInfo( _imageInfo->magick , &exception);
336  throwException( exception );
337  (void) DestroyExceptionInfo( &exception );
338
339  if (( magick_info != 0 ) &&
340      ( *magick_info->description != '\0' ))
341    return std::string( magick_info->description );
342
343  return std::string();
344}
345
346void Magick::Options::interlaceType ( Magick::InterlaceType interlace_ )
347{
348  _imageInfo->interlace = interlace_;
349}
350Magick::InterlaceType Magick::Options::interlaceType ( void ) const
351{
352  return static_cast<Magick::InterlaceType>(_imageInfo->interlace);
353}
354
355void Magick::Options::magick ( const std::string &magick_ )
356{
357  ExceptionInfo exception;
358
359  FormatLocaleString( _imageInfo->filename, MaxTextExtent, "%.1024s:", magick_.c_str() );
360  GetExceptionInfo(&exception);
361  SetImageInfo( _imageInfo, 1, &exception);
362  if ( *_imageInfo->magick == '\0' )
363    throwExceptionExplicit( OptionWarning, "Unrecognized image format",
364	    magick_.c_str() );
365  (void) DestroyExceptionInfo( &exception );
366}
367std::string Magick::Options::magick ( void ) const
368{
369  if ( _imageInfo->magick && *_imageInfo->magick )
370    return std::string( _imageInfo->magick );
371
372  return std::string();
373}
374
375void Magick::Options::matteColor ( const Magick::Color &matteColor_ )
376{
377  _imageInfo->matte_color = matteColor_;
378}
379Magick::Color Magick::Options::matteColor ( void ) const
380{
381  return Magick::Color( _imageInfo->matte_color );
382}
383
384void Magick::Options::monochrome ( bool monochromeFlag_ )
385{
386  _imageInfo->monochrome = (MagickBooleanType) monochromeFlag_;
387}
388bool Magick::Options::monochrome ( void ) const
389{
390  return static_cast<bool>(_imageInfo->monochrome);
391}
392
393void Magick::Options::page ( const Magick::Geometry &pageSize_ )
394{
395  if ( !pageSize_.isValid() )
396    _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page);
397  else
398    Magick::CloneString( &_imageInfo->page, pageSize_ );
399}
400Magick::Geometry Magick::Options::page ( void ) const
401{
402  if ( _imageInfo->page )
403    return Geometry( _imageInfo->page );
404
405    return Geometry();
406}
407
408void Magick::Options::quality ( size_t quality_ )
409{
410  _imageInfo->quality = quality_;
411}
412size_t Magick::Options::quality ( void ) const
413{
414  return _imageInfo->quality;
415}
416
417void Magick::Options::quantizeColors ( size_t colors_ )
418{
419  _quantizeInfo->number_colors = colors_;
420}
421size_t Magick::Options::quantizeColors ( void ) const
422{
423  return _quantizeInfo->number_colors;
424}
425
426void Magick::Options::quantizeColorSpace ( Magick::ColorspaceType colorSpace_ )
427{
428  _quantizeInfo->colorspace = colorSpace_;
429}
430Magick::ColorspaceType Magick::Options::quantizeColorSpace ( void ) const
431{
432  return static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace);
433}
434
435void Magick::Options::quantizeDither ( bool ditherFlag_ )
436{
437  _imageInfo->dither = (MagickBooleanType) ditherFlag_;
438  _quantizeInfo->dither_method = ditherFlag_ ? RiemersmaDitherMethod :
439    NoDitherMethod;
440}
441bool Magick::Options::quantizeDither ( void ) const
442{
443  return static_cast<bool>(_imageInfo->dither);
444}
445
446void Magick::Options::quantizeTreeDepth ( size_t treeDepth_ )
447{
448  _quantizeInfo->tree_depth = treeDepth_;
449}
450size_t Magick::Options::quantizeTreeDepth ( void ) const
451{
452  return _quantizeInfo->tree_depth;
453}
454
455void Magick::Options::resolutionUnits ( Magick::ResolutionType resolutionUnits_ )
456{
457  _imageInfo->units = resolutionUnits_;
458}
459Magick::ResolutionType Magick::Options::resolutionUnits ( void ) const
460{
461  return static_cast<Magick::ResolutionType>(_imageInfo->units);
462}
463
464void Magick::Options::samplingFactor ( const std::string &samplingFactor_ )
465{
466  if ( samplingFactor_.length() == 0 )
467    _imageInfo->sampling_factor=(char *) RelinquishMagickMemory(_imageInfo->sampling_factor);
468  else
469    Magick::CloneString( &_imageInfo->sampling_factor, samplingFactor_ );
470}
471std::string Magick::Options::samplingFactor ( void ) const
472{
473  if ( _imageInfo->sampling_factor )
474    return std::string( _imageInfo->sampling_factor );
475
476  return std::string();
477}
478
479void Magick::Options::size ( const Geometry &geometry_ )
480{
481  _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size);
482
483  if ( geometry_.isValid() )
484    Magick::CloneString( &_imageInfo->size, geometry_ );
485}
486Magick::Geometry Magick::Options::size ( void ) const
487{
488  if ( _imageInfo->size )
489    return Geometry( _imageInfo->size );
490
491  return Geometry();
492}
493
494void Magick::Options::strokeAntiAlias( bool flag_ )
495{
496  flag_ ? _drawInfo->stroke_antialias=MagickTrue : _drawInfo->stroke_antialias=MagickFalse;
497}
498bool Magick::Options::strokeAntiAlias( void ) const
499{
500  return (_drawInfo->stroke_antialias != 0 ? true : false);
501}
502
503// Color to use when drawing object outlines
504void Magick::Options::strokeColor ( const Magick::Color &strokeColor_ )
505{
506  _drawInfo->stroke = strokeColor_;
507}
508Magick::Color Magick::Options::strokeColor ( void ) const
509{
510  return _drawInfo->stroke;
511}
512
513void Magick::Options::strokeDashArray ( const double* strokeDashArray_ )
514{
515  _drawInfo->dash_pattern=(double *)
516    RelinquishMagickMemory(_drawInfo->dash_pattern);
517
518  if(strokeDashArray_)
519    {
520      // Count elements in dash array
521      size_t x;
522      for (x=0; strokeDashArray_[x]; x++) ;
523      // Allocate elements
524      _drawInfo->dash_pattern =
525        static_cast<double*>(AcquireMagickMemory((x+1)*sizeof(double)));
526      // Copy elements
527      memcpy(_drawInfo->dash_pattern,strokeDashArray_,
528             (x+1)*sizeof(double));
529    }
530}
531const double* Magick::Options::strokeDashArray ( void ) const
532{
533  return _drawInfo->dash_pattern;
534}
535
536void Magick::Options::strokeDashOffset ( double strokeDashOffset_ )
537{
538  _drawInfo->dash_offset = strokeDashOffset_;
539}
540double Magick::Options::strokeDashOffset ( void ) const
541{
542  return _drawInfo->dash_offset;
543}
544
545// Specify the shape to be used at the end of open subpaths when they
546// are stroked. Values of LineCap are ButtCap, RoundCap, and
547// SquareCap.
548void Magick::Options::strokeLineCap ( Magick::LineCap lineCap_ )
549{
550  _drawInfo->linecap = lineCap_;
551}
552Magick::LineCap Magick::Options::strokeLineCap ( void ) const
553{
554  return _drawInfo->linecap;
555}
556
557// Specify the shape to be used at the corners of paths (or other
558// vector shapes) when they are stroked.
559void Magick::Options::strokeLineJoin ( Magick::LineJoin lineJoin_ )
560{
561  _drawInfo->linejoin = lineJoin_;
562}
563Magick::LineJoin Magick::Options::strokeLineJoin ( void ) const
564{
565  return _drawInfo->linejoin;
566}
567
568// miterLimit for drawing lines, circles, ellipses, etc.
569void Magick::Options::strokeMiterLimit ( size_t miterLimit_ )
570{
571  _drawInfo->miterlimit = miterLimit_;
572}
573size_t Magick::Options::strokeMiterLimit ( void ) const
574{
575  return _drawInfo->miterlimit;
576}
577
578// Pattern image to use for stroked outlines
579void Magick::Options::strokePattern ( const MagickCore::Image *strokePattern_ )
580{
581  if ( _drawInfo->stroke_pattern )
582    {
583      DestroyImageList( _drawInfo->stroke_pattern );
584      _drawInfo->stroke_pattern = 0;
585    }
586
587  if ( strokePattern_ )
588    {
589      ExceptionInfo exceptionInfo;
590      GetExceptionInfo( &exceptionInfo );
591      _drawInfo->stroke_pattern =
592	CloneImage( const_cast<MagickCore::Image*>(strokePattern_),
593		    0,
594		    0,
595		    MagickTrue,
596		    &exceptionInfo );
597      throwException( exceptionInfo );
598      (void) DestroyExceptionInfo( &exceptionInfo );
599    }
600}
601const MagickCore::Image* Magick::Options::strokePattern ( void  ) const
602{
603  return _drawInfo->stroke_pattern;
604}
605
606// Stroke width for drawing lines, circles, ellipses, etc.
607void Magick::Options::strokeWidth ( double strokeWidth_ )
608{
609  _drawInfo->stroke_width = strokeWidth_;
610}
611double Magick::Options::strokeWidth ( void ) const
612{
613  return _drawInfo->stroke_width;
614}
615
616void Magick::Options::subImage ( size_t subImage_ )
617{
618  _imageInfo->scene = subImage_;
619}
620size_t Magick::Options::subImage ( void ) const
621{
622  return _imageInfo->scene;
623}
624
625void Magick::Options::subRange ( size_t subRange_ )
626{
627  _imageInfo->number_scenes = subRange_;
628}
629size_t Magick::Options::subRange ( void ) const
630{
631  return _imageInfo->number_scenes;
632}
633
634// Annotation text encoding (e.g. "UTF-16")
635void Magick::Options::textEncoding ( const std::string &encoding_ )
636{
637  CloneString(&_drawInfo->encoding, encoding_.c_str());
638}
639std::string Magick::Options::textEncoding ( void ) const
640{
641  if ( _drawInfo->encoding && *_drawInfo->encoding )
642    return std::string( _drawInfo->encoding );
643
644  return std::string();
645}
646
647// Image representation type
648void Magick::Options::type ( const Magick::ImageType type_ )
649{
650  _imageInfo->type = type_;
651}
652Magick::ImageType Magick::Options::type ( void ) const
653{
654  return _imageInfo->type;
655}
656
657// Origin of coordinate system to use when annotating with text or drawing
658void Magick::Options::transformOrigin ( double tx_, double ty_ )
659{
660  AffineMatrix current = _drawInfo->affine;
661  AffineMatrix affine;
662  affine.sx=1.0;
663  affine.rx=0.0;
664  affine.ry=0.0;
665  affine.sy=1.0;
666  affine.tx=0.0;
667  affine.ty=0.0;
668
669  affine.tx = tx_;
670  affine.ty = ty_;
671
672  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
673  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
674  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
675  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
676  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
677  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
678}
679
680// Reset transformation parameters to default
681void Magick::Options::transformReset ( void )
682{
683  _drawInfo->affine.sx=1.0;
684  _drawInfo->affine.rx=0.0;
685  _drawInfo->affine.ry=0.0;
686  _drawInfo->affine.sy=1.0;
687  _drawInfo->affine.tx=0.0;
688  _drawInfo->affine.ty=0.0;
689}
690
691// Rotation to use when annotating with text or drawing
692void Magick::Options::transformRotation ( double angle_ )
693{
694  AffineMatrix current = _drawInfo->affine;
695  AffineMatrix affine;
696  affine.sx=1.0;
697  affine.rx=0.0;
698  affine.ry=0.0;
699  affine.sy=1.0;
700  affine.tx=0.0;
701  affine.ty=0.0;
702
703  affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
704  affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
705  affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
706  affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
707
708  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
709  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
710  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
711  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
712  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
713  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
714}
715
716// Scale to use when annotating with text or drawing
717void Magick::Options::transformScale ( double sx_, double sy_ )
718{
719  AffineMatrix current = _drawInfo->affine;
720  AffineMatrix affine;
721  affine.sx=1.0;
722  affine.rx=0.0;
723  affine.ry=0.0;
724  affine.sy=1.0;
725  affine.tx=0.0;
726  affine.ty=0.0;
727
728  affine.sx = sx_;
729  affine.sy = sy_;
730
731  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
732  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
733  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
734  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
735  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
736  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
737}
738
739// Skew to use in X axis when annotating with text or drawing
740void Magick::Options::transformSkewX ( double skewx_ )
741{
742  AffineMatrix current = _drawInfo->affine;
743  AffineMatrix affine;
744  affine.sx=1.0;
745  affine.rx=0.0;
746  affine.ry=0.0;
747  affine.sy=1.0;
748  affine.tx=0.0;
749  affine.ty=0.0;
750
751  affine.sx=1.0;
752  affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
753  affine.sy=1.0;
754
755  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
756  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
757  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
758  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
759  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
760  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
761}
762
763// Skew to use in Y axis when annotating with text or drawing
764void Magick::Options::transformSkewY ( double skewy_ )
765{
766  AffineMatrix current = _drawInfo->affine;
767  AffineMatrix affine;
768  affine.sx=1.0;
769  affine.rx=0.0;
770  affine.ry=0.0;
771  affine.sy=1.0;
772  affine.tx=0.0;
773  affine.ty=0.0;
774
775  affine.sx=1.0;
776  affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
777  affine.sy=1.0;
778
779  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
780  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
781  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
782  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
783  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
784  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
785}
786
787void Magick::Options::verbose ( bool verboseFlag_ )
788{
789  _imageInfo->verbose = (MagickBooleanType) verboseFlag_;
790}
791bool Magick::Options::verbose ( void ) const
792{
793  return static_cast<bool>(_imageInfo->verbose);
794}
795
796void Magick::Options::view ( const std::string &view_ )
797{
798  if ( view_.length() == 0 )
799    _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
800  else
801    Magick::CloneString( &_imageInfo->view, view_ );
802}
803std::string Magick::Options::view ( void ) const
804{
805  if ( _imageInfo->view )
806    return std::string( _imageInfo->view );
807
808  return std::string();
809}
810
811void Magick::Options::x11Display ( const std::string &display_ )
812{
813  if ( display_.length() == 0 )
814    _imageInfo->server_name=(char *) RelinquishMagickMemory(_imageInfo->server_name);
815  else
816    Magick::CloneString( &_imageInfo->server_name, display_ );
817}
818std::string Magick::Options::x11Display ( void ) const
819{
820  if ( _imageInfo->server_name )
821    return std::string( _imageInfo->server_name );
822
823  return std::string();
824}
825
826//
827// Internal implementation methods.  Please do not use.
828//
829
830MagickCore::DrawInfo * Magick::Options::drawInfo( void )
831{
832  return _drawInfo;
833}
834
835MagickCore::ImageInfo * Magick::Options::imageInfo( void )
836{
837  return _imageInfo;
838}
839
840MagickCore::QuantizeInfo * Magick::Options::quantizeInfo( void )
841{
842  return _quantizeInfo;
843}
844