Commit e62e96e2 by Sascha Brawer Committed by Michael Koch

Fix for Classpath bug #6076.

2003-10-21  Sascha Brawer  <brawer@dandelis.ch>

	Fix for Classpath bug #6076.
	* java/awt/geom/GeneralPath.java (append): Re-written.

2003-10-21  Sascha Brawer  <brawer@dandelis.ch>

	Fix for Classpath bug #6089.
	* java/awt/geom/GeneralPath.java (curveTo): Set correct segment type.
	(getPathIterator, GeneralPathIterator): Re-written from scratch.

2003-10-21  Sascha Brawer  <brawer@dandelis.ch>

	* java/awt/geom/GeneralPath.java (getCurrentPoint): Return last
	point, not start of subpath.  Fixes Classpath bug #6075.

From-SVN: r72748
parent c4ff410a
2003-10-21 Sascha Brawer <brawer@dandelis.ch>
Fix for Classpath bug #6076.
* java/awt/geom/GeneralPath.java (append): Re-written.
2003-10-21 Sascha Brawer <brawer@dandelis.ch>
Fix for Classpath bug #6089.
* java/awt/geom/GeneralPath.java (curveTo): Set correct segment type.
(getPathIterator, GeneralPathIterator): Re-written from scratch.
2003-10-21 Sascha Brawer <brawer@dandelis.ch>
* java/awt/geom/GeneralPath.java (getCurrentPoint): Return last
point, not start of subpath. Fixes Classpath bug #6075.
2003-10-21 Michael Koch <konqueror@gmx.de> 2003-10-21 Michael Koch <konqueror@gmx.de>
* java/nio/ByteOrder.java, * java/nio/ByteOrder.java,
......
/* GeneralPath.java -- represents a shape built from subpaths /* GeneralPath.java -- represents a shape built from subpaths
Copyright (C) 2002 Free Software Foundation Copyright (C) 2002, 2003 Free Software Foundation
This file is part of GNU Classpath. This file is part of GNU Classpath.
...@@ -128,7 +128,7 @@ public final class GeneralPath implements Shape, Cloneable ...@@ -128,7 +128,7 @@ public final class GeneralPath implements Shape, Cloneable
float x3, float y3) float x3, float y3)
{ {
ensureSize(index + 6); ensureSize(index + 6);
types[index >> 1] = PathIterator.SEG_QUADTO; types[index >> 1] = PathIterator.SEG_CUBICTO;
points[index++] = x1; points[index++] = x1;
points[index++] = y1; points[index++] = y1;
points[index++] = x2; points[index++] = x2;
...@@ -148,40 +148,69 @@ public final class GeneralPath implements Shape, Cloneable ...@@ -148,40 +148,69 @@ public final class GeneralPath implements Shape, Cloneable
{ {
append(s.getPathIterator(null), connect); append(s.getPathIterator(null), connect);
} }
public void append(PathIterator i, boolean connect)
/**
* Appends the segments of a PathIterator to this GeneralPath.
* Optionally, the initial {@link PathIterator#SEG_MOVETO} segment
* of the appended path is changed into a {@link
* PathIterator#SEG_LINETO} segment.
*
* @param iter the PathIterator specifying which segments shall be
* appended.
*
* @param connect <code>true</code> for substituting the initial
* {@link PathIterator#SEG_MOVETO} segment by a {@link
* PathIterator#SEG_LINETO}, or <code>false</code> for not
* performing any substitution. If this GeneralPath is currently
* empty, <code>connect</code> is assumed to be <code>false</code>,
* thus leaving the initial {@link PathIterator#SEG_MOVETO}
* unchanged.
*/
public void append(PathIterator iter, boolean connect)
{ {
// A bad implementation of this method had caused Classpath bug #6076.
float[] f = new float[6]; float[] f = new float[6];
while (! i.isDone()) while (!iter.isDone())
{
switch (iter.currentSegment(f))
{ {
int result = i.currentSegment(f); case PathIterator.SEG_MOVETO:
switch (result) if (!connect || (index == 0))
{ {
case PathIterator.SEG_MOVETO: moveTo(f[0], f[1]);
if (! connect) break;
{ }
moveTo(f[0], f[1]);
break; if ((index >= 2) && (types[(index - 2) >> 2] == PathIterator.SEG_CLOSE)
} && (f[0] == points[index - 2]) && (f[1] == points[index - 1]))
if (subpath >= 0 && f[0] == points[subpath] break;
&& f[1] == points[subpath + 1])
break; // Fall through.
// Fallthrough.
case PathIterator.SEG_LINETO: case PathIterator.SEG_LINETO:
lineTo(f[0], f[1]); lineTo(f[0], f[1]);
break; break;
case PathIterator.SEG_QUADTO:
quadTo(f[0], f[1], f[2], f[3]); case PathIterator.SEG_QUADTO:
break; quadTo(f[0], f[1], f[2], f[3]);
case PathIterator.SEG_CUBICTO: break;
curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
break; case PathIterator.SEG_CUBICTO:
default: curveTo(f[0], f[1], f[2], f[3], f[4], f[5]);
closePath(); break;
}
connect = false; case PathIterator.SEG_CLOSE:
closePath();
break;
} }
connect = false;
iter.next();
}
} }
public int getWindingRule() public int getWindingRule()
{ {
return rule; return rule;
...@@ -197,7 +226,7 @@ public final class GeneralPath implements Shape, Cloneable ...@@ -197,7 +226,7 @@ public final class GeneralPath implements Shape, Cloneable
{ {
if (subpath < 0) if (subpath < 0)
return null; return null;
return new Point2D.Float(points[subpath], points[subpath + 1]); return new Point2D.Float(points[index - 2], points[index - 1]);
} }
public void reset() public void reset()
{ {
...@@ -254,80 +283,163 @@ public final class GeneralPath implements Shape, Cloneable ...@@ -254,80 +283,163 @@ public final class GeneralPath implements Shape, Cloneable
{ {
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
} }
public PathIterator getPathIterator(final AffineTransform at)
/**
* A PathIterator that iterates over the segments of a GeneralPath.
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
private static class GeneralPathIterator
implements PathIterator
{ {
return new PathIterator() /**
* The number of coordinate values for each segment type.
*/
private static final int[] NUM_COORDS =
{ {
int current = 0; /* 0: SEG_MOVETO */ 2,
/* 1: SEG_LINETO */ 2,
/* 2: SEG_QUADTO */ 4,
/* 3: SEG_CUBICTO */ 6,
/* 4: SEG_CLOSE */ 0
};
public int getWindingRule()
{
return rule;
}
public boolean isDone() /**
{ * The GeneralPath whose segments are being iterated.
return current >= index; */
} private final GeneralPath path;
public void next()
{
current++;
}
public int currentSegment(float[] coords) /**
* The affine transformation used to transform coordinates.
*/
private final AffineTransform transform;
/**
* The current position of the iterator.
*/
private int pos;
/**
* Constructs a new iterator for enumerating the segments of a
* GeneralPath.
*
* @param at an affine transformation for projecting the returned
* points, or <code>null</code> to return the original points
* without any mapping.
*/
GeneralPathIterator(GeneralPath path, AffineTransform transform)
{
this.path = path;
this.transform = transform;
}
/**
* Returns the current winding rule of the GeneralPath.
*/
public int getWindingRule()
{
return path.rule;
}
/**
* Determines whether the iterator has reached the last segment in
* the path.
*/
public boolean isDone()
{
return pos >= path.index;
}
/**
* Advances the iterator position by one segment.
*/
public void next()
{
int seg;
/* Increment pos by the number of coordinate values. Note that
* we store two values even for a SEG_CLOSE segment, which is
* why we increment pos at least by 2.
*/
seg = path.types[pos >> 1];
if (seg == SEG_CLOSE)
pos += 2;
else
pos += NUM_COORDS[seg];
}
/**
* Returns the current segment in float coordinates.
*/
public int currentSegment(float[] coords)
{
int seg, numCoords;
seg = path.types[pos >> 1];
numCoords = NUM_COORDS[seg];
if (numCoords > 0)
{ {
if (current >= index) if (transform == null)
return SEG_CLOSE; System.arraycopy(path.points, pos, coords, 0, numCoords);
int result = types[current >> 1]; else
int i = 0; transform.transform(/* src */ path.points, /* srcOffset */ pos,
if (result == 3) /* dest */ coords, /* destOffset */ 0,
{ /* 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;
} }
return seg;
}
/**
* Returns the current segment in double coordinates.
*/
public int currentSegment(double[] coords)
{
int seg, numCoords;
public int currentSegment(double[] coords) seg = path.types[pos >> 1];
numCoords = NUM_COORDS[seg];
if (numCoords > 0)
{ {
if (current >= index) if (transform == null)
return SEG_CLOSE; {
int result = types[current >> 1]; // System.arraycopy throws an exception if the source and destination
int i = 0; // array are not of the same primitive type.
if (result == 3) for (int i = 0; i < numCoords; i++)
{ coords[i] = (double) path.points[pos + i];
coords[i++] = points[current++]; }
coords[i++] = points[current++]; else
} transform.transform(/* src */ path.points, /* srcOffset */ pos,
if (result == 2) /* dest */ coords, /* destOffset */ 0,
{ /* 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;
} }
}; return seg;
}
}
/**
* Creates a PathIterator for iterating along the segments of this path.
*
* @param at an affine transformation for projecting the returned
* points, or <code>null</code> to let the created iterator return
* the original points without any mapping.
*/
public PathIterator getPathIterator(AffineTransform at)
{
return new GeneralPathIterator(this, at);
} }
public PathIterator getPathIterator(AffineTransform at, double flatness) public PathIterator getPathIterator(AffineTransform at, double flatness)
{ {
return new FlatteningPathIterator(getPathIterator(at), flatness); return new FlatteningPathIterator(getPathIterator(at), flatness);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment