ScummVM API documentation
atltypes.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef BAGEL_MFC_ATLTYPES_H
23 #define BAGEL_MFC_ATLTYPES_H
24 
25 #include "bagel/mfc/minwindef.h"
26 
27 namespace Bagel {
28 namespace MFC {
29 
31 // Classes declared in this file
32 
33 class CSize;
34 class CPoint;
35 class CRect;
36 
38 // CSize - An extent, similar to Windows SIZE structure.
39 
40 class CSize : public tagSIZE {
41 public:
42 
43  // Constructors
44  // construct an uninitialized size
45  CSize();
46  // create from two integers
47  CSize(int initCX, int initCY);
48  // create from another size
49  CSize(SIZE initSize);
50  // create from a point
51  CSize(POINT initPt);
52  // create from a uint32: cx = LOWORD(dw) cy = HIWORD(dw)
53  CSize(uint32 dwSize);
54 
55  // Operations
56  bool operator==(SIZE size) const;
57  bool operator!=(SIZE size) const;
58  void operator+=(SIZE size);
59  void operator-=(SIZE size);
60  void SetSize(int CX, int CY);
61 
62  // Operators returning CSize values
63  CSize operator+(SIZE size) const;
64  CSize operator-(SIZE size) const;
65  CSize operator-() const;
66 
67  // Operators returning CPoint values
68  CPoint operator+(POINT point) const;
69  CPoint operator-(POINT point) const;
70 
71  // Operators returning CRect values
72  CRect operator+(const RECT *lpRect) const;
73  CRect operator-(const RECT *lpRect) const;
74 };
75 
77 // CPoint - A 2-D point, similar to Windows POINT structure.
78 
79 class CPoint : public tagPOINT {
80 public:
81  // Constructors
82 
83  // create an uninitialized point
84  CPoint();
85  // create from two integers
86  CPoint(
87  int initX,
88  int initY);
89  // create from another point
90  CPoint(POINT initPt);
91  // create from a size
92  CPoint(SIZE initSize);
93  // create from an LPARAM: x = LOWORD(dw) y = HIWORD(dw)
94  CPoint(LPARAM dwPoint);
95 
96 
97  // Operations
98 
99  // translate the point
100  void Offset(
101  int xOffset,
102  int yOffset);
103  void Offset(POINT point);
104  void Offset(SIZE size);
105  void SetPoint(int X, int Y);
106 
107  bool operator==(POINT point) const;
108  bool operator!=(POINT point) const;
109  void operator+=(SIZE size);
110  void operator-=(SIZE size);
111  void operator+=(POINT point);
112  void operator-=(POINT point);
113 
114  // Operators returning CPoint values
115  CPoint operator+(SIZE size) const;
116  CPoint operator-(SIZE size) const;
117  CPoint operator-() const;
118  CPoint operator+(POINT point) const;
119 
120  // Operators returning CSize values
121  CSize operator-(POINT point) const;
122 
123  // Operators returning CRect values
124  CRect operator+(const RECT *lpRect) const;
125  CRect operator-(const RECT *lpRect) const;
126 };
127 
129 // CRect - A 2-D rectangle, similar to Windows RECT structure.
130 
131 class CRect : public tagRECT {
132 public:
133  // uninitialized rectangle
134  CRect();
135  // from left, top, right, and bottom
136  CRect(
137  int l,
138  int t,
139  int r,
140  int b);
141  // copy constructor
142  CRect(const RECT &srcRect);
143 
144  // from a pointer to another rect
145  CRect(const LPCRECT lpSrcRect);
146  // from a point and size
147  CRect(const POINT &point, const SIZE &size);
148  // from two points
149  CRect(const POINT &topLeft, const POINT &bottomRight);
150 
151  // Attributes (in addition to RECT members)
152 
153  // retrieves the width
154  int Width() const;
155  // returns the height
156  int Height() const;
157  // returns the size
158  CSize Size() const;
159  // the geometric center point of the rectangle
160  CPoint CenterPoint() const;
161  // swap the left and right
162  void SwapLeftRight();
163  static void WINAPI SwapLeftRight(LPRECT lpRect);
164 
165  // convert between CRect and LPRECT/LPCRECT (no need for &)
166  operator LPRECT();
167  operator LPCRECT() const;
168 
169  // returns true if rectangle has no area
170  bool IsRectEmpty() const;
171  // returns true if rectangle is at (0,0) and has no area
172  bool IsRectNull() const;
173  // returns true if point is within rectangle
174  bool PtInRect(POINT point) const;
175 
176  // Operations
177 
178  // set rectangle from left, top, right, and bottom
179  void SetRect(
180  int x1,
181  int y1,
182  int x2,
183  int y2);
184  void SetRect(
185  POINT topLeft,
186  POINT bottomRight);
187  // empty the rectangle
188  void SetRectEmpty();
189  // copy from another rectangle
190  void CopyRect(LPCRECT lpSrcRect);
191  // true if exactly the same as another rectangle
192  bool EqualRect(LPCRECT lpRect) const;
193 
194  // Inflate rectangle's width and height by
195  // x units to the left and right ends of the rectangle
196  // and y units to the top and bottom.
197  void InflateRect(
198  int x,
199  int y);
200  // Inflate rectangle's width and height by
201  // size.cx units to the left and right ends of the rectangle
202  // and size.cy units to the top and bottom.
203  void InflateRect(SIZE size);
204  // Inflate rectangle's width and height by moving individual sides.
205  // Left side is moved to the left, right side is moved to the right,
206  // top is moved up and bottom is moved down.
207  void InflateRect(LPCRECT lpRect);
208  void InflateRect(
209  int l,
210  int t,
211  int r,
212  int b);
213 
214  // deflate the rectangle's width and height without
215  // moving its top or left
216  void DeflateRect(
217  int x,
218  int y);
219  void DeflateRect(SIZE size);
220  void DeflateRect(LPCRECT lpRect);
221  void DeflateRect(
222  int l,
223  int t,
224  int r,
225  int b);
226 
227  // translate the rectangle by moving its top and left
228  void OffsetRect(
229  int x,
230  int y);
231  void OffsetRect(SIZE size);
232  void OffsetRect(POINT point);
233  void NormalizeRect();
234 
235  // absolute position of rectangle
236  void MoveToY(int y);
237  void MoveToX(int x);
238  void MoveToXY(
239  int x,
240  int y);
241  void MoveToXY(POINT point);
242 
243  // set this rectangle to intersection of two others
244  bool IntersectRect(
245  LPCRECT lpRect1,
246  LPCRECT lpRect2);
247 
248  // set this rectangle to bounding union of two others
249  bool UnionRect(
250  LPCRECT lpRect1,
251  LPCRECT lpRect2);
252 
253  // set this rectangle to minimum of two others
254  bool SubtractRect(
255  LPCRECT lpRectSrc1,
256  LPCRECT lpRectSrc2);
257 
258  // Additional Operations
259  void operator=(const RECT &srcRect);
260  bool operator==(const RECT &rect) const;
261  bool operator!=(const RECT &rect) const;
262  void operator+=(POINT point);
263  void operator+=(SIZE size);
264  void operator+=(LPCRECT lpRect);
265  void operator-=(POINT point);
266  void operator-=(SIZE size);
267  void operator-=(LPCRECT lpRect);
268  void operator&=(const RECT &rect);
269  void operator|=(const RECT &rect);
270 
271  // Operators returning CRect values
272  CRect operator+(POINT point) const;
273  CRect operator-(POINT point) const;
274  CRect operator+(LPCRECT lpRect) const;
275  CRect operator+(SIZE size) const;
276  CRect operator-(SIZE size) const;
277  CRect operator-(LPCRECT lpRect) const;
278  CRect operator&(const RECT &rect2) const;
279  CRect operator|(const RECT &rect2) const;
280  CRect MulDiv(
281  int nMultiplier,
282  int nDivisor) const;
283 
284  CPoint &TopLeft() {
285  return *((CPoint *)this);
286  }
287  CPoint &BottomRight() {
288  return *((CPoint *)&right);
289  }
290  const CPoint &TopLeft() const {
291  return *((const CPoint *)this);
292  }
293  const CPoint &BottomRight() const {
294  return *((const CPoint *)&right);
295  }
296 };
297 
298 // CSize
299 inline CSize::CSize() {
300  cx = 0;
301  cy = 0;
302 }
303 
304 inline CSize::CSize(
305  int initCX,
306  int initCY) {
307  cx = initCX;
308  cy = initCY;
309 }
310 
311 inline CSize::CSize(SIZE initSize) {
312  *(SIZE *)this = initSize;
313 }
314 
315 inline CSize::CSize(POINT initPt) {
316  *(POINT *)this = initPt;
317 }
318 
319 inline CSize::CSize(uint32 dwSize) {
320  cx = (short)LOWORD(dwSize);
321  cy = (short)HIWORD(dwSize);
322 }
323 
324 inline bool CSize::operator==(SIZE size) const {
325  return (cx == size.cx && cy == size.cy);
326 }
327 
328 inline bool CSize::operator!=(SIZE size) const {
329  return (cx != size.cx || cy != size.cy);
330 }
331 
332 inline void CSize::operator+=(SIZE size) {
333  cx += size.cx;
334  cy += size.cy;
335 }
336 
337 inline void CSize::operator-=(SIZE size) {
338  cx -= size.cx;
339  cy -= size.cy;
340 }
341 
342 inline void CSize::SetSize(
343  int CX,
344  int CY) {
345  cx = CX;
346  cy = CY;
347 }
348 
349 inline CSize CSize::operator+(SIZE size) const {
350  return CSize(cx + size.cx, cy + size.cy);
351 }
352 
353 inline CSize CSize::operator-(SIZE size) const {
354  return CSize(cx - size.cx, cy - size.cy);
355 }
356 
357 inline CSize CSize::operator-() const {
358  return CSize(-cx, -cy);
359 }
360 
361 inline CPoint CSize::operator+(POINT point) const {
362  return CPoint(cx + point.x, cy + point.y);
363 }
364 
365 inline CPoint CSize::operator-(POINT point) const {
366  return CPoint(cx - point.x, cy - point.y);
367 }
368 
369 inline CRect CSize::operator+(const RECT *lpRect) const {
370  return CRect(lpRect) + *this;
371 }
372 
373 inline CRect CSize::operator-(const RECT *lpRect) const {
374  return CRect(lpRect) - *this;
375 }
376 
377 // CPoint
378 inline CPoint::CPoint() {
379  x = 0;
380  y = 0;
381 }
382 
383 inline CPoint::CPoint(
384  int initX,
385  int initY) {
386  x = initX;
387  y = initY;
388 }
389 
390 inline CPoint::CPoint(POINT initPt) {
391  *(POINT *)this = initPt;
392 }
393 
394 inline CPoint::CPoint(SIZE initSize) {
395  *(SIZE *)this = initSize;
396 }
397 
398 inline CPoint::CPoint(LPARAM dwPoint) {
399  x = (short)LOWORD(dwPoint);
400  y = (short)HIWORD(dwPoint);
401 }
402 
403 inline void CPoint::Offset(
404  int xOffset,
405  int yOffset) {
406  x += xOffset;
407  y += yOffset;
408 }
409 
410 inline void CPoint::Offset(POINT point) {
411  x += point.x;
412  y += point.y;
413 }
414 
415 inline void CPoint::Offset(SIZE size) {
416  x += size.cx;
417  y += size.cy;
418 }
419 
420 inline void CPoint::SetPoint(
421  int X,
422  int Y) {
423  x = X;
424  y = Y;
425 }
426 
427 inline bool CPoint::operator==(POINT point) const {
428  return (x == point.x && y == point.y);
429 }
430 
431 inline bool CPoint::operator!=(POINT point) const {
432  return (x != point.x || y != point.y);
433 }
434 
435 inline void CPoint::operator+=(SIZE size) {
436  x += size.cx;
437  y += size.cy;
438 }
439 
440 inline void CPoint::operator-=(SIZE size) {
441  x -= size.cx;
442  y -= size.cy;
443 }
444 
445 inline void CPoint::operator+=(POINT point) {
446  x += point.x;
447  y += point.y;
448 }
449 
450 inline void CPoint::operator-=(POINT point) {
451  x -= point.x;
452  y -= point.y;
453 }
454 
455 inline CPoint CPoint::operator+(SIZE size) const {
456  return CPoint(x + size.cx, y + size.cy);
457 }
458 
459 inline CPoint CPoint::operator-(SIZE size) const {
460  return CPoint(x - size.cx, y - size.cy);
461 }
462 
463 inline CPoint CPoint::operator-() const {
464  return CPoint(-x, -y);
465 }
466 
467 inline CPoint CPoint::operator+(POINT point) const {
468  return CPoint(x + point.x, y + point.y);
469 }
470 
471 inline CSize CPoint::operator-(POINT point) const {
472  return CSize(x - point.x, y - point.y);
473 }
474 
475 inline CRect CPoint::operator+(const RECT *lpRect) const {
476  return CRect(lpRect) + *this;
477 }
478 
479 inline CRect CPoint::operator-(const RECT *lpRect) const {
480  return CRect(lpRect) - *this;
481 }
482 
483 // CRect
484 inline CRect::CRect() {
485  left = 0;
486  top = 0;
487  right = 0;
488  bottom = 0;
489 }
490 
491 inline CRect::CRect(
492  int l,
493  int t,
494  int r,
495  int b) {
496  left = l;
497  top = t;
498  right = r;
499  bottom = b;
500 }
501 
502 inline CRect::CRect(const RECT &srcRect) {
503  CopyRect(&srcRect);
504 }
505 
506 inline CRect::CRect(LPCRECT lpSrcRect) {
507  CopyRect(lpSrcRect);
508 }
509 
510 inline CRect::CRect(const POINT &point, const SIZE &size) {
511  right = (left = point.x) + size.cx;
512  bottom = (top = point.y) + size.cy;
513 }
514 
515 inline CRect::CRect(const POINT &topLeft, const POINT &bottomRight) {
516  left = topLeft.x;
517  top = topLeft.y;
518  right = bottomRight.x;
519  bottom = bottomRight.y;
520 }
521 
522 inline int CRect::Width() const {
523  return right - left;
524 }
525 
526 inline int CRect::Height() const {
527  return bottom - top;
528 }
529 
530 inline CSize CRect::Size() const {
531  return CSize(right - left, bottom - top);
532 }
533 
534 inline CPoint CRect::CenterPoint() const {
535  return CPoint((left + right) / 2, (top + bottom) / 2);
536 }
537 
538 inline void CRect::SwapLeftRight() {
539  SwapLeftRight(LPRECT(this));
540 }
541 
542 inline void WINAPI CRect::SwapLeftRight(LPRECT lpRect) {
543  long temp = lpRect->left;
544  lpRect->left = lpRect->right;
545  lpRect->right = temp;
546 }
547 
548 inline CRect::operator LPRECT() {
549  return this;
550 }
551 
552 inline CRect::operator LPCRECT() const {
553  return this;
554 }
555 
556 inline bool CRect::IsRectEmpty() const {
557  return (left >= right) && (top >= bottom);
558 }
559 
560 inline bool CRect::IsRectNull() const {
561  return (left == 0 && right == 0 && top == 0 && bottom == 0);
562 }
563 
564 inline bool CRect::PtInRect(POINT point) const {
565  return (point.x >= left) && (point.x < right) &&
566  (point.y >= top) && (point.y < bottom);
567 }
568 
569 inline void CRect::SetRect(int x1, int y1,
570  int x2, int y2) {
571  left = x1;
572  top = y1;
573  right = x2;
574  bottom = y2;
575 }
576 
577 inline void CRect::SetRect(
578  POINT topLeft,
579  POINT bottomRight) {
580  left = topLeft.x;
581  top = topLeft.y;
582  right = bottomRight.x;
583  bottom = bottomRight.y;
584 }
585 
586 inline void CRect::SetRectEmpty() {
587  left = top = right = bottom = 0;
588 }
589 
590 inline void CRect::CopyRect(LPCRECT lpSrcRect) {
591  left = lpSrcRect->left;
592  top = lpSrcRect->top;
593  right = lpSrcRect->right;
594  bottom = lpSrcRect->bottom;
595 }
596 
597 inline bool CRect::EqualRect(LPCRECT lpRect) const {
598  return left == lpRect->left &&
599  top == lpRect->top &&
600  right == lpRect->right &&
601  bottom == lpRect->bottom;
602 }
603 
604 inline void CRect::InflateRect(
605  int x, int y) {
606  left -= x;
607  top -= y;
608  right += x;
609  bottom += y;
610 }
611 
612 inline void CRect::InflateRect(SIZE size) {
613  left -= size.cx;
614  top -= size.cy;
615  right += size.cx;
616  bottom += size.cy;
617 }
618 
619 inline void CRect::DeflateRect(
620  int x, int y) {
621  InflateRect(-x, -y);
622 }
623 
624 inline void CRect::DeflateRect(SIZE size) {
625  InflateRect(-size.cx, -size.cy);
626 }
627 
628 inline void CRect::OffsetRect(
629  int x, int y) {
630  left += x;
631  top += y;
632  right += x;
633  bottom += y;
634 }
635 
636 inline void CRect::OffsetRect(POINT point) {
637  left += point.x;
638  top += point.y;
639  right += point.x;
640  bottom += point.y;
641 }
642 
643 inline void CRect::OffsetRect(SIZE size) {
644  OffsetRect(size.cx, size.cy);
645 }
646 
647 inline void CRect::MoveToY(int y) {
648  bottom = Height() + y;
649  top = y;
650 }
651 
652 inline void CRect::MoveToX(int x) {
653  right = Width() + x;
654  left = x;
655 }
656 
657 inline void CRect::MoveToXY(
658  int x,
659  int y) {
660  MoveToX(x);
661  MoveToY(y);
662 }
663 
664 inline void CRect::MoveToXY(POINT pt) {
665  MoveToX(pt.x);
666  MoveToY(pt.y);
667 }
668 
669 inline bool CRect::IntersectRect(
670  LPCRECT lpRect1, LPCRECT lpRect2) {
671  Common::Rect r = Common::Rect(*lpRect1).findIntersectingRect(*lpRect2);
672  SetRect(r.left, r.top, r.right, r.bottom);
673 
674  return !r.isEmpty();
675 }
676 
677 inline bool CRect::UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) {
678  if (!lpRect1 || !lpRect2) {
679  // Defensive: null input treated as empty
680  SetRect(0, 0, 0, 0);
681  return false;
682  }
683 
684  // Check for empty rects
685  bool empty1 = lpRect1->left >= lpRect1->right || lpRect1->top >= lpRect1->bottom;
686  bool empty2 = lpRect2->left >= lpRect2->right || lpRect2->top >= lpRect2->bottom;
687 
688  if (empty1 && empty2) {
689  SetRect(0, 0, 0, 0);
690  return false;
691  } else if (empty1) {
692  *this = *lpRect2;
693  return true;
694  } else if (empty2) {
695  *this = *lpRect1;
696  return true;
697  }
698 
699  // Compute union of two valid rects
700  left = MIN(lpRect1->left, lpRect2->left);
701  top = MIN(lpRect1->top, lpRect2->top);
702  right = MAX(lpRect1->right, lpRect2->right);
703  bottom = MAX(lpRect1->bottom, lpRect2->bottom);
704 
705  return true;
706 }
707 
708 inline void CRect::operator=(const RECT &srcRect) {
709  CopyRect(&srcRect);
710 }
711 
712 inline bool CRect::operator==(const RECT &rect) const {
713  return EqualRect(&rect);
714 }
715 
716 inline bool CRect::operator!=(const RECT &rect) const {
717  return !EqualRect(&rect);
718 }
719 
720 inline void CRect::operator+=(POINT point) {
721  OffsetRect(point.x, point.y);
722 }
723 
724 inline void CRect::operator+=(SIZE size) {
725  OffsetRect(size.cx, size.cy);
726 }
727 
728 inline void CRect::operator+=(LPCRECT lpRect) {
729  InflateRect(lpRect);
730 }
731 
732 inline void CRect::operator-=(POINT point) {
733  OffsetRect(-point.x, -point.y);
734 }
735 
736 inline void CRect::operator-=(SIZE size) {
737  OffsetRect(-size.cx, -size.cy);
738 }
739 
740 inline void CRect::operator-=(LPCRECT lpRect) {
741  DeflateRect(lpRect);
742 }
743 
744 inline void CRect::operator&=(const RECT &rect) {
745  IntersectRect(this, &rect);
746 }
747 
748 inline void CRect::operator|=(const RECT &rect) {
749  UnionRect(this, &rect);
750 }
751 
752 inline CRect CRect::operator+(POINT pt) const {
753  CRect rect(*this);
754  rect.OffsetRect(pt.x, pt.y);
755  return rect;
756 }
757 
758 inline CRect CRect::operator-(POINT pt) const {
759  CRect rect(*this);
760  rect.OffsetRect(-pt.x, -pt.y);
761  return rect;
762 }
763 
764 inline CRect CRect::operator+(SIZE size) const {
765  CRect rect(*this);
766  rect.OffsetRect(size.cx, size.cy);
767  return rect;
768 }
769 
770 inline CRect CRect::operator-(SIZE size) const {
771  CRect rect(*this);
772  rect.OffsetRect(-size.cx, -size.cy);
773  return rect;
774 }
775 
776 inline CRect CRect::operator+(LPCRECT lpRect) const {
777  CRect rect(this);
778  rect.InflateRect(lpRect);
779  return rect;
780 }
781 
782 inline CRect CRect::operator-(LPCRECT lpRect) const {
783  CRect rect(this);
784  rect.DeflateRect(lpRect);
785  return rect;
786 }
787 
788 inline CRect CRect::operator&(const RECT &rect2) const {
789  CRect rect;
790  rect.IntersectRect(this, &rect2);
791  return rect;
792 }
793 
794 inline CRect CRect::operator|(const RECT &rect2) const {
795  CRect rect;
796  rect.UnionRect(this, &rect2);
797  return rect;
798 }
799 
800 inline bool CRect::SubtractRect(
801  LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) {
802  // Calculate the intersection of the two rectangles
803  CRect intersect;
804  if (!intersect.IntersectRect(lpRectSrc1, lpRectSrc2)) {
805  // No overlap - return full original
806  *this = *lpRectSrc1;
807  return true;
808  }
809 
810  // If lpRectSrc2 fully covers lpRectSrc1, result is empty
811  if (intersect == *lpRectSrc1) {
812  SetRectEmpty();
813  return false;
814  }
815 
816  // Try to return a remaining portion that is a single rectangle
817 
818  // Top strip
819  if (intersect.top > lpRectSrc1->top &&
820  intersect.left <= lpRectSrc1->left &&
821  intersect.right >= lpRectSrc1->right) {
822  SetRect(lpRectSrc1->left, lpRectSrc1->top,
823  lpRectSrc1->right, intersect.top);
824  return true;
825  }
826 
827  // Bottom strip
828  if (intersect.bottom < lpRectSrc1->bottom &&
829  intersect.left <= lpRectSrc1->left &&
830  intersect.right >= lpRectSrc1->right) {
831  SetRect(lpRectSrc1->left, intersect.bottom,
832  lpRectSrc1->right, lpRectSrc1->bottom);
833  return true;
834  }
835 
836  // Left strip
837  if (intersect.left > lpRectSrc1->left &&
838  intersect.top <= lpRectSrc1->top &&
839  intersect.bottom >= lpRectSrc1->bottom) {
840  SetRect(lpRectSrc1->left, lpRectSrc1->top,
841  intersect.left, lpRectSrc1->bottom);
842  return true;
843  }
844 
845  // Right strip
846  if (intersect.right < lpRectSrc1->right &&
847  intersect.top <= lpRectSrc1->top &&
848  intersect.bottom >= lpRectSrc1->bottom) {
849  SetRect(intersect.right, lpRectSrc1->top,
850  lpRectSrc1->right, lpRectSrc1->bottom);
851  return true;
852  }
853 
854  // If none of the simple cases apply, we can't represent the subtraction
855  // as a single rectangle - result is undefined
856  SetRectEmpty();
857  return false;
858 }
859 
860 inline void CRect::NormalizeRect() {
861  int nTemp;
862  if (left > right) {
863  nTemp = left;
864  left = right;
865  right = nTemp;
866  }
867  if (top > bottom) {
868  nTemp = top;
869  top = bottom;
870  bottom = nTemp;
871  }
872 }
873 
874 inline void CRect::InflateRect(LPCRECT lpRect) {
875  left -= lpRect->left;
876  top -= lpRect->top;
877  right += lpRect->right;
878  bottom += lpRect->bottom;
879 }
880 
881 inline void CRect::InflateRect(
882  int l,
883  int t,
884  int r,
885  int b) {
886  left -= l;
887  top -= t;
888  right += r;
889  bottom += b;
890 }
891 
892 inline void CRect::DeflateRect(LPCRECT lpRect) {
893  left += lpRect->left;
894  top += lpRect->top;
895  right -= lpRect->right;
896  bottom -= lpRect->bottom;
897 }
898 
899 inline void CRect::DeflateRect(
900  int l,
901  int t,
902  int r,
903  int b) {
904  left += l;
905  top += t;
906  right -= r;
907  bottom -= b;
908 }
909 
910 inline int SafeMulDiv(int a, int b, int c) {
911  if (c == 0)
912  return 0; // Or handle divide-by-zero error
913 
914  // Use 64-bit intermediate result to avoid overflow
915  int64 temp = (int64)a * (int64)b;
916 
917  // Round to nearest
918  if ((temp >= 0))
919  return (int)((temp + (c / 2)) / c);
920  else
921  return (int)((temp - (c / 2)) / c);
922 }
923 
924 inline CRect CRect::MulDiv(
925  int nMultiplier,
926  int nDivisor) const {
927  return CRect(
928  SafeMulDiv(left, nMultiplier, nDivisor),
929  SafeMulDiv(top, nMultiplier, nDivisor),
930  SafeMulDiv(right, nMultiplier, nDivisor),
931  SafeMulDiv(bottom, nMultiplier, nDivisor));
932 }
933 
934 } // namespace MFC
935 } // namespace Bagel
936 
937 #endif
Definition: minwindef.h:166
T left
Definition: rect.h:170
ConcreteRect findIntersectingRect(const ConcreteRect &r) const
Definition: rect.h:302
Definition: atltypes.h:79
Definition: rect.h:524
Definition: minwindef.h:161
T right
Definition: rect.h:171
Definition: atltypes.h:40
bool isEmpty() const
Definition: rect.h:373
Definition: minwindef.h:179
Definition: afxwin.h:27
T MIN(T a, T b)
Definition: util.h:61
T MAX(T a, T b)
Definition: util.h:64
Definition: atltypes.h:131