summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2007-05-24 20:28:42 +0000
committerRoman Kennke <roman@kennke.org>2007-05-24 20:28:42 +0000
commitc559b24555d6917692118aa0245958918d389201 (patch)
tree64be1b5bfccbcaad6ea1cad44da9ab2720520436
parent38c26644fa4b5b32e6a4d049c04e814df4b08dbb (diff)
downloadclasspath-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--ChangeLog20
-rw-r--r--gnu/java/awt/java2d/AbstractGraphics2D.java2
-rw-r--r--gnu/java/awt/java2d/ScanlineConverter.java32
-rw-r--r--gnu/java/awt/java2d/ScanlineCoverage.java70
4 files changed, 107 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 0132d6c8a..c6cd0fbb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)