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 };
291 
292 // CSize
293 inline CSize::CSize() {
294  cx = 0;
295  cy = 0;
296 }
297 
298 inline CSize::CSize(
299  int initCX,
300  int initCY) {
301  cx = initCX;
302  cy = initCY;
303 }
304 
305 inline CSize::CSize(SIZE initSize) {
306  *(SIZE *)this = initSize;
307 }
308 
309 inline CSize::CSize(POINT initPt) {
310  *(POINT *)this = initPt;
311 }
312 
313 inline CSize::CSize(uint32 dwSize) {
314  cx = (short)LOWORD(dwSize);
315  cy = (short)HIWORD(dwSize);
316 }
317 
318 inline bool CSize::operator==(SIZE size) const {
319  return (cx == size.cx && cy == size.cy);
320 }
321 
322 inline bool CSize::operator!=(SIZE size) const {
323  return (cx != size.cx || cy != size.cy);
324 }
325 
326 inline void CSize::operator+=(SIZE size) {
327  cx += size.cx;
328  cy += size.cy;
329 }
330 
331 inline void CSize::operator-=(SIZE size) {
332  cx -= size.cx;
333  cy -= size.cy;
334 }
335 
336 inline void CSize::SetSize(
337  int CX,
338  int CY) {
339  cx = CX;
340  cy = CY;
341 }
342 
343 inline CSize CSize::operator+(SIZE size) const {
344  return CSize(cx + size.cx, cy + size.cy);
345 }
346 
347 inline CSize CSize::operator-(SIZE size) const {
348  return CSize(cx - size.cx, cy - size.cy);
349 }
350 
351 inline CSize CSize::operator-() const {
352  return CSize(-cx, -cy);
353 }
354 
355 inline CPoint CSize::operator+(POINT point) const {
356  return CPoint(cx + point.x, cy + point.y);
357 }
358 
359 inline CPoint CSize::operator-(POINT point) const {
360  return CPoint(cx - point.x, cy - point.y);
361 }
362 
363 inline CRect CSize::operator+(const RECT *lpRect) const {
364  return CRect(lpRect) + *this;
365 }
366 
367 inline CRect CSize::operator-(const RECT *lpRect) const {
368  return CRect(lpRect) - *this;
369 }
370 
371 // CPoint
372 inline CPoint::CPoint() {
373  x = 0;
374  y = 0;
375 }
376 
377 inline CPoint::CPoint(
378  int initX,
379  int initY) {
380  x = initX;
381  y = initY;
382 }
383 
384 inline CPoint::CPoint(POINT initPt) {
385  *(POINT *)this = initPt;
386 }
387 
388 inline CPoint::CPoint(SIZE initSize) {
389  *(SIZE *)this = initSize;
390 }
391 
392 inline CPoint::CPoint(LPARAM dwPoint) {
393  x = (short)LOWORD(dwPoint);
394  y = (short)HIWORD(dwPoint);
395 }
396 
397 inline void CPoint::Offset(
398  int xOffset,
399  int yOffset) {
400  x += xOffset;
401  y += yOffset;
402 }
403 
404 inline void CPoint::Offset(POINT point) {
405  x += point.x;
406  y += point.y;
407 }
408 
409 inline void CPoint::Offset(SIZE size) {
410  x += size.cx;
411  y += size.cy;
412 }
413 
414 inline void CPoint::SetPoint(
415  int X,
416  int Y) {
417  x = X;
418  y = Y;
419 }
420 
421 inline bool CPoint::operator==(POINT point) const {
422  return (x == point.x && y == point.y);
423 }
424 
425 inline bool CPoint::operator!=(POINT point) const {
426  return (x != point.x || y != point.y);
427 }
428 
429 inline void CPoint::operator+=(SIZE size) {
430  x += size.cx;
431  y += size.cy;
432 }
433 
434 inline void CPoint::operator-=(SIZE size) {
435  x -= size.cx;
436  y -= size.cy;
437 }
438 
439 inline void CPoint::operator+=(POINT point) {
440  x += point.x;
441  y += point.y;
442 }
443 
444 inline void CPoint::operator-=(POINT point) {
445  x -= point.x;
446  y -= point.y;
447 }
448 
449 inline CPoint CPoint::operator+(SIZE size) const {
450  return CPoint(x + size.cx, y + size.cy);
451 }
452 
453 inline CPoint CPoint::operator-(SIZE size) const {
454  return CPoint(x - size.cx, y - size.cy);
455 }
456 
457 inline CPoint CPoint::operator-() const {
458  return CPoint(-x, -y);
459 }
460 
461 inline CPoint CPoint::operator+(POINT point) const {
462  return CPoint(x + point.x, y + point.y);
463 }
464 
465 inline CSize CPoint::operator-(POINT point) const {
466  return CSize(x - point.x, y - point.y);
467 }
468 
469 inline CRect CPoint::operator+(const RECT *lpRect) const {
470  return CRect(lpRect) + *this;
471 }
472 
473 inline CRect CPoint::operator-(const RECT *lpRect) const {
474  return CRect(lpRect) - *this;
475 }
476 
477 // CRect
478 inline CRect::CRect() {
479  left = 0;
480  top = 0;
481  right = 0;
482  bottom = 0;
483 }
484 
485 inline CRect::CRect(
486  int l,
487  int t,
488  int r,
489  int b) {
490  left = l;
491  top = t;
492  right = r;
493  bottom = b;
494 }
495 
496 inline CRect::CRect(const RECT &srcRect) {
497  CopyRect(&srcRect);
498 }
499 
500 inline CRect::CRect(LPCRECT lpSrcRect) {
501  CopyRect(lpSrcRect);
502 }
503 
504 inline CRect::CRect(const POINT &point, const SIZE &size) {
505  right = (left = point.x) + size.cx;
506  bottom = (top = point.y) + size.cy;
507 }
508 
509 inline CRect::CRect(const POINT &topLeft, const POINT &bottomRight) {
510  left = topLeft.x;
511  top = topLeft.y;
512  right = bottomRight.x;
513  bottom = bottomRight.y;
514 }
515 
516 inline int CRect::Width() const {
517  return right - left;
518 }
519 
520 inline int CRect::Height() const {
521  return bottom - top;
522 }
523 
524 inline CSize CRect::Size() const {
525  return CSize(right - left, bottom - top);
526 }
527 
528 inline CPoint CRect::CenterPoint() const {
529  return CPoint((left + right) / 2, (top + bottom) / 2);
530 }
531 
532 inline void CRect::SwapLeftRight() {
533  SwapLeftRight(LPRECT(this));
534 }
535 
536 inline void WINAPI CRect::SwapLeftRight(LPRECT lpRect) {
537  long temp = lpRect->left;
538  lpRect->left = lpRect->right;
539  lpRect->right = temp;
540 }
541 
542 inline CRect::operator LPRECT() {
543  return this;
544 }
545 
546 inline CRect::operator LPCRECT() const {
547  return this;
548 }
549 
550 inline bool CRect::IsRectEmpty() const {
551  return (left >= right) && (top >= bottom);
552 }
553 
554 inline bool CRect::IsRectNull() const {
555  return (left == 0 && right == 0 && top == 0 && bottom == 0);
556 }
557 
558 inline bool CRect::PtInRect(POINT point) const {
559  return (point.x >= left) && (point.x < right) &&
560  (point.y >= top) && (point.y < bottom);
561 }
562 
563 inline void CRect::SetRect(int x1, int y1,
564  int x2, int y2) {
565  left = x1;
566  top = y1;
567  right = x2;
568  bottom = y2;
569 }
570 
571 inline void CRect::SetRect(
572  POINT topLeft,
573  POINT bottomRight) {
574  left = topLeft.x;
575  top = topLeft.y;
576  right = bottomRight.x;
577  bottom = bottomRight.y;
578 }
579 
580 inline void CRect::SetRectEmpty() {
581  left = top = right = bottom = 0;
582 }
583 
584 inline void CRect::CopyRect(LPCRECT lpSrcRect) {
585  left = lpSrcRect->left;
586  top = lpSrcRect->top;
587  right = lpSrcRect->right;
588  bottom = lpSrcRect->bottom;
589 }
590 
591 inline bool CRect::EqualRect(LPCRECT lpRect) const {
592  return left == lpRect->left &&
593  top == lpRect->top &&
594  right == lpRect->right &&
595  bottom == lpRect->bottom;
596 }
597 
598 inline void CRect::InflateRect(
599  int x, int y) {
600  left -= x;
601  top -= y;
602  right += x;
603  bottom += y;
604 }
605 
606 inline void CRect::InflateRect(SIZE size) {
607  left -= size.cx;
608  top -= size.cy;
609  right += size.cx;
610  bottom += size.cy;
611 }
612 
613 inline void CRect::DeflateRect(
614  int x, int y) {
615  InflateRect(-x, -y);
616 }
617 
618 inline void CRect::DeflateRect(SIZE size) {
619  InflateRect(-size.cx, -size.cy);
620 }
621 
622 inline void CRect::OffsetRect(
623  int x, int y) {
624  left += x;
625  top += y;
626  right += x;
627  bottom += y;
628 }
629 
630 inline void CRect::OffsetRect(POINT point) {
631  left += point.x;
632  top += point.y;
633  right += point.x;
634  bottom += point.y;
635 }
636 
637 inline void CRect::OffsetRect(SIZE size) {
638  OffsetRect(size.cx, size.cy);
639 }
640 
641 inline void CRect::MoveToY(int y) {
642  bottom = Height() + y;
643  top = y;
644 }
645 
646 inline void CRect::MoveToX(int x) {
647  right = Width() + x;
648  left = x;
649 }
650 
651 inline void CRect::MoveToXY(
652  int x,
653  int y) {
654  MoveToX(x);
655  MoveToY(y);
656 }
657 
658 inline void CRect::MoveToXY(POINT pt) {
659  MoveToX(pt.x);
660  MoveToY(pt.y);
661 }
662 
663 inline bool CRect::IntersectRect(
664  LPCRECT lpRect1, LPCRECT lpRect2) {
665  return (lpRect1->left < lpRect2->right) &&
666  (lpRect2->left < lpRect1->right) &&
667  (lpRect1->top < lpRect2->bottom) &&
668  (lpRect2->top < lpRect1->bottom);
669 }
670 
671 inline bool CRect::UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) {
672  if (!lpRect1 || !lpRect2) {
673  // Defensive: null input treated as empty
674  SetRect(0, 0, 0, 0);
675  return false;
676  }
677 
678  // Check for empty rects
679  bool empty1 = lpRect1->left >= lpRect1->right || lpRect1->top >= lpRect1->bottom;
680  bool empty2 = lpRect2->left >= lpRect2->right || lpRect2->top >= lpRect2->bottom;
681 
682  if (empty1 && empty2) {
683  SetRect(0, 0, 0, 0);
684  return false;
685  } else if (empty1) {
686  *this = *lpRect2;
687  return true;
688  } else if (empty2) {
689  *this = *lpRect1;
690  return true;
691  }
692 
693  // Compute union of two valid rects
694  left = MIN(lpRect1->left, lpRect2->left);
695  top = MIN(lpRect1->top, lpRect2->top);
696  right = MAX(lpRect1->right, lpRect2->right);
697  bottom = MAX(lpRect1->bottom, lpRect2->bottom);
698 
699  return true;
700 }
701 
702 inline void CRect::operator=(const RECT &srcRect) {
703  CopyRect(&srcRect);
704 }
705 
706 inline bool CRect::operator==(const RECT &rect) const {
707  return EqualRect(&rect);
708 }
709 
710 inline bool CRect::operator!=(const RECT &rect) const {
711  return !EqualRect(&rect);
712 }
713 
714 inline void CRect::operator+=(POINT point) {
715  OffsetRect(point.x, point.y);
716 }
717 
718 inline void CRect::operator+=(SIZE size) {
719  OffsetRect(size.cx, size.cy);
720 }
721 
722 inline void CRect::operator+=(LPCRECT lpRect) {
723  InflateRect(lpRect);
724 }
725 
726 inline void CRect::operator-=(POINT point) {
727  OffsetRect(-point.x, -point.y);
728 }
729 
730 inline void CRect::operator-=(SIZE size) {
731  OffsetRect(-size.cx, -size.cy);
732 }
733 
734 inline void CRect::operator-=(LPCRECT lpRect) {
735  DeflateRect(lpRect);
736 }
737 
738 inline void CRect::operator&=(const RECT &rect) {
739  IntersectRect(this, &rect);
740 }
741 
742 inline void CRect::operator|=(const RECT &rect) {
743  UnionRect(this, &rect);
744 }
745 
746 inline CRect CRect::operator+(POINT pt) const {
747  CRect rect(*this);
748  rect.OffsetRect(pt.x, pt.y);
749  return 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+(SIZE size) const {
759  CRect rect(*this);
760  rect.OffsetRect(size.cx, size.cy);
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+(LPCRECT lpRect) const {
771  CRect rect(this);
772  rect.InflateRect(lpRect);
773  return rect;
774 }
775 
776 inline CRect CRect::operator-(LPCRECT lpRect) const {
777  CRect rect(this);
778  rect.DeflateRect(lpRect);
779  return rect;
780 }
781 
782 inline CRect CRect::operator&(const RECT &rect2) const {
783  CRect rect;
784  rect.IntersectRect(this, &rect2);
785  return rect;
786 }
787 
788 inline CRect CRect::operator|(const RECT &rect2) const {
789  CRect rect;
790  rect.UnionRect(this, &rect2);
791  return rect;
792 }
793 
794 inline bool CRect::SubtractRect(
795  LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) {
796  // Calculate the intersection of the two rectangles
797  CRect intersect;
798  if (!intersect.IntersectRect(lpRectSrc1, lpRectSrc2)) {
799  // No overlap - return full original
800  *this = *lpRectSrc1;
801  return true;
802  }
803 
804  // If lpRectSrc2 fully covers lpRectSrc1, result is empty
805  if (intersect == *lpRectSrc1) {
806  SetRectEmpty();
807  return false;
808  }
809 
810  // Try to return a remaining portion that is a single rectangle
811 
812  // Top strip
813  if (intersect.top > lpRectSrc1->top &&
814  intersect.left <= lpRectSrc1->left &&
815  intersect.right >= lpRectSrc1->right) {
816  SetRect(lpRectSrc1->left, lpRectSrc1->top,
817  lpRectSrc1->right, intersect.top);
818  return true;
819  }
820 
821  // Bottom strip
822  if (intersect.bottom < lpRectSrc1->bottom &&
823  intersect.left <= lpRectSrc1->left &&
824  intersect.right >= lpRectSrc1->right) {
825  SetRect(lpRectSrc1->left, intersect.bottom,
826  lpRectSrc1->right, lpRectSrc1->bottom);
827  return true;
828  }
829 
830  // Left strip
831  if (intersect.left > lpRectSrc1->left &&
832  intersect.top <= lpRectSrc1->top &&
833  intersect.bottom >= lpRectSrc1->bottom) {
834  SetRect(lpRectSrc1->left, lpRectSrc1->top,
835  intersect.left, lpRectSrc1->bottom);
836  return true;
837  }
838 
839  // Right strip
840  if (intersect.right < lpRectSrc1->right &&
841  intersect.top <= lpRectSrc1->top &&
842  intersect.bottom >= lpRectSrc1->bottom) {
843  SetRect(intersect.right, lpRectSrc1->top,
844  lpRectSrc1->right, lpRectSrc1->bottom);
845  return true;
846  }
847 
848  // If none of the simple cases apply, we can't represent the subtraction
849  // as a single rectangle - result is undefined
850  SetRectEmpty();
851  return false;
852 }
853 
854 inline void CRect::NormalizeRect() {
855  int nTemp;
856  if (left > right) {
857  nTemp = left;
858  left = right;
859  right = nTemp;
860  }
861  if (top > bottom) {
862  nTemp = top;
863  top = bottom;
864  bottom = nTemp;
865  }
866 }
867 
868 inline void CRect::InflateRect(LPCRECT lpRect) {
869  left -= lpRect->left;
870  top -= lpRect->top;
871  right += lpRect->right;
872  bottom += lpRect->bottom;
873 }
874 
875 inline void CRect::InflateRect(
876  int l,
877  int t,
878  int r,
879  int b) {
880  left -= l;
881  top -= t;
882  right += r;
883  bottom += b;
884 }
885 
886 inline void CRect::DeflateRect(LPCRECT lpRect) {
887  left += lpRect->left;
888  top += lpRect->top;
889  right -= lpRect->right;
890  bottom -= lpRect->bottom;
891 }
892 
893 inline void CRect::DeflateRect(
894  int l,
895  int t,
896  int r,
897  int b) {
898  left += l;
899  top += t;
900  right -= r;
901  bottom -= b;
902 }
903 
904 inline int SafeMulDiv(int a, int b, int c) {
905  if (c == 0)
906  return 0; // Or handle divide-by-zero error
907 
908  // Use 64-bit intermediate result to avoid overflow
909  int64 temp = (int64)a * (int64)b;
910 
911  // Round to nearest
912  if ((temp >= 0))
913  return (int)((temp + (c / 2)) / c);
914  else
915  return (int)((temp - (c / 2)) / c);
916 }
917 
918 inline CRect CRect::MulDiv(
919  int nMultiplier,
920  int nDivisor) const {
921  return CRect(
922  SafeMulDiv(left, nMultiplier, nDivisor),
923  SafeMulDiv(top, nMultiplier, nDivisor),
924  SafeMulDiv(right, nMultiplier, nDivisor),
925  SafeMulDiv(bottom, nMultiplier, nDivisor));
926 }
927 
928 } // namespace MFC
929 } // namespace Bagel
930 
931 #endif
Definition: minwindef.h:165
Definition: atltypes.h:79
Definition: minwindef.h:160
Definition: atltypes.h:40
Definition: minwindef.h:178
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