diff options
author | Roman Kennke <roman@kennke.org> | 2007-05-24 20:28:42 +0000 |
---|---|---|
committer | Roman Kennke <roman@kennke.org> | 2007-05-24 20:28:42 +0000 |
commit | c559b24555d6917692118aa0245958918d389201 (patch) | |
tree | 64be1b5bfccbcaad6ea1cad44da9ab2720520436 | |
parent | 38c26644fa4b5b32e6a4d049c04e814df4b08dbb (diff) | |
download | classpath-c559b24555d6917692118aa0245958918d389201.tar.gz |
2007-05-24 Roman Kennke <roman@kennke.org>
* gnu/java/awt/java2d/AbstractGraphics2D.java
(fillShape): Pass rendering hints to scanline converter.
* gnu/java/awt/java2d/ScanlineConverter.java
(ONE): New constant for the number 1 as fixed point number.
(Y_RESOLUTION): New constant for the Y resolution.
(doScanline): Handle the Y resolution.
(renderShape): Accept rendering hints.
(setResolution): Adjust maximum resolution with Y resolution.
* gnu/java/awt/java2d/ScanlineCoverage.java
(Iterator.handledPixelCoverage): New field.
(Iterator.next): Handle single pixel coverage.
(Iterator.hasNext): Handle single pixel coverage.
(Iterator.reset): Reset single pixel coverage.
(Range.toString): New method.
(Coverage.pixelCoverage): New field.
(add): Include Y (pixel) coverage.
(findOrInsert): Reset Y coverage in reused entries.
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | gnu/java/awt/java2d/AbstractGraphics2D.java | 2 | ||||
-rw-r--r-- | gnu/java/awt/java2d/ScanlineConverter.java | 32 | ||||
-rw-r--r-- | gnu/java/awt/java2d/ScanlineCoverage.java | 70 |
4 files changed, 107 insertions, 17 deletions
@@ -1,5 +1,25 @@ 2007-05-24 Roman Kennke <roman@kennke.org> + * gnu/java/awt/java2d/AbstractGraphics2D.java + (fillShape): Pass rendering hints to scanline converter. + * gnu/java/awt/java2d/ScanlineConverter.java + (ONE): New constant for the number 1 as fixed point number. + (Y_RESOLUTION): New constant for the Y resolution. + (doScanline): Handle the Y resolution. + (renderShape): Accept rendering hints. + (setResolution): Adjust maximum resolution with Y resolution. + * gnu/java/awt/java2d/ScanlineCoverage.java + (Iterator.handledPixelCoverage): New field. + (Iterator.next): Handle single pixel coverage. + (Iterator.hasNext): Handle single pixel coverage. + (Iterator.reset): Reset single pixel coverage. + (Range.toString): New method. + (Coverage.pixelCoverage): New field. + (add): Include Y (pixel) coverage. + (findOrInsert): Reset Y coverage in reused entries. + +2007-05-24 Roman Kennke <roman@kennke.org> + * gnu/java/awt/java2d/ScanlineCoverage.java (Iterator): New class. (Range): New class. diff --git a/gnu/java/awt/java2d/AbstractGraphics2D.java b/gnu/java/awt/java2d/AbstractGraphics2D.java index 663ca2ee9..24256cc07 100644 --- a/gnu/java/awt/java2d/AbstractGraphics2D.java +++ b/gnu/java/awt/java2d/AbstractGraphics2D.java @@ -1568,7 +1568,7 @@ public abstract class AbstractGraphics2D // Adjust resolution according to rendering hints. resolution = 2; } - sc.renderShape(this, s, clip, transform, resolution); + sc.renderShape(this, s, clip, transform, resolution, renderingHints); } /** diff --git a/gnu/java/awt/java2d/ScanlineConverter.java b/gnu/java/awt/java2d/ScanlineConverter.java index 13f21efcb..2693a0b70 100644 --- a/gnu/java/awt/java2d/ScanlineConverter.java +++ b/gnu/java/awt/java2d/ScanlineConverter.java @@ -40,6 +40,7 @@ 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; @@ -56,6 +57,16 @@ public final class ScanlineConverter private static int FIXED_DIGITS = 6; /** + * The fixed point constant for the number one. + */ + private static int ONE = Fixed.fixedValue(FIXED_DIGITS, 1); + + /** + * The number of significant bits for the Y resolution. + */ + private static int Y_RESOLUTION = 4; + + /** * The actual number of scanlines. */ private int numScanlines; @@ -133,9 +144,12 @@ public final class ScanlineConverter * @param clip the clip * @param trans the transform */ - void renderShape(Pixelizer p, Shape shape, Shape clip, - AffineTransform trans, int res) + public void renderShape(Pixelizer p, Shape shape, Shape clip, + AffineTransform trans, int res, RenderingHints hints) { + // TODO: Do something useful with the rendering hints. Like, adjusting + // the resolution. + // Prepare resolution and upper bounds. clear(); setResolution(res); @@ -242,6 +256,7 @@ public final class ScanlineConverter { // 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; @@ -260,9 +275,13 @@ public final class ScanlineConverter 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); + 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 - Y_RESOLUTION); + frac1 = frac1 >> (FIXED_DIGITS - Y_RESOLUTION); + scanlineCoverage.add(pix0, 1 * (1 << Y_RESOLUTION), frac0); + scanlineCoverage.add(pix1, -1 * (1 << Y_RESOLUTION), -frac1); } if (edge.isClip) inClip = ! inClip; @@ -293,7 +312,8 @@ public final class ScanlineConverter int one = Fixed.fixedValue(FIXED_DIGITS, 1); resolution = one / (scanlinesPerPixel); halfStep = resolution / 2; - scanlineCoverage.setMaxCoverage(scanlinesPerPixel); + + scanlineCoverage.setMaxCoverage(scanlinesPerPixel << Y_RESOLUTION); } /** diff --git a/gnu/java/awt/java2d/ScanlineCoverage.java b/gnu/java/awt/java2d/ScanlineCoverage.java index 2bed5422c..6db7fb019 100644 --- a/gnu/java/awt/java2d/ScanlineCoverage.java +++ b/gnu/java/awt/java2d/ScanlineCoverage.java @@ -69,6 +69,12 @@ public final class ScanlineCoverage private int currentCoverage; /** + * True when the current pixel coverage has already been handled, false + * otherwise. + */ + private boolean handledPixelCoverage; + + /** * Creates a new CoverageIterator. */ Iterator() @@ -85,11 +91,26 @@ public final class ScanlineCoverage */ public Range next() { - currentCoverage += currentItem.covDelta; - range.setCoverage(currentCoverage); - range.setXPos(currentItem.xPos); - currentItem = currentItem.next; - range.setLength(currentItem.xPos - range.xPos); + // TODO: Lump together the single-pixel coverage and the + // between-pixel coverage when the pixel coverage delta is 0. + if (handledPixelCoverage == false) + { + // Handle single pixel coverage. + range.setXPos(currentItem.xPos); + range.setLength(1); + range.setCoverage(currentCoverage + currentItem.pixelCoverage); + handledPixelCoverage = true; + } + else + { + // Handle pixel span coverage. + currentCoverage += currentItem.covDelta; + range.setCoverage(currentCoverage); + range.setXPos(currentItem.xPos + 1); + currentItem = currentItem.next; + range.setLength(currentItem.xPos - range.xPos); + handledPixelCoverage = false; + } return range; } @@ -103,11 +124,21 @@ public final class ScanlineCoverage public boolean hasNext() { boolean hasNext; - if (currentItem == null || currentItem.next == null + if (currentItem != null && handledPixelCoverage == false) + { + // We have at least one more coverage item when there's a pixel + // coverage piece left. + hasNext = true; + } + else if (currentItem == null || currentItem.next == null || currentItem.next == last) - hasNext = false; + { + hasNext = false; + } else - hasNext = true; + { + hasNext = true; + } return hasNext; } @@ -118,6 +149,7 @@ public final class ScanlineCoverage { currentItem = head; currentCoverage = 0; + handledPixelCoverage = false; } } @@ -226,6 +258,15 @@ public final class ScanlineCoverage { return coverage; } + + /** + * Returns a string representation. + */ + public String toString() + { + return "Coverage range: xPos=" + xPos + ", length=" + length + + ", coverage: " + coverage; + } } /** @@ -239,11 +280,17 @@ public final class ScanlineCoverage int xPos; /** - * The X coverage delta. + * The coverage delta from the pixel at xPos to xPos + 1. */ int covDelta; /** + * The delta for the pixel at xPos. This is added to the pixel at xPos, + * but not to the following pixel. + */ + int pixelCoverage; + + /** * Implements a linked list. This points to the next element of the list. */ Coverage next; @@ -385,10 +432,11 @@ public final class ScanlineCoverage * @param xc the x coverage * @param yc the y coverage */ - public void add(int x, int xc) + public void add(int x, int xc, int yc) { Coverage bucket = findOrInsert(x); bucket.covDelta += xc; + bucket.pixelCoverage += yc; minX = Math.min(minX, x); maxX = Math.max(maxX, x); } @@ -491,6 +539,7 @@ public final class ScanlineCoverage lastPrev = match; match.xPos = x; match.covDelta = 0; + match.pixelCoverage = 0; // Keep link to last element or null, indicating the end of the list. current = match; currentPrev = prev; @@ -528,6 +577,7 @@ public final class ScanlineCoverage cov.xPos = x; cov.covDelta = 0; + cov.pixelCoverage = 0; // Insert this item in the list. if (prev != null) |