Options.cpp revision b51dff5c0d16a4c1b69ff683e786cb3b4c467694
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 "Magick++/Include.h"
14#include <string>
15#include <string.h>
16#include <stdlib.h>
17#include <math.h>
18#include "Magick++/Options.h"
19#include "Magick++/Functions.h"
20#include "Magick++/Exception.h"
21
22#define MagickPI  3.14159265358979323846264338327950288419716939937510
23#define DegreesToRadians(x)  (MagickPI*(x)/180.0)
24
25// Constructor
26Magick::Options::Options( void )
27  : _imageInfo(static_cast<ImageInfo*>(AcquireMagickMemory(sizeof(ImageInfo)))),
28    _quantizeInfo(static_cast<QuantizeInfo*>(AcquireMagickMemory(sizeof(QuantizeInfo)))),
29    _drawInfo(static_cast<DrawInfo*>(AcquireMagickMemory( sizeof(DrawInfo))))
30{
31  // Initialize image info with defaults
32  GetImageInfo( _imageInfo );
33
34  // Initialize quantization info
35  GetQuantizeInfo( _quantizeInfo );
36
37  // Initialize drawing info
38  GetDrawInfo( _imageInfo, _drawInfo );
39}
40
41// Copy constructor
42Magick::Options::Options( const Magick::Options& options_ )
43  : _imageInfo(CloneImageInfo( options_._imageInfo )),
44    _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
45    _drawInfo(CloneDrawInfo(_imageInfo, options_._drawInfo))
46{
47}
48
49// Construct using raw structures
50Magick::Options::Options( const MagickCore::ImageInfo* imageInfo_,
51                          const MagickCore::QuantizeInfo* quantizeInfo_,
52                          const MagickCore::DrawInfo* drawInfo_ )
53: _imageInfo(0),
54  _quantizeInfo(0),
55  _drawInfo(0)
56{
57  _imageInfo = CloneImageInfo(imageInfo_);
58  _quantizeInfo = CloneQuantizeInfo(quantizeInfo_);
59  _drawInfo = CloneDrawInfo(imageInfo_,drawInfo_);
60}
61
62// Destructor
63Magick::Options::~Options()
64{
65  // Destroy image info
66   _imageInfo =DestroyImageInfo( _imageInfo );
67  _imageInfo=0;
68
69  // Destroy quantization info
70   _quantizeInfo =DestroyQuantizeInfo( _quantizeInfo );
71  _quantizeInfo=0;
72
73  // Destroy drawing info
74   _drawInfo =DestroyDrawInfo( _drawInfo );
75  _drawInfo=0;
76}
77
78/*
79 * Methods for setting image attributes
80 *
81 */
82
83// Anti-alias Postscript and TrueType fonts (default true)
84void Magick::Options::antiAlias( bool flag_ )
85{
86  _drawInfo->text_antialias = static_cast<MagickBooleanType>
87    (flag_ ? MagickTrue : MagickFalse);
88}
89bool Magick::Options::antiAlias( void ) const
90{
91  return static_cast<bool>(_drawInfo->text_antialias);
92}
93
94void Magick::Options::adjoin ( bool flag_ )
95{
96  _imageInfo->adjoin = static_cast<MagickBooleanType>
97    (flag_ ? MagickTrue : MagickFalse);
98}
99bool Magick::Options::adjoin ( void ) const
100{
101  return static_cast<bool>(_imageInfo->adjoin);
102}
103
104void Magick::Options::backgroundColor ( const Magick::Color &color_ )
105{
106  _imageInfo->background_color = color_;
107}
108Magick::Color Magick::Options::backgroundColor ( void ) const
109{
110  return Magick::Color( _imageInfo->background_color );
111}
112
113void Magick::Options::backgroundTexture ( const std::string &backgroundTexture_ )
114{
115  if ( backgroundTexture_.length() == 0 )
116    _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture);
117  else
118    Magick::CloneString( &_imageInfo->texture, backgroundTexture_ );
119}
120std::string Magick::Options::backgroundTexture ( void ) const
121{
122  if ( _imageInfo->texture )
123    return std::string( _imageInfo->texture );
124  else
125    return std::string();
126}
127
128void Magick::Options::borderColor ( const Color &color_ )
129{
130  _imageInfo->border_color = color_;
131  _drawInfo->border_color = color_;
132}
133Magick::Color Magick::Options::borderColor ( void ) const
134{
135  return Magick::Color( _imageInfo->border_color );
136}
137
138// Text bounding-box base color
139void Magick::Options::boxColor ( const Magick::Color &boxColor_ )
140{
141  _drawInfo->undercolor = boxColor_;
142}
143Magick::Color Magick::Options::boxColor ( void ) const
144{
145  return Magick::Color( _drawInfo->undercolor );
146}
147
148void Magick::Options::colorspaceType ( Magick::ColorspaceType colorspace_ )
149{
150  _imageInfo->colorspace = colorspace_;
151}
152Magick::ColorspaceType Magick::Options::colorspaceType ( void ) const
153{
154  return static_cast<Magick::ColorspaceType>(_imageInfo->colorspace);
155}
156
157void Magick::Options::compressType ( CompressionType compressType_ )
158{
159  _imageInfo->compression = compressType_;
160}
161Magick::CompressionType Magick::Options::compressType ( void ) const
162{
163  return static_cast<Magick::CompressionType>(_imageInfo->compression);
164}
165
166void Magick::Options::colorFuzz ( double fuzz_ )
167{
168  _imageInfo->fuzz = fuzz_;
169}
170double Magick::Options::colorFuzz ( void ) const
171{
172  return _imageInfo->fuzz;
173}
174
175// Enable printing of debug messages from ImageMagick
176void Magick::Options::debug ( bool flag_ )
177{
178  if(flag_)
179    {
180      SetLogEventMask("All");
181    }
182  else
183    {
184      SetLogEventMask("None");
185    }
186}
187bool Magick::Options::debug ( void ) const
188{
189  if( IsEventLogging() )
190    {
191      return true;
192    }
193  return false;
194}
195
196void Magick::Options::density ( const Magick::Geometry &density_ )
197{
198  if ( !density_.isValid() )
199    _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density);
200  else
201    Magick::CloneString( &_imageInfo->density, density_ );
202}
203Magick::Geometry Magick::Options::density ( void ) const
204{
205  if ( _imageInfo->density )
206    return Geometry( _imageInfo->density );
207
208  return Geometry();
209}
210
211void Magick::Options::depth ( size_t depth_ )
212{
213  _imageInfo->depth = depth_;
214}
215size_t Magick::Options::depth ( void ) const
216{
217  return _imageInfo->depth;
218}
219
220// Endianness (little like Intel or big like SPARC) for image
221// formats which support endian-specific options.
222void Magick::Options::endian ( Magick::EndianType endian_ )
223{
224  _imageInfo->endian = endian_;
225}
226Magick::EndianType Magick::Options::endian ( void ) const
227{
228  return _imageInfo->endian;
229}
230
231void Magick::Options::file ( FILE *file_ )
232{
233  SetImageInfoFile( _imageInfo, file_ );
234}
235FILE *Magick::Options::file ( void ) const
236{
237  return GetImageInfoFile( _imageInfo );
238}
239
240void Magick::Options::fileName ( const std::string &fileName_ )
241{
242  fileName_.copy( _imageInfo->filename, MaxTextExtent-1 );
243  _imageInfo->filename[ fileName_.length() ] = 0;
244}
245std::string Magick::Options::fileName ( void ) const
246{
247  return std::string( _imageInfo->filename );
248}
249
250// Color to use when drawing inside an object
251void Magick::Options::fillColor ( const Magick::Color &fillColor_ )
252{
253  _drawInfo->fill = fillColor_;
254  if (fillColor_ == Magick::Color())
255    fillPattern((const MagickCore::Image*) NULL);
256}
257Magick::Color Magick::Options::fillColor ( void ) const
258{
259  return _drawInfo->fill;
260}
261// Pattern image to use when filling objects
262void Magick::Options::fillPattern ( const MagickCore::Image *fillPattern_ )
263{
264  if ( _drawInfo->fill_pattern )
265    {
266      DestroyImageList( _drawInfo->fill_pattern );
267      _drawInfo->fill_pattern = 0;
268    }
269  if ( fillPattern_ )
270    {
271      ExceptionInfo exceptionInfo;
272      GetExceptionInfo( &exceptionInfo );
273      _drawInfo->fill_pattern =
274	CloneImage( const_cast<MagickCore::Image*>(fillPattern_),
275		    0,
276		    0,
277		    static_cast<MagickBooleanType>(MagickTrue),
278		    &exceptionInfo );
279      throwException( exceptionInfo );
280      (void) DestroyExceptionInfo( &exceptionInfo );
281    }
282}
283const MagickCore::Image* Magick::Options::fillPattern ( void  ) const
284{
285  return _drawInfo->fill_pattern;
286}
287
288// Rule to use when filling drawn objects
289void Magick::Options::fillRule ( const Magick::FillRule &fillRule_ )
290{
291  _drawInfo->fill_rule = fillRule_;
292}
293Magick::FillRule Magick::Options::fillRule ( void ) const
294{
295  return _drawInfo->fill_rule;
296}
297
298void Magick::Options::font ( const std::string &font_ )
299{
300  if ( font_.length() == 0 )
301    {
302      _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font);
303      _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font);
304    }
305  else
306    {
307      Magick::CloneString( &_imageInfo->font, font_ );
308      Magick::CloneString( &_drawInfo->font, font_ );
309    }
310}
311std::string Magick::Options::font ( void ) const
312{
313  if ( _imageInfo->font )
314    return std::string( _imageInfo->font );
315
316  return std::string();
317}
318
319void Magick::Options::fontPointsize ( double pointSize_ )
320{
321  _imageInfo->pointsize = pointSize_;
322  _drawInfo->pointsize = pointSize_;
323}
324double Magick::Options::fontPointsize ( void ) const
325{
326  return _imageInfo->pointsize;
327}
328
329std::string Magick::Options::format ( void ) const
330{
331  ExceptionInfo exception;
332
333  const MagickInfo * magick_info = 0;
334  GetExceptionInfo(&exception);
335  if ( *_imageInfo->magick != '\0' )
336    magick_info = GetMagickInfo( _imageInfo->magick , &exception);
337  throwException( exception );
338  (void) DestroyExceptionInfo( &exception );
339
340  if (( magick_info != 0 ) &&
341      ( *magick_info->description != '\0' ))
342    return std::string( magick_info->description );
343
344  return std::string();
345}
346
347void Magick::Options::interlaceType ( Magick::InterlaceType interlace_ )
348{
349  _imageInfo->interlace = interlace_;
350}
351Magick::InterlaceType Magick::Options::interlaceType ( void ) const
352{
353  return static_cast<Magick::InterlaceType>(_imageInfo->interlace);
354}
355
356void Magick::Options::magick ( const std::string &magick_ )
357{
358  ExceptionInfo exception;
359
360  FormatLocaleString( _imageInfo->filename, MaxTextExtent, "%.1024s:", magick_.c_str() );
361  GetExceptionInfo(&exception);
362  SetImageInfo( _imageInfo, 1, &exception);
363  if ( *_imageInfo->magick == '\0' )
364    throwExceptionExplicit( OptionWarning, "Unrecognized image format",
365	    magick_.c_str() );
366  (void) DestroyExceptionInfo( &exception );
367}
368std::string Magick::Options::magick ( void ) const
369{
370  if ( _imageInfo->magick && *_imageInfo->magick )
371    return std::string( _imageInfo->magick );
372
373  return std::string();
374}
375
376void Magick::Options::matteColor ( const Magick::Color &matteColor_ )
377{
378  _imageInfo->matte_color = matteColor_;
379}
380Magick::Color Magick::Options::matteColor ( void ) const
381{
382  return Magick::Color( _imageInfo->matte_color );
383}
384
385void Magick::Options::monochrome ( bool monochromeFlag_ )
386{
387  _imageInfo->monochrome = (MagickBooleanType) monochromeFlag_;
388}
389bool Magick::Options::monochrome ( void ) const
390{
391  return static_cast<bool>(_imageInfo->monochrome);
392}
393
394void Magick::Options::page ( const Magick::Geometry &pageSize_ )
395{
396  if ( !pageSize_.isValid() )
397    _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page);
398  else
399    Magick::CloneString( &_imageInfo->page, pageSize_ );
400}
401Magick::Geometry Magick::Options::page ( void ) const
402{
403  if ( _imageInfo->page )
404    return Geometry( _imageInfo->page );
405
406    return Geometry();
407}
408
409void Magick::Options::quality ( size_t quality_ )
410{
411  _imageInfo->quality = quality_;
412}
413size_t Magick::Options::quality ( void ) const
414{
415  return _imageInfo->quality;
416}
417
418void Magick::Options::quantizeColors ( size_t colors_ )
419{
420  _quantizeInfo->number_colors = colors_;
421}
422size_t Magick::Options::quantizeColors ( void ) const
423{
424  return _quantizeInfo->number_colors;
425}
426
427void Magick::Options::quantizeColorSpace ( Magick::ColorspaceType colorSpace_ )
428{
429  _quantizeInfo->colorspace = colorSpace_;
430}
431Magick::ColorspaceType Magick::Options::quantizeColorSpace ( void ) const
432{
433  return static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace);
434}
435
436void Magick::Options::quantizeDither ( bool ditherFlag_ )
437{
438  _imageInfo->dither = (MagickBooleanType) ditherFlag_;
439  _quantizeInfo->dither = (MagickBooleanType) ditherFlag_;
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
647void Magick::Options::tileName ( const std::string &tileName_ )
648{
649  if ( tileName_.length() == 0 )
650    _imageInfo->tile=(char *) RelinquishMagickMemory(_imageInfo->tile);
651  else
652    Magick::CloneString( &_imageInfo->tile, tileName_ );
653}
654std::string Magick::Options::tileName ( void ) const
655{
656  if ( _imageInfo->tile )
657    return std::string( _imageInfo->tile );
658  return std::string();
659}
660
661// Image representation type
662void Magick::Options::type ( const Magick::ImageType type_ )
663{
664  _imageInfo->type = type_;
665}
666Magick::ImageType Magick::Options::type ( void ) const
667{
668  return _imageInfo->type;
669}
670
671// Origin of coordinate system to use when annotating with text or drawing
672void Magick::Options::transformOrigin ( double tx_, double ty_ )
673{
674  AffineMatrix current = _drawInfo->affine;
675  AffineMatrix affine;
676  affine.sx=1.0;
677  affine.rx=0.0;
678  affine.ry=0.0;
679  affine.sy=1.0;
680  affine.tx=0.0;
681  affine.ty=0.0;
682
683  affine.tx = tx_;
684  affine.ty = ty_;
685
686  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
687  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
688  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
689  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
690  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
691  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
692}
693
694// Reset transformation parameters to default
695void Magick::Options::transformReset ( void )
696{
697  _drawInfo->affine.sx=1.0;
698  _drawInfo->affine.rx=0.0;
699  _drawInfo->affine.ry=0.0;
700  _drawInfo->affine.sy=1.0;
701  _drawInfo->affine.tx=0.0;
702  _drawInfo->affine.ty=0.0;
703}
704
705// Rotation to use when annotating with text or drawing
706void Magick::Options::transformRotation ( double angle_ )
707{
708  AffineMatrix current = _drawInfo->affine;
709  AffineMatrix affine;
710  affine.sx=1.0;
711  affine.rx=0.0;
712  affine.ry=0.0;
713  affine.sy=1.0;
714  affine.tx=0.0;
715  affine.ty=0.0;
716
717  affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
718  affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
719  affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
720  affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
721
722  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
723  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
724  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
725  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
726  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
727  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
728}
729
730// Scale to use when annotating with text or drawing
731void Magick::Options::transformScale ( double sx_, double sy_ )
732{
733  AffineMatrix current = _drawInfo->affine;
734  AffineMatrix affine;
735  affine.sx=1.0;
736  affine.rx=0.0;
737  affine.ry=0.0;
738  affine.sy=1.0;
739  affine.tx=0.0;
740  affine.ty=0.0;
741
742  affine.sx = sx_;
743  affine.sy = sy_;
744
745  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
746  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
747  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
748  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
749  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
750  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
751}
752
753// Skew to use in X axis when annotating with text or drawing
754void Magick::Options::transformSkewX ( double skewx_ )
755{
756  AffineMatrix current = _drawInfo->affine;
757  AffineMatrix affine;
758  affine.sx=1.0;
759  affine.rx=0.0;
760  affine.ry=0.0;
761  affine.sy=1.0;
762  affine.tx=0.0;
763  affine.ty=0.0;
764
765  affine.sx=1.0;
766  affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
767  affine.sy=1.0;
768
769  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
770  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
771  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
772  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
773  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
774  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
775}
776
777// Skew to use in Y axis when annotating with text or drawing
778void Magick::Options::transformSkewY ( double skewy_ )
779{
780  AffineMatrix current = _drawInfo->affine;
781  AffineMatrix affine;
782  affine.sx=1.0;
783  affine.rx=0.0;
784  affine.ry=0.0;
785  affine.sy=1.0;
786  affine.tx=0.0;
787  affine.ty=0.0;
788
789  affine.sx=1.0;
790  affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
791  affine.sy=1.0;
792
793  _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
794  _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
795  _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
796  _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
797  _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
798  _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
799}
800
801void Magick::Options::verbose ( bool verboseFlag_ )
802{
803  _imageInfo->verbose = (MagickBooleanType) verboseFlag_;
804}
805bool Magick::Options::verbose ( void ) const
806{
807  return static_cast<bool>(_imageInfo->verbose);
808}
809
810void Magick::Options::virtualPixelMethod ( VirtualPixelMethod virtual_pixel_method_ )
811{
812  _imageInfo->virtual_pixel_method = virtual_pixel_method_;
813}
814Magick::VirtualPixelMethod Magick::Options::virtualPixelMethod ( void ) const
815{
816  return static_cast<Magick::VirtualPixelMethod>(_imageInfo->virtual_pixel_method);
817}
818
819void Magick::Options::view ( const std::string &view_ )
820{
821  if ( view_.length() == 0 )
822    _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
823  else
824    Magick::CloneString( &_imageInfo->view, view_ );
825}
826std::string Magick::Options::view ( void ) const
827{
828  if ( _imageInfo->view )
829    return std::string( _imageInfo->view );
830
831  return std::string();
832}
833
834void Magick::Options::x11Display ( const std::string &display_ )
835{
836  if ( display_.length() == 0 )
837    _imageInfo->server_name=(char *) RelinquishMagickMemory(_imageInfo->server_name);
838  else
839    Magick::CloneString( &_imageInfo->server_name, display_ );
840}
841std::string Magick::Options::x11Display ( void ) const
842{
843  if ( _imageInfo->server_name )
844    return std::string( _imageInfo->server_name );
845
846  return std::string();
847}
848
849//
850// Internal implementation methods.  Please do not use.
851//
852
853MagickCore::DrawInfo * Magick::Options::drawInfo( void )
854{
855  return _drawInfo;
856}
857
858MagickCore::ImageInfo * Magick::Options::imageInfo( void )
859{
860  return _imageInfo;
861}
862
863MagickCore::QuantizeInfo * Magick::Options::quantizeInfo( void )
864{
865  return _quantizeInfo;
866}
867