Magick++ 6.9.13
Loading...
Searching...
No Matches
Geometry.cpp
1// This may look like C code, but it is really -*- C++ -*-
2//
3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
4// Copyright Dirk Lemstra 2014
5//
6// Geometry implementation
7//
8
9#define MAGICKCORE_IMPLEMENTATION 1
10#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
11
12#include "Magick++/Include.h"
13#include <string>
14#include <ctype.h> // for isdigit
15#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
16#include <strings.h>
17#endif
18
19#include "Magick++/Geometry.h"
20#include "Magick++/Exception.h"
21
22using namespace std;
23
24MagickPPExport int Magick::operator == (const Magick::Geometry& left_,
25 const Magick::Geometry& right_)
26{
27 return((left_.aspect() == right_.aspect()) &&
28 (left_.fillArea() == right_.fillArea()) &&
29 (left_.greater() == right_.greater()) &&
30 (left_.height() == right_.height()) &&
31 (left_.isValid() == right_.isValid()) &&
32 (left_.less() == right_.less()) &&
33 (left_.limitPixels() == right_.limitPixels()) &&
34 (left_.percent() == right_.percent()) &&
35 (left_.width() == right_.width()) &&
36 (left_.xNegative() == right_.xNegative()) &&
37 (left_.xOff() == right_.xOff()) &&
38 (left_.yNegative() == right_.yNegative()) &&
39 (left_.yOff() == right_.yOff()));
40}
41
42MagickPPExport int Magick::operator != (const Magick::Geometry& left_,
43 const Magick::Geometry& right_)
44{
45 return(!(left_ == right_));
46}
47
48MagickPPExport int Magick::operator > (const Magick::Geometry& left_,
49 const Magick::Geometry& right_)
50{
51 return(!(left_ < right_) && (left_ != right_));
52}
53
54MagickPPExport int Magick::operator < (const Magick::Geometry& left_,
55 const Magick::Geometry& right_)
56{
57 return((left_.width()*left_.height()) < (right_.width()*right_.height()));
58}
59
60MagickPPExport int Magick::operator >= (const Magick::Geometry& left_,
61 const Magick::Geometry& right_)
62{
63 return((left_ > right_) || (left_ == right_));
64}
65
66MagickPPExport int Magick::operator <= (const Magick::Geometry& left_,
67 const Magick::Geometry& right_ )
68{
69 return((left_ < right_) || (left_ == right_));
70}
71
72Magick::Geometry::Geometry(void)
73 : _width(0),
74 _height(0),
75 _xOff(0),
76 _yOff(0),
77 _xNegative(false),
78 _yNegative(false),
79 _isValid(false),
80 _percent(false),
81 _aspect(false),
82 _greater(false),
83 _less(false),
84 _fillArea(false),
85 _limitPixels(false)
86{
87}
88
89Magick::Geometry::Geometry(const char *geometry_)
90 : _width(0),
91 _height(0),
92 _xOff(0),
93 _yOff(0),
94 _xNegative(false),
95 _yNegative(false),
96 _isValid(false),
97 _percent(false),
98 _aspect(false),
99 _greater(false),
100 _less(false),
101 _fillArea(false),
102 _limitPixels(false)
103{
104 *this=geometry_; // Use assignment operator
105}
106
107Magick::Geometry::Geometry(const Geometry &geometry_)
108 : _width(geometry_._width),
109 _height(geometry_._height),
110 _xOff(geometry_._xOff),
111 _yOff(geometry_._yOff),
112 _xNegative(geometry_._xNegative),
113 _yNegative(geometry_._yNegative),
114 _isValid(geometry_._isValid),
115 _percent(geometry_._percent),
116 _aspect(geometry_._aspect),
117 _greater(geometry_._greater),
118 _less(geometry_._less),
119 _fillArea(geometry_._fillArea),
120 _limitPixels(geometry_._limitPixels)
121{
122}
123
124Magick::Geometry::Geometry(const std::string &geometry_)
125 : _width(0),
126 _height(0),
127 _xOff(0),
128 _yOff(0),
129 _xNegative(false),
130 _yNegative(false),
131 _isValid(false),
132 _percent(false),
133 _aspect(false),
134 _greater(false),
135 _less(false),
136 _fillArea(false),
137 _limitPixels(false)
138{
139 *this=geometry_; // Use assignment operator
140}
141
142Magick::Geometry::Geometry(size_t width_,size_t height_,ssize_t xOff_,
143 ssize_t yOff_,bool xNegative_,bool yNegative_)
144 : _width(width_),
145 _height(height_),
146 _xOff(xOff_),
147 _yOff(yOff_),
148 _xNegative(xNegative_),
149 _yNegative(yNegative_),
150 _isValid(true),
151 _percent(false),
152 _aspect(false),
153 _greater(false),
154 _less(false),
155 _fillArea(false),
156 _limitPixels(false)
157{
158}
159
160Magick::Geometry::~Geometry(void)
161{
162}
163
164const Magick::Geometry& Magick::Geometry::operator=(const char * geometry_)
165{
166 *this=std::string(geometry_);
167 return(*this);
168}
169
170Magick::Geometry& Magick::Geometry::operator=(const Geometry& geometry_)
171{
172 // If not being set to ourself
173 if (this != &geometry_)
174 {
175 _width=geometry_._width;
176 _height=geometry_._height;
177 _xOff=geometry_._xOff;
178 _yOff=geometry_._yOff;
179 _xNegative=geometry_._xNegative;
180 _yNegative=geometry_._yNegative;
181 _isValid=geometry_._isValid;
182 _percent=geometry_._percent;
183 _aspect=geometry_._aspect;
184 _greater=geometry_._greater;
185 _less=geometry_._less;
186 _fillArea=geometry_._fillArea;
187 _limitPixels=geometry_._limitPixels;
188 }
189 return(*this);
190}
191
192const Magick::Geometry& Magick::Geometry::operator=(
193 const std::string &geometry_)
194{
195 char
196 geom[MaxTextExtent];
197
198 char
199 *pageptr;
200
201 ssize_t
202 flags,
203 x = 0,
204 y = 0;
205
206 size_t
207 height_val=0,
208 width_val=0;
209
210 // If argument does not start with digit, presume that it is a
211 // page-size specification that needs to be converted to an
212 // equivalent geometry specification using PostscriptGeometry()
213 (void) CopyMagickString(geom,geometry_.c_str(),MaxTextExtent);
214 if (geom[0] != '-' && geom[0] != '+' && geom[0] != 'x' &&
215 !isdigit(static_cast<int>(geom[0])))
216 {
217 pageptr=GetPageGeometry(geom);
218 if (pageptr != 0)
219 {
220 (void) CopyMagickString(geom,pageptr,MaxTextExtent);
221 pageptr=(char *) RelinquishMagickMemory(pageptr);
222 }
223 }
224
225 flags=GetGeometry(geom,&x,&y,&width_val,&height_val);
226
227 if (flags == NoValue)
228 {
229 // Total failure!
230 *this=Geometry();
231 isValid(false);
232 return(*this);
233 }
234
235 if ((flags & WidthValue) != 0)
236 {
237 _width=width_val;
238 isValid(true);
239 }
240
241 if ((flags & HeightValue) != 0)
242 {
243 _height=height_val;
244 isValid(true);
245 }
246
247 if ((flags & XValue) != 0)
248 {
249 _xOff=static_cast<ssize_t>(x);
250 isValid(true);
251 }
252
253 if ((flags & YValue) != 0)
254 {
255 _yOff=static_cast<ssize_t>(y);
256 isValid(true);
257 }
258
259 if ((flags & XNegative) != 0)
260 _xNegative=true;
261
262 if ((flags & YNegative) != 0)
263 _yNegative=true;
264
265 if ((flags & PercentValue) != 0)
266 _percent=true;
267
268 if ((flags & AspectValue) != 0)
269 _aspect=true;
270
271 if ((flags & LessValue) != 0)
272 _less=true;
273
274 if ((flags & GreaterValue) != 0)
275 _greater=true;
276
277 if ((flags & MinimumValue) != 0)
278 _fillArea=true;
279
280 if ((flags & AreaValue) != 0)
281 _limitPixels=true;
282
283 return(*this);
284}
285
286Magick::Geometry::operator std::string() const
287{
288 char
289 buffer[MaxTextExtent];
290
291 std::string
292 geometry;
293
294 if (!isValid())
295 throwExceptionExplicit(OptionError,"Invalid geometry argument");
296
297 if (_width)
298 {
299 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _width);
300 geometry+=buffer;
301 }
302
303 if (_height)
304 {
305 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _height);
306 geometry+='x';
307 geometry+=buffer;
308 }
309
310 if (_xOff || _yOff)
311 {
312 if (_xNegative)
313 geometry+='-';
314 else
315 geometry+='+';
316
317 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _xOff);
318 geometry+=buffer;
319
320 if (_yNegative)
321 geometry+='-';
322 else
323 geometry+='+';
324
325 FormatLocaleString(buffer,MaxTextExtent,"%.20g",(double) _yOff);
326 geometry+=buffer;
327 }
328
329 if (_percent)
330 geometry+='%';
331
332 if (_aspect)
333 geometry+='!';
334
335 if (_greater)
336 geometry+='>';
337
338 if (_less)
339 geometry+='<';
340
341 if (_fillArea)
342 geometry+='^';
343
344 if (_limitPixels)
345 geometry+='@';
346
347 return(geometry);
348}
349
350Magick::Geometry::Geometry(const MagickCore::RectangleInfo &rectangle_)
351 : _width(static_cast<size_t>(rectangle_.width)),
352 _height(static_cast<size_t>(rectangle_.height)),
353 _xOff(static_cast<ssize_t>(rectangle_.x)),
354 _yOff(static_cast<ssize_t>(rectangle_.y)),
355 _xNegative(rectangle_.x < 0 ? true : false),
356 _yNegative(rectangle_.y < 0 ? true : false),
357 _isValid(true),
358 _percent(false),
359 _aspect(false),
360 _greater(false),
361 _less(false),
362 _fillArea(false),
363 _limitPixels(false)
364{
365}
366
367const Magick::Geometry& Magick::Geometry::operator=(
368 const MagickCore::RectangleInfo &rectangle_)
369{
370 _width=static_cast<size_t>(rectangle_.width),
371 _height=static_cast<size_t>(rectangle_.height),
372 _xOff=static_cast<ssize_t>(rectangle_.x),
373 _yOff=static_cast<ssize_t>(rectangle_.y),
374 _xNegative=rectangle_.x < 0 ? true : false,
375 _yNegative=rectangle_.y < 0 ? true : false,
376 _isValid=true;
377 return(*this);
378}
379
380Magick::Geometry::operator MagickCore::RectangleInfo() const
381{
382 RectangleInfo rectangle;
383 rectangle.width=_width;
384 rectangle.height=_height;
385 rectangle.x=_xOff;
386 rectangle.y=_yOff;
387 return(rectangle);
388}
389
390MagickPPExport int Magick::operator == (const Magick::Offset& left_,
391 const Magick::Offset& right_)
392{
393 return((left_.x() == right_.x()) &&
394 (left_.y() == right_.y()));
395}
396
397MagickPPExport int Magick::operator != (const Magick::Offset& left_,
398 const Magick::Offset& right_)
399{
400 return(!(left_ == right_));
401}
402
403Magick::Offset::Offset(void)
404 : _x(0),
405 _y(0)
406{
407}
408
409Magick::Offset::Offset(const char *offset_)
410 : _x(0),
411 _y(0)
412{
413 *this=offset_; // Use assignment operator
414}
415
416Magick::Offset::Offset(const Offset &offset_)
417 : _x(offset_._x),
418 _y(offset_._y)
419{
420}
421
422Magick::Offset::Offset(const std::string &offset_)
423 : _x(0),
424 _y(0)
425{
426 *this=offset_; // Use assignment operator
427}
428
429Magick::Offset::Offset(ssize_t x_,ssize_t y_)
430 : _x(x_),
431 _y(y_)
432{
433}
434
435Magick::Offset::~Offset(void)
436{
437}
438
439const Magick::Offset& Magick::Offset::operator=(const char *offset_)
440{
441 MagickCore::GeometryInfo
442 geometry_info;
443
444 MagickCore::MagickStatusType
445 flags;
446
447 flags=ParseGeometry(offset_,&geometry_info);
448 _x=(ssize_t) geometry_info.rho;
449 _y=(ssize_t) geometry_info.sigma;
450 if ((flags & MagickCore::SigmaValue) == 0)
451 _y=_x;
452 return(*this);
453}
454
455Magick::Offset& Magick::Offset::operator=(const Offset &offset_)
456{
457 // If not being set to ourself
458 if (this != &offset_)
459 {
460 _x=offset_._x;
461 _y=offset_._y;
462 }
463 return(*this);
464}
465
466const Magick::Offset& Magick::Offset::operator=(const std::string &offset_)
467{
468 *this=offset_.c_str();
469 return(*this);
470}
471
472ssize_t Magick::Offset::x(void) const
473{
474 return(_x);
475}
476
477ssize_t Magick::Offset::y(void) const
478{
479 return(_y);
480}
481
482Magick::Offset::operator MagickCore::OffsetInfo() const
483{
484 OffsetInfo offset;
485 offset.x=_x;
486 offset.y=_y;
487 return(offset);
488}