File: EmRect.h

package info (click to toggle)
pose 3.5-7
  • links: PTS
  • area: contrib
  • in suites: sarge
  • size: 14,136 kB
  • ctags: 29,490
  • sloc: cpp: 93,990; ansic: 62,838; sh: 27,519; perl: 1,891; python: 1,242; makefile: 652
file content (389 lines) | stat: -rw-r--r-- 13,381 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
/* -*- mode: C++; tab-width: 4 -*- */
/* ===================================================================== *\
	Copyright (c) 2000-2001 Palm, Inc. or its subsidiaries.
	All rights reserved.

	This file is part of the Palm OS Emulator.

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
\* ===================================================================== */

#ifndef EmRect_h
#define EmRect_h

/*
	Contains classes for working with rectangles:

		EmRectTempl<coord>:	Generic template class. The type of rectangle
							coordinate is provided by the client.

		EmRect:				Specific specialization of EmRectTempl for EmCoord.

	For flexibility, the x/y ordering of coordinates within the object
	is controlled by the XYRect pre-processor symbol. Choosing a
	particular order enables certain conversion operations; choosing the
	other order enables other conversion operations. For instance, when
	using long coordinates and XY ordering, we can produce a RECT*
	(Win32 rect), but not a VRect* (MacApp rect).

	EmRect offers no new operations. What it does offer is constructors
	for creation from a platform-specific rectangle (like Rect, RECT, CRect,
	or VRect) or for producing some variant of a platform-specific
	rectangle. The different kinds of rects that EmRect attempts to convert
	to/from are:

		RECT		Rect
		CRect		VRect

	Where possible, EmRect produces pointers, const pointers, references,
	and const references to the above types.

	Note that there are no virtual functions. These rect classes are
	not intended to be used polymorphically.
*/

#include "EmPoint.h"			// EmPoint

#if PLATFORM_WINDOWS
	#define XYRect 1
#else
	#define XYRect 0
#endif

#undef topLeft

template <class coord>
class EmRectTempl
{
	public:
								EmRectTempl	()
								{}
								EmRectTempl	(coord left, coord top, coord right, coord bottom) :
#if XYRect
									fLeft (left),
									fTop (top),
									fRight (right),
									fBottom (bottom)
#else
									fTop (top),
									fLeft (left),
									fBottom (bottom),
									fRight (right)
#endif
								{}
								EmRectTempl	(const EmPointTempl<coord>& topLeft, const EmPointTempl<coord>& bottomRight) :
#if XYRect
									fLeft (topLeft.fX),
									fTop (topLeft.fY),
									fRight (bottomRight.fX),
									fBottom (bottomRight.fY)
#else
									fTop (topLeft.fY),
									fLeft (topLeft.fX),
									fBottom (bottomRight.fY),
									fRight (bottomRight.fX)
#endif
								{}
								EmRectTempl	(const EmRectTempl<coord>& other) :
#if XYRect
									fLeft (other.fLeft),
									fTop (other.fTop),
									fRight (other.fRight),
									fBottom (other.fBottom)
#else
									fTop (other.fTop),
									fLeft (other.fLeft),
									fBottom (other.fBottom),
									fRight (other.fRight)
#endif
								{}

//								~EmRectTempl() {};
			// Constructors/Destructor. The default constructor doesn't do anything,
			// including setting its members to zero. There is no destructor to cut
			// down on the amount of code generated for this lightweight class.

		coord					Width		(void) const;
		coord					Height		(void) const;
			// Return the width and height of the rectangle. The return type
			// is the same as the coordinate type.

		EmPointTempl<coord>		Size		(void) const;
			// Return the size of the rectangle. The return type is an
			// EmPointTempl<coord> with the same type as the coordinate type.

		EmPointTempl<coord>		TopLeft		(void) const;
		EmPointTempl<coord>		TopRight	(void) const;
		EmPointTempl<coord>		BottomLeft	(void) const;
		EmPointTempl<coord>		BottomRight	(void) const;
		EmPointTempl<coord>		North		(void) const;
		EmPointTempl<coord>		South		(void) const;
		EmPointTempl<coord>		East		(void) const;
		EmPointTempl<coord>		West		(void) const;
		EmPointTempl<coord>		Center		(void) const;
			// Return the following marked points of a rectangle. The return
			// type is an EmPointTempl<coord> with the same type as the coordinate
			// type.
			//				    North
			//		TopLeft X-----X-----X TopRight
			// 				|           |
			//				|           |
			//		   West X     X     X East
			//				|    Ctr    |
			//				|           |
			//	 BottomLeft X-----X-----X BottomRight
			//				    South

		Bool					IsEmpty		(void) const;
			// Returns whether or not the rectangle contains positive area. The
			// coordinates do not necessarily have to be zero.

		Bool					IsNull		(void) const;
			// Returns whether or not all four coordinates are zero.

		Bool					IsEqual		(const EmRectTempl<coord>& other) const;
			// Returns whether or not two rectangles have the same coordinates.
			// Same as operator==().

		Bool					Contains	(const EmPointTempl<coord>&) const;
		Bool					Contains	(const EmRectTempl<coord>&) const;
			// Returns whether or not the given point or rectangle is contained
			// by the rectangle. Comparisons are made on a half-open interval.

		Bool					Intersects	(const EmRectTempl<coord>&) const;
			// Returns whether or not the two rectangles intersect each other.

		void					Set			(coord left, coord top, coord right, coord bottom);
		void					Set			(const EmPointTempl<coord>& topLeft, const EmPointTempl<coord>& bottomRight);
			// Set the coordinates of an already created rectangle. Performs
			// essentially the same operation as the constructors.

		void					BeEmpty		(void);
			// Set all four coordinates to zero. Technically, I supposed this
			// is a "SetNull" operation, but a future implementation could
			// conceivably just set fRight to fLeft.

		void					Inset		(coord x, coord y);
			// Inset the four coordinates by the given amounts.

		void					Offset		(coord x, coord y);
			// Add x and y to the rects's coordinates. Same as operator+=()
			// except that you specify coordinates, not another point.

		void					ScaleUp		(coord x, coord y);
			// Multiply the rects's coordinates by x and y. Same as operator*=()
			// except that you specify coordinates, not another point.

		void					ScaleDown	(coord x, coord y);
			// Divide the rects's coordinates by x and y. Same as operator/=()
			// except that you specify coordinates, not another point.

		void					IntersectWith(const EmRectTempl<coord>& other);
			// Intersect *this with other, storing the result in *this.
			// If other is an empty rectangle, *this will end up being an
			// empty rectangle, but no other guarantee is made about its
			// coordinates.

		void					UnionWith	(const EmRectTempl<coord>& other);
			// Union *this with other, storing the result in *this.
			// Empty rectangles are ignored (i.e., if *this is an empty
			// rectangle, other is copied into *this. If other is an empty
			// rectangle, *this is unchanged).

		void					ExtendTo	(const EmPointTempl<coord>& pt);
		void					ExtendTo	(const EmRectTempl<coord>& other);
			// Extend *this to contain the points expressed by the given
			// point or rectangle. The version taking a rectangle is similar
			// to UnionWith, the difference being that empty rectangles are
			// not ignored.

		void					Normalize	(void);
			// Order the coordinates such that fLeft <= fRight and fTop
			// <= fBottom.

		EmRectTempl<coord>		operator+	(const EmPointTempl<coord>& pt) const;
		EmRectTempl<coord>		operator-	(const EmPointTempl<coord>& pt) const;
		EmRectTempl<coord>&		operator+=	(const EmPointTempl<coord>& pt);
		EmRectTempl<coord>&		operator-=	(const EmPointTempl<coord>& pt);
			// Offset the rectangle by the amounts indicated by the EmPointTempl
			// parameter. The first two methods return a new EmRectTempl, leaving
			// the original untouched. The second two alter the original
			// rectangle in-place.

		EmRectTempl<coord>		operator*	(const EmPointTempl<coord>& pt) const;
		EmRectTempl<coord>		operator/	(const EmPointTempl<coord>& pt) const;
		EmRectTempl<coord>&		operator*=	(const EmPointTempl<coord>& pt);
		EmRectTempl<coord>&		operator/=	(const EmPointTempl<coord>& pt);
			// Scale the rectangle by the amounts indicated by the EmPointTempl
			// parameter. The first two methods return a new EmRectTempl, leaving
			// the original untouched. The second two alter the original
			// rectangle in-place.

		Bool					operator==	(const EmRectTempl<coord>& rt) const;
		Bool					operator!=	(const EmRectTempl<coord>& rt) const;
			// (In)equality operators. Returns whether or not the coordinates
			// of the two rectangles are equal to each other.

		EmRectTempl<coord>		operator&	(const EmRectTempl<coord>& rt) const;	// Intersection
		EmRectTempl<coord>		operator|	(const EmRectTempl<coord>& rt) const;	// Union
		EmRectTempl<coord>&		operator&=	(const EmRectTempl<coord>& rt);
		EmRectTempl<coord>&		operator|=	(const EmRectTempl<coord>& rt);
			// Synonyms for Intersect and Union, respectively. The first
			// two operators return the result in a new EmRectTempl. The second
			// pair of operators alter the target rectangle in-place.

			// Directly accessible data members.
#if XYRect
		coord	fLeft;
		coord	fTop;
		coord	fRight;
		coord	fBottom;
#else
		coord	fTop;
		coord	fLeft;
		coord	fBottom;
		coord	fRight;
#endif
};


// ----------------------------------------------------------------------
//	Types we interoperate with
// ----------------------------------------------------------------------

struct	tagRECT;
typedef struct tagRECT RECT;
class	CRect;

struct	Rect;
struct	VRect;


/* ----------------------------------------------------------------------
	Macros to help with creating the massive number of constructors and
	conversion operators we support:

		RECT_LIST_XY_SHORT:		List of rect-types using x/y coordinate
								ordering and short coordinates.

		RECT_LIST_XY_LONG:		List of rect-types using x/y coordinate
								ordering and long coordinates.

		RECT_LIST_YX_SHORT:		List of rect-types using y/x coordinate
								ordering and short coordinates.

		RECT_LIST_YX_LONG:		List of rect-types using y/x coordinate
								ordering and long coordinates.

		RECT_LIST_SHORT:		List of rect-types using short coordinates.
								Only rect-types using the same x/y ordering
								as indicated by XYRect are included.

		RECT_LIST_LONG:			List of rect-types using long coordinates.
								Only point-types using the same x/y ordering
								as indicated by XYRect are included.

	Each of the above lists includes a reference to a rect-type using a
	FOR_RECT macro. The FOR_RECT macro takes as parameters the
	rect-type, the size of coordinates, and offsets to each coordinate.
	This information is all that's needed for constructing all of
	constructors and convertion operators, both declarations and
	implementations. To perform the actual construction, FOR_RECT is
	defined to expand to the appropriate code for a single constructor
	or conversion, and then the appropriate RECT_LIST macro from above
	is "invoked" to expand the list as needed.
  ---------------------------------------------------------------------- */

#define RECT_LIST_XY_SHORT				\
	FOR_RECT(AbsRectType, short, 0, 1, 2, 3)

#define RECT_LIST_XY_LONG				\
	FOR_RECT(RECT, long, 0, 1, 2, 3)	\
	FOR_RECT(CRect, long, 0, 1, 2, 3)

#define RECT_LIST_YX_SHORT				\
	FOR_RECT(Rect, short, 1, 0, 3, 2)

#define RECT_LIST_YX_LONG				\
	FOR_RECT(VRect, long, 1, 0, 3, 2)

#if XYRect
	#define RECT_LIST_LONG	RECT_LIST_XY_LONG
	#define RECT_LIST_SHORT	RECT_LIST_XY_SHORT
#else
	#define RECT_LIST_LONG	RECT_LIST_YX_LONG
	#define RECT_LIST_SHORT	RECT_LIST_YX_SHORT
#endif

// ----------------------------------------------------------------------
//	* EmRect
// ----------------------------------------------------------------------

class EmRect : public EmRectTempl<EmCoord>
{
	public:
								EmRect	()
								{}
								EmRect	(EmCoord left, EmCoord top, EmCoord right, EmCoord bottom) :
									EmRectTempl<EmCoord> (left, top, right, bottom)
								{}
								EmRect	(const RectangleType& r) :
									EmRectTempl<EmCoord> (	r.topLeft.x, r.topLeft.y,
															r.topLeft.x + r.extent.x,
															r.topLeft.y + r.extent.y)
								{}
								EmRect	(const EmPointTempl<EmCoord>& topLeft, const EmPointTempl<EmCoord>& bottomRight) :
									EmRectTempl<EmCoord>(topLeft, bottomRight)
								{}
								EmRect	(const EmRectTempl<EmCoord>& r) :
									EmRectTempl<EmCoord>(r)
								{}

//								~EmRect() {};

	//
	// Construct from another kind of rectangle
	// Assigned from another kind of rectangle
	// !!! Move functionality inline?
	//
		#undef FOR_RECT
		#define FOR_RECT(cls, size, l, t, b, r)		\
			EmRect (const cls&); 					\
			const EmRect& operator= (const cls&);

		RECT_LIST_XY_SHORT
		RECT_LIST_XY_LONG
		RECT_LIST_YX_SHORT
		RECT_LIST_YX_LONG

	//
	// Return another kind of rectangle
	// !!! Move functionality inline?
	//
		#undef FOR_RECT
		#define FOR_RECT(cls, size, l, t, b, r)		\
			operator cls () const;

		RECT_LIST_XY_LONG
		RECT_LIST_YX_LONG
		RECT_LIST_XY_SHORT
		RECT_LIST_YX_SHORT

	//
	// Return a [const] (* | &) to another kind of rectangle
	// !!! Move functionality inline?
	//
		#undef FOR_RECT
		#define FOR_RECT(cls, size, l, t, b, r)	\
			operator const cls* () const; 		\
			operator cls* (); 					\
			operator const cls& () const; 		\
			operator cls& ();

		RECT_LIST_LONG
};

#endif	// EmRect_h