android: Update app-specific/MIME type icons
[LibreOffice.git] / include / tools / gen.hxx
blob11d26b0372f2fbd2cbbd562e341a54feb3b05e09
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 .
20 #pragma once
22 #include <tools/toolsdllapi.h>
24 #include <tools/long.hxx>
25 #include <tools/degree.hxx>
26 #include <limits.h>
27 #include <algorithm>
28 #include <ostream>
29 #include <config_options.h>
30 #include <o3tl/unit_conversion.hxx>
32 class SvStream;
33 namespace rtl
35 class OString;
38 enum TriState { TRISTATE_FALSE, TRISTATE_TRUE, TRISTATE_INDET };
40 // Pair
42 class SAL_WARN_UNUSED Pair
44 public:
45 constexpr Pair() : mnA(0), mnB(0) {}
46 constexpr Pair( tools::Long nA, tools::Long nB ) : mnA(nA), mnB(nB) {}
48 tools::Long A() const { return mnA; }
49 tools::Long B() const { return mnB; }
51 tools::Long& A() { return mnA; }
52 tools::Long& B() { return mnB; }
54 TOOLS_DLLPUBLIC rtl::OString toString() const;
56 // Compute value usable as hash.
57 TOOLS_DLLPUBLIC size_t GetHashValue() const;
59 protected:
60 tools::Long mnA;
61 tools::Long mnB;
64 namespace tools::detail {
66 // Used to implement operator == for subclasses of Pair:
67 inline bool equal(Pair const & p1, Pair const & p2)
69 return p1.A() == p2.A() && p1.B() == p2.B();
74 // Point
76 class Size;
77 class SAL_WARN_UNUSED UNLESS_MERGELIBS(SAL_DLLPUBLIC_EXPORT) Point final : protected Pair
79 public:
80 constexpr Point() {}
81 constexpr Point( tools::Long nX, tools::Long nY ) : Pair( nX, nY ) {}
83 constexpr tools::Long X() const { return mnA; }
84 constexpr tools::Long Y() const { return mnB; }
86 void Move( tools::Long nHorzMove, tools::Long nVertMove );
87 void Move( Size const & s );
88 tools::Long AdjustX( tools::Long nHorzMove ) { mnA += nHorzMove; return mnA; }
89 tools::Long AdjustY( tools::Long nVertMove ) { mnB += nVertMove; return mnB; }
91 void RotateAround( tools::Long& rX, tools::Long& rY, Degree10 nOrientation ) const;
92 void RotateAround( Point&, Degree10 nOrientation ) const;
94 Point& operator += ( const Point& rPoint );
95 Point& operator -= ( const Point& rPoint );
96 Point& operator *= ( const tools::Long nVal );
97 Point& operator /= ( const tools::Long nVal );
99 friend inline Point operator+( const Point &rVal1, const Point &rVal2 );
100 friend inline Point operator-( const Point &rVal1, const Point &rVal2 );
101 friend inline Point operator*( const Point &rVal1, const tools::Long nVal2 );
102 friend inline Point operator/( const Point &rVal1, const tools::Long nVal2 );
104 constexpr tools::Long getX() const { return X(); }
105 constexpr tools::Long getY() const { return Y(); }
106 void setX(tools::Long nX) { mnA = nX; }
107 void setY(tools::Long nY) { mnB = nY; }
109 Pair const & toPair() const { return *this; }
110 Pair & toPair() { return *this; }
112 // Scales relative to 0,0
113 constexpr inline Point scale(sal_Int64 nMulX, sal_Int64 nDivX,
114 sal_Int64 nMulY, sal_Int64 nDivY) const;
116 using Pair::toString;
117 using Pair::GetHashValue;
120 inline void Point::Move( tools::Long nHorzMove, tools::Long nVertMove )
122 mnA += nHorzMove;
123 mnB += nVertMove;
126 inline Point& Point::operator += ( const Point& rPoint )
128 mnA += rPoint.mnA;
129 mnB += rPoint.mnB;
130 return *this;
133 inline Point& Point::operator -= ( const Point& rPoint )
135 mnA -= rPoint.mnA;
136 mnB -= rPoint.mnB;
137 return *this;
140 inline Point& Point::operator *= ( const tools::Long nVal )
142 mnA *= nVal;
143 mnB *= nVal;
144 return *this;
147 inline Point& Point::operator /= ( const tools::Long nVal )
149 mnA /= nVal;
150 mnB /= nVal;
151 return *this;
154 inline Point operator+( const Point &rVal1, const Point &rVal2 )
156 return Point( rVal1.mnA+rVal2.mnA, rVal1.mnB+rVal2.mnB );
159 inline Point operator-( const Point &rVal1, const Point &rVal2 )
161 return Point( rVal1.mnA-rVal2.mnA, rVal1.mnB-rVal2.mnB );
164 inline Point operator*( const Point &rVal1, const tools::Long nVal2 )
166 return Point( rVal1.mnA*nVal2, rVal1.mnB*nVal2 );
169 inline Point operator/( const Point &rVal1, const tools::Long nVal2 )
171 return Point( rVal1.mnA/nVal2, rVal1.mnB/nVal2 );
174 inline bool operator ==(Point const & p1, Point const & p2)
176 return tools::detail::equal(p1.toPair(), p2.toPair());
179 inline bool operator !=(Point const & p1, Point const & p2)
181 return !(p1 == p2);
184 constexpr inline Point Point::scale(sal_Int64 nMulX, sal_Int64 nDivX, sal_Int64 nMulY, sal_Int64 nDivY) const
186 return Point(o3tl::convert(getX(), nMulX, nDivX),
187 o3tl::convert(getY(), nMulY, nDivY));
190 namespace o3tl
193 constexpr Point convert(const Point& rPoint, o3tl::Length eFrom, o3tl::Length eTo)
195 const auto [num, den] = o3tl::getConversionMulDiv(eFrom, eTo);
196 return rPoint.scale(num, den, num, den);
199 } // end o3tl
201 template< typename charT, typename traits >
202 inline std::basic_ostream<charT, traits> & operator <<(
203 std::basic_ostream<charT, traits> & stream, const Point& point )
205 return stream << point.X() << ',' << point.Y();
208 // Size
210 class SAL_WARN_UNUSED Size final : protected Pair
212 public:
213 constexpr Size() {}
214 constexpr Size( tools::Long nWidth, tools::Long nHeight ) : Pair( nWidth, nHeight ) {}
216 constexpr tools::Long Width() const { return mnA; }
217 constexpr tools::Long Height() const { return mnB; }
219 tools::Long AdjustWidth( tools::Long n ) { mnA += n; return mnA; }
220 tools::Long AdjustHeight( tools::Long n ) { mnB += n; return mnB; }
222 constexpr tools::Long getWidth() const { return Width(); }
223 constexpr tools::Long getHeight() const { return Height(); }
224 void setWidth(tools::Long nWidth) { mnA = nWidth; }
225 void setHeight(tools::Long nHeight) { mnB = nHeight; }
227 bool IsEmpty() const { return mnA <= 0 || mnB <= 0; }
229 void extendBy(tools::Long x, tools::Long y)
231 mnA += x;
232 mnB += y;
235 Pair const & toPair() const { return *this; }
236 Pair & toPair() { return *this; }
238 using Pair::toString;
239 using Pair::GetHashValue;
241 Size& operator += ( const Size& rSize );
242 Size& operator -= ( const Size& rSize );
243 Size& operator *= ( const tools::Long nVal );
244 Size& operator /= ( const tools::Long nVal );
246 friend inline Size operator+( const Size &rVal1, const Size &rVal2 );
247 friend inline Size operator-( const Size &rVal1, const Size &rVal2 );
248 friend inline Size operator*( const Size &rVal1, const tools::Long nVal2 );
249 friend inline Size operator/( const Size &rVal1, const tools::Long nVal2 );
251 constexpr inline Size scale(sal_Int64 nMulX, sal_Int64 nDivX,
252 sal_Int64 nMulY, sal_Int64 nDivY) const;
256 inline bool operator ==(Size const & s1, Size const & s2)
258 return tools::detail::equal(s1.toPair(), s2.toPair());
261 inline bool operator !=(Size const & s1, Size const & s2)
263 return !(s1 == s2);
266 inline Size& Size::operator += ( const Size& rSize )
268 mnA += rSize.mnA;
269 mnB += rSize.mnB;
270 return *this;
273 inline Size& Size::operator -= ( const Size& rSize )
275 mnA -= rSize.mnA;
276 mnB -= rSize.mnB;
277 return *this;
280 inline Size& Size::operator *= ( const tools::Long nVal )
282 mnA *= nVal;
283 mnB *= nVal;
284 return *this;
287 inline Size& Size::operator /= ( const tools::Long nVal )
289 mnA /= nVal;
290 mnB /= nVal;
291 return *this;
294 inline Size operator+( const Size &rVal1, const Size &rVal2 )
296 return Size( rVal1.mnA+rVal2.mnA, rVal1.mnB+rVal2.mnB );
299 inline Size operator-( const Size &rVal1, const Size &rVal2 )
301 return Size( rVal1.mnA-rVal2.mnA, rVal1.mnB-rVal2.mnB );
304 inline Size operator*( const Size &rVal1, const tools::Long nVal2 )
306 return Size( rVal1.mnA*nVal2, rVal1.mnB*nVal2 );
309 inline Size operator/( const Size &rVal1, const tools::Long nVal2 )
311 return Size( rVal1.mnA/nVal2, rVal1.mnB/nVal2 );
314 constexpr inline Size Size::scale(sal_Int64 nMulX, sal_Int64 nDivX,
315 sal_Int64 nMulY, sal_Int64 nDivY) const
317 return Size(o3tl::convert(Width(), nMulX, nDivX),
318 o3tl::convert(Height(), nMulY, nDivY));
321 namespace o3tl
324 constexpr Size convert(const Size& rSize, o3tl::Length eFrom, o3tl::Length eTo)
326 const auto [num, den] = o3tl::getConversionMulDiv(eFrom, eTo);
327 return rSize.scale(num, den, num, den);
330 } // end o3tl
332 template< typename charT, typename traits >
333 inline std::basic_ostream<charT, traits> & operator <<(
334 std::basic_ostream<charT, traits> & stream, const Size& size )
336 return stream << size.Width() << 'x' << size.Height();
339 inline void Point::Move( Size const & s )
341 AdjustX(s.Width());
342 AdjustY(s.Height());
345 // Range
347 #define RANGE_MAX LONG_MAX
349 class SAL_WARN_UNUSED Range final : protected Pair
351 public:
352 constexpr Range() {}
353 constexpr Range( tools::Long nMin, tools::Long nMax ) : Pair( nMin, nMax ) {}
355 tools::Long Min() const { return mnA; }
356 tools::Long Max() const { return mnB; }
357 tools::Long Len() const { return mnB - mnA + 1; }
359 tools::Long& Min() { return mnA; }
360 tools::Long& Max() { return mnB; }
362 bool Contains( tools::Long nIs ) const;
364 void Normalize();
366 Pair const & toPair() const { return *this; }
367 Pair & toPair() { return *this; }
369 using Pair::toString;
372 inline bool Range::Contains( tools::Long nIs ) const
374 return ((mnA <= nIs) && (nIs <= mnB ));
377 inline void Range::Normalize()
379 if ( mnA > mnB )
380 std::swap(mnA, mnB);
383 inline bool operator ==(Range const & r1, Range const & r2)
385 return tools::detail::equal(r1.toPair(), r2.toPair());
388 inline bool operator !=(Range const & r1, Range const & r2)
390 return !(r1 == r2);
393 template< typename charT, typename traits >
394 inline std::basic_ostream<charT, traits> & operator <<(
395 std::basic_ostream<charT, traits> & stream, const Range& range )
397 return stream << range.Min() << '-' << range.Max();
400 // Selection
402 #define SELECTION_MIN LONG_MIN
403 #define SELECTION_MAX LONG_MAX
405 class SAL_WARN_UNUSED Selection final : protected Pair
407 public:
408 Selection() {}
409 Selection( tools::Long nPos ) : Pair( nPos, nPos ) {}
410 Selection( tools::Long nMin, tools::Long nMax ) : Pair( nMin, nMax ) {}
412 tools::Long Min() const { return mnA; }
413 tools::Long Max() const { return mnB; }
414 tools::Long Len() const { return mnB - mnA; }
416 tools::Long& Min() { return mnA; }
417 tools::Long& Max() { return mnB; }
419 bool Contains( tools::Long nIs ) const;
421 void Normalize();
423 bool operator !() const { return !Len(); }
425 tools::Long getMin() const { return Min(); }
426 void setMin(tools::Long nMin) { Min() = nMin; }
427 void setMax(tools::Long nMax) { Max() = nMax; }
429 Pair const & toPair() const { return *this; }
430 Pair & toPair() { return *this; }
432 using Pair::toString;
435 inline bool Selection::Contains( tools::Long nIs ) const
437 return ((mnA <= nIs) && (nIs < mnB ));
440 inline void Selection::Normalize()
442 if ( mnA > mnB )
443 std::swap(mnA, mnB);
446 inline bool operator ==(Selection const & s1, Selection const & s2)
448 return tools::detail::equal(s1.toPair(), s2.toPair());
451 inline bool operator !=(Selection const & s1, Selection const & s2)
453 return !(s1 == s2);
456 template< typename charT, typename traits >
457 inline std::basic_ostream<charT, traits> & operator <<(
458 std::basic_ostream<charT, traits> & stream, const Selection& selection )
460 return stream << selection.Min() << '-' << selection.Max();
462 // Rectangle
464 #define RECT_MAX LONG_MAX
465 #define RECT_MIN LONG_MIN
467 /// Note: this class is a true marvel of engineering: because the author
468 /// could not decide whether it's better to have a closed or half-open
469 /// interval, they just implemented *both* in the same class!
471 /// If you have the misfortune of having to use this class, don't immediately
472 /// despair but first take note that the uppercase GetWidth() / GetHeight()
473 /// etc. methods interpret the interval as closed. To use the half open versions,
474 /// use GetOpenWidth() / GetOpenHeight().
476 /// If you want to work with Size, you must use the closed interval functions!
477 /// And don't add GetOpenSize() / setSize; this will probably just introduce
478 /// bugs, especially when used in combination with list-initialization.
480 /// (Eventually you might notice, that the same engineer was also working on
481 /// Qt at some point; see documentation on QRect::bottom / QRect::right ;-).
482 namespace tools
484 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle final
486 static constexpr short RECT_EMPTY = -32767;
487 public:
488 constexpr Rectangle() = default;
489 constexpr Rectangle( const Point& rLT, const Point& rRB );
490 constexpr Rectangle( tools::Long mnLeft, tools::Long mnTop,
491 tools::Long mnRight, tools::Long mnBottom );
492 /// Constructs an empty Rectangle, with top/left at the specified params
493 constexpr Rectangle( tools::Long mnLeft, tools::Long mnTop );
494 /// Constructs a closed interval rectangle
495 constexpr Rectangle( const Point& rLT, const Size& rSize );
497 constexpr inline static Rectangle Normalize(const Point& rLT, const Point& rRB);
499 constexpr tools::Long Left() const { return mnLeft; }
500 constexpr tools::Long Right() const { return IsWidthEmpty() ? mnLeft : mnRight; }
501 constexpr tools::Long Top() const { return mnTop; }
502 constexpr tools::Long Bottom() const { return IsHeightEmpty() ? mnTop : mnBottom; }
504 constexpr void SetLeft(tools::Long v) { mnLeft = v; }
505 constexpr void SetRight(tools::Long v) { mnRight = v; }
506 constexpr void SetTop(tools::Long v) { mnTop = v; }
507 constexpr void SetBottom(tools::Long v) { mnBottom = v; }
509 constexpr Point TopLeft() const { return { Left(), Top() }; }
510 constexpr Point TopRight() const { return { Right(), Top() }; }
511 constexpr Point TopCenter() const { return { (Left() + Right()) / 2, Top() }; }
512 constexpr Point BottomLeft() const { return { Left(), Bottom() }; }
513 constexpr Point BottomRight() const { return { Right(), Bottom() }; }
514 constexpr Point BottomCenter() const { return { (Left() + Right()) / 2, Bottom() }; }
515 constexpr Point LeftCenter() const { return { Left(), (Top() + Bottom()) / 2 }; }
516 constexpr Point RightCenter() const { return { Right(), (Top() + Bottom()) / 2 }; }
517 constexpr Point Center() const { return { (Left() + Right()) / 2, (Top() + Bottom()) / 2 }; }
519 /// Move the top and left edges by a delta, preserving width and height
520 inline void Move( tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta );
521 void Move( Size const & s ) { Move(s.Width(), s.Height()); }
522 tools::Long AdjustLeft( tools::Long nHorzMoveDelta ) { mnLeft += nHorzMoveDelta; return mnLeft; }
523 tools::Long AdjustRight( tools::Long nHorzMoveDelta );
524 tools::Long AdjustTop( tools::Long nVertMoveDelta ) { mnTop += nVertMoveDelta; return mnTop; }
525 tools::Long AdjustBottom( tools::Long nVertMoveDelta );
526 /// Set the left edge of the rectangle to x, preserving the width
527 inline void SetPosX(tools::Long x);
528 /// Set the top edge of the rectangle to y, preserving the height
529 inline void SetPosY(tools::Long y);
530 inline void SetPos( const Point& rPoint );
531 inline void SetWidth(tools::Long);
532 inline void SetHeight(tools::Long);
533 inline void SetSize(const Size&);
535 constexpr Point GetPos() const { return TopLeft(); }
536 constexpr Size GetSize() const { return { GetWidth(), GetHeight() }; }
538 /// Returns the difference between right and left, assuming the range is inclusive.
539 constexpr inline tools::Long GetWidth() const;
540 /// Returns the difference between bottom and top, assuming the range is inclusive.
541 constexpr inline tools::Long GetHeight() const;
543 tools::Rectangle& Union( const tools::Rectangle& rRect );
544 tools::Rectangle& Intersection( const tools::Rectangle& rRect );
545 inline tools::Rectangle GetUnion( const tools::Rectangle& rRect ) const;
546 inline tools::Rectangle GetIntersection( const tools::Rectangle& rRect ) const;
548 void Normalize();
550 bool Contains( const Point& rPOINT ) const;
551 bool Contains( const tools::Rectangle& rRect ) const;
552 bool Overlaps( const tools::Rectangle& rRect ) const;
554 void SetEmpty() { mnRight = mnBottom = RECT_EMPTY; }
555 void SetWidthEmpty() { mnRight = RECT_EMPTY; }
556 void SetHeightEmpty() { mnBottom = RECT_EMPTY; }
557 constexpr bool IsEmpty() const { return IsWidthEmpty() || IsHeightEmpty(); }
558 constexpr bool IsWidthEmpty() const { return mnRight == RECT_EMPTY; }
559 constexpr bool IsHeightEmpty() const { return mnBottom == RECT_EMPTY; }
561 inline bool operator == ( const tools::Rectangle& rRect ) const;
562 inline bool operator != ( const tools::Rectangle& rRect ) const;
564 inline tools::Rectangle& operator += ( const Point& rPt );
565 inline tools::Rectangle& operator -= ( const Point& rPt );
567 friend inline tools::Rectangle operator + ( const tools::Rectangle& rRect, const Point& rPt );
568 friend inline tools::Rectangle operator - ( const tools::Rectangle& rRect, const Point& rPt );
570 tools::Long getX() const { return mnLeft; }
571 tools::Long getY() const { return mnTop; }
572 /// Returns the difference between right and left, assuming the range includes one end, but not the other.
573 tools::Long getOpenWidth() const { return Right() - Left(); }
574 /// Returns the difference between bottom and top, assuming the range includes one end, but not the other.
575 tools::Long getOpenHeight() const { return Bottom() - Top(); }
576 void setWidth( tools::Long n ) { mnRight = mnLeft + n; }
577 void setHeight( tools::Long n ) { mnBottom = mnTop + n; }
578 /// Returns the string representation of the rectangle, format is "x, y, width, height".
579 rtl::OString toString() const;
582 * Expands the rectangle in all directions by the input value.
584 void expand(tools::Long nExpandBy);
585 void shrink(tools::Long nShrinkBy);
588 * Sanitizing variants for handling data from the outside
590 void SaturatingSetSize(const Size& rSize);
591 void SaturatingSetPosX(tools::Long x);
592 void SaturatingSetPosY(tools::Long y);
594 // Scales relative to 0,0
595 constexpr inline tools::Rectangle scale(sal_Int64 nMulX, sal_Int64 nDivX,
596 sal_Int64 nMulY, sal_Int64 nDivY) const;
598 private:
599 tools::Long mnLeft = 0;
600 tools::Long mnTop = 0;
601 tools::Long mnRight = RECT_EMPTY;
602 tools::Long mnBottom = RECT_EMPTY;
606 constexpr inline tools::Rectangle::Rectangle( const Point& rLT, const Point& rRB )
607 : Rectangle(rLT.X(), rLT.Y(), rRB.X(), rRB.Y())
610 constexpr inline tools::Rectangle::Rectangle( tools::Long nLeft, tools::Long nTop,
611 tools::Long nRight, tools::Long nBottom )
612 : mnLeft( nLeft )
613 , mnTop( nTop )
614 , mnRight( nRight )
615 , mnBottom( nBottom )
618 constexpr inline tools::Rectangle::Rectangle( tools::Long nLeft, tools::Long nTop )
619 : mnLeft(nLeft)
620 , mnTop(nTop)
623 constexpr inline tools::Rectangle::Rectangle( const Point& rLT, const Size& rSize )
624 : mnLeft( rLT.X())
625 , mnTop( rLT.Y())
626 , mnRight(rSize.Width() ? mnLeft + (rSize.Width() + (rSize.Width() > 0 ? -1 : 1)) : RECT_EMPTY)
627 , mnBottom(rSize.Height() ? mnTop + (rSize.Height() + (rSize.Height() > 0 ? -1 : 1)) : RECT_EMPTY)
630 constexpr inline tools::Rectangle tools::Rectangle::Normalize(const Point& rLT, const Point& rRB)
632 const std::pair<tools::Long, tools::Long> aLeftRight = std::minmax(rLT.X(), rRB.X());
633 const std::pair<tools::Long, tools::Long> aTopBottom = std::minmax(rLT.Y(), rRB.Y());
634 return { aLeftRight.first, aTopBottom.first, aLeftRight.second, aTopBottom.second };
637 inline void tools::Rectangle::Move( tools::Long nHorzMove, tools::Long nVertMove )
639 mnLeft += nHorzMove;
640 mnTop += nVertMove;
641 if (!IsWidthEmpty())
642 mnRight += nHorzMove;
643 if (!IsHeightEmpty())
644 mnBottom += nVertMove;
647 inline void tools::Rectangle::SetPosX(tools::Long x)
649 if (!IsWidthEmpty())
650 mnRight += x - mnLeft;
651 mnLeft = x;
654 inline void tools::Rectangle::SetPosY(tools::Long y)
656 if (!IsHeightEmpty())
657 mnBottom += y - mnTop;
658 mnTop = y;
661 inline void tools::Rectangle::SetPos( const Point& rPoint )
663 SetPosX(rPoint.X());
664 SetPosY(rPoint.Y());
667 inline void tools::Rectangle::SetWidth(tools::Long nWidth)
669 if (nWidth < 0)
670 mnRight = mnLeft + nWidth + 1;
671 else if (nWidth > 0)
672 mnRight = mnLeft + nWidth - 1;
673 else
674 SetWidthEmpty();
677 inline void tools::Rectangle::SetHeight(tools::Long nHeight)
679 if (nHeight < 0)
680 mnBottom = mnTop + nHeight + 1;
681 else if (nHeight > 0)
682 mnBottom = mnTop + nHeight - 1;
683 else
684 SetHeightEmpty();
687 inline void tools::Rectangle::SetSize(const Size& rSize)
689 SetWidth(rSize.Width());
690 SetHeight(rSize.Height());
693 constexpr inline tools::Long tools::Rectangle::GetWidth() const
695 tools::Long n = 0;
697 if (!IsWidthEmpty())
699 n = mnRight - mnLeft;
700 if (n < 0)
701 n--;
702 else
703 n++;
706 return n;
709 constexpr inline tools::Long tools::Rectangle::GetHeight() const
711 tools::Long n = 0;
713 if (!IsHeightEmpty())
715 n = mnBottom - mnTop;
716 if (n < 0)
717 n--;
718 else
719 n++;
722 return n;
725 inline tools::Rectangle tools::Rectangle::GetUnion( const tools::Rectangle& rRect ) const
727 tools::Rectangle aTmpRect( *this );
728 return aTmpRect.Union( rRect );
731 inline tools::Rectangle tools::Rectangle::GetIntersection( const tools::Rectangle& rRect ) const
733 tools::Rectangle aTmpRect( *this );
734 return aTmpRect.Intersection( rRect );
737 inline bool tools::Rectangle::operator == ( const tools::Rectangle& rRect ) const
739 return (mnLeft == rRect.mnLeft ) &&
740 (mnTop == rRect.mnTop ) &&
741 (mnRight == rRect.mnRight ) &&
742 (mnBottom == rRect.mnBottom );
745 inline bool tools::Rectangle::operator != ( const tools::Rectangle& rRect ) const
747 return (mnLeft != rRect.mnLeft ) ||
748 (mnTop != rRect.mnTop ) ||
749 (mnRight != rRect.mnRight ) ||
750 (mnBottom != rRect.mnBottom );
753 inline tools::Rectangle& tools::Rectangle::operator +=( const Point& rPt )
755 Move(rPt.X(), rPt.Y());
756 return *this;
759 inline tools::Rectangle& tools::Rectangle::operator -= ( const Point& rPt )
761 Move(-rPt.X(), -rPt.Y());
762 return *this;
765 namespace tools
767 inline Rectangle operator + ( const Rectangle& rRect, const Point& rPt )
769 return Rectangle{ rRect }.operator+=(rPt);
772 inline Rectangle operator - ( const Rectangle& rRect, const Point& rPt )
774 return Rectangle{ rRect }.operator-=(rPt);
779 constexpr inline tools::Rectangle tools::Rectangle::scale(sal_Int64 nMulX, sal_Int64 nDivX,
780 sal_Int64 nMulY, sal_Int64 nDivY) const
782 // 1. Create an empty rectangle with correct left and top
783 tools::Rectangle aRect(o3tl::convert(Left(), nMulX, nDivX),
784 o3tl::convert(Top(), nMulY, nDivY));
785 // 2. If source has width/height, set respective right and bottom
786 if (!IsWidthEmpty())
787 aRect.SetRight(o3tl::convert(Right(), nMulX, nDivX));
788 if (!IsHeightEmpty())
789 aRect.SetBottom(o3tl::convert(Bottom(), nMulY, nDivY));
790 return aRect;
793 namespace o3tl
796 constexpr tools::Rectangle convert(const tools::Rectangle& rRectangle, o3tl::Length eFrom, o3tl::Length eTo)
798 const auto [num, den] = o3tl::getConversionMulDiv(eFrom, eTo);
799 return rRectangle.scale(num, den, num, den);
802 } // end o3tl
804 namespace tools
806 template< typename charT, typename traits >
807 inline std::basic_ostream<charT, traits> & operator <<(
808 std::basic_ostream<charT, traits> & stream, const tools::Rectangle& rectangle )
810 if (rectangle.IsEmpty())
811 return stream << "EMPTY";
812 else
813 return stream << rectangle.GetWidth() << 'x' << rectangle.GetHeight()
814 << "@(" << rectangle.getX() << ',' << rectangle.getY() << ")";
818 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */