ScummVM API documentation
geometry.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 //=============================================================================
23 //
24 // Geometry data structures and helper functions
25 //
26 //=============================================================================
27 
28 #ifndef AGS_SHARED_UTIL_GEOMETRY_H
29 #define AGS_SHARED_UTIL_GEOMETRY_H
30 
31 #include "ags/shared/util/math.h"
32 
33 namespace AGS3 {
34 
35 namespace AGSMath = AGS::Shared::Math;
36 //namespace AGS
37 //{
38 //namespace Shared
39 //{
40 
41 // Type of alignment of a geometric item of rectangular boundaries.
42 enum FrameAlignment {
43  kAlignNone = 0,
44 
45  // Alignment options are representing 8 sides of a frame (rectangle);
46  // they are implemented as flags that may be combined together if it
47  // is wanted to define alignment to multiple sides at once.
48  kAlignTopLeft = 0x0001,
49  kAlignTopCenter = 0x0002,
50  kAlignTopRight = 0x0004,
51  kAlignMiddleLeft = 0x0008,
52  kAlignMiddleCenter = 0x0010,
53  kAlignMiddleRight = 0x0020,
54  kAlignBottomLeft = 0x0040,
55  kAlignBottomCenter = 0x0080,
56  kAlignBottomRight = 0x0100,
57 
58  // Masks are helping to determine whether alignment parameter contains
59  // particular horizontal or vertical component (for example: left side
60  // or bottom side)
61  kMAlignLeft = kAlignTopLeft | kAlignMiddleLeft | kAlignBottomLeft,
62  kMAlignRight = kAlignTopRight | kAlignMiddleRight | kAlignBottomRight,
63  kMAlignTop = kAlignTopLeft | kAlignTopCenter | kAlignTopRight,
64  kMAlignBottom = kAlignBottomLeft | kAlignBottomCenter | kAlignBottomRight,
65  kMAlignHCenter = kAlignTopCenter | kAlignMiddleCenter | kAlignBottomCenter,
66  kMAlignVCenter = kAlignMiddleLeft | kAlignMiddleCenter | kAlignMiddleRight
67 };
68 
69 // Horizontal alignment; based on FrameAlignment, used to restrict alignment
70 // setting to left/right/center option, while keeping compatibility with any
71 // alignment in case it will be supported in the future.
72 enum HorAlignment {
73  kHAlignNone = kAlignNone,
74  kHAlignLeft = kAlignTopLeft,
75  kHAlignRight = kAlignTopRight,
76  kHAlignCenter = kAlignTopCenter
77 };
78 
79 enum RectPlacement {
80  kPlaceOffset,
81  kPlaceCenter,
82  kPlaceStretch,
83  kPlaceStretchProportional,
84  kNumRectPlacement
85 };
86 
87 struct Point {
88  int X;
89  int Y;
90 
91  Point() {
92  X = 0;
93  Y = 0;
94  }
95 
96  Point(int x, int y) {
97  X = x;
98  Y = y;
99  }
100 
101  inline bool operator ==(const Point &p) const {
102  return X == p.X && Y == p.Y;
103  }
104 
105  inline bool operator !=(const Point &p) const {
106  return X != p.X || Y != p.Y;
107  }
108 
109  inline Point operator +(const Point &p) const {
110  return Point(X + p.X, Y + p.Y);
111  }
112 };
113 
114 struct Line {
115  int X1;
116  int Y1;
117  int X2;
118  int Y2;
119 
120  Line() {
121  X1 = 0;
122  Y1 = 0;
123  X2 = 0;
124  Y2 = 0;
125  }
126 
127  Line(int x1, int y1, int x2, int y2) {
128  X1 = x1;
129  Y1 = y1;
130  X2 = x2;
131  Y2 = y2;
132  }
133 };
134 
135 // Helper factory functions
136 inline Line HLine(int x1, int x2, int y) {
137  return Line(x1, y, x2, y);
138 }
139 
140 inline Line VLine(int x, int y1, int y2) {
141  return Line(x, y1, x, y2);
142 }
143 
144 struct Size {
145  int Width;
146  int Height;
147 
148  Size() {
149  Width = 0;
150  Height = 0;
151  }
152 
153  Size(int width, int height) {
154  Width = width;
155  Height = height;
156  }
157 
158  inline bool IsNull() const {
159  return Width <= 0 || Height <= 0;
160  }
161 
162  inline static Size Clamp(const Size &sz, const Size &floor, const Size &ceil) {
163  return Size(AGSMath::Clamp(sz.Width, floor.Width, ceil.Width),
164  AGSMath::Clamp(sz.Height, floor.Height, ceil.Height));
165  }
166 
167  // Indicates if current size exceeds other size by any metric
168  inline bool ExceedsByAny(const Size size) const {
169  return Width > size.Width || Height > size.Height;
170  }
171 
172  inline bool operator==(const Size size) const {
173  return Width == size.Width && Height == size.Height;
174  }
175 
176  inline bool operator!=(const Size size) const {
177  return Width != size.Width || Height != size.Height;
178  }
179 
180  inline bool operator<(const Size &other) const { // TODO: this implementation is silly and not universally useful; make a realistic one and replace with another function where necessary
181  return Width < other.Width || (Width == other.Width && Height < other.Height);
182  }
183 
184  inline Size operator+(const Size &size) const {
185  return Size(Width + size.Width, Height + size.Height);
186  }
187 
188  inline Size operator-(const Size &size) const {
189  return Size(Width - size.Width, Height - size.Height);
190  }
191 
192  inline Size operator *(int x) const {
193  return Size(Width * x, Height * x);
194  }
195 
196  inline Size operator /(int x) const {
197  return Size(Width / x, Height / x);
198  }
199 
200  inline Size &operator *=(int x) {
201  Width *= x;
202  Height *= x;
203  return *this;
204  }
205 
206  inline Size &operator /=(int x) {
207  Width /= x;
208  Height /= x;
209  return *this;
210  }
211 };
212 
213 // TODO: consider making Rect have right-bottom coordinate with +1 offset
214 // to comply with many other libraries (i.e. Right - Left == Width)
215 struct Rect {
216  int Left;
217  int Top;
218  int Right;
219  int Bottom;
220 
221  Rect() {
222  Left = 0;
223  Top = 0;
224  Right = -1;
225  Bottom = -1;
226  }
227 
228  Rect(int l, int t, int r, int b) {
229  Left = l;
230  Top = t;
231  Right = r;
232  Bottom = b;
233  }
234 
235  inline Point GetLT() const {
236  return Point(Left, Top);
237  }
238 
239  inline Point GetCenter() const {
240  return Point(Left + GetWidth() / 2, Top + GetHeight() / 2);
241  }
242 
243  inline int GetWidth() const {
244  return Right - Left + 1;
245  }
246 
247  inline int GetHeight() const {
248  return Bottom - Top + 1;
249  }
250 
251  inline Size GetSize() const {
252  return Size(GetWidth(), GetHeight());
253  }
254 
255  inline bool IsEmpty() const {
256  return Right < Left || Bottom < Top;
257  }
258 
259  inline bool IsInside(int x, int y) const {
260  return x >= Left && y >= Top && (x <= Right) && (y <= Bottom);
261  }
262 
263  inline bool IsInside(const Point &pt) const {
264  return IsInside(pt.X, pt.Y);
265  }
266 
267  inline void MoveToX(int x) {
268  Right += x - Left;
269  Left = x;
270  }
271 
272  inline void MoveToY(int y) {
273  Bottom += y - Top;
274  Top = y;
275  }
276 
277  inline void MoveTo(const Point &pt) {
278  MoveToX(pt.X);
279  MoveToY(pt.Y);
280  }
281 
282  inline void SetWidth(int width) {
283  Right = Left + width - 1;
284  }
285 
286  inline void SetHeight(int height) {
287  Bottom = Top + height - 1;
288  }
289 
290  inline static Rect MoveBy(const Rect &r, int x, int y) {
291  return Rect(r.Left + x, r.Top + y, r.Right + x, r.Bottom + y);
292  }
293 
294  inline bool operator ==(const Rect &r) const {
295  return Left == r.Left && Top == r.Top &&
296  Right == r.Right && Bottom == r.Bottom;
297  }
298 };
299 
300 // Helper factory function
301 inline Rect RectWH(int x, int y, int width, int height) {
302  return Rect(x, y, x + width - 1, y + height - 1);
303 }
304 
305 inline Rect RectWH(const Size &sz) {
306  return Rect(0, 0, sz.Width - 1, sz.Height - 1);
307 }
308 
309 
310 struct Triangle {
311  int X1;
312  int Y1;
313  int X2;
314  int Y2;
315  int X3;
316  int Y3;
317 
318  Triangle() {
319  X1 = 0;
320  Y1 = 0;
321  X2 = 0;
322  Y2 = 0;
323  X3 = 0;
324  Y3 = 0;
325  }
326 
327  Triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
328  X1 = x1;
329  Y1 = y1;
330  X2 = x2;
331  Y2 = y2;
332  X3 = x3;
333  Y3 = y3;
334  }
335 };
336 
337 struct Circle {
338  int X;
339  int Y;
340  int Radius;
341 
342  Circle() {
343  X = 0;
344  Y = 0;
345  Radius = 0;
346  }
347 
348  Circle(int x, int y, int radius) {
349  X = x;
350  Y = y;
351  Radius = radius;
352  }
353 
354 };
355 
356 
357 // Tells if two rectangles intersect (overlap) at least partially
358 bool AreRectsIntersecting(const Rect &r1, const Rect &r2);
359 // Tells if the item is completely inside place
360 bool IsRectInsideRect(const Rect &place, const Rect &item);
361 // Calculates a distance between two axis-aligned rectangles, returns 0 if they intersect
362 float DistanceBetween(const Rect &r1, const Rect &r2);
363 
364 int AlignInHRange(int x1, int x2, int off_x, int width, FrameAlignment align);
365 int AlignInVRange(int y1, int y2, int off_y, int height, FrameAlignment align);
366 Rect AlignInRect(const Rect &frame, const Rect &item, FrameAlignment align);
367 
368 Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h);
369 Size ProportionalStretch(const Size &dest, const Size &item);
370 
371 Rect OffsetRect(const Rect &r, const Point off);
372 Rect CenterInRect(const Rect &place, const Rect &item);
373 Rect ClampToRect(const Rect &place, const Rect &item);
374 Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement);
375 // Sum two rectangles, the result is the rectangle bounding them both
376 Rect SumRects(const Rect &r1, const Rect &r2);
377 // Intersect two rectangles, the resolt is the rectangle bounding their intersection
378 Rect IntersectRects(const Rect &r1, const Rect &r2);
379 
380 //} // namespace Shared
381 //} // namespace AGS
382 } // namespace AGS3
383 
384 #endif
Definition: geometry.h:87
Definition: geometry.h:310
Definition: geometry.h:114
Definition: geometry.h:215
Definition: geometry.h:144
Definition: geometry.h:337
Definition: ags.h:40