summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java')
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java451
1 files changed, 0 insertions, 451 deletions
diff --git a/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java b/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
deleted file mode 100644
index 2c3481b6c10..00000000000
--- a/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/* ScanlineConverter.java -- Rasterizes Shapes
- Copyright (C) 2006, 2007 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-
-package gnu.java.awt.java2d;
-
-import gnu.java.math.Fixed;
-
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-
-/**
- * Rasterizes {@link Shape} objects on an AbstractGraphics2D.
- */
-public final class ScanlineConverter
-{
-
- /**
- * The number of digits to use for fixed point arithmetics.
- */
- private static int FIXED_DIGITS = 6;
-
- /**
- * The fixed point constant for the number one.
- */
- private static int ONE = Fixed.fixedValue(FIXED_DIGITS, 1);
-
- /**
- * The actual number of scanlines.
- */
- private int numScanlines;
-
- /**
- * The number of scanlines. This can contain more elements than we have
- * scanlines. The real number of scanlines is stored in
- * {@link #numScanlines}. This can also contain null values for empty
- * scanlines.
- */
- private Scanline[] scanlines;
-
- /**
- * The upper bounds which correspond to the index 0 in the scanline array.
- *
- * This is a fixed point value.
- */
- private int upperBounds;
-
- /**
- * The resolution of the scanline converter.
- *
- * This is a fixed point value.
- */
- private int resolution;
-
- /**
- * The number of significant bits for the 'Y' resolution.
- */
- private int yResolution;
-
- /**
- * One half step according to the resolution. This is stored to avoid
- * unnecessary operations during rendering.
- */
- private int halfStep;
-
- /**
- * This is used in {@link #addShape(PathIterator, boolean)} to
- * receive the coordinates of the path.
- */
- private float[] coords;
-
- /**
- * The active edges.
- */
- private ActiveEdges activeEdges;
-
- private PolyEdge edgePool;
- private PolyEdge edgePoolLast;
-
- private int minY;
- private int maxY;
- private int minX;
- private int maxX;
-
- /**
- * Holds and manages information about the pixel coverage.
- */
- private ScanlineCoverage scanlineCoverage;
-
- /**
- * Create a new ScanlineConverter.
- */
- ScanlineConverter()
- {
- scanlines = new Scanline[10];
- coords = new float[6];
- 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
- */
- public void renderShape(Pixelizer p, Shape shape, Shape clip,
- AffineTransform trans, int res, int yRes,
- RenderingHints hints)
- {
- // TODO: Do something useful with the rendering hints. Like, adjusting
- // the resolution.
-
- // Prepare resolution and upper bounds.
- clear();
- setResolution(res, yRes);
-
- boolean haveClip = clip != null;
-
- // Add shapes.
- float flatness = Fixed.floatValue(FIXED_DIGITS, resolution / 2);
- PathIterator path = shape.getPathIterator(trans, flatness);
- addShape(path, false);
- if (haveClip)
- {
- path= clip.getPathIterator(trans, flatness);
- addShape(path, true);
- }
-
- setUpperBounds(minY);
-
- PolyEdge edge = edgePool;
- while (edge != edgePoolLast)
- {
- addEdge(edge);
- edge = edge.poolNext;
- }
-
- int y = upperBounds;
- int index;
- activeEdges.clear();
- // The render loop...
- Scanline scanline = null;
- int lastRealY = Fixed.intValue(FIXED_DIGITS, y);
- while (y <= maxY)
- {
- // First we put together our list of active edges.
- index = scanlineIndex(y);
- // If we go outside the scanline array we still need to render the
- // remaining edges until they end.
- scanline = index < scanlines.length ? scanlines[index] : null;
- if (scanline != null)
- {
- edge = scanline.getEdges();
- while (edge != null)
- {
- activeEdges.add(edge);
- edge = edge.scanlineNext;
- }
- }
-
- // Then we intersect all active edges with the current scanline
- // and sort them according to their intersection points.
- activeEdges.intersectSortAndPack(FIXED_DIGITS, y + halfStep);
-
- // Ok, now we can perform the actual scanlining.
- int realY = Fixed.intValue(FIXED_DIGITS, y + resolution);
- boolean push = lastRealY != realY;
-
- doScanline(p, y, push, haveClip);
-
- // Remove obsolete active edges.
- //activeEdges.remove(y + halfStep);
- // Go on with the next line...
- y += resolution;
- lastRealY = realY;
-
- }
- }
-
- /**
- * Clears all scanlines.
- */
- private void clear()
- {
- // Reset edge pool.
- edgePoolLast = edgePool;
-
- // Reset scanlines.
- for (int i = scanlines.length - 1; i >= 0 ; i--)
- {
- Scanline sl = scanlines[i];
- if (sl != null)
- sl.clear();
- }
-
- // Reset scanline coverage.
- scanlineCoverage.clear();
-
- // Reset bounds.
- minY = Integer.MAX_VALUE;
- maxY = Integer.MIN_VALUE;
- minX = Integer.MAX_VALUE;
- maxX = Integer.MIN_VALUE;
- }
-
- /**
- * 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(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;
- boolean inShape = false;
- PolyEdge lastEdge = null;
- int numEdges = activeEdges.getNumActiveEdges();
- for (int i = 0; i < numEdges; i++)
- {
- PolyEdge edge = activeEdges.getActiveEdge(i);
- if (inClip && inShape)
- {
- assert lastEdge != null;
- int x0 = lastEdge.xIntersection;
- int x1 = edge.xIntersection;
- assert x0 <= x1;
-
- int pix0 = Fixed.intValue(FIXED_DIGITS, x0);
- int pix1 = Fixed.intValue(FIXED_DIGITS, x1);
- int frac0 = ONE - Fixed.trunc(FIXED_DIGITS, x0);
- int frac1 = ONE - Fixed.trunc(FIXED_DIGITS, x1);
- // Only keep the first 4 digits after the point.
- frac0 = frac0 >> (FIXED_DIGITS - yResolution);
- frac1 = frac1 >> (FIXED_DIGITS - yResolution);
- scanlineCoverage.add(pix0, 1 * (1 << yResolution), frac0);
- scanlineCoverage.add(pix1, -1 * (1 << yResolution), -frac1);
- }
- if (edge.isClip)
- inClip = ! inClip;
- else
- inShape = ! inShape;
-
- lastEdge = edge;
- }
-
- // Push out the whole scanline to the pixelizer.
- if (push && ! scanlineCoverage.isEmpty())
- {
- p.renderScanline(Fixed.intValue(FIXED_DIGITS, y), scanlineCoverage);
- scanlineCoverage.clear();
- }
- }
-
-
- /**
- * Sets the resolution. A value of 0 rasterizes the shape normally without
- * anti-aliasing. Greater values renders with a resolution of 2 ^ res.
- *
- * @param res the resolution
- */
- private void setResolution(int res, int yRes)
- {
- int scanlinesPerPixel = 1 << res;
- int one = Fixed.fixedValue(FIXED_DIGITS, 1);
- resolution = one / (scanlinesPerPixel);
- halfStep = resolution / 2;
-
- scanlineCoverage.setMaxCoverage(scanlinesPerPixel << yResolution);
-
- yResolution = yRes;
- }
-
- /**
- * Sets the vertical bounds of that shape that is beeing rendered.
- *
- * @param y0 the upper bounds
- */
- private void setUpperBounds(int y0)
- {
- upperBounds = fit(y0);
- }
-
- /**
- * Add a shape to the scanline converter.
- *
- * @param path
- * @param clip
- */
- private void addShape(PathIterator path, boolean clip)
- {
- int startX = 0;
- int startY = 0;
- int lastX = 0;
- int lastY = 0;
- while (! path.isDone())
- {
- int type = path.currentSegment(coords);
- switch (type)
- {
- case PathIterator.SEG_MOVETO:
- startX = lastX = Fixed.fixedValue(FIXED_DIGITS, coords[0]);
- startY = lastY = Fixed.fixedValue(FIXED_DIGITS, coords[1]);
- minY = Math.min(startY, minY);
- maxY = Math.max(startY, maxY);
- minX = Math.min(startX, minX);
- maxX = Math.max(startX, maxX);
- break;
- case PathIterator.SEG_LINETO:
- int x = Fixed.fixedValue(FIXED_DIGITS, coords[0]);
- int y = Fixed.fixedValue(FIXED_DIGITS, coords[1]);
- edgePoolAdd(lastX, lastY, x, y, clip);
- lastX = x;
- lastY = y;
- minY = Math.min(lastY, minY);
- maxY = Math.max(lastY, maxY);
- minX = Math.min(lastX, minX);
- maxX = Math.max(lastX, maxX);
- break;
- case PathIterator.SEG_CLOSE:
- edgePoolAdd(lastX, lastY, startX, startY, clip);
- lastX = startX;
- lastY = startY;
- break;
- case PathIterator.SEG_CUBICTO:
- case PathIterator.SEG_QUADTO:
- default:
- assert false;
- }
- path.next();
- }
- }
-
- /**
- * Adds an edge into the scanline array.
- */
- private void addEdge(PolyEdge edge)
- {
- // Determine index.
- int upper = Math.min(edge.y0, edge.y1);
- // Fit to raster.
- int index = scanlineIndex(upper);
- // Grow array when necessary.
- if (index >= scanlines.length)
- {
- int oldSize = scanlines.length;
- int newSize = Math.max(oldSize + oldSize / 2 + 1, index + 10);
- Scanline[] newScanlines = new Scanline[newSize];
- System.arraycopy(scanlines, 0, newScanlines, 0, oldSize);
- scanlines = newScanlines;
- }
-
- // Add edge.
- if (scanlines[index] == null)
- {
- scanlines[index] = new Scanline();
- }
- scanlines[index].addEdge(edge);
- }
-
- /**
- * Fits an Y coordinate to the grid.
- *
- * @param y the Y coordinate to fit
- *
- * @return the fitted Y coordinate
- */
- private int fit(int y)
- {
- int val1 = Fixed.div(FIXED_DIGITS, y, resolution);
- int rounded = Fixed.round(FIXED_DIGITS, val1);
- return Fixed.mul(FIXED_DIGITS, rounded, resolution);
- }
-
- /**
- * Calculates the scanline index for the specified y coordinate.
- *
- * @param y the y coordinate as fixed point value
- *
- * @return the scanline index
- */
- private int scanlineIndex(int y)
- {
- int fitted = fit(y);
- // Cleverly skip the fixed point conversions here.
- return (fitted - upperBounds)/ resolution;
- }
-
- private void edgePoolAdd(int x0, int y0, int x1, int y1, boolean clip)
- {
- // Don't need no horizontal edges.
- if (y0 != y1)
- {
- edgePoolLast.init(FIXED_DIGITS, x0, y0, x1, y1, clip);
- if (edgePoolLast.poolNext == null)
- {
- edgePoolLast.poolNext = new PolyEdge();
- }
- edgePoolLast = edgePoolLast.poolNext;
- }
- }
-}