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 .
22 #include <tools/toolsdllapi.h>
24 #include <tools/long.hxx>
25 #include <tools/degree.hxx>
29 #include <config_options.h>
30 #include <o3tl/unit_conversion.hxx>
38 enum TriState
{ TRISTATE_FALSE
, TRISTATE_TRUE
, TRISTATE_INDET
};
42 class SAL_WARN_UNUSED Pair
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;
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();
77 class SAL_WARN_UNUSED
UNLESS_MERGELIBS(SAL_DLLPUBLIC_EXPORT
) Point final
: protected Pair
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
)
126 inline Point
& Point::operator += ( const Point
& rPoint
)
133 inline Point
& Point::operator -= ( const Point
& rPoint
)
140 inline Point
& Point::operator *= ( const tools::Long nVal
)
147 inline Point
& Point::operator /= ( const tools::Long nVal
)
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
)
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
));
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
);
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();
210 class SAL_WARN_UNUSED Size final
: protected Pair
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
)
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
)
266 inline Size
& Size::operator += ( const Size
& rSize
)
273 inline Size
& Size::operator -= ( const Size
& rSize
)
280 inline Size
& Size::operator *= ( const tools::Long nVal
)
287 inline Size
& Size::operator /= ( const tools::Long nVal
)
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
));
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
);
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
)
347 #define RANGE_MAX LONG_MAX
349 class SAL_WARN_UNUSED Range final
: protected Pair
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;
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()
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
)
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();
402 #define SELECTION_MIN LONG_MIN
403 #define SELECTION_MAX LONG_MAX
405 class SAL_WARN_UNUSED Selection final
: protected Pair
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;
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()
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
)
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();
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 ;-).
484 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle final
486 static constexpr short RECT_EMPTY
= -32767;
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;
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;
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
)
615 , mnBottom( nBottom
)
618 constexpr inline tools::Rectangle::Rectangle( tools::Long nLeft
, tools::Long nTop
)
623 constexpr inline tools::Rectangle::Rectangle( const Point
& rLT
, const Size
& rSize
)
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
)
642 mnRight
+= nHorzMove
;
643 if (!IsHeightEmpty())
644 mnBottom
+= nVertMove
;
647 inline void tools::Rectangle::SetPosX(tools::Long x
)
650 mnRight
+= x
- mnLeft
;
654 inline void tools::Rectangle::SetPosY(tools::Long y
)
656 if (!IsHeightEmpty())
657 mnBottom
+= y
- mnTop
;
661 inline void tools::Rectangle::SetPos( const Point
& rPoint
)
667 inline void tools::Rectangle::SetWidth(tools::Long nWidth
)
670 mnRight
= mnLeft
+ nWidth
+ 1;
672 mnRight
= mnLeft
+ nWidth
- 1;
677 inline void tools::Rectangle::SetHeight(tools::Long nHeight
)
680 mnBottom
= mnTop
+ nHeight
+ 1;
681 else if (nHeight
> 0)
682 mnBottom
= mnTop
+ nHeight
- 1;
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
699 n
= mnRight
- mnLeft
;
709 constexpr inline tools::Long
tools::Rectangle::GetHeight() const
713 if (!IsHeightEmpty())
715 n
= mnBottom
- mnTop
;
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());
759 inline tools::Rectangle
& tools::Rectangle::operator -= ( const Point
& rPt
)
761 Move(-rPt
.X(), -rPt
.Y());
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
787 aRect
.SetRight(o3tl::convert(Right(), nMulX
, nDivX
));
788 if (!IsHeightEmpty())
789 aRect
.SetBottom(o3tl::convert(Bottom(), nMulY
, nDivY
));
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
);
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";
813 return stream
<< rectangle
.GetWidth() << 'x' << rectangle
.GetHeight()
814 << "@(" << rectangle
.getX() << ',' << rectangle
.getY() << ")";
818 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */