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
|
/* -*- 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 EmRegion_h
#define EmRegion_h
/*
EmRegion is a cross-platform region class. It provides for the following needs:
- A common API that can be used on both Mac and Windows
- An internal 32-bit representation so that regions can be calculated
in a 32-bit coordinate plane.
- Automatic management of heap structures so that you don't have to
remember to call DisposeRgn or DeleteObject.
Use regions as you would something like EmRect. Create them on the stack,
declare them as data members, pass them by reference, etc. For instance,
ScriptViewCore uses regions as follows to determine the highlight area:
{
EmRegion scratch;
EmRect aRect;
// The selection's bounding rectangle
aRect = ...; // Calculate full bounds
highlight = aRect;
// ... minus beginning of the first line
aRect = ...; // Calculate leading area to subtract
scratch = aRect;
highlight.Subtract(scratch);
// ... and the end of the last line
aRect = ...; // Calculate trailing area to subtract
scratch = aRect;
highlight.Subtract(scratch);
}
If you need to decompose the region into a series of rectangles, you can use
the EmRegionRectIterator class for this. It can be used as follows:
EmRegionRectIterator iter(*this);
EmRect r;
while (iter.Next(r))
{
// ...do something with the rect...
}
This region class is based on the region class from ET++ 3.2.2, used by
permission from Andr Weinand:
Regions: yes sure, just use the code and send me the bugs!
--andre
P.S.: my official life-long mail address is weinand@acm.org
*/
#include "EmPoint.h" // EmPoint
#include "EmRect.h" // EmRect
#include "EmRefCounted.h"
class EmRegion
{
public:
EmRegion (void);
// Creates a region spanning {0, 0, 0, 0}.
EmRegion (const EmRect& r);
// Creates a region spanning the given rectangle.
EmRegion (const EmRegion& r);
// Copy constructor. The internal data is copied via an internal
// reference counted object, so cloning regions is quick.
~EmRegion (void);
EmRegion& operator= (const EmRegion& r);
EmRegion& operator= (const EmRect& r);
// Assignment operator. Similar to copy constructor. There is also
// a version that takes an EmRect as an r-value.
void BeEmpty (void);
// Quickly empty out a region so that you don't have to do anything
// goofy like assigning a NULL rectangle to it.
const EmRect& Bounds (void) const;
// Returns an EmRect containing the bounds of the region.
long GetRects (EmRect* r) const;
// Decompose the region into a set of rectangles, returning the
// number of rectangles. You pass in a pointer to a buffer that
// will receive the rectangles. If you pass in NULL, no rectangles
// will be returned, but you'll still get the rectangle count.
// You should probably use a region iterator instead of this method
// if you want to mess with the rectangles.
Bool IsEmpty (void) const;
// Returns whether or not the region encompases any area.
Bool IsEqual (const EmRegion& r2) const;
// Compares two regions, returning whether or not they encompass
// the same area (set of pixels).
Bool Contains (const EmPoint& p) const;
// Returns whether or not the given point is in the interior of
// the area described by the region. Testing is performed on the
// normal half-open interval.
friend inline Bool operator== (const EmRegion& r1, const EmRegion& r2);
friend inline Bool operator!= (const EmRegion& r1, const EmRegion& r2);
// Shortcuts for the IsEqual method
void Offset (const EmPoint&);
void Offset (EmCoord dx, EmCoord dy);
// Offset the region by the given deltas. Positive deltas move
// the region down and to the right.
void Inset (const EmPoint&);
void Inset (EmCoord dx, EmCoord dy);
// Inset the region by the given deltas. Positive deltas move
// the region inward.
EmRegion& UnionWith (const EmRegion&);
EmRegion& IntersectWith(const EmRegion&);
EmRegion& Subtract (const EmRegion&);
EmRegion& XorWith (const EmRegion&);
// Modify the region in place. Note that XorWith is synthesized from
// the other operations, so it's not quite as effiecient as it
// could be.
friend inline EmRegion Union (const EmRegion& r1, const EmRegion& r2);
friend inline EmRegion Intersection(const EmRegion& r1, const EmRegion& r2);
friend inline EmRegion Difference (const EmRegion& r1, const EmRegion& r2);
friend inline EmRegion Xor (const EmRegion& r1, const EmRegion& r2);
// Versions of the previous four operations, with the difference
// being that neither of the given regions are modified. Instead,
// a new region containing the result is returned.
private:
enum EOpcode
{
eUnion = 0,
eDifference = 1,
eRevDifference = 2,
eIntersection = 3
};
EmRegion (const EmCoord* s, long len);
EmCoord* GetBuf (void) const;
long Length (void) const;
static EmRegion RegionOp (EOpcode code, const EmRegion& r1, const EmRegion& r2);
friend class EmRegionRectIterator;
class EmRegionImpl : public EmRefCounted
{
public:
EmRegionImpl (void);
EmRegionImpl (const EmCoord* s, long len);
EmRegionImpl (const EmRect& r);
EmRegionImpl (const EmRegion& r);
~EmRegionImpl (void);
Bool operator== (const EmRegionImpl& other) const;
long GetRects (EmRect* r) const;
Bool IsEqual (const EmRegionImpl&) const;
Bool Contains (const EmPoint& p) const;
void Offset (EmCoord dx, EmCoord dy);
protected:
void CalcBounds (void);
protected:
friend class EmRegion;
EmRect fBounds;
long fCapacity;
EmCoord* fBuf;
EmCoord fRectBuf[7];
};
EmRefCounter<EmRegionImpl> fImpl;
};
class EmRegionRectIterator
{
public:
EmRegionRectIterator (const EmRegion& r);
void Reset (void);
Bool Next (EmRect& r);
private:
EmRegion fRegion;
EmCoord* fBufPtr;
long fNext;
};
#endif // EmRegion_h
|