1 // This may look like C code, but it is really -*- C++ -*-
3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
5 // Implementation of Options
7 // A wrapper around DrawInfo, ImageInfo, and QuantizeInfo
10 #define MAGICKCORE_IMPLEMENTATION 1
11 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1
13 #include "Magick++/Include.h"
19 #include "Magick++/Options.h"
20 #include "Magick++/Functions.h"
21 #include "Magick++/Exception.h"
23 #define DegreesToRadians(x) (MagickPI*(x)/180.0)
26 Magick::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))))
31 // Initialize image info with defaults
32 GetImageInfo( _imageInfo );
34 // Initialize quantization info
35 GetQuantizeInfo( _quantizeInfo );
37 // Initialize drawing info
38 GetDrawInfo( _imageInfo, _drawInfo );
42 Magick::Options::Options( const Magick::Options& options_ )
43 : _imageInfo(CloneImageInfo( options_._imageInfo )),
44 _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
45 _drawInfo(CloneDrawInfo(_imageInfo, options_._drawInfo))
49 // Construct using raw structures
50 Magick::Options::Options( const MagickCore::ImageInfo* imageInfo_,
51 const MagickCore::QuantizeInfo* quantizeInfo_,
52 const MagickCore::DrawInfo* drawInfo_ )
57 _imageInfo = CloneImageInfo(imageInfo_);
58 _quantizeInfo = CloneQuantizeInfo(quantizeInfo_);
59 _drawInfo = CloneDrawInfo(imageInfo_,drawInfo_);
63 Magick::Options::~Options()
66 _imageInfo =DestroyImageInfo( _imageInfo );
69 // Destroy quantization info
70 _quantizeInfo =DestroyQuantizeInfo( _quantizeInfo );
73 // Destroy drawing info
74 _drawInfo =DestroyDrawInfo( _drawInfo );
79 * Methods for setting image attributes
83 // Anti-alias Postscript and TrueType fonts (default true)
84 void Magick::Options::antiAlias( bool flag_ )
86 _drawInfo->text_antialias = static_cast<MagickBooleanType>
87 (flag_ ? MagickTrue : MagickFalse);
89 bool Magick::Options::antiAlias( void ) const
91 return static_cast<bool>(_drawInfo->text_antialias);
94 void Magick::Options::adjoin ( bool flag_ )
96 _imageInfo->adjoin = static_cast<MagickBooleanType>
97 (flag_ ? MagickTrue : MagickFalse);
99 bool Magick::Options::adjoin ( void ) const
101 return static_cast<bool>(_imageInfo->adjoin);
104 void Magick::Options::backgroundColor ( const Magick::Color &color_ )
106 _imageInfo->background_color = color_;
108 Magick::Color Magick::Options::backgroundColor ( void ) const
110 return Magick::Color( _imageInfo->background_color );
113 void Magick::Options::backgroundTexture ( const std::string &backgroundTexture_ )
115 if ( backgroundTexture_.length() == 0 )
116 _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture);
118 Magick::CloneString( &_imageInfo->texture, backgroundTexture_ );
120 std::string Magick::Options::backgroundTexture ( void ) const
122 if ( _imageInfo->texture )
123 return std::string( _imageInfo->texture );
125 return std::string();
128 void Magick::Options::borderColor ( const Color &color_ )
130 _imageInfo->border_color = color_;
131 _drawInfo->border_color = color_;
133 Magick::Color Magick::Options::borderColor ( void ) const
135 return Magick::Color( _imageInfo->border_color );
138 // Text bounding-box base color
139 void Magick::Options::boxColor ( const Magick::Color &boxColor_ )
141 _drawInfo->undercolor = boxColor_;
143 Magick::Color Magick::Options::boxColor ( void ) const
145 return Magick::Color( _drawInfo->undercolor );
148 void Magick::Options::colorspaceType ( Magick::ColorspaceType colorspace_ )
150 _imageInfo->colorspace = colorspace_;
152 Magick::ColorspaceType Magick::Options::colorspaceType ( void ) const
154 return static_cast<Magick::ColorspaceType>(_imageInfo->colorspace);
157 void Magick::Options::compressType ( CompressionType compressType_ )
159 _imageInfo->compression = compressType_;
161 Magick::CompressionType Magick::Options::compressType ( void ) const
163 return static_cast<Magick::CompressionType>(_imageInfo->compression);
166 void Magick::Options::colorFuzz ( double fuzz_ )
168 _imageInfo->fuzz = fuzz_;
170 double Magick::Options::colorFuzz ( void ) const
172 return _imageInfo->fuzz;
175 // Enable printing of debug messages from ImageMagick
176 void Magick::Options::debug ( bool flag_ )
180 SetLogEventMask("All");
184 SetLogEventMask("None");
187 bool Magick::Options::debug ( void ) const
189 if( IsEventLogging() )
196 void Magick::Options::density ( const Magick::Geometry &density_ )
198 if ( !density_.isValid() )
199 _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density);
201 Magick::CloneString( &_imageInfo->density, density_ );
203 Magick::Geometry Magick::Options::density ( void ) const
205 if ( _imageInfo->density )
206 return Geometry( _imageInfo->density );
211 void Magick::Options::depth ( size_t depth_ )
213 _imageInfo->depth = depth_;
215 size_t Magick::Options::depth ( void ) const
217 return _imageInfo->depth;
220 // Endianness (little like Intel or big like SPARC) for image
221 // formats which support endian-specific options.
222 void Magick::Options::endian ( Magick::EndianType endian_ )
224 _imageInfo->endian = endian_;
226 Magick::EndianType Magick::Options::endian ( void ) const
228 return _imageInfo->endian;
231 void Magick::Options::file ( FILE *file_ )
233 SetImageInfoFile( _imageInfo, file_ );
235 FILE *Magick::Options::file ( void ) const
237 return GetImageInfoFile( _imageInfo );
240 void Magick::Options::fileName ( const std::string &fileName_ )
242 fileName_.copy( _imageInfo->filename, MaxTextExtent-1 );
243 _imageInfo->filename[ fileName_.length() ] = 0;
245 std::string Magick::Options::fileName ( void ) const
247 return std::string( _imageInfo->filename );
250 // Color to use when drawing inside an object
251 void Magick::Options::fillColor ( const Magick::Color &fillColor_ )
253 _drawInfo->fill = fillColor_;
254 if (fillColor_ == Magick::Color())
255 fillPattern((const MagickCore::Image*) NULL);
257 Magick::Color Magick::Options::fillColor ( void ) const
259 return _drawInfo->fill;
261 // Pattern image to use when filling objects
262 void Magick::Options::fillPattern ( const MagickCore::Image *fillPattern_ )
264 if ( _drawInfo->fill_pattern )
266 DestroyImageList( _drawInfo->fill_pattern );
267 _drawInfo->fill_pattern = 0;
271 ExceptionInfo exceptionInfo;
272 GetExceptionInfo( &exceptionInfo );
273 _drawInfo->fill_pattern =
274 CloneImage( const_cast<MagickCore::Image*>(fillPattern_),
277 static_cast<MagickBooleanType>(MagickTrue),
279 throwException( exceptionInfo );
280 (void) DestroyExceptionInfo( &exceptionInfo );
283 const MagickCore::Image* Magick::Options::fillPattern ( void ) const
285 return _drawInfo->fill_pattern;
288 // Rule to use when filling drawn objects
289 void Magick::Options::fillRule ( const Magick::FillRule &fillRule_ )
291 _drawInfo->fill_rule = fillRule_;
293 Magick::FillRule Magick::Options::fillRule ( void ) const
295 return _drawInfo->fill_rule;
298 void Magick::Options::font ( const std::string &font_ )
300 if ( font_.length() == 0 )
302 _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font);
303 _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font);
307 Magick::CloneString( &_imageInfo->font, font_ );
308 Magick::CloneString( &_drawInfo->font, font_ );
311 std::string Magick::Options::font ( void ) const
313 if ( _imageInfo->font )
314 return std::string( _imageInfo->font );
316 return std::string();
319 void Magick::Options::fontPointsize ( double pointSize_ )
321 _imageInfo->pointsize = pointSize_;
322 _drawInfo->pointsize = pointSize_;
324 double Magick::Options::fontPointsize ( void ) const
326 return _imageInfo->pointsize;
329 std::string Magick::Options::format ( void ) const
331 ExceptionInfo exception;
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 );
340 if (( magick_info != 0 ) &&
341 ( *magick_info->description != '\0' ))
342 return std::string( magick_info->description );
344 return std::string();
347 void Magick::Options::interlaceType ( Magick::InterlaceType interlace_ )
349 _imageInfo->interlace = interlace_;
351 Magick::InterlaceType Magick::Options::interlaceType ( void ) const
353 return static_cast<Magick::InterlaceType>(_imageInfo->interlace);
356 void Magick::Options::magick ( const std::string &magick_ )
358 ExceptionInfo exception;
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",
366 (void) DestroyExceptionInfo( &exception );
368 std::string Magick::Options::magick ( void ) const
370 if ( _imageInfo->magick && *_imageInfo->magick )
371 return std::string( _imageInfo->magick );
373 return std::string();
376 void Magick::Options::matteColor ( const Magick::Color &matteColor_ )
378 _imageInfo->matte_color = matteColor_;
380 Magick::Color Magick::Options::matteColor ( void ) const
382 return Magick::Color( _imageInfo->matte_color );
385 void Magick::Options::monochrome ( bool monochromeFlag_ )
387 _imageInfo->monochrome = (MagickBooleanType) monochromeFlag_;
389 bool Magick::Options::monochrome ( void ) const
391 return static_cast<bool>(_imageInfo->monochrome);
394 void Magick::Options::page ( const Magick::Geometry &pageSize_ )
396 if ( !pageSize_.isValid() )
397 _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page);
399 Magick::CloneString( &_imageInfo->page, pageSize_ );
401 Magick::Geometry Magick::Options::page ( void ) const
403 if ( _imageInfo->page )
404 return Geometry( _imageInfo->page );
409 void Magick::Options::quality ( size_t quality_ )
411 _imageInfo->quality = quality_;
413 size_t Magick::Options::quality ( void ) const
415 return _imageInfo->quality;
418 void Magick::Options::quantizeColors ( size_t colors_ )
420 _quantizeInfo->number_colors = colors_;
422 size_t Magick::Options::quantizeColors ( void ) const
424 return _quantizeInfo->number_colors;
427 void Magick::Options::quantizeColorSpace ( Magick::ColorspaceType colorSpace_ )
429 _quantizeInfo->colorspace = colorSpace_;
431 Magick::ColorspaceType Magick::Options::quantizeColorSpace ( void ) const
433 return static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace);
436 void Magick::Options::quantizeDither ( bool ditherFlag_ )
438 _imageInfo->dither = (MagickBooleanType) ditherFlag_;
439 _quantizeInfo->dither_method = ditherFlag_ ? RiemersmaDitherMethod :
442 bool Magick::Options::quantizeDither ( void ) const
444 return static_cast<bool>(_imageInfo->dither);
447 void Magick::Options::quantizeTreeDepth ( size_t treeDepth_ )
449 _quantizeInfo->tree_depth = treeDepth_;
451 size_t Magick::Options::quantizeTreeDepth ( void ) const
453 return _quantizeInfo->tree_depth;
456 void Magick::Options::resolutionUnits ( Magick::ResolutionType resolutionUnits_ )
458 _imageInfo->units = resolutionUnits_;
460 Magick::ResolutionType Magick::Options::resolutionUnits ( void ) const
462 return static_cast<Magick::ResolutionType>(_imageInfo->units);
465 void Magick::Options::samplingFactor ( const std::string &samplingFactor_ )
467 if ( samplingFactor_.length() == 0 )
468 _imageInfo->sampling_factor=(char *) RelinquishMagickMemory(_imageInfo->sampling_factor);
470 Magick::CloneString( &_imageInfo->sampling_factor, samplingFactor_ );
472 std::string Magick::Options::samplingFactor ( void ) const
474 if ( _imageInfo->sampling_factor )
475 return std::string( _imageInfo->sampling_factor );
477 return std::string();
480 void Magick::Options::size ( const Geometry &geometry_ )
482 _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size);
484 if ( geometry_.isValid() )
485 Magick::CloneString( &_imageInfo->size, geometry_ );
487 Magick::Geometry Magick::Options::size ( void ) const
489 if ( _imageInfo->size )
490 return Geometry( _imageInfo->size );
495 void Magick::Options::strokeAntiAlias( bool flag_ )
497 flag_ ? _drawInfo->stroke_antialias=MagickTrue : _drawInfo->stroke_antialias=MagickFalse;
499 bool Magick::Options::strokeAntiAlias( void ) const
501 return (_drawInfo->stroke_antialias != 0 ? true : false);
504 // Color to use when drawing object outlines
505 void Magick::Options::strokeColor ( const Magick::Color &strokeColor_ )
507 _drawInfo->stroke = strokeColor_;
509 Magick::Color Magick::Options::strokeColor ( void ) const
511 return _drawInfo->stroke;
514 void Magick::Options::strokeDashArray ( const double* strokeDashArray_ )
516 _drawInfo->dash_pattern=(double *)
517 RelinquishMagickMemory(_drawInfo->dash_pattern);
521 // Count elements in dash array
523 for (x=0; strokeDashArray_[x]; x++) ;
525 _drawInfo->dash_pattern =
526 static_cast<double*>(AcquireMagickMemory((x+1)*sizeof(double)));
528 memcpy(_drawInfo->dash_pattern,strokeDashArray_,
529 (x+1)*sizeof(double));
532 const double* Magick::Options::strokeDashArray ( void ) const
534 return _drawInfo->dash_pattern;
537 void Magick::Options::strokeDashOffset ( double strokeDashOffset_ )
539 _drawInfo->dash_offset = strokeDashOffset_;
541 double Magick::Options::strokeDashOffset ( void ) const
543 return _drawInfo->dash_offset;
546 // Specify the shape to be used at the end of open subpaths when they
547 // are stroked. Values of LineCap are ButtCap, RoundCap, and
549 void Magick::Options::strokeLineCap ( Magick::LineCap lineCap_ )
551 _drawInfo->linecap = lineCap_;
553 Magick::LineCap Magick::Options::strokeLineCap ( void ) const
555 return _drawInfo->linecap;
558 // Specify the shape to be used at the corners of paths (or other
559 // vector shapes) when they are stroked.
560 void Magick::Options::strokeLineJoin ( Magick::LineJoin lineJoin_ )
562 _drawInfo->linejoin = lineJoin_;
564 Magick::LineJoin Magick::Options::strokeLineJoin ( void ) const
566 return _drawInfo->linejoin;
569 // miterLimit for drawing lines, circles, ellipses, etc.
570 void Magick::Options::strokeMiterLimit ( size_t miterLimit_ )
572 _drawInfo->miterlimit = miterLimit_;
574 size_t Magick::Options::strokeMiterLimit ( void ) const
576 return _drawInfo->miterlimit;
579 // Pattern image to use for stroked outlines
580 void Magick::Options::strokePattern ( const MagickCore::Image *strokePattern_ )
582 if ( _drawInfo->stroke_pattern )
584 DestroyImageList( _drawInfo->stroke_pattern );
585 _drawInfo->stroke_pattern = 0;
588 if ( strokePattern_ )
590 ExceptionInfo exceptionInfo;
591 GetExceptionInfo( &exceptionInfo );
592 _drawInfo->stroke_pattern =
593 CloneImage( const_cast<MagickCore::Image*>(strokePattern_),
598 throwException( exceptionInfo );
599 (void) DestroyExceptionInfo( &exceptionInfo );
602 const MagickCore::Image* Magick::Options::strokePattern ( void ) const
604 return _drawInfo->stroke_pattern;
607 // Stroke width for drawing lines, circles, ellipses, etc.
608 void Magick::Options::strokeWidth ( double strokeWidth_ )
610 _drawInfo->stroke_width = strokeWidth_;
612 double Magick::Options::strokeWidth ( void ) const
614 return _drawInfo->stroke_width;
617 void Magick::Options::subImage ( size_t subImage_ )
619 _imageInfo->scene = subImage_;
621 size_t Magick::Options::subImage ( void ) const
623 return _imageInfo->scene;
626 void Magick::Options::subRange ( size_t subRange_ )
628 _imageInfo->number_scenes = subRange_;
630 size_t Magick::Options::subRange ( void ) const
632 return _imageInfo->number_scenes;
635 // Annotation text encoding (e.g. "UTF-16")
636 void Magick::Options::textEncoding ( const std::string &encoding_ )
638 CloneString(&_drawInfo->encoding, encoding_.c_str());
640 std::string Magick::Options::textEncoding ( void ) const
642 if ( _drawInfo->encoding && *_drawInfo->encoding )
643 return std::string( _drawInfo->encoding );
645 return std::string();
648 // Image representation type
649 void Magick::Options::type ( const Magick::ImageType type_ )
651 _imageInfo->type = type_;
653 Magick::ImageType Magick::Options::type ( void ) const
655 return _imageInfo->type;
658 // Origin of coordinate system to use when annotating with text or drawing
659 void Magick::Options::transformOrigin ( double tx_, double ty_ )
661 AffineMatrix current = _drawInfo->affine;
673 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
674 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
675 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
676 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
677 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
678 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
681 // Reset transformation parameters to default
682 void Magick::Options::transformReset ( void )
684 _drawInfo->affine.sx=1.0;
685 _drawInfo->affine.rx=0.0;
686 _drawInfo->affine.ry=0.0;
687 _drawInfo->affine.sy=1.0;
688 _drawInfo->affine.tx=0.0;
689 _drawInfo->affine.ty=0.0;
692 // Rotation to use when annotating with text or drawing
693 void Magick::Options::transformRotation ( double angle_ )
695 AffineMatrix current = _drawInfo->affine;
704 affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
705 affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
706 affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
707 affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
709 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
710 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
711 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
712 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
713 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
714 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
717 // Scale to use when annotating with text or drawing
718 void Magick::Options::transformScale ( double sx_, double sy_ )
720 AffineMatrix current = _drawInfo->affine;
732 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
733 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
734 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
735 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
736 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
737 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
740 // Skew to use in X axis when annotating with text or drawing
741 void Magick::Options::transformSkewX ( double skewx_ )
743 AffineMatrix current = _drawInfo->affine;
753 affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
756 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
757 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
758 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
759 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
760 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
761 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
764 // Skew to use in Y axis when annotating with text or drawing
765 void Magick::Options::transformSkewY ( double skewy_ )
767 AffineMatrix current = _drawInfo->affine;
777 affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
780 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
781 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
782 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
783 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
784 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
785 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
788 void Magick::Options::verbose ( bool verboseFlag_ )
790 _imageInfo->verbose = (MagickBooleanType) verboseFlag_;
792 bool Magick::Options::verbose ( void ) const
794 return static_cast<bool>(_imageInfo->verbose);
797 void Magick::Options::view ( const std::string &view_ )
799 if ( view_.length() == 0 )
800 _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
802 Magick::CloneString( &_imageInfo->view, view_ );
804 std::string Magick::Options::view ( void ) const
806 if ( _imageInfo->view )
807 return std::string( _imageInfo->view );
809 return std::string();
812 void Magick::Options::x11Display ( const std::string &display_ )
814 if ( display_.length() == 0 )
815 _imageInfo->server_name=(char *) RelinquishMagickMemory(_imageInfo->server_name);
817 Magick::CloneString( &_imageInfo->server_name, display_ );
819 std::string Magick::Options::x11Display ( void ) const
821 if ( _imageInfo->server_name )
822 return std::string( _imageInfo->server_name );
824 return std::string();
828 // Internal implementation methods. Please do not use.
831 MagickCore::DrawInfo * Magick::Options::drawInfo( void )
836 MagickCore::ImageInfo * Magick::Options::imageInfo( void )
841 MagickCore::QuantizeInfo * Magick::Options::quantizeInfo( void )
843 return _quantizeInfo;