1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
34 enum TriState
{ TRISTATE_FALSE
, TRISTATE_TRUE
, TRISTATE_INDET
};
38 class SAL_WARN_UNUSED Pair
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;
57 namespace tools
{ namespace detail
{
59 // Used to implement operator == for subclasses of Pair:
60 inline bool equal(Pair
const & p1
, Pair
const & p2
)
62 return p1
.A() == p2
.A() && p1
.B() == p2
.B();
70 class SAL_WARN_UNUSED SAL_DLLPUBLIC_EXPORT Point final
: protected Pair
74 Point( long nX
, long nY
) : Pair( nX
, nY
) {}
76 long X() const { return nA
; }
77 long Y() const { return nB
; }
79 void Move( long nHorzMove
, long nVertMove
);
80 void Move( Size
const & s
);
81 long AdjustX( long nHorzMove
) { nA
+= nHorzMove
; return nA
; }
82 long AdjustY( long nVertMove
) { nB
+= nVertMove
; return nB
; }
84 void RotateAround( long& rX
, long& rY
, short nOrientation
) const;
85 void RotateAround( Point
&, short nOrientation
) const;
87 Point
& operator += ( const Point
& rPoint
);
88 Point
& operator -= ( const Point
& rPoint
);
89 Point
& operator *= ( const long nVal
);
90 Point
& operator /= ( const long nVal
);
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
);
97 long getX() const { return X(); }
98 long getY() const { return Y(); }
99 void setX(long nX
) { nA
= nX
; }
100 void setY(long nY
) { nB
= nY
; }
102 Pair
const & toPair() const { return *this; }
103 Pair
& toPair() { return *this; }
105 using Pair::toString
;
108 inline void Point::Move( long nHorzMove
, long nVertMove
)
114 inline Point
& Point::operator += ( const Point
& rPoint
)
121 inline Point
& Point::operator -= ( const Point
& rPoint
)
128 inline Point
& Point::operator *= ( const long nVal
)
135 inline Point
& Point::operator /= ( const long nVal
)
142 inline Point
operator+( const Point
&rVal1
, const Point
&rVal2
)
144 return Point( rVal1
.nA
+rVal2
.nA
, rVal1
.nB
+rVal2
.nB
);
147 inline Point
operator-( const Point
&rVal1
, const Point
&rVal2
)
149 return Point( rVal1
.nA
-rVal2
.nA
, rVal1
.nB
-rVal2
.nB
);
152 inline Point
operator*( const Point
&rVal1
, const long nVal2
)
154 return Point( rVal1
.nA
*nVal2
, rVal1
.nB
*nVal2
);
157 inline Point
operator/( const Point
&rVal1
, const long nVal2
)
159 return Point( rVal1
.nA
/nVal2
, rVal1
.nB
/nVal2
);
162 inline bool operator ==(Point
const & p1
, Point
const & p2
)
164 return tools::detail::equal(p1
.toPair(), p2
.toPair());
167 inline bool operator !=(Point
const & p1
, Point
const & p2
)
172 template< typename charT
, typename traits
>
173 inline std::basic_ostream
<charT
, traits
> & operator <<(
174 std::basic_ostream
<charT
, traits
> & stream
, const Point
& point
)
176 return stream
<< point
.X() << ',' << point
.Y();
181 class SAL_WARN_UNUSED Size final
: protected Pair
185 Size( long nWidth
, long nHeight
) : Pair( nWidth
, nHeight
) {}
187 long Width() const { return nA
; }
188 long Height() const { return nB
; }
190 long AdjustWidth( long n
) { nA
+= n
; return nA
; }
191 long AdjustHeight( long n
) { nB
+= n
; return nB
; }
193 long getWidth() const { return Width(); }
194 long getHeight() const { return Height(); }
195 void setWidth(long nWidth
) { nA
= nWidth
; }
196 void setHeight(long nHeight
) { nB
= nHeight
; }
198 void extendBy(long x
, long y
)
204 Pair
const & toPair() const { return *this; }
205 Pair
& toPair() { return *this; }
207 using Pair::toString
;
210 inline bool operator ==(Size
const & s1
, Size
const & s2
)
212 return tools::detail::equal(s1
.toPair(), s2
.toPair());
215 inline bool operator !=(Size
const & s1
, Size
const & s2
)
220 template< typename charT
, typename traits
>
221 inline std::basic_ostream
<charT
, traits
> & operator <<(
222 std::basic_ostream
<charT
, traits
> & stream
, const Size
& size
)
224 return stream
<< size
.Width() << 'x' << size
.Height();
227 inline void Point::Move( Size
const & s
)
235 #define RANGE_MAX LONG_MAX
237 class SAL_WARN_UNUSED Range final
: protected Pair
241 Range( long nMin
, long nMax
) : Pair( nMin
, nMax
) {}
243 long Min() const { return nA
; }
244 long Max() const { return nB
; }
245 long Len() const { return nB
- nA
+ 1; }
247 long& Min() { return nA
; }
248 long& Max() { return nB
; }
250 bool IsInside( long nIs
) const;
254 Pair
const & toPair() const { return *this; }
255 Pair
& toPair() { return *this; }
257 using Pair::toString
;
260 inline bool Range::IsInside( long nIs
) const
262 return ((nA
<= nIs
) && (nIs
<= nB
));
265 inline void Range::Justify()
275 inline bool operator ==(Range
const & r1
, Range
const & r2
)
277 return tools::detail::equal(r1
.toPair(), r2
.toPair());
280 inline bool operator !=(Range
const & r1
, Range
const & r2
)
285 template< typename charT
, typename traits
>
286 inline std::basic_ostream
<charT
, traits
> & operator <<(
287 std::basic_ostream
<charT
, traits
> & stream
, const Range
& range
)
289 return stream
<< range
.Min() << '-' << range
.Max();
294 #define SELECTION_MIN LONG_MIN
295 #define SELECTION_MAX LONG_MAX
297 class SAL_WARN_UNUSED Selection final
: protected Pair
301 Selection( long nPos
) : Pair( nPos
, nPos
) {}
302 Selection( long nMin
, long nMax
) : Pair( nMin
, nMax
) {}
304 long Min() const { return nA
; }
305 long Max() const { return nB
; }
306 long Len() const { return nB
- nA
; }
308 long& Min() { return nA
; }
309 long& Max() { return nB
; }
311 bool IsInside( long nIs
) const;
315 bool operator !() const { return !Len(); }
317 long getMin() const { return Min(); }
318 void setMin(long nMin
) { Min() = nMin
; }
319 void setMax(long nMax
) { Max() = nMax
; }
321 Pair
const & toPair() const { return *this; }
322 Pair
& toPair() { return *this; }
324 using Pair::toString
;
327 inline bool Selection::IsInside( long nIs
) const
329 return ((nA
<= nIs
) && (nIs
< nB
));
332 inline void Selection::Justify()
342 inline bool operator ==(Selection
const & s1
, Selection
const & s2
)
344 return tools::detail::equal(s1
.toPair(), s2
.toPair());
347 inline bool operator !=(Selection
const & s1
, Selection
const & s2
)
352 template< typename charT
, typename traits
>
353 inline std::basic_ostream
<charT
, traits
> & operator <<(
354 std::basic_ostream
<charT
, traits
> & stream
, const Selection
& selection
)
356 return stream
<< selection
.Min() << '-' << selection
.Max();
360 #define RECT_MAX LONG_MAX
361 #define RECT_MIN LONG_MIN
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!
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.
374 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle final
376 static constexpr short RECT_EMPTY
= -32767;
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
);
386 long Left() const { return nLeft
; }
388 long Top() const { return nTop
; }
391 void SetLeft(long v
) { nLeft
= v
; }
392 void SetRight(long v
) { nRight
= v
; }
393 void SetTop(long v
) { nTop
= v
; }
394 void SetBottom(long v
) { nBottom
= v
; }
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;
406 /// Move the top and left edges by a delta, preserving width and height
407 inline void Move( long nHorzMoveDelta
, long nVertMoveDelta
);
408 void Move( Size
const & s
) { Move(s
.Width(), s
.Height()); }
409 long AdjustLeft( long nHorzMoveDelta
) { nLeft
+= nHorzMoveDelta
; return nLeft
; }
410 long AdjustRight( long nHorzMoveDelta
);
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;
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;
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;
429 bool IsInside( const Point
& rPOINT
) const;
430 bool IsInside( const tools::Rectangle
& rRect
) const;
431 bool IsOver( const tools::Rectangle
& rRect
) const;
433 void SetEmpty() { nRight
= nBottom
= RECT_EMPTY
; }
434 void SetWidthEmpty() { nRight
= RECT_EMPTY
; }
435 void SetHeightEmpty() { nBottom
= RECT_EMPTY
; }
436 inline bool IsEmpty() const;
437 bool IsWidthEmpty() const { return nRight
== RECT_EMPTY
; }
438 bool IsHeightEmpty() const { return nBottom
== RECT_EMPTY
; }
440 inline bool operator == ( const tools::Rectangle
& rRect
) const;
441 inline bool operator != ( const tools::Rectangle
& rRect
) const;
443 inline tools::Rectangle
& operator += ( const Point
& rPt
);
444 inline tools::Rectangle
& operator -= ( const Point
& rPt
);
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
);
450 long getX() const { return nLeft
; }
451 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
458 /// Set the top edge of the rectangle to y, preserving the height
460 void setWidth( long n
) { nRight
= nLeft
+ 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;
466 * Expands the rectangle in all directions by the input value.
468 void expand(long nExpandBy
);
469 void shrink(long nShrinkBy
);
472 * Sanitizing variants for handling data from the outside
474 void SaturatingSetSize(const Size
& rSize
);
475 void SaturatingSetX(long x
);
476 void SaturatingSetY(long y
);
486 inline tools::Rectangle::Rectangle()
489 nRight
= nBottom
= RECT_EMPTY
;
492 inline tools::Rectangle::Rectangle( const Point
& rLT
, const Point
& rRB
)
500 inline tools::Rectangle::Rectangle( long _nLeft
, long _nTop
,
501 long _nRight
, long _nBottom
)
509 inline tools::Rectangle::Rectangle( long _nLeft
, long _nTop
)
513 nRight
= nBottom
= RECT_EMPTY
;
516 inline tools::Rectangle::Rectangle( const Point
& rLT
, const Size
& rSize
)
520 nRight
= rSize
.Width() ? nLeft
+(rSize
.Width()-1) : RECT_EMPTY
;
521 nBottom
= rSize
.Height() ? nTop
+(rSize
.Height()-1) : RECT_EMPTY
;
524 inline bool tools::Rectangle::IsEmpty() const
526 return (nRight
== RECT_EMPTY
) || (nBottom
== RECT_EMPTY
);
529 inline Point
tools::Rectangle::TopLeft() const
531 return Point( nLeft
, nTop
);
534 inline Point
tools::Rectangle::TopRight() const
536 return Point( (nRight
== RECT_EMPTY
) ? nLeft
: nRight
, nTop
);
539 inline Point
tools::Rectangle::BottomLeft() const
541 return Point( nLeft
, (nBottom
== RECT_EMPTY
) ? nTop
: nBottom
);
544 inline Point
tools::Rectangle::BottomRight() const
546 return Point( (nRight
== RECT_EMPTY
) ? nLeft
: nRight
,
547 (nBottom
== RECT_EMPTY
) ? nTop
: nBottom
);
550 inline Point
tools::Rectangle::TopCenter() const
553 return Point( nLeft
, nTop
);
555 return Point( std::min( nLeft
, nRight
) + std::abs( (nRight
- nLeft
)/2 ),
556 std::min( nTop
, nBottom
) );
559 inline Point
tools::Rectangle::BottomCenter() const
562 return Point( nLeft
, nTop
);
564 return Point( std::min( nLeft
, nRight
) + std::abs( (nRight
- nLeft
)/2 ),
565 std::max( nTop
, nBottom
) );
568 inline Point
tools::Rectangle::LeftCenter() const
571 return Point( nLeft
, nTop
);
573 return Point( std::min( nLeft
, nRight
), nTop
+ (nBottom
- nTop
)/2 );
576 inline Point
tools::Rectangle::RightCenter() const
579 return Point( nLeft
, nTop
);
581 return Point( std::max( nLeft
, nRight
), nTop
+ (nBottom
- nTop
)/2 );
584 inline Point
tools::Rectangle::Center() const
587 return Point( nLeft
, nTop
);
589 return Point( nLeft
+(nRight
-nLeft
)/2 , nTop
+(nBottom
-nTop
)/2 );
592 inline void tools::Rectangle::Move( long nHorzMove
, long nVertMove
)
596 if ( nRight
!= RECT_EMPTY
)
598 if ( nBottom
!= RECT_EMPTY
)
599 nBottom
+= nVertMove
;
602 inline void tools::Rectangle::SetPos( const Point
& rPoint
)
604 if ( nRight
!= RECT_EMPTY
)
605 nRight
+= rPoint
.X() - nLeft
;
606 if ( nBottom
!= RECT_EMPTY
)
607 nBottom
+= rPoint
.Y() - nTop
;
612 inline long tools::Rectangle::GetWidth() const
615 if ( nRight
== RECT_EMPTY
)
629 inline long tools::Rectangle::GetHeight() const
632 if ( nBottom
== RECT_EMPTY
)
646 inline Size
tools::Rectangle::GetSize() const
648 return Size( GetWidth(), GetHeight() );
651 inline tools::Rectangle
tools::Rectangle::GetUnion( const tools::Rectangle
& rRect
) const
653 tools::Rectangle
aTmpRect( *this );
654 return aTmpRect
.Union( rRect
);
657 inline tools::Rectangle
tools::Rectangle::GetIntersection( const tools::Rectangle
& rRect
) const
659 tools::Rectangle
aTmpRect( *this );
660 return aTmpRect
.Intersection( rRect
);
663 inline bool tools::Rectangle::operator == ( const tools::Rectangle
& rRect
) const
665 return (nLeft
== rRect
.nLeft
) &&
666 (nTop
== rRect
.nTop
) &&
667 (nRight
== rRect
.nRight
) &&
668 (nBottom
== rRect
.nBottom
);
671 inline bool tools::Rectangle::operator != ( const tools::Rectangle
& rRect
) const
673 return (nLeft
!= rRect
.nLeft
) ||
674 (nTop
!= rRect
.nTop
) ||
675 (nRight
!= rRect
.nRight
) ||
676 (nBottom
!= rRect
.nBottom
);
679 inline tools::Rectangle
& tools::Rectangle::operator +=( const Point
& rPt
)
683 if ( nRight
!= RECT_EMPTY
)
685 if ( nBottom
!= RECT_EMPTY
)
690 inline tools::Rectangle
& tools::Rectangle::operator -= ( const Point
& rPt
)
694 if ( nRight
!= RECT_EMPTY
)
696 if ( nBottom
!= RECT_EMPTY
)
703 inline Rectangle
operator + ( const Rectangle
& rRect
, const Point
& rPt
)
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() );
711 inline Rectangle
operator - ( const Rectangle
& rRect
, const Point
& rPt
)
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() );
720 template< typename charT
, typename traits
>
721 inline std::basic_ostream
<charT
, traits
> & operator <<(
722 std::basic_ostream
<charT
, traits
> & stream
, const tools::Rectangle
& rectangle
)
724 if (rectangle
.IsEmpty())
725 return stream
<< "EMPTY";
727 return stream
<< rectangle
.getWidth() << 'x' << rectangle
.getHeight()
728 << "@(" << rectangle
.getX() << ',' << rectangle
.getY() << ")";
733 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */