1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19 #ifndef INCLUDED_TOOLS_GEN_HXX
20 #define INCLUDED_TOOLS_GEN_HXX
21
22 #include <tools/toolsdllapi.h>
23
24 #include <limits.h>
25 #include <algorithm>
26 #include <ostream>
27
28 class SvStream;
29 namespace rtl
30 {
31 class OString;
32 }
33
34 enum TriState { TRISTATE_FALSE, TRISTATE_TRUE, TRISTATE_INDET };
35
36 // Pair
37
38 class SAL_WARN_UNUSED Pair
39 {
40 public:
Pair()41 Pair() : nA(0), nB(0) {}
Pair(long _nA,long _nB)42 Pair( long _nA, long _nB ) : nA(_nA), nB(_nB) {}
43
A() const44 long A() const { return nA; }
B() const45 long B() const { return nB; }
46
A()47 long& A() { return nA; }
B()48 long& B() { return nB; }
49
50 TOOLS_DLLPUBLIC rtl::OString toString() const;
51
52 protected:
53 long nA;
54 long nB;
55 };
56
57 namespace tools { namespace detail {
58
59 // Used to implement operator == for subclasses of Pair:
equal(Pair const & p1,Pair const & p2)60 inline bool equal(Pair const & p1, Pair const & p2)
61 {
62 return p1.A() == p2.A() && p1.B() == p2.B();
63 }
64
65 } }
66
67 // Point
68
69 class Size;
70 class SAL_WARN_UNUSED SAL_DLLPUBLIC_EXPORT Point final : protected Pair
71 {
72 public:
Point()73 Point() {}
Point(long nX,long nY)74 Point( long nX, long nY ) : Pair( nX, nY ) {}
75
X() const76 long X() const { return nA; }
Y() const77 long Y() const { return nB; }
78
79 void Move( long nHorzMove, long nVertMove );
80 void Move( Size const & s );
AdjustX(long nHorzMove)81 long AdjustX( long nHorzMove ) { nA += nHorzMove; return nA; }
AdjustY(long nVertMove)82 long AdjustY( long nVertMove ) { nB += nVertMove; return nB; }
83
84 void RotateAround( long& rX, long& rY, short nOrientation ) const;
85 void RotateAround( Point&, short nOrientation ) const;
86
87 Point& operator += ( const Point& rPoint );
88 Point& operator -= ( const Point& rPoint );
89 Point& operator *= ( const long nVal );
90 Point& operator /= ( const long nVal );
91
92 friend inline Point operator+( const Point &rVal1, const Point &rVal2 );
93 friend inline Point operator-( const Point &rVal1, const Point &rVal2 );
94 friend inline Point operator*( const Point &rVal1, const long nVal2 );
95 friend inline Point operator/( const Point &rVal1, const long nVal2 );
96
getX() const97 long getX() const { return X(); }
getY() const98 long getY() const { return Y(); }
setX(long nX)99 void setX(long nX) { nA = nX; }
setY(long nY)100 void setY(long nY) { nB = nY; }
101
toPair() const102 Pair const & toPair() const { return *this; }
toPair()103 Pair & toPair() { return *this; }
104
105 using Pair::toString;
106 };
107
Move(long nHorzMove,long nVertMove)108 inline void Point::Move( long nHorzMove, long nVertMove )
109 {
110 nA += nHorzMove;
111 nB += nVertMove;
112 }
113
operator +=(const Point & rPoint)114 inline Point& Point::operator += ( const Point& rPoint )
115 {
116 nA += rPoint.nA;
117 nB += rPoint.nB;
118 return *this;
119 }
120
operator -=(const Point & rPoint)121 inline Point& Point::operator -= ( const Point& rPoint )
122 {
123 nA -= rPoint.nA;
124 nB -= rPoint.nB;
125 return *this;
126 }
127
operator *=(const long nVal)128 inline Point& Point::operator *= ( const long nVal )
129 {
130 nA *= nVal;
131 nB *= nVal;
132 return *this;
133 }
134
operator /=(const long nVal)135 inline Point& Point::operator /= ( const long nVal )
136 {
137 nA /= nVal;
138 nB /= nVal;
139 return *this;
140 }
141
operator +(const Point & rVal1,const Point & rVal2)142 inline Point operator+( const Point &rVal1, const Point &rVal2 )
143 {
144 return Point( rVal1.nA+rVal2.nA, rVal1.nB+rVal2.nB );
145 }
146
operator -(const Point & rVal1,const Point & rVal2)147 inline Point operator-( const Point &rVal1, const Point &rVal2 )
148 {
149 return Point( rVal1.nA-rVal2.nA, rVal1.nB-rVal2.nB );
150 }
151
operator *(const Point & rVal1,const long nVal2)152 inline Point operator*( const Point &rVal1, const long nVal2 )
153 {
154 return Point( rVal1.nA*nVal2, rVal1.nB*nVal2 );
155 }
156
operator /(const Point & rVal1,const long nVal2)157 inline Point operator/( const Point &rVal1, const long nVal2 )
158 {
159 return Point( rVal1.nA/nVal2, rVal1.nB/nVal2 );
160 }
161
operator ==(Point const & p1,Point const & p2)162 inline bool operator ==(Point const & p1, Point const & p2)
163 {
164 return tools::detail::equal(p1.toPair(), p2.toPair());
165 }
166
operator !=(Point const & p1,Point const & p2)167 inline bool operator !=(Point const & p1, Point const & p2)
168 {
169 return !(p1 == p2);
170 }
171
172 template< typename charT, typename traits >
operator <<(std::basic_ostream<charT,traits> & stream,const Point & point)173 inline std::basic_ostream<charT, traits> & operator <<(
174 std::basic_ostream<charT, traits> & stream, const Point& point )
175 {
176 return stream << point.X() << ',' << point.Y();
177 }
178
179 // Size
180
181 class SAL_WARN_UNUSED Size final : protected Pair
182 {
183 public:
Size()184 Size() {}
Size(long nWidth,long nHeight)185 Size( long nWidth, long nHeight ) : Pair( nWidth, nHeight ) {}
186
Width() const187 long Width() const { return nA; }
Height() const188 long Height() const { return nB; }
189
AdjustWidth(long n)190 long AdjustWidth( long n ) { nA += n; return nA; }
AdjustHeight(long n)191 long AdjustHeight( long n ) { nB += n; return nB; }
192
getWidth() const193 long getWidth() const { return Width(); }
getHeight() const194 long getHeight() const { return Height(); }
setWidth(long nWidth)195 void setWidth(long nWidth) { nA = nWidth; }
setHeight(long nHeight)196 void setHeight(long nHeight) { nB = nHeight; }
197
extendBy(long x,long y)198 void extendBy(long x, long y)
199 {
200 nA += x;
201 nB += y;
202 }
203
toPair() const204 Pair const & toPair() const { return *this; }
toPair()205 Pair & toPair() { return *this; }
206
207 using Pair::toString;
208 };
209
operator ==(Size const & s1,Size const & s2)210 inline bool operator ==(Size const & s1, Size const & s2)
211 {
212 return tools::detail::equal(s1.toPair(), s2.toPair());
213 }
214
operator !=(Size const & s1,Size const & s2)215 inline bool operator !=(Size const & s1, Size const & s2)
216 {
217 return !(s1 == s2);
218 }
219
220 template< typename charT, typename traits >
operator <<(std::basic_ostream<charT,traits> & stream,const Size & size)221 inline std::basic_ostream<charT, traits> & operator <<(
222 std::basic_ostream<charT, traits> & stream, const Size& size )
223 {
224 return stream << size.Width() << 'x' << size.Height();
225 }
226
Move(Size const & s)227 inline void Point::Move( Size const & s )
228 {
229 AdjustX(s.Width());
230 AdjustY(s.Height());
231 }
232
233 // Range
234
235 #define RANGE_MAX LONG_MAX
236
237 class SAL_WARN_UNUSED Range final : protected Pair
238 {
239 public:
Range()240 Range() {}
Range(long nMin,long nMax)241 Range( long nMin, long nMax ) : Pair( nMin, nMax ) {}
242
Min() const243 long Min() const { return nA; }
Max() const244 long Max() const { return nB; }
Len() const245 long Len() const { return nB - nA + 1; }
246
Min()247 long& Min() { return nA; }
Max()248 long& Max() { return nB; }
249
250 bool IsInside( long nIs ) const;
251
252 void Justify();
253
toPair() const254 Pair const & toPair() const { return *this; }
toPair()255 Pair & toPair() { return *this; }
256
257 using Pair::toString;
258 };
259
IsInside(long nIs) const260 inline bool Range::IsInside( long nIs ) const
261 {
262 return ((nA <= nIs) && (nIs <= nB ));
263 }
264
Justify()265 inline void Range::Justify()
266 {
267 if ( nA > nB )
268 {
269 long nHelp = nA;
270 nA = nB;
271 nB = nHelp;
272 }
273 }
274
operator ==(Range const & r1,Range const & r2)275 inline bool operator ==(Range const & r1, Range const & r2)
276 {
277 return tools::detail::equal(r1.toPair(), r2.toPair());
278 }
279
operator !=(Range const & r1,Range const & r2)280 inline bool operator !=(Range const & r1, Range const & r2)
281 {
282 return !(r1 == r2);
283 }
284
285 template< typename charT, typename traits >
operator <<(std::basic_ostream<charT,traits> & stream,const Range & range)286 inline std::basic_ostream<charT, traits> & operator <<(
287 std::basic_ostream<charT, traits> & stream, const Range& range )
288 {
289 return stream << range.Min() << '-' << range.Max();
290 }
291
292 // Selection
293
294 #define SELECTION_MIN LONG_MIN
295 #define SELECTION_MAX LONG_MAX
296
297 class SAL_WARN_UNUSED Selection final : protected Pair
298 {
299 public:
Selection()300 Selection() {}
Selection(long nPos)301 Selection( long nPos ) : Pair( nPos, nPos ) {}
Selection(long nMin,long nMax)302 Selection( long nMin, long nMax ) : Pair( nMin, nMax ) {}
303
Min() const304 long Min() const { return nA; }
Max() const305 long Max() const { return nB; }
Len() const306 long Len() const { return nB - nA; }
307
Min()308 long& Min() { return nA; }
Max()309 long& Max() { return nB; }
310
311 bool IsInside( long nIs ) const;
312
313 void Justify();
314
operator !() const315 bool operator !() const { return !Len(); }
316
getMin() const317 long getMin() const { return Min(); }
setMin(long nMin)318 void setMin(long nMin) { Min() = nMin; }
setMax(long nMax)319 void setMax(long nMax) { Max() = nMax; }
320
toPair() const321 Pair const & toPair() const { return *this; }
toPair()322 Pair & toPair() { return *this; }
323
324 using Pair::toString;
325 };
326
IsInside(long nIs) const327 inline bool Selection::IsInside( long nIs ) const
328 {
329 return ((nA <= nIs) && (nIs < nB ));
330 }
331
Justify()332 inline void Selection::Justify()
333 {
334 if ( nA > nB )
335 {
336 long nHelp = nA;
337 nA = nB;
338 nB = nHelp;
339 }
340 }
341
operator ==(Selection const & s1,Selection const & s2)342 inline bool operator ==(Selection const & s1, Selection const & s2)
343 {
344 return tools::detail::equal(s1.toPair(), s2.toPair());
345 }
346
operator !=(Selection const & s1,Selection const & s2)347 inline bool operator !=(Selection const & s1, Selection const & s2)
348 {
349 return !(s1 == s2);
350 }
351
352 template< typename charT, typename traits >
operator <<(std::basic_ostream<charT,traits> & stream,const Selection & selection)353 inline std::basic_ostream<charT, traits> & operator <<(
354 std::basic_ostream<charT, traits> & stream, const Selection& selection )
355 {
356 return stream << selection.Min() << '-' << selection.Max();
357 }
358 // Rectangle
359
360 #define RECT_MAX LONG_MAX
361 #define RECT_MIN LONG_MIN
362
363 /// Note: this class is a true marvel of engineering: because the author
364 /// could not decide whether it's better to have a closed or half-open
365 /// interval, they just implemented *both* in the same class!
366 ///
367 /// If you have the misfortune of having to use this class, don't immediately
368 /// despair but first take note that the uppercase GetWidth() / GetHeight()
369 /// etc. methods interpret the interval as closed, while the lowercase
370 /// getWidth() / getHeight() etc. methods interpret the interval as half-open.
371 /// Ok, now is the time for despair.
372 namespace tools
373 {
374 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle final
375 {
376 static constexpr short RECT_EMPTY = -32767;
377 public:
378 Rectangle();
379 Rectangle( const Point& rLT, const Point& rRB );
380 Rectangle( long nLeft, long nTop,
381 long nRight, long nBottom );
382 /// Constructs an empty Rectangle, with top/left at the specified params
383 Rectangle( long nLeft, long nTop );
384 Rectangle( const Point& rLT, const Size& rSize );
385
Left() const386 long Left() const { return nLeft; }
387 long Right() const;
Top() const388 long Top() const { return nTop; }
389 long Bottom() const;
390
SetLeft(long v)391 void SetLeft(long v) { nLeft = v; }
SetRight(long v)392 void SetRight(long v) { nRight = v; }
SetTop(long v)393 void SetTop(long v) { nTop = v; }
SetBottom(long v)394 void SetBottom(long v) { nBottom = v; }
395
396 inline Point TopLeft() const;
397 inline Point TopRight() const;
398 inline Point TopCenter() const;
399 inline Point BottomLeft() const;
400 inline Point BottomRight() const;
401 inline Point BottomCenter() const;
402 inline Point LeftCenter() const;
403 inline Point RightCenter() const;
404 inline Point Center() const;
405
406 /// Move the top and left edges by a delta, preserving width and height
407 inline void Move( long nHorzMoveDelta, long nVertMoveDelta );
Move(Size const & s)408 void Move( Size const & s ) { Move(s.Width(), s.Height()); }
AdjustLeft(long nHorzMoveDelta)409 long AdjustLeft( long nHorzMoveDelta ) { nLeft += nHorzMoveDelta; return nLeft; }
410 long AdjustRight( long nHorzMoveDelta );
AdjustTop(long nVertMoveDelta)411 long AdjustTop( long nVertMoveDelta ) { nTop += nVertMoveDelta; return nTop; }
412 long AdjustBottom( long nVertMoveDelta );
413 inline void SetPos( const Point& rPoint );
414 void SetSize( const Size& rSize );
415 inline Size GetSize() const;
416
417 /// Returns the difference between right and left, assuming the range is inclusive.
418 inline long GetWidth() const;
419 /// Returns the difference between bottom and top, assuming the range is inclusive.
420 inline long GetHeight() const;
421
422 tools::Rectangle& Union( const tools::Rectangle& rRect );
423 tools::Rectangle& Intersection( const tools::Rectangle& rRect );
424 inline tools::Rectangle GetUnion( const tools::Rectangle& rRect ) const;
425 inline tools::Rectangle GetIntersection( const tools::Rectangle& rRect ) const;
426
427 void Justify();
428
429 bool IsInside( const Point& rPOINT ) const;
430 bool IsInside( const tools::Rectangle& rRect ) const;
431 bool IsOver( const tools::Rectangle& rRect ) const;
432
SetEmpty()433 void SetEmpty() { nRight = nBottom = RECT_EMPTY; }
SetWidthEmpty()434 void SetWidthEmpty() { nRight = RECT_EMPTY; }
SetHeightEmpty()435 void SetHeightEmpty() { nBottom = RECT_EMPTY; }
436 inline bool IsEmpty() const;
IsWidthEmpty() const437 bool IsWidthEmpty() const { return nRight == RECT_EMPTY; }
IsHeightEmpty() const438 bool IsHeightEmpty() const { return nBottom == RECT_EMPTY; }
439
440 inline bool operator == ( const tools::Rectangle& rRect ) const;
441 inline bool operator != ( const tools::Rectangle& rRect ) const;
442
443 inline tools::Rectangle& operator += ( const Point& rPt );
444 inline tools::Rectangle& operator -= ( const Point& rPt );
445
446 friend inline tools::Rectangle operator + ( const tools::Rectangle& rRect, const Point& rPt );
447 friend inline tools::Rectangle operator - ( const tools::Rectangle& rRect, const Point& rPt );
448
449 // ONE
getX() const450 long getX() const { return nLeft; }
getY() const451 long getY() const { return nTop; }
452 /// Returns the difference between right and left, assuming the range includes one end, but not the other.
453 long getWidth() const;
454 /// Returns the difference between bottom and top, assuming the range includes one end, but not the other.
455 long getHeight() const;
456 /// Set the left edge of the rectangle to x, preserving the width
457 void setX( long x );
458 /// Set the top edge of the rectangle to y, preserving the height
459 void setY( long y );
setWidth(long n)460 void setWidth( long n ) { nRight = nLeft + n; }
setHeight(long n)461 void setHeight( long n ) { nBottom = nTop + n; }
462 /// Returns the string representation of the rectangle, format is "x, y, width, height".
463 rtl::OString toString() const;
464
465 /**
466 * Expands the rectangle in all directions by the input value.
467 */
468 void expand(long nExpandBy);
469 void shrink(long nShrinkBy);
470
471 /**
472 * Sanitizing variants for handling data from the outside
473 */
474 void SaturatingSetSize(const Size& rSize);
475 void SaturatingSetX(long x);
476 void SaturatingSetY(long y);
477
478 private:
479 long nLeft;
480 long nTop;
481 long nRight;
482 long nBottom;
483 };
484 }
485
Rectangle()486 inline tools::Rectangle::Rectangle()
487 {
488 nLeft = nTop = 0;
489 nRight = nBottom = RECT_EMPTY;
490 }
491
Rectangle(const Point & rLT,const Point & rRB)492 inline tools::Rectangle::Rectangle( const Point& rLT, const Point& rRB )
493 {
494 nLeft = rLT.X();
495 nTop = rLT.Y();
496 nRight = rRB.X();
497 nBottom = rRB.Y();
498 }
499
Rectangle(long _nLeft,long _nTop,long _nRight,long _nBottom)500 inline tools::Rectangle::Rectangle( long _nLeft, long _nTop,
501 long _nRight, long _nBottom )
502 {
503 nLeft = _nLeft;
504 nTop = _nTop;
505 nRight = _nRight;
506 nBottom = _nBottom;
507 }
508
Rectangle(long _nLeft,long _nTop)509 inline tools::Rectangle::Rectangle( long _nLeft, long _nTop )
510 {
511 nLeft = _nLeft;
512 nTop = _nTop;
513 nRight = nBottom = RECT_EMPTY;
514 }
515
Rectangle(const Point & rLT,const Size & rSize)516 inline tools::Rectangle::Rectangle( const Point& rLT, const Size& rSize )
517 {
518 nLeft = rLT.X();
519 nTop = rLT.Y();
520 nRight = rSize.Width() ? nLeft+(rSize.Width()-1) : RECT_EMPTY;
521 nBottom = rSize.Height() ? nTop+(rSize.Height()-1) : RECT_EMPTY;
522 }
523
IsEmpty() const524 inline bool tools::Rectangle::IsEmpty() const
525 {
526 return (nRight == RECT_EMPTY) || (nBottom == RECT_EMPTY);
527 }
528
TopLeft() const529 inline Point tools::Rectangle::TopLeft() const
530 {
531 return Point( nLeft, nTop );
532 }
533
TopRight() const534 inline Point tools::Rectangle::TopRight() const
535 {
536 return Point( (nRight == RECT_EMPTY) ? nLeft : nRight, nTop );
537 }
538
BottomLeft() const539 inline Point tools::Rectangle::BottomLeft() const
540 {
541 return Point( nLeft, (nBottom == RECT_EMPTY) ? nTop : nBottom );
542 }
543
BottomRight() const544 inline Point tools::Rectangle::BottomRight() const
545 {
546 return Point( (nRight == RECT_EMPTY) ? nLeft : nRight,
547 (nBottom == RECT_EMPTY) ? nTop : nBottom );
548 }
549
TopCenter() const550 inline Point tools::Rectangle::TopCenter() const
551 {
552 if ( IsEmpty() )
553 return Point( nLeft, nTop );
554 else
555 return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ),
556 std::min( nTop, nBottom) );
557 }
558
BottomCenter() const559 inline Point tools::Rectangle::BottomCenter() const
560 {
561 if ( IsEmpty() )
562 return Point( nLeft, nTop );
563 else
564 return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ),
565 std::max( nTop, nBottom) );
566 }
567
LeftCenter() const568 inline Point tools::Rectangle::LeftCenter() const
569 {
570 if ( IsEmpty() )
571 return Point( nLeft, nTop );
572 else
573 return Point( std::min( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
574 }
575
RightCenter() const576 inline Point tools::Rectangle::RightCenter() const
577 {
578 if ( IsEmpty() )
579 return Point( nLeft, nTop );
580 else
581 return Point( std::max( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
582 }
583
Center() const584 inline Point tools::Rectangle::Center() const
585 {
586 if ( IsEmpty() )
587 return Point( nLeft, nTop );
588 else
589 return Point( nLeft+(nRight-nLeft)/2 , nTop+(nBottom-nTop)/2 );
590 }
591
Move(long nHorzMove,long nVertMove)592 inline void tools::Rectangle::Move( long nHorzMove, long nVertMove )
593 {
594 nLeft += nHorzMove;
595 nTop += nVertMove;
596 if ( nRight != RECT_EMPTY )
597 nRight += nHorzMove;
598 if ( nBottom != RECT_EMPTY )
599 nBottom += nVertMove;
600 }
601
SetPos(const Point & rPoint)602 inline void tools::Rectangle::SetPos( const Point& rPoint )
603 {
604 if ( nRight != RECT_EMPTY )
605 nRight += rPoint.X() - nLeft;
606 if ( nBottom != RECT_EMPTY )
607 nBottom += rPoint.Y() - nTop;
608 nLeft = rPoint.X();
609 nTop = rPoint.Y();
610 }
611
GetWidth() const612 inline long tools::Rectangle::GetWidth() const
613 {
614 long n;
615 if ( nRight == RECT_EMPTY )
616 n = 0;
617 else
618 {
619 n = nRight - nLeft;
620 if( n < 0 )
621 n--;
622 else
623 n++;
624 }
625
626 return n;
627 }
628
GetHeight() const629 inline long tools::Rectangle::GetHeight() const
630 {
631 long n;
632 if ( nBottom == RECT_EMPTY )
633 n = 0;
634 else
635 {
636 n = nBottom - nTop;
637 if ( n < 0 )
638 n--;
639 else
640 n++;
641 }
642
643 return n;
644 }
645
GetSize() const646 inline Size tools::Rectangle::GetSize() const
647 {
648 return Size( GetWidth(), GetHeight() );
649 }
650
GetUnion(const tools::Rectangle & rRect) const651 inline tools::Rectangle tools::Rectangle::GetUnion( const tools::Rectangle& rRect ) const
652 {
653 tools::Rectangle aTmpRect( *this );
654 return aTmpRect.Union( rRect );
655 }
656
GetIntersection(const tools::Rectangle & rRect) const657 inline tools::Rectangle tools::Rectangle::GetIntersection( const tools::Rectangle& rRect ) const
658 {
659 tools::Rectangle aTmpRect( *this );
660 return aTmpRect.Intersection( rRect );
661 }
662
operator ==(const tools::Rectangle & rRect) const663 inline bool tools::Rectangle::operator == ( const tools::Rectangle& rRect ) const
664 {
665 return (nLeft == rRect.nLeft ) &&
666 (nTop == rRect.nTop ) &&
667 (nRight == rRect.nRight ) &&
668 (nBottom == rRect.nBottom );
669 }
670
operator !=(const tools::Rectangle & rRect) const671 inline bool tools::Rectangle::operator != ( const tools::Rectangle& rRect ) const
672 {
673 return (nLeft != rRect.nLeft ) ||
674 (nTop != rRect.nTop ) ||
675 (nRight != rRect.nRight ) ||
676 (nBottom != rRect.nBottom );
677 }
678
operator +=(const Point & rPt)679 inline tools::Rectangle& tools::Rectangle::operator +=( const Point& rPt )
680 {
681 nLeft += rPt.X();
682 nTop += rPt.Y();
683 if ( nRight != RECT_EMPTY )
684 nRight += rPt.X();
685 if ( nBottom != RECT_EMPTY )
686 nBottom += rPt.Y();
687 return *this;
688 }
689
operator -=(const Point & rPt)690 inline tools::Rectangle& tools::Rectangle::operator -= ( const Point& rPt )
691 {
692 nLeft -= rPt.X();
693 nTop -= rPt.Y();
694 if ( nRight != RECT_EMPTY )
695 nRight -= rPt.X();
696 if ( nBottom != RECT_EMPTY )
697 nBottom -= rPt.Y();
698 return *this;
699 }
700
701 namespace tools
702 {
operator +(const Rectangle & rRect,const Point & rPt)703 inline Rectangle operator + ( const Rectangle& rRect, const Point& rPt )
704 {
705 return rRect.IsEmpty()
706 ? Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y() )
707 : Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y(),
708 rRect.nRight + rPt.X(), rRect.nBottom + rPt.Y() );
709 }
710
operator -(const Rectangle & rRect,const Point & rPt)711 inline Rectangle operator - ( const Rectangle& rRect, const Point& rPt )
712 {
713 return rRect.IsEmpty()
714 ? Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y() )
715 : Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y(),
716 rRect.nRight - rPt.X(), rRect.nBottom - rPt.Y() );
717 }
718 }
719
720 template< typename charT, typename traits >
operator <<(std::basic_ostream<charT,traits> & stream,const tools::Rectangle & rectangle)721 inline std::basic_ostream<charT, traits> & operator <<(
722 std::basic_ostream<charT, traits> & stream, const tools::Rectangle& rectangle )
723 {
724 if (rectangle.IsEmpty())
725 return stream << "EMPTY";
726 else
727 return stream << rectangle.getWidth() << 'x' << rectangle.getHeight()
728 << "@(" << rectangle.getX() << ',' << rectangle.getY() << ")";
729 }
730
731 #endif
732
733 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
734