Cosmetics.
[LibreOffice.git] / include / tools / gen.hxx
blob0d9a81ebdceefb2fc613926a33c846b1cca521bc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_TOOLS_GEN_HXX
20 #define INCLUDED_TOOLS_GEN_HXX
22 #include <tools/toolsdllapi.h>
24 #include <limits.h>
25 #include <algorithm>
26 #include <ostream>
28 class SvStream;
29 namespace rtl
31 class OString;
34 enum TriState { TRISTATE_FALSE, TRISTATE_TRUE, TRISTATE_INDET };
36 // Pair
38 class SAL_WARN_UNUSED Pair
40 public:
41 Pair() : nA(0), nB(0) {}
42 Pair( long _nA, long _nB ) : nA(_nA), nB(_nB) {}
44 long A() const { return nA; }
45 long B() const { return nB; }
47 long& A() { return nA; }
48 long& B() { return nB; }
50 TOOLS_DLLPUBLIC rtl::OString toString() const;
51 TOOLS_DLLPUBLIC friend SvStream& ReadPair( SvStream& rIStream, Pair& rPair );
52 TOOLS_DLLPUBLIC friend SvStream& WritePair( SvStream& rOStream, const Pair& rPair );
54 protected:
55 long nA;
56 long nB;
59 namespace tools { namespace detail {
61 // Used to implement operator == for subclasses of Pair:
62 inline bool equal(Pair const & p1, Pair const & p2)
64 return p1.A() == p2.A() && p1.B() == p2.B();
67 } }
69 // Point
71 class Size;
72 class SAL_WARN_UNUSED SAL_DLLPUBLIC_EXPORT Point final : protected Pair
74 public:
75 Point() {}
76 Point( long nX, long nY ) : Pair( nX, nY ) {}
78 long X() const { return nA; }
79 long Y() const { return nB; }
81 void Move( long nHorzMove, long nVertMove );
82 void Move( Size const & s );
83 long AdjustX( long nHorzMove ) { nA += nHorzMove; return nA; }
84 long AdjustY( long nVertMove ) { nB += nVertMove; return nB; }
86 void RotateAround( long& rX, long& rY, short nOrientation ) const;
87 void RotateAround( Point&, short nOrientation ) const;
89 Point& operator += ( const Point& rPoint );
90 Point& operator -= ( const Point& rPoint );
91 Point& operator *= ( const long nVal );
92 Point& operator /= ( const long nVal );
94 friend inline Point operator+( const Point &rVal1, const Point &rVal2 );
95 friend inline Point operator-( const Point &rVal1, const Point &rVal2 );
96 friend inline Point operator*( const Point &rVal1, const long nVal2 );
97 friend inline Point operator/( const Point &rVal1, const long nVal2 );
99 long getX() const { return X(); }
100 long getY() const { return Y(); }
101 void setX(long nX) { nA = nX; }
102 void setY(long nY) { nB = nY; }
104 Pair const & toPair() const { return *this; }
105 Pair & toPair() { return *this; }
107 using Pair::toString;
110 inline void Point::Move( long nHorzMove, long nVertMove )
112 nA += nHorzMove;
113 nB += nVertMove;
116 inline Point& Point::operator += ( const Point& rPoint )
118 nA += rPoint.nA;
119 nB += rPoint.nB;
120 return *this;
123 inline Point& Point::operator -= ( const Point& rPoint )
125 nA -= rPoint.nA;
126 nB -= rPoint.nB;
127 return *this;
130 inline Point& Point::operator *= ( const long nVal )
132 nA *= nVal;
133 nB *= nVal;
134 return *this;
137 inline Point& Point::operator /= ( const long nVal )
139 nA /= nVal;
140 nB /= nVal;
141 return *this;
144 inline Point operator+( const Point &rVal1, const Point &rVal2 )
146 return Point( rVal1.nA+rVal2.nA, rVal1.nB+rVal2.nB );
149 inline Point operator-( const Point &rVal1, const Point &rVal2 )
151 return Point( rVal1.nA-rVal2.nA, rVal1.nB-rVal2.nB );
154 inline Point operator*( const Point &rVal1, const long nVal2 )
156 return Point( rVal1.nA*nVal2, rVal1.nB*nVal2 );
159 inline Point operator/( const Point &rVal1, const long nVal2 )
161 return Point( rVal1.nA/nVal2, rVal1.nB/nVal2 );
164 inline bool operator ==(Point const & p1, Point const & p2)
166 return tools::detail::equal(p1.toPair(), p2.toPair());
169 inline bool operator !=(Point const & p1, Point const & p2)
171 return !(p1 == p2);
174 template< typename charT, typename traits >
175 inline std::basic_ostream<charT, traits> & operator <<(
176 std::basic_ostream<charT, traits> & stream, const Point& point )
178 return stream << point.X() << ',' << point.Y();
181 // Size
183 class SAL_WARN_UNUSED Size final : protected Pair
185 public:
186 Size() {}
187 Size( long nWidth, long nHeight ) : Pair( nWidth, nHeight ) {}
189 long Width() const { return nA; }
190 long Height() const { return nB; }
192 long AdjustWidth( long n ) { nA += n; return nA; }
193 long AdjustHeight( long n ) { nB += n; return nB; }
195 long getWidth() const { return Width(); }
196 long getHeight() const { return Height(); }
197 void setWidth(long nWidth) { nA = nWidth; }
198 void setHeight(long nHeight) { nB = nHeight; }
200 void extendBy(long x, long y)
202 nA += x;
203 nB += y;
206 Pair const & toPair() const { return *this; }
207 Pair & toPair() { return *this; }
209 using Pair::toString;
212 inline bool operator ==(Size const & s1, Size const & s2)
214 return tools::detail::equal(s1.toPair(), s2.toPair());
217 inline bool operator !=(Size const & s1, Size const & s2)
219 return !(s1 == s2);
222 template< typename charT, typename traits >
223 inline std::basic_ostream<charT, traits> & operator <<(
224 std::basic_ostream<charT, traits> & stream, const Size& size )
226 return stream << size.Width() << 'x' << size.Height();
229 inline void Point::Move( Size const & s )
231 AdjustX(s.Width());
232 AdjustY(s.Height());
235 // Range
237 #define RANGE_MAX LONG_MAX
239 class SAL_WARN_UNUSED Range final : protected Pair
241 public:
242 Range() {}
243 Range( long nMin, long nMax ) : Pair( nMin, nMax ) {}
245 long Min() const { return nA; }
246 long Max() const { return nB; }
247 long Len() const { return nB - nA + 1; }
249 long& Min() { return nA; }
250 long& Max() { return nB; }
252 bool IsInside( long nIs ) const;
254 void Justify();
256 Pair const & toPair() const { return *this; }
257 Pair & toPair() { return *this; }
259 using Pair::toString;
262 inline bool Range::IsInside( long nIs ) const
264 return ((nA <= nIs) && (nIs <= nB ));
267 inline void Range::Justify()
269 if ( nA > nB )
271 long nHelp = nA;
272 nA = nB;
273 nB = nHelp;
277 inline bool operator ==(Range const & r1, Range const & r2)
279 return tools::detail::equal(r1.toPair(), r2.toPair());
282 inline bool operator !=(Range const & r1, Range const & r2)
284 return !(r1 == r2);
287 template< typename charT, typename traits >
288 inline std::basic_ostream<charT, traits> & operator <<(
289 std::basic_ostream<charT, traits> & stream, const Range& range )
291 return stream << range.Min() << '-' << range.Max();
294 // Selection
296 #define SELECTION_MIN LONG_MIN
297 #define SELECTION_MAX LONG_MAX
299 class SAL_WARN_UNUSED Selection final : protected Pair
301 public:
302 Selection() {}
303 Selection( long nPos ) : Pair( nPos, nPos ) {}
304 Selection( long nMin, long nMax ) : Pair( nMin, nMax ) {}
306 long Min() const { return nA; }
307 long Max() const { return nB; }
308 long Len() const { return nB - nA; }
310 long& Min() { return nA; }
311 long& Max() { return nB; }
313 bool IsInside( long nIs ) const;
315 void Justify();
317 bool operator !() const { return !Len(); }
319 long getMin() const { return Min(); }
320 void setMin(long nMin) { Min() = nMin; }
321 void setMax(long nMax) { Max() = nMax; }
323 Pair const & toPair() const { return *this; }
324 Pair & toPair() { return *this; }
326 using Pair::toString;
329 inline bool Selection::IsInside( long nIs ) const
331 return ((nA <= nIs) && (nIs < nB ));
334 inline void Selection::Justify()
336 if ( nA > nB )
338 long nHelp = nA;
339 nA = nB;
340 nB = nHelp;
344 inline bool operator ==(Selection const & s1, Selection const & s2)
346 return tools::detail::equal(s1.toPair(), s2.toPair());
349 inline bool operator !=(Selection const & s1, Selection const & s2)
351 return !(s1 == s2);
354 template< typename charT, typename traits >
355 inline std::basic_ostream<charT, traits> & operator <<(
356 std::basic_ostream<charT, traits> & stream, const Selection& selection )
358 return stream << selection.Min() << '-' << selection.Max();
360 // Rectangle
362 #define RECT_MAX LONG_MAX
363 #define RECT_MIN LONG_MIN
365 /// Note: this class is a true marvel of engineering: because the author
366 /// could not decide whether it's better to have a closed or half-open
367 /// interval, they just implemented *both* in the same class!
369 /// If you have the misfortune of having to use this class, don't immediately
370 /// despair but first take note that the uppercase GetWidth() / GetHeight()
371 /// etc. methods interpret the interval as closed, while the lowercase
372 /// getWidth() / getHeight() etc. methods interpret the interval as half-open.
373 /// Ok, now is the time for despair.
374 namespace tools
376 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle final
378 static constexpr short RECT_EMPTY = -32767;
379 public:
380 Rectangle();
381 Rectangle( const Point& rLT, const Point& rRB );
382 Rectangle( long nLeft, long nTop,
383 long nRight, long nBottom );
384 /// Constructs an empty Rectangle, with top/left at the specified params
385 Rectangle( long nLeft, long nTop );
386 Rectangle( const Point& rLT, const Size& rSize );
388 long Left() const { return nLeft; }
389 long Right() const { return nRight; }
390 long Top() const { return nTop; }
391 long Bottom() const { return nBottom; }
393 void SetLeft(long v) { nLeft = v; }
394 void SetRight(long v) { nRight = v; }
395 void SetTop(long v) { nTop = v; }
396 void SetBottom(long v) { nBottom = v; }
398 inline Point TopLeft() const;
399 inline Point TopRight() const;
400 inline Point TopCenter() const;
401 inline Point BottomLeft() const;
402 inline Point BottomRight() const;
403 inline Point BottomCenter() const;
404 inline Point LeftCenter() const;
405 inline Point RightCenter() const;
406 inline Point Center() const;
408 /// Move the top and left edges by a delta, preserving width and height
409 inline void Move( long nHorzMoveDelta, long nVertMoveDelta );
410 void Move( Size const & s ) { Move(s.Width(), s.Height()); }
411 long AdjustLeft( long nHorzMoveDelta ) { nLeft += nHorzMoveDelta; return nLeft; }
412 long AdjustRight( long nHorzMoveDelta ) { nRight += nHorzMoveDelta; return nRight; }
413 long AdjustTop( long nVertMoveDelta ) { nTop += nVertMoveDelta; return nTop; }
414 long AdjustBottom( long nVertMoveDelta ) { nBottom += nVertMoveDelta; return nBottom; }
415 inline void SetPos( const Point& rPoint );
416 void SetSize( const Size& rSize );
417 inline Size GetSize() const;
419 /// Returns the difference between right and left, assuming the range is inclusive.
420 inline long GetWidth() const;
421 /// Returns the difference between bottom and top, assuming the range is inclusive.
422 inline long GetHeight() const;
424 tools::Rectangle& Union( const tools::Rectangle& rRect );
425 tools::Rectangle& Intersection( const tools::Rectangle& rRect );
426 inline tools::Rectangle GetUnion( const tools::Rectangle& rRect ) const;
427 inline tools::Rectangle GetIntersection( const tools::Rectangle& rRect ) const;
429 void Justify();
431 bool IsInside( const Point& rPOINT ) const;
432 bool IsInside( const tools::Rectangle& rRect ) const;
433 bool IsOver( const tools::Rectangle& rRect ) const;
435 void SetEmpty() { nRight = nBottom = RECT_EMPTY; }
436 void SetWidthEmpty() { nRight = RECT_EMPTY; }
437 void SetHeightEmpty() { nBottom = RECT_EMPTY; }
438 inline bool IsEmpty() const;
439 bool IsWidthEmpty() const { return nRight == RECT_EMPTY; }
440 bool IsHeightEmpty() const { return nBottom == RECT_EMPTY; }
442 inline bool operator == ( const tools::Rectangle& rRect ) const;
443 inline bool operator != ( const tools::Rectangle& rRect ) const;
445 inline tools::Rectangle& operator += ( const Point& rPt );
446 inline tools::Rectangle& operator -= ( const Point& rPt );
448 friend inline tools::Rectangle operator + ( const tools::Rectangle& rRect, const Point& rPt );
449 friend inline tools::Rectangle operator - ( const tools::Rectangle& rRect, const Point& rPt );
451 TOOLS_DLLPUBLIC friend SvStream& ReadRectangle( SvStream& rIStream, tools::Rectangle& rRect );
452 TOOLS_DLLPUBLIC friend SvStream& WriteRectangle( SvStream& rOStream, const tools::Rectangle& rRect );
454 // ONE
455 long getX() const { return nLeft; }
456 long getY() const { return nTop; }
457 /// Returns the difference between right and left, assuming the range includes one end, but not the other.
458 long getWidth() const { return nRight - nLeft; }
459 /// Returns the difference between bottom and top, assuming the range includes one end, but not the other.
460 long getHeight() const { return nBottom - nTop; }
461 /// Set the left edge of the rectangle to x, preserving the width
462 void setX( long x ) { nRight += x - nLeft; nLeft = x; }
463 /// Set the top edge of the rectangle to y, preserving the height
464 void setY( long y ) { nBottom += y - nTop; nTop = y; }
465 void setWidth( long n ) { nRight = nLeft + n; }
466 void setHeight( long n ) { nBottom = nTop + n; }
467 /// Returns the string representation of the rectangle, format is "x, y, width, height".
468 rtl::OString toString() const;
471 * Expands the rectangle in all directions by the input value.
473 inline void expand(long nExpandBy);
474 inline void shrink(long nShrinkBy);
477 * Sanitizing variants for handling data from the outside
479 void SaturatingSetSize(const Size& rSize);
480 void SaturatingSetX(long x);
481 void SaturatingSetY(long y);
483 private:
484 long nLeft;
485 long nTop;
486 long nRight;
487 long nBottom;
491 inline tools::Rectangle::Rectangle()
493 nLeft = nTop = 0;
494 nRight = nBottom = RECT_EMPTY;
497 inline tools::Rectangle::Rectangle( const Point& rLT, const Point& rRB )
499 nLeft = rLT.X();
500 nTop = rLT.Y();
501 nRight = rRB.X();
502 nBottom = rRB.Y();
505 inline tools::Rectangle::Rectangle( long _nLeft, long _nTop,
506 long _nRight, long _nBottom )
508 nLeft = _nLeft;
509 nTop = _nTop;
510 nRight = _nRight;
511 nBottom = _nBottom;
514 inline tools::Rectangle::Rectangle( long _nLeft, long _nTop )
516 nLeft = _nLeft;
517 nTop = _nTop;
518 nRight = nBottom = RECT_EMPTY;
521 inline tools::Rectangle::Rectangle( const Point& rLT, const Size& rSize )
523 nLeft = rLT.X();
524 nTop = rLT.Y();
525 nRight = rSize.Width() ? nLeft+(rSize.Width()-1) : RECT_EMPTY;
526 nBottom = rSize.Height() ? nTop+(rSize.Height()-1) : RECT_EMPTY;
529 inline bool tools::Rectangle::IsEmpty() const
531 return (nRight == RECT_EMPTY) || (nBottom == RECT_EMPTY);
534 inline Point tools::Rectangle::TopLeft() const
536 return Point( nLeft, nTop );
539 inline Point tools::Rectangle::TopRight() const
541 return Point( (nRight == RECT_EMPTY) ? nLeft : nRight, nTop );
544 inline Point tools::Rectangle::BottomLeft() const
546 return Point( nLeft, (nBottom == RECT_EMPTY) ? nTop : nBottom );
549 inline Point tools::Rectangle::BottomRight() const
551 return Point( (nRight == RECT_EMPTY) ? nLeft : nRight,
552 (nBottom == RECT_EMPTY) ? nTop : nBottom );
555 inline Point tools::Rectangle::TopCenter() const
557 if ( IsEmpty() )
558 return Point( nLeft, nTop );
559 else
560 return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ),
561 std::min( nTop, nBottom) );
564 inline Point tools::Rectangle::BottomCenter() const
566 if ( IsEmpty() )
567 return Point( nLeft, nTop );
568 else
569 return Point( std::min( nLeft, nRight ) + std::abs( (nRight - nLeft)/2 ),
570 std::max( nTop, nBottom) );
573 inline Point tools::Rectangle::LeftCenter() const
575 if ( IsEmpty() )
576 return Point( nLeft, nTop );
577 else
578 return Point( std::min( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
581 inline Point tools::Rectangle::RightCenter() const
583 if ( IsEmpty() )
584 return Point( nLeft, nTop );
585 else
586 return Point( std::max( nLeft, nRight ), nTop + (nBottom - nTop)/2 );
589 inline Point tools::Rectangle::Center() const
591 if ( IsEmpty() )
592 return Point( nLeft, nTop );
593 else
594 return Point( nLeft+(nRight-nLeft)/2 , nTop+(nBottom-nTop)/2 );
597 inline void tools::Rectangle::Move( long nHorzMove, long nVertMove )
599 nLeft += nHorzMove;
600 nTop += nVertMove;
601 if ( nRight != RECT_EMPTY )
602 nRight += nHorzMove;
603 if ( nBottom != RECT_EMPTY )
604 nBottom += nVertMove;
607 inline void tools::Rectangle::SetPos( const Point& rPoint )
609 if ( nRight != RECT_EMPTY )
610 nRight += rPoint.X() - nLeft;
611 if ( nBottom != RECT_EMPTY )
612 nBottom += rPoint.Y() - nTop;
613 nLeft = rPoint.X();
614 nTop = rPoint.Y();
617 inline long tools::Rectangle::GetWidth() const
619 long n;
620 if ( nRight == RECT_EMPTY )
621 n = 0;
622 else
624 n = nRight - nLeft;
625 if( n < 0 )
626 n--;
627 else
628 n++;
631 return n;
634 inline long tools::Rectangle::GetHeight() const
636 long n;
637 if ( nBottom == RECT_EMPTY )
638 n = 0;
639 else
641 n = nBottom - nTop;
642 if ( n < 0 )
643 n--;
644 else
645 n++;
648 return n;
651 inline Size tools::Rectangle::GetSize() const
653 return Size( GetWidth(), GetHeight() );
656 inline tools::Rectangle tools::Rectangle::GetUnion( const tools::Rectangle& rRect ) const
658 tools::Rectangle aTmpRect( *this );
659 return aTmpRect.Union( rRect );
662 inline tools::Rectangle tools::Rectangle::GetIntersection( const tools::Rectangle& rRect ) const
664 tools::Rectangle aTmpRect( *this );
665 return aTmpRect.Intersection( rRect );
668 inline bool tools::Rectangle::operator == ( const tools::Rectangle& rRect ) const
670 return (nLeft == rRect.nLeft ) &&
671 (nTop == rRect.nTop ) &&
672 (nRight == rRect.nRight ) &&
673 (nBottom == rRect.nBottom );
676 inline bool tools::Rectangle::operator != ( const tools::Rectangle& rRect ) const
678 return (nLeft != rRect.nLeft ) ||
679 (nTop != rRect.nTop ) ||
680 (nRight != rRect.nRight ) ||
681 (nBottom != rRect.nBottom );
684 inline tools::Rectangle& tools::Rectangle::operator +=( const Point& rPt )
686 nLeft += rPt.X();
687 nTop += rPt.Y();
688 if ( nRight != RECT_EMPTY )
689 nRight += rPt.X();
690 if ( nBottom != RECT_EMPTY )
691 nBottom += rPt.Y();
692 return *this;
695 inline tools::Rectangle& tools::Rectangle::operator -= ( const Point& rPt )
697 nLeft -= rPt.X();
698 nTop -= rPt.Y();
699 if ( nRight != RECT_EMPTY )
700 nRight -= rPt.X();
701 if ( nBottom != RECT_EMPTY )
702 nBottom -= rPt.Y();
703 return *this;
706 namespace tools
708 inline Rectangle operator + ( const Rectangle& rRect, const Point& rPt )
710 return rRect.IsEmpty()
711 ? Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y() )
712 : Rectangle( rRect.nLeft + rPt.X(), rRect.nTop + rPt.Y(),
713 rRect.nRight + rPt.X(), rRect.nBottom + rPt.Y() );
716 inline Rectangle operator - ( const Rectangle& rRect, const Point& rPt )
718 return rRect.IsEmpty()
719 ? Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y() )
720 : Rectangle( rRect.nLeft - rPt.X(), rRect.nTop - rPt.Y(),
721 rRect.nRight - rPt.X(), rRect.nBottom - rPt.Y() );
725 inline void tools::Rectangle::expand(long nExpandBy)
727 nLeft -= nExpandBy;
728 nTop -= nExpandBy;
729 nRight += nExpandBy;
730 nBottom += nExpandBy;
733 inline void tools::Rectangle::shrink(long nShrinkBy)
735 nLeft += nShrinkBy;
736 nTop += nShrinkBy;
737 nRight -= nShrinkBy;
738 nBottom -= nShrinkBy;
741 template< typename charT, typename traits >
742 inline std::basic_ostream<charT, traits> & operator <<(
743 std::basic_ostream<charT, traits> & stream, const tools::Rectangle& rectangle )
745 if (rectangle.IsEmpty())
746 return stream << "EMPTY";
747 else
748 return stream << rectangle.getWidth() << 'x' << rectangle.getHeight()
749 << "@(" << rectangle.getX() << ',' << rectangle.getY() << ")";
752 inline SvStream& ReadPair( SvStream& rIStream, Point& v ) { return ReadPair(rIStream, v.toPair()); }
753 inline SvStream& WritePair( SvStream& rOStream, const Point& v ) { return WritePair(rOStream, v.toPair()); }
754 inline SvStream& ReadPair( SvStream& rIStream, Size& v ) { return ReadPair(rIStream, v.toPair()); }
755 inline SvStream& WritePair( SvStream& rOStream, const Size& v ) { return WritePair(rOStream, v.toPair()); }
757 #endif
759 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */