Geometry.cpp revision 4e0eef0224b2612b06c74d42d7f7c20f66f7f8b3
1// This may look like C code, but it is really -*- C++ -*- 2// 3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003 4// 5// Geometry implementation 6// 7 8#define MAGICKCORE_IMPLEMENTATION 1 9#define MAGICK_PLUSPLUS_IMPLEMENTATION 1 10 11#include "Magick++/Include.h" 12#include <string> 13#include <ctype.h> // for isdigit 14#if !defined(MAGICKCORE_WINDOWS_SUPPORT) 15#include <strings.h> 16#endif 17 18using namespace std; 19 20#include "Magick++/Geometry.h" 21#include "Magick++/Exception.h" 22 23#define AbsoluteValue(x) ((x) < 0 ? -(x) : (x)) 24 25int Magick::operator == ( const Magick::Geometry& left_, 26 const Magick::Geometry& right_ ) 27{ 28 return ( 29 ( left_.isValid() == right_.isValid() ) && 30 ( left_.width() == right_.width() ) && 31 ( left_.height() == right_.height() ) && 32 ( left_.xOff() == right_.xOff() ) && 33 ( left_.yOff() == right_.yOff() ) && 34 ( left_.xNegative() == right_.xNegative() ) && 35 ( left_.yNegative() == right_.yNegative() ) && 36 ( left_.percent() == right_.percent() ) && 37 ( left_.aspect() == right_.aspect() ) && 38 ( left_.greater() == right_.greater() ) && 39 ( left_.less() == right_.less() ) 40 ); 41} 42int Magick::operator != ( const Magick::Geometry& left_, 43 const Magick::Geometry& right_ ) 44{ 45 return ( ! (left_ == right_) ); 46} 47int Magick::operator > ( const Magick::Geometry& left_, 48 const Magick::Geometry& right_ ) 49{ 50 return ( !( left_ < right_ ) && ( left_ != right_ ) ); 51} 52int Magick::operator < ( const Magick::Geometry& left_, 53 const Magick::Geometry& right_ ) 54{ 55 return ( 56 ( left_.width() * left_.height() ) 57 < 58 ( right_.width() * right_.height() ) 59 ); 60} 61int Magick::operator >= ( const Magick::Geometry& left_, 62 const Magick::Geometry& right_ ) 63{ 64 return ( ( left_ > right_ ) || ( left_ == right_ ) ); 65} 66int Magick::operator <= ( const Magick::Geometry& left_, 67 const Magick::Geometry& right_ ) 68{ 69 return ( ( left_ < right_ ) || ( left_ == right_ ) ); 70} 71 72// Construct using parameterized arguments 73Magick::Geometry::Geometry ( size_t width_, 74 size_t height_, 75 ssize_t xOff_, 76 ssize_t yOff_, 77 bool xNegative_, 78 bool yNegative_ ) 79 : _width( width_ ), 80 _height( height_ ), 81 _xOff( xOff_ ), 82 _yOff( yOff_ ), 83 _xNegative( xNegative_ ), 84 _yNegative( yNegative_ ), 85 _isValid( true ), 86 _percent( false ), 87 _aspect( false ), 88 _greater( false ), 89 _less( false ) 90{ 91} 92 93// Assignment from C++ string 94Magick::Geometry::Geometry ( const std::string &geometry_ ) 95 : _width( 0 ), 96 _height( 0 ), 97 _xOff( 0 ), 98 _yOff( 0 ), 99 _xNegative( false ), 100 _yNegative( false ), 101 _isValid( false ), 102 _percent( false ), 103 _aspect( false ), 104 _greater( false ), 105 _less( false ) 106{ 107 *this = geometry_; // Use assignment operator 108} 109 110 111// Assignment from C character string 112Magick::Geometry::Geometry ( const char *geometry_ ) 113 : _width( 0 ), 114 _height( 0 ), 115 _xOff( 0 ), 116 _yOff( 0 ), 117 _xNegative( false ), 118 _yNegative( false ), 119 _isValid( false ), 120 _percent( false ), 121 _aspect( false ), 122 _greater( false ), 123 _less( false ) 124{ 125 *this = geometry_; // Use assignment operator 126} 127 128// Copy constructor 129Magick::Geometry::Geometry ( const Geometry &geometry_ ) 130 : _width( geometry_._width ), 131 _height( geometry_._height ), 132 _xOff( geometry_._xOff ), 133 _yOff( geometry_._yOff ), 134 _xNegative( geometry_._xNegative ), 135 _yNegative( geometry_._yNegative ), 136 _isValid ( geometry_._isValid ), 137 _percent( geometry_._percent ), 138 _aspect( geometry_._aspect ), 139 _greater( geometry_._greater ), 140 _less( geometry_._less ) 141{ 142} 143 144// Default constructor 145Magick::Geometry::Geometry ( void ) 146 : _width( 0 ), 147 _height( 0 ), 148 _xOff( 0 ), 149 _yOff( 0 ), 150 _xNegative( false ), 151 _yNegative( false ), 152 _isValid ( false ), 153 _percent( false ), 154 _aspect( false ), 155 _greater( false ), 156 _less( false ) 157{ 158} 159 160/* virtual */ Magick::Geometry::~Geometry ( void ) 161{ 162 // Nothing to do 163} 164 165Magick::Geometry& Magick::Geometry::operator = ( const Geometry& geometry_ ) 166{ 167 // If not being set to ourself 168 if ( this != &geometry_ ) 169 { 170 _width = geometry_._width; 171 _height = geometry_._height; 172 _xOff = geometry_._xOff; 173 _yOff = geometry_._yOff; 174 _xNegative = geometry_._xNegative; 175 _yNegative = geometry_._yNegative; 176 _isValid = geometry_._isValid; 177 _percent = geometry_._percent; 178 _aspect = geometry_._aspect; 179 _greater = geometry_._greater; 180 _less = geometry_._less; 181 } 182 return *this; 183} 184 185// Set value via geometry string 186/* virtual */ const Magick::Geometry& 187Magick::Geometry::operator = ( const std::string &geometry_ ) 188{ 189 char 190 geom[MaxTextExtent]; 191 192 // If argument does not start with digit, presume that it is a 193 // page-size specification that needs to be converted to an 194 // equivalent geometry specification using PostscriptGeometry() 195 (void) CopyMagickString(geom,geometry_.c_str(),MaxTextExtent); 196 if ( geom[0] != '-' && 197 geom[0] != '+' && 198 geom[0] != 'x' && 199 !isdigit(static_cast<int>(geom[0]))) 200 { 201 char *pageptr = GetPageGeometry( geom ); 202 if ( pageptr != 0 ) 203 { 204 (void) CopyMagickString(geom,pageptr,MaxTextExtent); 205 pageptr=(char *) RelinquishMagickMemory( pageptr ); 206 } 207 } 208 209 ssize_t x = 0; 210 ssize_t y = 0; 211 size_t width_val = 0; 212 size_t height_val = 0; 213 ssize_t flags = GetGeometry (geom, &x, &y, &width_val, &height_val ); 214 215 if (flags == NoValue) 216 { 217 // Total failure! 218 *this=Geometry(); 219 isValid( false ); 220 return *this; 221 } 222 223 if ( ( flags & WidthValue ) != 0 ) 224 { 225 _width = width_val; 226 isValid( true ); 227 } 228 229 if ( ( flags & HeightValue ) != 0 ) 230 { 231 _height = height_val; 232 isValid( true ); 233 } 234 235 if ( ( flags & XValue ) != 0 ) 236 { 237 _xOff = static_cast<ssize_t>(x); 238 isValid( true ); 239 } 240 241 if ( ( flags & YValue ) != 0 ) 242 { 243 _yOff = static_cast<ssize_t>(y); 244 isValid( true ); 245 } 246 247 if ( ( flags & XNegative ) != 0 ) 248 _xNegative = true; 249 250 if ( ( flags & YNegative ) != 0 ) 251 _yNegative = true; 252 253 if ( ( flags & PercentValue ) != 0 ) 254 _percent = true; 255 256 if ( ( flags & AspectValue ) != 0 ) 257 _aspect = true; 258 259 if ( ( flags & LessValue ) != 0 ) 260 _less = true; 261 262 if ( ( flags & GreaterValue ) != 0 ) 263 _greater = true; 264 265 return *this; 266} 267 268 269// Set value via geometry C string 270/* virtual */ const Magick::Geometry& Magick::Geometry::operator = ( const char * geometry_ ) 271{ 272 *this = std::string(geometry_); 273 return *this; 274} 275 276// Return geometry string 277Magick::Geometry::operator std::string() const 278{ 279 if (!isValid()) 280 { 281 throwExceptionExplicit( OptionError, "Invalid geometry argument" ); 282 } 283 284 string geometry; 285 char buffer[32]; 286 287 if ( _width ) 288 { 289 FormatMagickString( buffer, MaxTextExtent, "%u", _width ); 290 geometry += buffer; 291 } 292 293 if ( _height ) 294 { 295 FormatMagickString( buffer, MaxTextExtent, "%u", _height); 296 geometry += 'x'; 297 geometry += buffer; 298 } 299 300 if ( _xOff || _yOff ) 301 { 302 if ( _xNegative ) 303 geometry += '-'; 304 else 305 geometry += '+'; 306 307 FormatMagickString( buffer, MaxTextExtent, "%u", _xOff); 308 geometry += buffer; 309 310 if ( _yNegative ) 311 geometry += '-'; 312 else 313 geometry += '+'; 314 315 FormatMagickString( buffer, MaxTextExtent, "%u", _yOff); 316 geometry += buffer; 317 } 318 319 if ( _percent ) 320 geometry += '%'; 321 322 if ( _aspect ) 323 geometry += '!'; 324 325 if ( _greater ) 326 geometry += '>'; 327 328 if ( _less ) 329 geometry += '<'; 330 331 return geometry; 332} 333 334// Construct from RectangleInfo 335Magick::Geometry::Geometry ( const MagickCore::RectangleInfo &rectangle_ ) 336 : _width(static_cast<size_t>(rectangle_.width)), 337 _height(static_cast<size_t>(rectangle_.height)), 338 _xOff(static_cast<ssize_t>(rectangle_.x)), 339 _yOff(static_cast<ssize_t>(rectangle_.y)), 340 _xNegative(rectangle_.x < 0 ? true : false), 341 _yNegative(rectangle_.y < 0 ? true : false), 342 _isValid(true), 343 _percent(false), 344 _aspect(false), 345 _greater(false), 346 _less(false) 347{ 348} 349 350// Return an ImageMagick RectangleInfo struct 351Magick::Geometry::operator MagickCore::RectangleInfo() const 352{ 353 RectangleInfo rectangle; 354 rectangle.width = _width; 355 rectangle.height = _height; 356 _xNegative ? rectangle.x = static_cast<ssize_t>(0-_xOff) : rectangle.x = static_cast<ssize_t>(_xOff); 357 _yNegative ? rectangle.y = static_cast<ssize_t>(0-_yOff) : rectangle.y = static_cast<ssize_t>(_yOff); 358 return rectangle; 359} 360