summaryrefslogtreecommitdiff
path: root/gnu/java/awt/java2d/ScanlineConverter.java
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2007-05-18 16:22:39 +0000
committerRoman Kennke <roman@kennke.org>2007-05-18 16:22:39 +0000
commit76ac22c61bbf8c759f06c96d0021af0b5854a404 (patch)
tree16013e081e61cadfbaaf3b581597e448214e271b /gnu/java/awt/java2d/ScanlineConverter.java
parent46e5d7d81bb441ebffe6a89723f4d7c2eceadf60 (diff)
downloadclasspath-76ac22c61bbf8c759f06c96d0021af0b5854a404.tar.gz
2007-05-18 Roman Kennke <roman@kennke.org>
* gnu/java/awt/java2d/AbstractGraphics2D.java (fillScanlineAA): Removed. Replaced by renderScanline(). (fillScanline): Dito. (renderScanline): New method. Renders a scanline according to the coverage information from the scanline converter. * gnu/java/awt/java2d/Pixelizer.java: New interface. Describes the targets of the rasterizer. * gnu/java/awt/java2d/ScanlineConverter.java (alphaRes): Removed. (ONE): Removed. (scanlineCoverage): New field. Manages the coverage information. (scanlinesPerPixel): Removed. (scanlineXCov): Removed. (scanlineYCov): Removed. (slPix0): Removed. (ScanlineConverter): Initialize scanline coverage data structure. (clear): Also clear the scanline coverage. (doScanline): Work with Pixelizer objects. Use the ScanlineCoverage datastructure. (main): New method. Performs some tests. (renderShape): Work with pixelizer objects rather than directly on AbstractGraphic2D. Adjust to use ScanlineCoverage datastructure. (setResolution): Set resolution on ScanlineCoverage data too. * gnu/java/awt/java2d/ScanlineCoverage.java: New class. Stores and manages scanline coverage information.
Diffstat (limited to 'gnu/java/awt/java2d/ScanlineConverter.java')
-rw-r--r--gnu/java/awt/java2d/ScanlineConverter.java126
1 files changed, 45 insertions, 81 deletions
diff --git a/gnu/java/awt/java2d/ScanlineConverter.java b/gnu/java/awt/java2d/ScanlineConverter.java
index 5254af901..71f70d3e9 100644
--- a/gnu/java/awt/java2d/ScanlineConverter.java
+++ b/gnu/java/awt/java2d/ScanlineConverter.java
@@ -1,5 +1,5 @@
/* ScanlineConverter.java -- Rasterizes Shapes
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,7 +47,7 @@ import java.awt.geom.PathIterator;
/**
* Rasterizes {@link Shape} objects on an AbstractGraphics2D.
*/
-final class ScanlineConverter
+public final class ScanlineConverter
{
/**
@@ -56,11 +56,6 @@ final class ScanlineConverter
private static int FIXED_DIGITS = 6;
/**
- * The fixed value for the number 1.
- */
- private static int ONE = Fixed.fixedValue(FIXED_DIGITS, 1);
-
- /**
* The actual number of scanlines.
*/
private int numScanlines;
@@ -87,8 +82,6 @@ final class ScanlineConverter
*/
private int resolution;
- private int scanlinesPerPixel;
-
/**
* One half step according to the resolution. This is stored to avoid
* unnecessary operations during rendering.
@@ -114,10 +107,10 @@ final class ScanlineConverter
private int minX;
private int maxX;
- private int[] scanlineYCov;
- private int[] scanlineXCov;
- private int slPix0;
- private int alphaRes;
+ /**
+ * Holds and manages information about the pixel coverage.
+ */
+ private ScanlineCoverage scanlineCoverage;
/**
* Create a new ScanlineConverter.
@@ -129,16 +122,18 @@ final class ScanlineConverter
activeEdges = new ActiveEdges();
edgePool = new PolyEdge();
edgePoolLast = edgePool;
+ scanlineCoverage = new ScanlineCoverage();
}
/**
* Renders the specified shape using the specified clip and transform.
*
+ * @param p the pixelizer that receives the coverage information
* @param shape the shape to render
* @param clip the clip
* @param trans the transform
*/
- void renderShape(AbstractGraphics2D g, Shape shape, Shape clip,
+ void renderShape(Pixelizer p, Shape shape, Shape clip,
AffineTransform trans, int res)
{
// Prepare resolution and upper bounds.
@@ -166,20 +161,6 @@ final class ScanlineConverter
edge = edge.poolNext;
}
- // For AA: Prepare the scanline pixels array.
- if (resolution < ONE)
- {
- int x0 = Fixed.intValue(FIXED_DIGITS, minX);
- int x1 = Fixed.intValue(FIXED_DIGITS, maxX) + 1;
- int span = x1 - x0;
- if (scanlineYCov == null || span >= scanlineYCov.length)
- {
- scanlineYCov = new int[span];
- scanlineXCov = new int[span];
- }
- slPix0 = x0;
- }
-
int y = upperBounds;
int index;
activeEdges.clear();
@@ -210,7 +191,7 @@ final class ScanlineConverter
// Ok, now we can perform the actual scanlining.
int realY = Fixed.intValue(FIXED_DIGITS, y + resolution);
boolean push = lastRealY != realY;
- doScanline(g, y, push, haveClip);
+ doScanline(p, y, push, haveClip);
// Remove obsolete active edges.
//activeEdges.remove(y + halfStep);
@@ -237,6 +218,9 @@ final class ScanlineConverter
sl.clear();
}
+ // Reset scanline coverage.
+ scanlineCoverage.clear();
+
// Reset bounds.
minY = Integer.MAX_VALUE;
maxY = Integer.MIN_VALUE;
@@ -246,11 +230,18 @@ final class ScanlineConverter
/**
* Performs the scanlining on the current set of active edges.
+ *
+ * @param p the pixelizer to receive the pixel coverage data
+ * @param y the Y coordinate
+ * @param push true when the scanline is ready to be pushed to the
+ * pixelizer
+ * @param haveClip true when there's a clip, false otherwise
*/
- private void doScanline(AbstractGraphics2D g, int y, boolean push,
+ private void doScanline(Pixelizer p, int y, boolean push,
boolean haveClip)
{
-
+ // First, rewind the scanline coverage.
+ scanlineCoverage.rewind();
// We begin outside the clip and outside the shape. We only draw when
// we are inside the clip AND inside the shape.
boolean inClip = ! haveClip;
@@ -266,25 +257,12 @@ final class ScanlineConverter
int x0 = lastEdge.xIntersection;
int x1 = edge.xIntersection;
assert x0 <= x1;
- if (resolution == ONE)
- {
- // Non-AA rendering.
- g.fillScanline(Fixed.intValue(FIXED_DIGITS, x0 + resolution / 2),
- Fixed.intValue(FIXED_DIGITS, x1 - resolution / 2),
- Fixed.intValue(FIXED_DIGITS, y));
- }
- else
- {
- int pix0 = Fixed.intValue(FIXED_DIGITS, x0);
- int frac0 = ONE - (x0 - Fixed.floor(FIXED_DIGITS, x0));
- int pix1 = Fixed.intValue(FIXED_DIGITS, x1);
- int frac1 = ONE - (x1 - Fixed.floor(FIXED_DIGITS, x1));
- //System.err.println("render scanline AA: " + Fixed.floatValue(FIXED_DIGITS, y) + ", " + pix0 + ", " + pix1 + "(" + Fixed.floatValue(FIXED_DIGITS, x0) + ", " + Fixed.floatValue(FIXED_DIGITS, x1) +")");
- scanlineYCov[pix0 - slPix0] += alphaRes;
- scanlineYCov[pix1 - slPix0] -= alphaRes;
- scanlineXCov[pix0 - slPix0] += frac0;
- scanlineXCov[pix1 - slPix0] += frac1;
- }
+
+ int pix0 = Fixed.intValue(FIXED_DIGITS, x0);
+ int pix1 = Fixed.intValue(FIXED_DIGITS, x1);
+ //System.err.println("render scanline AA: " + Fixed.floatValue(FIXED_DIGITS, y) + ", " + pix0 + ", " + pix1 + "(" + Fixed.floatValue(FIXED_DIGITS, x0) + ", " + Fixed.floatValue(FIXED_DIGITS, x1) +")")
+ scanlineCoverage.add(pix0, 1);
+ scanlineCoverage.add(pix1, -1);
}
if (edge.isClip)
inClip = ! inClip;
@@ -294,35 +272,11 @@ final class ScanlineConverter
lastEdge = edge;
}
- // For AA we push out the scanline when necessary.
- if (push && ONE > resolution)
+ // Push out the whole scanline to the pixelizer.
+ if (push && ! scanlineCoverage.isEmpty())
{
- // Push out AA'ed scanline.
- int rx1 = 0;
- int alpha = 0;
- for (int idx = 0; idx < scanlineYCov.length; idx++)
- {
- rx1 = slPix0 + idx;
- if (scanlineYCov[idx] != 0)
- {
- // Render transitioning pixel with x coverage included.
- int transAlpha = alpha + (scanlineYCov[idx] * scanlineXCov[idx]) / (scanlinesPerPixel * 64);
- //System.err.println("pixel: " + rx1 + " old alpha: " + alpha + " ycov:" + scanlineYCov[idx] + " xcov: " + scanlineXCov[idx] + " tAlpha: " + transAlpha);
- g.fillScanlineAA(rx1, rx1,
- Fixed.intValue(FIXED_DIGITS, y),
- Math.max(Math.min(transAlpha, 255), 0));
- alpha = alpha + scanlineYCov[idx];
- }
- else if (alpha > 0)
- {
- //System.err.println("pixel: " + rx1 + " alpha: " + alpha);
- g.fillScanlineAA(rx1, rx1,
- Fixed.intValue(FIXED_DIGITS, y),
- Math.min(alpha, 255));
- }
- scanlineYCov[idx] = 0;
- scanlineXCov[idx] = 0;
- }
+ p.renderScanline(Fixed.intValue(FIXED_DIGITS, y), scanlineCoverage);
+ scanlineCoverage.clear();
}
}
@@ -335,11 +289,11 @@ final class ScanlineConverter
*/
private void setResolution(int res)
{
- scanlinesPerPixel = 1 << res;
+ int scanlinesPerPixel = 1 << res;
int one = Fixed.fixedValue(FIXED_DIGITS, 1);
- resolution = one / (1 << res);
+ resolution = one / (scanlinesPerPixel);
halfStep = resolution / 2;
- alphaRes = 256 >> res;
+ scanlineCoverage.setMaxCoverage(scanlinesPerPixel);
}
/**
@@ -470,4 +424,14 @@ final class ScanlineConverter
edgePoolLast = edgePoolLast.poolNext;
}
}
+
+ /**
+ * Performs some tests.
+ *
+ * @param args
+ */
+ public static void main(String[] args)
+ {
+ ScanlineCoverage.test();
+ }
}