Geometry.cpp revision 1ee51feb00157bb5e477116c48dc0d14d3078226
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 23MagickPPExport int Magick::operator == (const Magick::Geometry& left_, 24 const Magick::Geometry& right_) 25{ 26 return((left_.aspect() == right_.aspect()) && 27 (left_.fillArea() == right_.fillArea()) && 28 (left_.greater() == right_.greater()) && 29 (left_.height() == right_.height()) && 30 (left_.isValid() == right_.isValid()) && 31 (left_.less() == right_.less()) && 32 (left_.limitPixels() == right_.limitPixels()) && 33 (left_.percent() == right_.percent()) && 34 (left_.width() == right_.width()) && 35 (left_.xOff() == right_.xOff()) && 36 (left_.yOff() == right_.yOff())); 37} 38 39MagickPPExport int Magick::operator != (const Magick::Geometry& left_, 40 const Magick::Geometry& right_) 41{ 42 return(!(left_ == right_)); 43} 44 45MagickPPExport int Magick::operator > (const Magick::Geometry& left_, 46 const Magick::Geometry& right_) 47{ 48 return(!(left_ < right_) && (left_ != right_)); 49} 50 51MagickPPExport int Magick::operator < (const Magick::Geometry& left_, 52 const Magick::Geometry& right_) 53{ 54 return((left_.width()*left_.height()) < (right_.width()*right_.height())); 55} 56 57MagickPPExport int Magick::operator >= (const Magick::Geometry& left_, 58 const Magick::Geometry& right_) 59{ 60 return((left_ > right_) || (left_ == right_)); 61} 62 63MagickPPExport int Magick::operator <= (const Magick::Geometry& left_, 64 const Magick::Geometry& right_ ) 65{ 66 return((left_ < right_) || (left_ == right_)); 67} 68 69Magick::Geometry::Geometry(void) 70 : _width(0), 71 _height(0), 72 _xOff(0), 73 _yOff(0), 74 _isValid(false), 75 _percent(false), 76 _aspect(false), 77 _greater(false), 78 _less(false), 79 _fillArea(false), 80 _limitPixels(false) 81{ 82} 83 84Magick::Geometry::Geometry(const char *geometry_) 85 : _width(0), 86 _height(0), 87 _xOff(0), 88 _yOff(0), 89 _isValid(false), 90 _percent(false), 91 _aspect(false), 92 _greater(false), 93 _less(false), 94 _fillArea(false), 95 _limitPixels(false) 96{ 97 *this=geometry_; // Use assignment operator 98} 99 100Magick::Geometry::Geometry(const Geometry &geometry_) 101 : _width(geometry_._width), 102 _height(geometry_._height), 103 _xOff(geometry_._xOff), 104 _yOff(geometry_._yOff), 105 _isValid(geometry_._isValid), 106 _percent(geometry_._percent), 107 _aspect(geometry_._aspect), 108 _greater(geometry_._greater), 109 _less(geometry_._less), 110 _fillArea(geometry_._fillArea), 111 _limitPixels(geometry_._limitPixels) 112{ 113} 114 115Magick::Geometry::Geometry(const std::string &geometry_) 116 : _width(0), 117 _height(0), 118 _xOff(0), 119 _yOff(0), 120 _isValid(false), 121 _percent(false), 122 _aspect(false), 123 _greater(false), 124 _less(false), 125 _fillArea(false), 126 _limitPixels(false) 127{ 128 *this=geometry_; // Use assignment operator 129} 130 131Magick::Geometry::Geometry(size_t width_,size_t height_,ssize_t xOff_, 132 ssize_t yOff_) 133 : _width(width_), 134 _height(height_), 135 _xOff(xOff_), 136 _yOff(yOff_), 137 _isValid(true), 138 _percent(false), 139 _aspect(false), 140 _greater(false), 141 _less(false), 142 _fillArea(false), 143 _limitPixels(false) 144{ 145} 146 147Magick::Geometry::~Geometry(void) 148{ 149} 150 151const Magick::Geometry& Magick::Geometry::operator=(const char *geometry_) 152{ 153 *this=std::string(geometry_); 154 return(*this); 155} 156 157Magick::Geometry& Magick::Geometry::operator=(const Geometry &geometry_) 158{ 159 // If not being set to ourself 160 if (this != &geometry_) 161 { 162 _width=geometry_._width; 163 _height=geometry_._height; 164 _xOff=geometry_._xOff; 165 _yOff=geometry_._yOff; 166 _isValid=geometry_._isValid; 167 _percent=geometry_._percent; 168 _aspect=geometry_._aspect; 169 _greater=geometry_._greater; 170 _less=geometry_._less; 171 _fillArea=geometry_._fillArea; 172 _limitPixels=geometry_._limitPixels; 173 } 174 return(*this); 175} 176 177const Magick::Geometry& Magick::Geometry::operator=( 178 const std::string &geometry_) 179{ 180 char 181 geom[MaxTextExtent]; 182 183 char 184 *pageptr; 185 186 ssize_t 187 flags, 188 x = 0, 189 y = 0; 190 191 size_t 192 height_val=0, 193 width_val=0; 194 195 // If argument does not start with digit, presume that it is a 196 // page-size specification that needs to be converted to an 197 // equivalent geometry specification using PostscriptGeometry() 198 (void) CopyMagickString(geom,geometry_.c_str(),MaxTextExtent); 199 if (geom[0] != '-' && geom[0] != '+' && geom[0] != 'x' && 200 !isdigit(static_cast<int>(geom[0]))) 201 { 202 pageptr=GetPageGeometry(geom); 203 if (pageptr != 0) 204 { 205 (void) CopyMagickString(geom,pageptr,MaxTextExtent); 206 pageptr=(char *) RelinquishMagickMemory(pageptr); 207 } 208 } 209 210 flags=GetGeometry(geom,&x,&y,&width_val,&height_val); 211 212 if (flags == NoValue) 213 { 214 // Total failure! 215 *this=Geometry(); 216 isValid(false); 217 return(*this); 218 } 219 220 if ((flags & WidthValue) != 0) 221 { 222 _width=width_val; 223 isValid(true); 224 } 225 226 if ((flags & HeightValue) != 0) 227 { 228 _height=height_val; 229 isValid(true); 230 } 231 232 if ((flags & XValue) != 0) 233 { 234 _xOff=static_cast<ssize_t>(x); 235 isValid(true); 236 } 237 238 if ((flags & YValue) != 0) 239 { 240 _yOff=static_cast<ssize_t>(y); 241 isValid(true); 242 } 243 244 if ((flags & XNegative) != 0) 245 _xOff=-_xOff; 246 247 if ((flags & YNegative) != 0) 248 _yOff=-_yOff; 249 250 if ((flags & PercentValue) != 0) 251 _percent=true; 252 253 if ((flags & AspectValue) != 0) 254 _aspect=true; 255 256 if ((flags & LessValue) != 0) 257 _less=true; 258 259 if ((flags & GreaterValue) != 0) 260 _greater=true; 261 262 if ((flags & MinimumValue) != 0) 263 _fillArea=true; 264 265 if ((flags & AreaValue) != 0) 266 _limitPixels=true; 267 268 return(*this); 269} 270 271Magick::Geometry::operator std::string() const 272{ 273 char 274 buffer[MaxTextExtent]; 275 276 string 277 geometry; 278 279 if (!isValid()) 280 throwExceptionExplicit(OptionError,"Invalid geometry argument"); 281 282 if (_width) 283 { 284 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _width); 285 geometry+=buffer; 286 } 287 288 if (_height) 289 { 290 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _height); 291 geometry+='x'; 292 geometry+=buffer; 293 } 294 295 if (_xOff || _yOff) 296 { 297 if (_xOff < 0) 298 geometry+='-'; 299 else 300 geometry+='+'; 301 302 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _xOff); 303 geometry+=buffer; 304 305 if (_yOff < 0) 306 geometry+='-'; 307 else 308 geometry+='+'; 309 310 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _yOff); 311 geometry+=buffer; 312 } 313 314 if (_percent) 315 geometry+='%'; 316 317 if (_aspect) 318 geometry+='!'; 319 320 if (_greater) 321 geometry+='>'; 322 323 if (_less) 324 geometry+='<'; 325 326 if (_fillArea) 327 geometry+='^'; 328 329 if (_limitPixels) 330 geometry+='@'; 331 332 return(geometry); 333} 334 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 _isValid(true), 341 _percent(false), 342 _aspect(false), 343 _greater(false), 344 _less(false), 345 _fillArea(false), 346 _limitPixels(false) 347{ 348} 349 350const Magick::Geometry& Magick::Geometry::operator=( 351 const MagickCore::RectangleInfo &rectangle_) 352{ 353 _width=static_cast<size_t>(rectangle_.width), 354 _height=static_cast<size_t>(rectangle_.height), 355 _xOff=static_cast<ssize_t>(rectangle_.x), 356 _yOff=static_cast<ssize_t>(rectangle_.y), 357 _isValid=true; 358 return(*this); 359} 360 361Magick::Geometry::operator MagickCore::RectangleInfo() const 362{ 363 RectangleInfo rectangle; 364 rectangle.width=_width; 365 rectangle.height=_height; 366 rectangle.x=_xOff; 367 rectangle.y=_yOff; 368 return(rectangle); 369} 370 371void Magick::Geometry::aspect(bool aspect_) 372{ 373 _aspect=aspect_; 374} 375 376bool Magick::Geometry::aspect(void) const 377{ 378 return(_aspect); 379} 380 381void Magick::Geometry::fillArea(bool fillArea_) 382{ 383 _fillArea=fillArea_; 384} 385 386bool Magick::Geometry::fillArea(void) const 387{ 388 return(_fillArea); 389} 390 391void Magick::Geometry::greater(bool greater_) 392{ 393 _greater=greater_; 394} 395 396bool Magick::Geometry::greater(void) const 397{ 398 return(_greater); 399} 400 401void Magick::Geometry::height(size_t height_) 402{ 403 _height=height_; 404} 405 406size_t Magick::Geometry::height(void) const 407{ 408 return(_height); 409} 410 411void Magick::Geometry::isValid(bool isValid_) 412{ 413 _isValid=isValid_; 414} 415 416bool Magick::Geometry::isValid(void) const 417{ 418 return(_isValid); 419} 420 421void Magick::Geometry::less(bool less_) 422{ 423 _less=less_; 424} 425 426bool Magick::Geometry::less(void) const 427{ 428 return(_less); 429} 430 431void Magick::Geometry::limitPixels(bool limitPixels_) 432{ 433 _limitPixels=limitPixels_; 434} 435 436bool Magick::Geometry::limitPixels(void) const 437{ 438 return(_limitPixels); 439} 440 441void Magick::Geometry::width(size_t width_) 442{ 443 _width=width_; 444 isValid(true); 445} 446 447void Magick::Geometry::percent(bool percent_) 448{ 449 _percent = percent_; 450} 451 452bool Magick::Geometry::percent(void) const 453{ 454 return(_percent); 455} 456 457size_t Magick::Geometry::width(void) const 458{ 459 return(_width); 460} 461 462void Magick::Geometry::xOff(::ssize_t xOff_) 463{ 464 _xOff=xOff_; 465} 466 467::ssize_t Magick::Geometry::xOff(void) const 468{ 469 return(_xOff); 470} 471 472inline void Magick::Geometry::yOff(::ssize_t yOff_) 473{ 474 _yOff=yOff_; 475} 476 477::ssize_t Magick::Geometry::yOff(void) const 478{ 479 return(_yOff); 480} 481 482MagickPPExport int Magick::operator == (const Magick::Point& left_, 483 const Magick::Point& right_) 484{ 485 return((left_.x() == right_.x()) && 486 (left_.y() == right_.y())); 487} 488 489MagickPPExport int Magick::operator != (const Magick::Point& left_, 490 const Magick::Point& right_) 491{ 492 return(!(left_ == right_)); 493} 494 495Magick::Point::Point(void) 496 : _x(0.0), 497 _y(0.0) 498{ 499} 500 501Magick::Point::Point(const char *point_) 502 : _x(0.0), 503 _y(0.0) 504{ 505 *this=point_; // Use assignment operator 506} 507 508Magick::Point::Point(const Point &point_) 509 : _x(point_._x), 510 _y(point_._y) 511{ 512} 513 514Magick::Point::Point(const std::string &point_) 515 : _x(0.0), 516 _y(0.0) 517{ 518 *this=point_; // Use assignment operator 519} 520 521Magick::Point::Point(double x_,double y_) 522 : _x(x_), 523 _y(y_) 524{ 525} 526 527Magick::Point::Point(double xy_) 528 : _x(xy_), 529 _y(xy_) 530{ 531} 532 533Magick::Point::~Point(void) 534{ 535} 536 537const Magick::Point& Magick::Point::operator=(const char *point_) 538{ 539 MagickCore::GeometryInfo 540 geometry_info; 541 542 MagickCore::MagickStatusType 543 flags; 544 545 flags=ParseGeometry(point_,&geometry_info); 546 _x=geometry_info.rho; 547 _y=geometry_info.sigma; 548 if ((flags & MagickCore::SigmaValue) == 0) 549 _y=_x; 550 return(*this); 551} 552 553const Magick::Point& Magick::Point::operator=(const double xy_) 554{ 555 _x=xy_; 556 _y=xy_; 557 return(*this); 558} 559 560Magick::Point& Magick::Point::operator=(const Point &point_) 561{ 562 // If not being set to ourself 563 if (this != &point_) 564 { 565 _x=point_._x; 566 _y=point_._y; 567 } 568 return(*this); 569} 570 571const Magick::Point& Magick::Point::operator=(const std::string &point_) 572{ 573 *this=point_.c_str(); 574 return(*this); 575} 576 577Magick::Point::operator std::string() const 578{ 579 char 580 buffer[MaxTextExtent]; 581 582 string 583 point; 584 585 if (_x < 0.0) 586 point+="-"; 587 else 588 point+="+"; 589 590 FormatLocaleString(buffer,MaxTextExtent,"%.20g",_x); 591 point+=buffer; 592 593 if (_y < 0.0) 594 point+="x-"; 595 else 596 point+="x+"; 597 598 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _y); 599 point+=buffer; 600 601 return(point); 602} 603 604bool Magick::Point::isValid(void) const 605{ 606 return(_x > 0.0); 607} 608 609double Magick::Point::x(void) const 610{ 611 return(_x); 612} 613 614double Magick::Point::y(void) const 615{ 616 return(_y); 617}