blob: 1ded7bc7ac90b64615702986b4608ea42fd314d7 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001// 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
cristy3ed852e2009-09-05 21:47:34 +000013#include <string>
14#include <string.h>
15#include <stdlib.h>
16#include <math.h>
cristy4c08aed2011-07-01 19:47:50 +000017#include "Magick++/Include.h"
cristy3ed852e2009-09-05 21:47:34 +000018#include "Magick++/Options.h"
19#include "Magick++/Functions.h"
20#include "Magick++/Exception.h"
21
cristy3ed852e2009-09-05 21:47:34 +000022#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
cristyeaedf062010-05-29 22:36:02 +0000210void Magick::Options::depth ( size_t depth_ )
cristy3ed852e2009-09-05 21:47:34 +0000211{
212 _imageInfo->depth = depth_;
213}
cristyeaedf062010-05-29 22:36:02 +0000214size_t Magick::Options::depth ( void ) const
cristy3ed852e2009-09-05 21:47:34 +0000215{
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
cristy15781e52009-12-05 23:05:27 +0000230void Magick::Options::file ( FILE *file_ )
231{
cristyc3ff8d82009-12-05 23:55:49 +0000232 SetImageInfoFile( _imageInfo, file_ );
cristy15781e52009-12-05 23:05:27 +0000233}
234FILE *Magick::Options::file ( void ) const
235{
cristy658cdd12009-12-06 15:13:04 +0000236 return GetImageInfoFile( _imageInfo );
cristy15781e52009-12-05 23:05:27 +0000237}
238
cristy3ed852e2009-09-05 21:47:34 +0000239void 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
cristyb51dff52011-05-19 16:55:47 +0000359 FormatLocaleString( _imageInfo->filename, MaxTextExtent, "%.1024s:", magick_.c_str() );
cristy3ed852e2009-09-05 21:47:34 +0000360 GetExceptionInfo(&exception);
cristyd965a422010-03-03 17:47:35 +0000361 SetImageInfo( _imageInfo, 1, &exception);
cristy3ed852e2009-09-05 21:47:34 +0000362 if ( *_imageInfo->magick == '\0' )
cristyd965a422010-03-03 17:47:35 +0000363 throwExceptionExplicit( OptionWarning, "Unrecognized image format",
364 magick_.c_str() );
cristy3ed852e2009-09-05 21:47:34 +0000365 (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
cristyeaedf062010-05-29 22:36:02 +0000408void Magick::Options::quality ( size_t quality_ )
cristy3ed852e2009-09-05 21:47:34 +0000409{
410 _imageInfo->quality = quality_;
411}
cristyeaedf062010-05-29 22:36:02 +0000412size_t Magick::Options::quality ( void ) const
cristy3ed852e2009-09-05 21:47:34 +0000413{
414 return _imageInfo->quality;
415}
416
cristyeaedf062010-05-29 22:36:02 +0000417void Magick::Options::quantizeColors ( size_t colors_ )
cristy3ed852e2009-09-05 21:47:34 +0000418{
419 _quantizeInfo->number_colors = colors_;
420}
cristyeaedf062010-05-29 22:36:02 +0000421size_t Magick::Options::quantizeColors ( void ) const
cristy3ed852e2009-09-05 21:47:34 +0000422{
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 = (MagickBooleanType) ditherFlag_;
439}
440bool Magick::Options::quantizeDither ( void ) const
441{
442 return static_cast<bool>(_imageInfo->dither);
443}
444
cristyeaedf062010-05-29 22:36:02 +0000445void Magick::Options::quantizeTreeDepth ( size_t treeDepth_ )
cristy3ed852e2009-09-05 21:47:34 +0000446{
447 _quantizeInfo->tree_depth = treeDepth_;
448}
cristyeaedf062010-05-29 22:36:02 +0000449size_t Magick::Options::quantizeTreeDepth ( void ) const
cristy3ed852e2009-09-05 21:47:34 +0000450{
451 return _quantizeInfo->tree_depth;
452}
453
454void Magick::Options::resolutionUnits ( Magick::ResolutionType resolutionUnits_ )
455{
456 _imageInfo->units = resolutionUnits_;
457}
458Magick::ResolutionType Magick::Options::resolutionUnits ( void ) const
459{
460 return static_cast<Magick::ResolutionType>(_imageInfo->units);
461}
462
463void Magick::Options::samplingFactor ( const std::string &samplingFactor_ )
464{
465 if ( samplingFactor_.length() == 0 )
466 _imageInfo->sampling_factor=(char *) RelinquishMagickMemory(_imageInfo->sampling_factor);
467 else
468 Magick::CloneString( &_imageInfo->sampling_factor, samplingFactor_ );
469}
470std::string Magick::Options::samplingFactor ( void ) const
471{
472 if ( _imageInfo->sampling_factor )
473 return std::string( _imageInfo->sampling_factor );
474
475 return std::string();
476}
477
478void Magick::Options::size ( const Geometry &geometry_ )
479{
480 _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size);
481
482 if ( geometry_.isValid() )
483 Magick::CloneString( &_imageInfo->size, geometry_ );
484}
485Magick::Geometry Magick::Options::size ( void ) const
486{
487 if ( _imageInfo->size )
488 return Geometry( _imageInfo->size );
489
490 return Geometry();
491}
492
493void Magick::Options::strokeAntiAlias( bool flag_ )
494{
495 flag_ ? _drawInfo->stroke_antialias=MagickTrue : _drawInfo->stroke_antialias=MagickFalse;
496}
497bool Magick::Options::strokeAntiAlias( void ) const
498{
499 return (_drawInfo->stroke_antialias != 0 ? true : false);
500}
501
502// Color to use when drawing object outlines
503void Magick::Options::strokeColor ( const Magick::Color &strokeColor_ )
504{
505 _drawInfo->stroke = strokeColor_;
506}
507Magick::Color Magick::Options::strokeColor ( void ) const
508{
509 return _drawInfo->stroke;
510}
511
512void Magick::Options::strokeDashArray ( const double* strokeDashArray_ )
513{
514 _drawInfo->dash_pattern=(double *)
515 RelinquishMagickMemory(_drawInfo->dash_pattern);
516
517 if(strokeDashArray_)
518 {
519 // Count elements in dash array
cristyeaedf062010-05-29 22:36:02 +0000520 size_t x;
cristy3ed852e2009-09-05 21:47:34 +0000521 for (x=0; strokeDashArray_[x]; x++) ;
522 // Allocate elements
523 _drawInfo->dash_pattern =
524 static_cast<double*>(AcquireMagickMemory((x+1)*sizeof(double)));
525 // Copy elements
526 memcpy(_drawInfo->dash_pattern,strokeDashArray_,
527 (x+1)*sizeof(double));
528 }
529}
530const double* Magick::Options::strokeDashArray ( void ) const
531{
532 return _drawInfo->dash_pattern;
533}
534
535void Magick::Options::strokeDashOffset ( double strokeDashOffset_ )
536{
537 _drawInfo->dash_offset = strokeDashOffset_;
538}
539double Magick::Options::strokeDashOffset ( void ) const
540{
541 return _drawInfo->dash_offset;
542}
543
544// Specify the shape to be used at the end of open subpaths when they
545// are stroked. Values of LineCap are ButtCap, RoundCap, and
546// SquareCap.
547void Magick::Options::strokeLineCap ( Magick::LineCap lineCap_ )
548{
549 _drawInfo->linecap = lineCap_;
550}
551Magick::LineCap Magick::Options::strokeLineCap ( void ) const
552{
553 return _drawInfo->linecap;
554}
555
556// Specify the shape to be used at the corners of paths (or other
557// vector shapes) when they are stroked.
558void Magick::Options::strokeLineJoin ( Magick::LineJoin lineJoin_ )
559{
560 _drawInfo->linejoin = lineJoin_;
561}
562Magick::LineJoin Magick::Options::strokeLineJoin ( void ) const
563{
564 return _drawInfo->linejoin;
565}
566
567// miterLimit for drawing lines, circles, ellipses, etc.
cristyeaedf062010-05-29 22:36:02 +0000568void Magick::Options::strokeMiterLimit ( size_t miterLimit_ )
cristy3ed852e2009-09-05 21:47:34 +0000569{
570 _drawInfo->miterlimit = miterLimit_;
571}
cristyeaedf062010-05-29 22:36:02 +0000572size_t Magick::Options::strokeMiterLimit ( void ) const
cristy3ed852e2009-09-05 21:47:34 +0000573{
574 return _drawInfo->miterlimit;
575}
576
577// Pattern image to use for stroked outlines
578void Magick::Options::strokePattern ( const MagickCore::Image *strokePattern_ )
579{
580 if ( _drawInfo->stroke_pattern )
581 {
582 DestroyImageList( _drawInfo->stroke_pattern );
583 _drawInfo->stroke_pattern = 0;
584 }
585
586 if ( strokePattern_ )
587 {
588 ExceptionInfo exceptionInfo;
589 GetExceptionInfo( &exceptionInfo );
590 _drawInfo->stroke_pattern =
591 CloneImage( const_cast<MagickCore::Image*>(strokePattern_),
592 0,
593 0,
594 MagickTrue,
595 &exceptionInfo );
596 throwException( exceptionInfo );
597 (void) DestroyExceptionInfo( &exceptionInfo );
598 }
599}
600const MagickCore::Image* Magick::Options::strokePattern ( void ) const
601{
602 return _drawInfo->stroke_pattern;
603}
604
605// Stroke width for drawing lines, circles, ellipses, etc.
606void Magick::Options::strokeWidth ( double strokeWidth_ )
607{
608 _drawInfo->stroke_width = strokeWidth_;
609}
610double Magick::Options::strokeWidth ( void ) const
611{
612 return _drawInfo->stroke_width;
613}
614
cristyeaedf062010-05-29 22:36:02 +0000615void Magick::Options::subImage ( size_t subImage_ )
cristy3ed852e2009-09-05 21:47:34 +0000616{
617 _imageInfo->scene = subImage_;
618}
cristyeaedf062010-05-29 22:36:02 +0000619size_t Magick::Options::subImage ( void ) const
cristy3ed852e2009-09-05 21:47:34 +0000620{
621 return _imageInfo->scene;
622}
623
cristyeaedf062010-05-29 22:36:02 +0000624void Magick::Options::subRange ( size_t subRange_ )
cristy3ed852e2009-09-05 21:47:34 +0000625{
626 _imageInfo->number_scenes = subRange_;
627}
cristyeaedf062010-05-29 22:36:02 +0000628size_t Magick::Options::subRange ( void ) const
cristy3ed852e2009-09-05 21:47:34 +0000629{
630 return _imageInfo->number_scenes;
631}
632
633// Annotation text encoding (e.g. "UTF-16")
634void Magick::Options::textEncoding ( const std::string &encoding_ )
635{
636 CloneString(&_drawInfo->encoding, encoding_.c_str());
637}
638std::string Magick::Options::textEncoding ( void ) const
639{
640 if ( _drawInfo->encoding && *_drawInfo->encoding )
641 return std::string( _drawInfo->encoding );
642
643 return std::string();
644}
645
cristy3ed852e2009-09-05 21:47:34 +0000646// Image representation type
647void Magick::Options::type ( const Magick::ImageType type_ )
648{
649 _imageInfo->type = type_;
650}
651Magick::ImageType Magick::Options::type ( void ) const
652{
653 return _imageInfo->type;
654}
655
656// Origin of coordinate system to use when annotating with text or drawing
657void Magick::Options::transformOrigin ( double tx_, double ty_ )
658{
659 AffineMatrix current = _drawInfo->affine;
660 AffineMatrix affine;
661 affine.sx=1.0;
662 affine.rx=0.0;
663 affine.ry=0.0;
664 affine.sy=1.0;
665 affine.tx=0.0;
666 affine.ty=0.0;
667
668 affine.tx = tx_;
669 affine.ty = ty_;
670
671 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
672 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
673 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
674 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
675 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
676 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
677}
678
679// Reset transformation parameters to default
680void Magick::Options::transformReset ( void )
681{
682 _drawInfo->affine.sx=1.0;
683 _drawInfo->affine.rx=0.0;
684 _drawInfo->affine.ry=0.0;
685 _drawInfo->affine.sy=1.0;
686 _drawInfo->affine.tx=0.0;
687 _drawInfo->affine.ty=0.0;
688}
689
690// Rotation to use when annotating with text or drawing
691void Magick::Options::transformRotation ( double angle_ )
692{
693 AffineMatrix current = _drawInfo->affine;
694 AffineMatrix affine;
695 affine.sx=1.0;
696 affine.rx=0.0;
697 affine.ry=0.0;
698 affine.sy=1.0;
699 affine.tx=0.0;
700 affine.ty=0.0;
701
702 affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
703 affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
704 affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
705 affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
706
707 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
708 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
709 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
710 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
711 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
712 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
713}
714
715// Scale to use when annotating with text or drawing
716void Magick::Options::transformScale ( double sx_, double sy_ )
717{
718 AffineMatrix current = _drawInfo->affine;
719 AffineMatrix affine;
720 affine.sx=1.0;
721 affine.rx=0.0;
722 affine.ry=0.0;
723 affine.sy=1.0;
724 affine.tx=0.0;
725 affine.ty=0.0;
726
727 affine.sx = sx_;
728 affine.sy = sy_;
729
730 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
731 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
732 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
733 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
734 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
735 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
736}
737
738// Skew to use in X axis when annotating with text or drawing
739void Magick::Options::transformSkewX ( double skewx_ )
740{
741 AffineMatrix current = _drawInfo->affine;
742 AffineMatrix affine;
743 affine.sx=1.0;
744 affine.rx=0.0;
745 affine.ry=0.0;
746 affine.sy=1.0;
747 affine.tx=0.0;
748 affine.ty=0.0;
749
750 affine.sx=1.0;
751 affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
752 affine.sy=1.0;
753
754 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
755 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
756 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
757 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
758 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
759 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
760}
761
762// Skew to use in Y axis when annotating with text or drawing
763void Magick::Options::transformSkewY ( double skewy_ )
764{
765 AffineMatrix current = _drawInfo->affine;
766 AffineMatrix affine;
767 affine.sx=1.0;
768 affine.rx=0.0;
769 affine.ry=0.0;
770 affine.sy=1.0;
771 affine.tx=0.0;
772 affine.ty=0.0;
773
774 affine.sx=1.0;
775 affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
776 affine.sy=1.0;
777
778 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
779 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
780 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
781 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
782 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
783 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
784}
785
786void Magick::Options::verbose ( bool verboseFlag_ )
787{
788 _imageInfo->verbose = (MagickBooleanType) verboseFlag_;
789}
790bool Magick::Options::verbose ( void ) const
791{
792 return static_cast<bool>(_imageInfo->verbose);
793}
794
795void Magick::Options::virtualPixelMethod ( VirtualPixelMethod virtual_pixel_method_ )
796{
797 _imageInfo->virtual_pixel_method = virtual_pixel_method_;
798}
799Magick::VirtualPixelMethod Magick::Options::virtualPixelMethod ( void ) const
800{
801 return static_cast<Magick::VirtualPixelMethod>(_imageInfo->virtual_pixel_method);
802}
803
804void Magick::Options::view ( const std::string &view_ )
805{
806 if ( view_.length() == 0 )
807 _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
808 else
809 Magick::CloneString( &_imageInfo->view, view_ );
810}
811std::string Magick::Options::view ( void ) const
812{
813 if ( _imageInfo->view )
814 return std::string( _imageInfo->view );
815
816 return std::string();
817}
818
819void Magick::Options::x11Display ( const std::string &display_ )
820{
821 if ( display_.length() == 0 )
822 _imageInfo->server_name=(char *) RelinquishMagickMemory(_imageInfo->server_name);
823 else
824 Magick::CloneString( &_imageInfo->server_name, display_ );
825}
826std::string Magick::Options::x11Display ( void ) const
827{
828 if ( _imageInfo->server_name )
829 return std::string( _imageInfo->server_name );
830
831 return std::string();
832}
833
834//
835// Internal implementation methods. Please do not use.
836//
837
838MagickCore::DrawInfo * Magick::Options::drawInfo( void )
839{
840 return _drawInfo;
841}
842
843MagickCore::ImageInfo * Magick::Options::imageInfo( void )
844{
845 return _imageInfo;
846}
847
848MagickCore::QuantizeInfo * Magick::Options::quantizeInfo( void )
849{
850 return _quantizeInfo;
851}