1 |
/* GeneralPath.java -- represents a shape built from subpaths |
/* GeneralPath.java -- represents a shape built from subpaths |
2 |
Copyright (C) 2002 Free Software Foundation |
Copyright (C) 2002, 2003 Free Software Foundation |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
128 |
float x3, float y3) |
float x3, float y3) |
129 |
{ |
{ |
130 |
ensureSize(index + 6); |
ensureSize(index + 6); |
131 |
types[index >> 1] = PathIterator.SEG_QUADTO; |
types[index >> 1] = PathIterator.SEG_CUBICTO; |
132 |
points[index++] = x1; |
points[index++] = x1; |
133 |
points[index++] = y1; |
points[index++] = y1; |
134 |
points[index++] = x2; |
points[index++] = x2; |
254 |
{ |
{ |
255 |
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); |
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); |
256 |
} |
} |
257 |
public PathIterator getPathIterator(final AffineTransform at) |
|
258 |
|
|
259 |
|
/** |
260 |
|
* A PathIterator that iterates over the segments of a GeneralPath. |
261 |
|
* |
262 |
|
* @author Sascha Brawer (brawer@dandelis.ch) |
263 |
|
*/ |
264 |
|
private static class GeneralPathIterator |
265 |
|
implements PathIterator |
266 |
{ |
{ |
267 |
return new PathIterator() |
/** |
268 |
|
* The number of coordinate values for each segment type. |
269 |
|
*/ |
270 |
|
private static final int[] NUM_COORDS = |
271 |
{ |
{ |
272 |
int current = 0; |
/* 0: SEG_MOVETO */ 2, |
273 |
|
/* 1: SEG_LINETO */ 2, |
274 |
|
/* 2: SEG_QUADTO */ 4, |
275 |
|
/* 3: SEG_CUBICTO */ 6, |
276 |
|
/* 4: SEG_CLOSE */ 0 |
277 |
|
}; |
278 |
|
|
|
public int getWindingRule() |
|
|
{ |
|
|
return rule; |
|
|
} |
|
279 |
|
|
280 |
public boolean isDone() |
/** |
281 |
{ |
* The GeneralPath whose segments are being iterated. |
282 |
return current >= index; |
*/ |
283 |
} |
private final GeneralPath path; |
284 |
|
|
285 |
|
|
286 |
|
/** |
287 |
|
* The affine transformation used to transform coordinates. |
288 |
|
*/ |
289 |
|
private final AffineTransform transform; |
290 |
|
|
291 |
|
|
292 |
|
/** |
293 |
|
* The current position of the iterator. |
294 |
|
*/ |
295 |
|
private int pos; |
296 |
|
|
297 |
|
|
298 |
|
/** |
299 |
|
* Constructs a new iterator for enumerating the segments of a |
300 |
|
* GeneralPath. |
301 |
|
* |
302 |
|
* @param at an affine transformation for projecting the returned |
303 |
|
* points, or <code>null</code> to return the original points |
304 |
|
* without any mapping. |
305 |
|
*/ |
306 |
|
GeneralPathIterator(GeneralPath path, AffineTransform transform) |
307 |
|
{ |
308 |
|
this.path = path; |
309 |
|
this.transform = transform; |
310 |
|
} |
311 |
|
|
|
public void next() |
|
|
{ |
|
|
current++; |
|
|
} |
|
312 |
|
|
313 |
public int currentSegment(float[] coords) |
/** |
314 |
|
* Returns the current winding rule of the GeneralPath. |
315 |
|
*/ |
316 |
|
public int getWindingRule() |
317 |
|
{ |
318 |
|
return path.rule; |
319 |
|
} |
320 |
|
|
321 |
|
|
322 |
|
/** |
323 |
|
* Determines whether the iterator has reached the last segment in |
324 |
|
* the path. |
325 |
|
*/ |
326 |
|
public boolean isDone() |
327 |
|
{ |
328 |
|
return pos >= path.index; |
329 |
|
} |
330 |
|
|
331 |
|
|
332 |
|
/** |
333 |
|
* Advances the iterator position by one segment. |
334 |
|
*/ |
335 |
|
public void next() |
336 |
|
{ |
337 |
|
int seg; |
338 |
|
|
339 |
|
/* Increment pos by the number of coordinate values. Note that |
340 |
|
* we store two values even for a SEG_CLOSE segment, which is |
341 |
|
* why we increment pos at least by 2. |
342 |
|
*/ |
343 |
|
seg = path.types[pos >> 1]; |
344 |
|
if (seg == SEG_CLOSE) |
345 |
|
pos += 2; |
346 |
|
else |
347 |
|
pos += NUM_COORDS[seg]; |
348 |
|
} |
349 |
|
|
350 |
|
|
351 |
|
/** |
352 |
|
* Returns the current segment in float coordinates. |
353 |
|
*/ |
354 |
|
public int currentSegment(float[] coords) |
355 |
|
{ |
356 |
|
int seg, numCoords; |
357 |
|
|
358 |
|
seg = path.types[pos >> 1]; |
359 |
|
numCoords = NUM_COORDS[seg]; |
360 |
|
if (numCoords > 0) |
361 |
{ |
{ |
362 |
if (current >= index) |
if (transform == null) |
363 |
return SEG_CLOSE; |
System.arraycopy(path.points, pos, coords, 0, numCoords); |
364 |
int result = types[current >> 1]; |
else |
365 |
int i = 0; |
transform.transform(/* src */ path.points, /* srcOffset */ pos, |
366 |
if (result == 3) |
/* dest */ coords, /* destOffset */ 0, |
367 |
{ |
/* numPoints */ numCoords >> 1); |
|
coords[i++] = points[current++]; |
|
|
coords[i++] = points[current++]; |
|
|
} |
|
|
if (result == 2) |
|
|
{ |
|
|
coords[i++] = points[current++]; |
|
|
coords[i++] = points[current++]; |
|
|
} |
|
|
if (result < 2) |
|
|
{ |
|
|
coords[i++] = points[current++]; |
|
|
coords[i++] = points[current++]; |
|
|
if (at != null) |
|
|
at.transform(coords, 0, coords, 0, result == 0 ? 1 : result); |
|
|
} |
|
|
return result; |
|
368 |
} |
} |
369 |
|
return seg; |
370 |
|
} |
371 |
|
|
372 |
|
|
373 |
public int currentSegment(double[] coords) |
/** |
374 |
|
* Returns the current segment in double coordinates. |
375 |
|
*/ |
376 |
|
public int currentSegment(double[] coords) |
377 |
|
{ |
378 |
|
int seg, numCoords; |
379 |
|
|
380 |
|
seg = path.types[pos >> 1]; |
381 |
|
numCoords = NUM_COORDS[seg]; |
382 |
|
if (numCoords > 0) |
383 |
{ |
{ |
384 |
if (current >= index) |
if (transform == null) |
385 |
return SEG_CLOSE; |
{ |
386 |
int result = types[current >> 1]; |
// System.arraycopy throws an exception if the source and destination |
387 |
int i = 0; |
// array are not of the same primitive type. |
388 |
if (result == 3) |
for (int i = 0; i < numCoords; i++) |
389 |
{ |
coords[i] = (double) path.points[pos + i]; |
390 |
coords[i++] = points[current++]; |
} |
391 |
coords[i++] = points[current++]; |
else |
392 |
} |
transform.transform(/* src */ path.points, /* srcOffset */ pos, |
393 |
if (result == 2) |
/* dest */ coords, /* destOffset */ 0, |
394 |
{ |
/* numPoints */ numCoords >> 1); |
|
coords[i++] = points[current++]; |
|
|
coords[i++] = points[current++]; |
|
|
} |
|
|
if (result < 2) |
|
|
{ |
|
|
coords[i++] = points[current++]; |
|
|
coords[i++] = points[current++]; |
|
|
if (at != null) |
|
|
at.transform(coords, 0, coords, 0, result == 0 ? 1 : result); |
|
|
} |
|
|
return result; |
|
395 |
} |
} |
396 |
}; |
return seg; |
397 |
|
} |
398 |
} |
} |
399 |
|
|
400 |
|
|
401 |
|
/** |
402 |
|
* Creates a PathIterator for iterating along the segments of this path. |
403 |
|
* |
404 |
|
* @param at an affine transformation for projecting the returned |
405 |
|
* points, or <code>null</code> to let the created iterator return |
406 |
|
* the original points without any mapping. |
407 |
|
*/ |
408 |
|
public PathIterator getPathIterator(AffineTransform at) |
409 |
|
{ |
410 |
|
return new GeneralPathIterator(this, at); |
411 |
|
} |
412 |
|
|
413 |
|
|
414 |
public PathIterator getPathIterator(AffineTransform at, double flatness) |
public PathIterator getPathIterator(AffineTransform at, double flatness) |
415 |
{ |
{ |
416 |
return new FlatteningPathIterator(getPathIterator(at), flatness); |
return new FlatteningPathIterator(getPathIterator(at), flatness); |