7 namespace System.Drawing.Drawing2D
\r
9 internal class ExtendedGeneralPath : Shape, ICloneable
\r
13 public const int WIND_EVEN_ODD = 0; //PathIterator__Finals.WIND_EVEN_ODD;
\r
14 public const int WIND_NON_ZERO = 1; //PathIterator__Finals.WIND_NON_ZERO;
\r
16 public const sbyte SEG_MOVETO = 0; //(byte) PathIterator__Finals.SEG_MOVETO;
\r
17 public const sbyte SEG_LINETO = 1; //(byte) PathIterator__Finals.SEG_LINETO;
\r
18 public const sbyte SEG_QUADTO = 2; //(byte) PathIterator__Finals.SEG_QUADTO;
\r
19 public const sbyte SEG_CUBICTO = 3; //(byte) PathIterator__Finals.SEG_CUBICTO;
\r
20 public const sbyte SEG_CLOSE = 4; //(byte) PathIterator__Finals.SEG_CLOSE;
\r
22 public const sbyte SEG_START = 16; // segment start
\r
24 public const sbyte SEG_MASK = SEG_MOVETO | SEG_LINETO | SEG_QUADTO | SEG_CUBICTO | SEG_CLOSE; // mask to eliminate SEG_CLOSE and SEG_MARKER
\r
26 private const sbyte SEG_MARKER = 32; // path marker
\r
29 private sbyte [] _types;
\r
30 private float [] _coords;
\r
31 private int _typesCount;
\r
32 private int _coordsCount;
\r
33 private int _windingRule;
\r
35 const int INIT_SIZE = 20;
\r
36 const int EXPAND_MAX = 500;
\r
38 #endregion // Fileds
\r
40 #region Constructors
\r
42 public ExtendedGeneralPath() : this (WIND_NON_ZERO, INIT_SIZE, INIT_SIZE)
\r
46 public ExtendedGeneralPath(int rule) : this (rule, INIT_SIZE, INIT_SIZE)
\r
50 public ExtendedGeneralPath(int rule, int initialCapacity) : this (rule, initialCapacity, initialCapacity)
\r
54 public ExtendedGeneralPath(Shape s) : this(WIND_NON_ZERO, INIT_SIZE, INIT_SIZE)
\r
56 PathIterator pi = s.getPathIterator (null);
\r
57 setWindingRule (pi.getWindingRule ());
\r
61 private ExtendedGeneralPath(int rule, int initialTypes, int initialCoords)
\r
63 setWindingRule(rule);
\r
64 _types = new sbyte [initialTypes];
\r
65 _coords = new float [initialCoords * 2];
\r
68 #endregion // Constructors
\r
72 private GeneralPath GeneralPath
\r
75 PathIterator iter = getPathIterator (null);
\r
76 GeneralPath path = new GeneralPath ();
\r
77 path.append (iter, false);
\r
82 public sbyte [] Types
\r
84 get { return _types; }
\r
87 public float [] Coords
\r
89 get { return _coords; }
\r
92 public int TypesCount
\r
94 get { return _typesCount; }
\r
97 public int CoordsCount
\r
99 get { return _coordsCount; }
\r
102 public bool LastFigureClosed
\r
105 return ((TypesCount == 0) ||
\r
106 ((Types [TypesCount - 1] & ExtendedGeneralPath.SEG_CLOSE) != 0) ||
\r
107 ((Types [TypesCount - 1] & ExtendedGeneralPath.SEG_START) != 0));
\r
113 #endregion // Properties
\r
117 public void append(Shape s)
\r
119 append (s, !LastFigureClosed);
\r
122 #region GeneralPath
\r
124 public void append(PathIterator pi, bool connect)
\r
126 float [] coords = new float [6];
\r
127 while (!pi.isDone ()) {
\r
128 switch (pi.currentSegment (coords)) {
\r
130 if (!connect || _typesCount < 1 || _coordsCount < 2) {
\r
131 moveTo (coords [0], coords [1]);
\r
134 if (_types [_typesCount - 1] != SEG_CLOSE &&
\r
135 _coords [_coordsCount - 2] == coords [0] &&
\r
136 _coords [_coordsCount - 1] == coords [1])
\r
138 goto case SEG_LINETO;
\r
140 lineTo (coords [0], coords [1]);
\r
143 quadTo (coords [0], coords [1], coords [2], coords [3]);
\r
146 curveTo (coords [0], coords [1], coords [2], coords [3], coords [4], coords [5]);
\r
157 public void append(Shape s, bool connect)
\r
159 PathIterator pi = s.getPathIterator (null);
\r
160 append (pi,connect);
\r
163 public object Clone()
\r
165 ExtendedGeneralPath copy = new ExtendedGeneralPath ();
\r
166 copy._types = (sbyte []) _types.Clone ();
\r
167 copy._coords = (float []) _coords.Clone ();
\r
171 public void closePath()
\r
173 if (_typesCount == 0 || _types[_typesCount - 1] != SEG_CLOSE) {
\r
174 needRoom (1, 0, true);
\r
175 _types [_typesCount++] = SEG_CLOSE;
\r
179 public bool contains(double x, double y)
\r
181 return GeneralPath.contains (x, y);
\r
184 public bool contains(double x, double y, double w, double h)
\r
186 return GeneralPath.contains (x, y, w, h);
\r
189 public bool contains(Point2D p)
\r
191 return contains (p.getX (), p.getY ());
\r
194 public bool contains(Rectangle2D r)
\r
196 return contains (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
\r
199 public Shape createTransformedShape(AffineTransform at)
\r
201 ExtendedGeneralPath gp = (ExtendedGeneralPath) Clone ();
\r
208 public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3)
\r
210 needRoom (1, 6, true);
\r
211 _types [_typesCount++] = SEG_CUBICTO;
\r
212 _coords [_coordsCount++] = x1;
\r
213 _coords [_coordsCount++] = y1;
\r
214 _coords [_coordsCount++] = x2;
\r
215 _coords [_coordsCount++] = y2;
\r
216 _coords [_coordsCount++] = x3;
\r
217 _coords [_coordsCount++] = y3;
\r
220 public java.awt.Rectangle getBounds()
\r
222 return getBounds2D ().getBounds ();
\r
225 public Rectangle2D getBounds2D()
\r
227 float x1, y1, x2, y2;
\r
228 int i = _coordsCount;
\r
230 y1 = y2 = _coords [--i];
\r
231 x1 = x2 = _coords [--i];
\r
233 float y = _coords [--i];
\r
234 float x = _coords [--i];
\r
235 if (x < x1) x1 = x;
\r
236 if (y < y1) y1 = y;
\r
237 if (x > x2) x2 = x;
\r
238 if (y > y2) y2 = y;
\r
242 x1 = y1 = x2 = y2 = 0f;
\r
244 return new Rectangle2D.Float (x1, y1, x2 - x1, y2 - y1);
\r
247 public Point2D getCurrentPoint()
\r
249 if (_typesCount < 1 || _coordsCount < 2)
\r
252 int index = _coordsCount;
\r
253 if (_types [_typesCount - 1] == SEG_CLOSE)
\r
254 for (int i = _typesCount - 2; i > 0; i--) {
\r
255 switch (_types [i]) {
\r
274 return new Point2D.Float (_coords [index - 2], _coords [index - 1]);
\r
277 public PathIterator getPathIterator(AffineTransform at) {
\r
278 return new GeneralPathIterator (this, at);
\r
281 public PathIterator getPathIterator(AffineTransform at, double flatness) {
\r
282 return new FlatteningPathIterator (getPathIterator (at), flatness);
\r
285 public int getWindingRule()
\r
287 return _windingRule;
\r
290 public bool intersects(double x, double y, double w, double h)
\r
292 return GeneralPath.intersects (x, y, w, h);
\r
295 public bool intersects(Rectangle2D r)
\r
297 return intersects (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
\r
300 public void lineTo(float x, float y)
\r
302 needRoom (1, 2, true);
\r
303 _types [_typesCount++] = SEG_LINETO;
\r
304 _coords [_coordsCount++] = x;
\r
305 _coords [_coordsCount++] = y;
\r
308 public void moveTo(float x, float y)
\r
310 if (_typesCount > 0 && _types [_typesCount - 1] == SEG_MOVETO) {
\r
311 _coords [_coordsCount - 2] = x;
\r
312 _coords [_coordsCount - 1] = y;
\r
315 needRoom (1, 2, false);
\r
316 _types [_typesCount++] = SEG_MOVETO;
\r
317 _coords [_coordsCount++] = x;
\r
318 _coords [_coordsCount++] = y;
\r
322 public void quadTo(float x1, float y1, float x2, float y2)
\r
324 needRoom (1, 4, true);
\r
325 _types [_typesCount++] = SEG_QUADTO;
\r
326 _coords [_coordsCount++] = x1;
\r
327 _coords [_coordsCount++] = y1;
\r
328 _coords [_coordsCount++] = x2;
\r
329 _coords [_coordsCount++] = y2;
\r
332 public void reset()
\r
338 public void setWindingRule(int rule)
\r
340 if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
\r
341 throw new IllegalArgumentException ("winding rule must be WIND_EVEN_ODD or WIND_NON_ZERO");
\r
343 _windingRule = rule;
\r
346 public void transform(AffineTransform at)
\r
348 at.transform (_coords, 0, _coords, 0, _coordsCount/2);
\r
351 private void needRoom(int newTypes, int newCoords, bool needMove)
\r
353 if (needMove && _typesCount == 0)
\r
354 throw new IllegalPathStateException ("missing initial moveto in path definition");
\r
356 int size = _coords.Length;
\r
357 if (_coordsCount + newCoords > size) {
\r
359 if (grow > EXPAND_MAX * 2)
\r
360 grow = EXPAND_MAX * 2;
\r
362 if (grow < newCoords)
\r
365 float [] arr = new float [size + grow];
\r
366 Array.Copy (_coords, 0, arr, 0, _coordsCount);
\r
369 size = _types.Length;
\r
370 if (_typesCount + newTypes > size) {
\r
372 if (grow > EXPAND_MAX)
\r
375 if (grow < newTypes)
\r
378 sbyte [] arr = new sbyte [size + grow];
\r
379 Array.Copy (_types, 0, arr, 0, _typesCount);
\r
384 #endregion // GeneralPath
\r
386 public void SetMarkers()
\r
388 Types [ TypesCount - 1] |= SEG_MARKER;
\r
391 public void ClearMarkers()
\r
393 for (int i = 0; i < TypesCount; i++)
\r
394 Types [i] &= ~SEG_MARKER;
\r
397 #endregion //Methods
\r