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  inline bool Equals(const int x, const int y) const {
114  return X == x && Y == y;
115  }
116 };
117 
118 struct Line {
119  int X1;
120  int Y1;
121  int X2;
122  int Y2;
123 
124  Line() {
125  X1 = 0;
126  Y1 = 0;
127  X2 = 0;
128  Y2 = 0;
129  }
130 
131  Line(int x1, int y1, int x2, int y2) {
132  X1 = x1;
133  Y1 = y1;
134  X2 = x2;
135  Y2 = y2;
136  }
137 };
138 
139 // Helper factory functions
140 inline Line HLine(int x1, int x2, int y) {
141  return Line(x1, y, x2, y);
142 }
143 
144 inline Line VLine(int x, int y1, int y2) {
145  return Line(x, y1, x, y2);
146 }
147 
148 struct Size {
149  int Width;
150  int Height;
151 
152  Size() {
153  Width = 0;
154  Height = 0;
155  }
156 
157  Size(int width, int height) {
158  Width = width;
159  Height = height;
160  }
161 
162  inline bool IsNull() const {
163  return Width <= 0 || Height <= 0;
164  }
165 
166  inline static Size Clamp(const Size &sz, const Size &floor, const Size &ceil) {
167  return Size(AGSMath::Clamp(sz.Width, floor.Width, ceil.Width),
168  AGSMath::Clamp(sz.Height, floor.Height, ceil.Height));
169  }
170 
171  // Indicates if current size exceeds other size by any metric
172  inline bool ExceedsByAny(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 &size) const {
181  return Width != size.Width || Height != size.Height;
182  }
183 
184  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
185  return Width < other.Width || (Width == other.Width && Height < other.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-(const Size &size) const {
193  return Size(Width - size.Width, Height - size.Height);
194  }
195 
196  inline Size operator *(int x) const {
197  return Size(Width * x, Height * x);
198  }
199 
200  inline Size operator /(int x) const {
201  return Size(Width / x, Height / x);
202  }
203 
204  inline Size &operator *=(int x) {
205  Width *= x;
206  Height *= x;
207  return *this;
208  }
209 
210  inline Size &operator /=(int x) {
211  Width /= x;
212  Height /= x;
213  return *this;
214  }
215 };
216 
217 // TODO: consider making Rect have right-bottom coordinate with +1 offset
218 // to comply with many other libraries (i.e. Right - Left == Width)
219 struct Rect {
220  int Left;
221  int Top;
222  int Right;
223  int Bottom;
224 
225  Rect() {
226  Left = 0;
227  Top = 0;
228  Right = -1;
229  Bottom = -1;
230  }
231 
232  Rect(int l, int t, int r, int b) {
233  Left = l;
234  Top = t;
235  Right = r;
236  Bottom = b;
237  }
238 
239  inline Point GetLT() const {
240  return Point(Left, Top);
241  }
242 
243  inline Point GetCenter() const {
244  return Point(Left + GetWidth() / 2, Top + GetHeight() / 2);
245  }
246 
247  inline int GetWidth() const {
248  return Right - Left + 1;
249  }
250 
251  inline int GetHeight() const {
252  return Bottom - Top + 1;
253  }
254 
255  inline Size GetSize() const {
256  return Size(GetWidth(), GetHeight());
257  }
258 
259  inline bool IsEmpty() const {
260  return Right < Left || Bottom < Top;
261  }
262 
263  inline bool IsInside(int x, int y) const {
264  return x >= Left && y >= Top && (x <= Right) && (y <= Bottom);
265  }
266 
267  inline bool IsInside(const Point &pt) const {
268  return IsInside(pt.X, pt.Y);
269  }
270 
271  inline void MoveToX(int x) {
272  Right += x - Left;
273  Left = x;
274  }
275 
276  inline void MoveToY(int y) {
277  Bottom += y - Top;
278  Top = y;
279  }
280 
281  inline void MoveTo(const Point &pt) {
282  MoveToX(pt.X);
283  MoveToY(pt.Y);
284  }
285 
286  inline void SetWidth(int width) {
287  Right = Left + width - 1;
288  }
289 
290  inline void SetHeight(int height) {
291  Bottom = Top + height - 1;
292  }
293 
294  inline static Rect MoveBy(const Rect &r, int x, int y) {
295  return Rect(r.Left + x, r.Top + y, r.Right + x, r.Bottom + y);
296  }
297 
298  inline bool operator ==(const Rect &r) const {
299  return Left == r.Left && Top == r.Top &&
300  Right == r.Right && Bottom == r.Bottom;
301  }
302 };
303 
304 // Helper factory function
305 inline Rect RectWH(int x, int y, int width, int height) {
306  return Rect(x, y, x + width - 1, y + height - 1);
307 }
308 
309 inline Rect RectWH(const Size &sz) {
310  return Rect(0, 0, sz.Width - 1, sz.Height - 1);
311 }
312 
313 
314 struct Triangle {
315  int X1;
316  int Y1;
317  int X2;
318  int Y2;
319  int X3;
320  int Y3;
321 
322  Triangle() {
323  X1 = 0;
324  Y1 = 0;
325  X2 = 0;
326  Y2 = 0;
327  X3 = 0;
328  Y3 = 0;
329  }
330 
331  Triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
332  X1 = x1;
333  Y1 = y1;
334  X2 = x2;
335  Y2 = y2;
336  X3 = x3;
337  Y3 = y3;
338  }
339 };
340 
341 struct Circle {
342  int X;
343  int Y;
344  int Radius;
345 
346  Circle() {
347  X = 0;
348  Y = 0;
349  Radius = 0;
350  }
351 
352  Circle(int x, int y, int radius) {
353  X = x;
354  Y = y;
355  Radius = radius;
356  }
357 
358 };
359 
360 
361 // Tells if two rectangles intersect (overlap) at least partially
362 bool AreRectsIntersecting(const Rect &r1, const Rect &r2);
363 // Tells if the item is completely inside place
364 bool IsRectInsideRect(const Rect &place, const Rect &item);
365 // Calculates a distance between two axis-aligned rectangles, returns 0 if they intersect
366 float DistanceBetween(const Rect &r1, const Rect &r2);
367 
368 int AlignInHRange(int x1, int x2, int off_x, int width, FrameAlignment align);
369 int AlignInVRange(int y1, int y2, int off_y, int height, FrameAlignment align);
370 Rect AlignInRect(const Rect &frame, const Rect &item, FrameAlignment align);
371 
372 Size ProportionalStretch(int dest_w, int dest_h, int item_w, int item_h);
373 Size ProportionalStretch(const Size &dest, const Size &item);
374 
375 Rect OffsetRect(const Rect &r, const Point off);
376 Rect CenterInRect(const Rect &place, const Rect &item);
377 Rect ClampToRect(const Rect &place, const Rect &item);
378 Rect PlaceInRect(const Rect &place, const Rect &item, const RectPlacement &placement);
379 // Sum two rectangles, the result is the rectangle bounding them both
380 Rect SumRects(const Rect &r1, const Rect &r2);
381 // Intersect two rectangles, the resolt is the rectangle bounding their intersection
382 Rect IntersectRects(const Rect &r1, const Rect &r2);
383 
384 //} // namespace Shared
385 //} // namespace AGS
386 } // namespace AGS3
387 
388 #endif
Definition: geometry.h:87
Definition: geometry.h:314
Definition: geometry.h:118
Definition: geometry.h:219
Definition: geometry.h:148
Definition: geometry.h:341
Definition: ags.h:40