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;
51 TOOLS_DLLPUBLIC
friend SvStream
& ReadPair( SvStream
& rIStream
, Pair
& rPair
);
52 TOOLS_DLLPUBLIC
friend SvStream
& WritePair( SvStream
& rOStream
, const Pair
& rPair
);
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();
72 class SAL_WARN_UNUSED SAL_DLLPUBLIC_EXPORT Point final
: protected Pair
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
)
116 inline Point
& Point::operator += ( const Point
& rPoint
)
123 inline Point
& Point::operator -= ( const Point
& rPoint
)
130 inline Point
& Point::operator *= ( const long nVal
)
137 inline Point
& Point::operator /= ( const long nVal
)
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
)
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();
183 class SAL_WARN_UNUSED Size final
: protected Pair
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
)
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
)
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
)
237 #define RANGE_MAX LONG_MAX
239 class SAL_WARN_UNUSED Range final
: protected Pair
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;
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()
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
)
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();
296 #define SELECTION_MIN LONG_MIN
297 #define SELECTION_MAX LONG_MAX
299 class SAL_WARN_UNUSED Selection final
: protected Pair
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;
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()
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
)
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();
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.
376 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle final
378 static constexpr short RECT_EMPTY
= -32767;
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;
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
);
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
);
491 inline tools::Rectangle::Rectangle()
494 nRight
= nBottom
= RECT_EMPTY
;
497 inline tools::Rectangle::Rectangle( const Point
& rLT
, const Point
& rRB
)
505 inline tools::Rectangle::Rectangle( long _nLeft
, long _nTop
,
506 long _nRight
, long _nBottom
)
514 inline tools::Rectangle::Rectangle( long _nLeft
, long _nTop
)
518 nRight
= nBottom
= RECT_EMPTY
;
521 inline tools::Rectangle::Rectangle( const Point
& rLT
, const Size
& rSize
)
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
558 return Point( nLeft
, nTop
);
560 return Point( std::min( nLeft
, nRight
) + std::abs( (nRight
- nLeft
)/2 ),
561 std::min( nTop
, nBottom
) );
564 inline Point
tools::Rectangle::BottomCenter() const
567 return Point( nLeft
, nTop
);
569 return Point( std::min( nLeft
, nRight
) + std::abs( (nRight
- nLeft
)/2 ),
570 std::max( nTop
, nBottom
) );
573 inline Point
tools::Rectangle::LeftCenter() const
576 return Point( nLeft
, nTop
);
578 return Point( std::min( nLeft
, nRight
), nTop
+ (nBottom
- nTop
)/2 );
581 inline Point
tools::Rectangle::RightCenter() const
584 return Point( nLeft
, nTop
);
586 return Point( std::max( nLeft
, nRight
), nTop
+ (nBottom
- nTop
)/2 );
589 inline Point
tools::Rectangle::Center() const
592 return Point( nLeft
, nTop
);
594 return Point( nLeft
+(nRight
-nLeft
)/2 , nTop
+(nBottom
-nTop
)/2 );
597 inline void tools::Rectangle::Move( long nHorzMove
, long nVertMove
)
601 if ( nRight
!= RECT_EMPTY
)
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
;
617 inline long tools::Rectangle::GetWidth() const
620 if ( nRight
== RECT_EMPTY
)
634 inline long tools::Rectangle::GetHeight() const
637 if ( nBottom
== RECT_EMPTY
)
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
)
688 if ( nRight
!= RECT_EMPTY
)
690 if ( nBottom
!= RECT_EMPTY
)
695 inline tools::Rectangle
& tools::Rectangle::operator -= ( const Point
& rPt
)
699 if ( nRight
!= RECT_EMPTY
)
701 if ( nBottom
!= RECT_EMPTY
)
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
)
730 nBottom
+= nExpandBy
;
733 inline void tools::Rectangle::shrink(long 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";
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()); }
759 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */