aboutsummaryrefslogtreecommitdiff
path: root/SrcShared/EmRect.h
diff options
context:
space:
mode:
Diffstat (limited to 'SrcShared/EmRect.h')
-rw-r--r--SrcShared/EmRect.h389
1 files changed, 389 insertions, 0 deletions
diff --git a/SrcShared/EmRect.h b/SrcShared/EmRect.h
new file mode 100644
index 0000000..efffda8
--- /dev/null
+++ b/SrcShared/EmRect.h
@@ -0,0 +1,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