Hi, the attached patch fixes rendering with AbstractGraphics2D, most importantly it limits the scanline area to the device bounds, so it doesn't try to render outside the device.
2006-06-09 Roman Kennke <[EMAIL PROTECTED]>
* gnu/java/awt/java2d/AbstractGraphics2D.java
(drawImage): Fixed scaling.
(fillShape): Removed offset handling.
(fillShapeImpl): Limit scanlining to device bounds.
(getSegments): Removed offset handling.
* gnu/java/awt/java2d/PolyEdge.java
(toString): Include isClip flag in output.
/Roman
--
“Improvement makes straight roads, but the crooked roads, without
Improvement, are roads of Genius.” - William Blake
Index: gnu/java/awt/java2d/AbstractGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java,v
retrieving revision 1.8
diff -u -1 -0 -r1.8 AbstractGraphics2D.java
--- gnu/java/awt/java2d/AbstractGraphics2D.java 19 May 2006 22:23:01 -0000 1.8
+++ gnu/java/awt/java2d/AbstractGraphics2D.java 9 Jun 2006 20:45:14 -0000
@@ -1324,22 +1324,22 @@
* @param y the y location to render to
* @param width the target width of the image
* @param height the target height of the image
* @param observer the image observer to receive notification
*/
public boolean drawImage(Image image, int x, int y, int width, int height,
ImageObserver observer)
{
AffineTransform t = new AffineTransform();
t.translate(x, y);
- double scaleX = (double) image.getWidth(observer) / (double) width;
- double scaleY = (double) image.getHeight(observer) / (double) height;
+ double scaleX = (double) width / (double) image.getWidth(observer);
+ double scaleY = (double) height / (double) image.getHeight(observer);
t.scale(scaleX, scaleY);
return drawImage(image, t, observer);
}
/**
* Draws the specified image at the specified location. This forwards
* to [EMAIL PROTECTED] #drawImage(Image, AffineTransform, ImageObserver)}.
*
* @param image the image to render
* @param x the x location to render to
@@ -1466,29 +1466,25 @@
// good hinting implemented.
antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//|| v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
}
else
{
Object v = renderingHints.get(RenderingHints.KEY_ANTIALIASING);
antialias = (v == RenderingHints.VALUE_ANTIALIAS_ON);
}
- double offs = 0.5;
- if (antialias)
- offs = offs / AA_SAMPLING;
-
Rectangle2D userBounds = s.getBounds2D();
Rectangle2D deviceBounds = new Rectangle2D.Double();
- ArrayList segs = getSegments(s, transform, deviceBounds, false, offs);
+ ArrayList segs = getSegments(s, transform, deviceBounds, false);
Rectangle2D clipBounds = new Rectangle2D.Double();
- ArrayList clipSegs = getSegments(clip, transform, clipBounds, true, offs);
+ ArrayList clipSegs = getSegments(clip, transform, clipBounds, true);
segs.addAll(clipSegs);
Rectangle2D inclClipBounds = new Rectangle2D.Double();
Rectangle2D.union(clipBounds, deviceBounds, inclClipBounds);
if (segs.size() > 0)
{
if (antialias)
fillShapeAntialias(segs, deviceBounds, userBounds, inclClipBounds);
else
fillShapeImpl(segs, deviceBounds, userBounds, inclClipBounds);
}
@@ -1669,21 +1665,24 @@
// Collections.sort(edgeTable[y]);
// }
// The activeEdges list contains all the edges of the current scanline
// ordered by their intersection points with this scanline.
ArrayList activeEdges = new ArrayList();
PolyEdgeComparator comparator = new PolyEdgeComparator();
// Scan all relevant lines.
int minYInt = (int) Math.ceil(icMinY);
- for (int y = minYInt; y <= maxY; y++)
+
+ Rectangle devClip = getDeviceBounds();
+ int scanlineMax = (int) Math.min(maxY, devClip.getMaxY());
+ for (int y = minYInt; y < scanlineMax; y++)
{
ArrayList bucket = edgeTable[y - minYInt];
// Update all the x intersections in the current activeEdges table
// and remove entries that are no longer in the scanline.
for (Iterator i = activeEdges.iterator(); i.hasNext();)
{
PolyEdge edge = (PolyEdge) i.next();
if (y > edge.y1)
i.remove();
else
@@ -2162,22 +2161,21 @@
* @param s the shape to convert
* @param t the transformation to apply before converting
* @param deviceBounds an output parameter; holds the bounding rectangle of
* s in device space after return
* @param isClip true when the shape is a clip, false for normal shapes;
* this influences the settings in the created PolyEdge instances.
*
* @return a list of PolyEdge that form the shape in device space
*/
private ArrayList getSegments(Shape s, AffineTransform t,
- Rectangle2D deviceBounds, boolean isClip,
- double offs)
+ Rectangle2D deviceBounds, boolean isClip)
{
// Flatten the path. TODO: Determine the best flattening factor
// wrt to speed and quality.
PathIterator path = s.getPathIterator(getTransform(), 1.0);
// Build up polygons and let the native backend render this using
// rawFillShape() which would provide a default implementation for
// drawPixel using a PolyScan algorithm.
double[] seg = new double[6];
@@ -2206,28 +2204,28 @@
if (segType == PathIterator.SEG_MOVETO)
{
segX = seg[0];
segY = seg[1];
polyX = seg[0];
polyY = seg[1];
}
else if (segType == PathIterator.SEG_CLOSE)
{
// Close the polyline.
- PolyEdge edge = new PolyEdge(segX, segY - offs,
- polyX, polyY - offs, isClip);
+ PolyEdge edge = new PolyEdge(segX, segY,
+ polyX, polyY, isClip);
segs.add(edge);
}
else if (segType == PathIterator.SEG_LINETO)
{
- PolyEdge edge = new PolyEdge(segX, segY - offs,
- seg[0], seg[1] - offs, isClip);
+ PolyEdge edge = new PolyEdge(segX, segY,
+ seg[0], seg[1], isClip);
segs.add(edge);
segX = seg[0];
segY = seg[1];
}
path.next();
}
deviceBounds.setRect(minX, minY, maxX - minX, maxY - minY);
return segs;
}
}
Index: gnu/java/awt/java2d/PolyEdge.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/java2d/PolyEdge.java,v
retrieving revision 1.2
diff -u -1 -0 -r1.2 PolyEdge.java
--- gnu/java/awt/java2d/PolyEdge.java 8 May 2006 14:39:17 -0000 1.2
+++ gnu/java/awt/java2d/PolyEdge.java 9 Jun 2006 20:45:14 -0000
@@ -111,13 +111,14 @@
if (x0 < other.x0)
comp = -1;
else if (x0 > other.x0)
comp = 1;
return comp;
}
public String toString()
{
return "Edge: " + x0 + ", " + y0 + ", " + x1 + ", " + y1 + ", slope: "
- + slope + ", xIntersection: " + xIntersection;
+ + slope + ", xIntersection: " + xIntersection
+ + ", isClip: " + isClip;
}
}
signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
