summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/java/awt/java2d
diff options
context:
space:
mode:
authordoko <doko@138bc75d-0d04-0410-961f-82ee72b054a4>2008-06-28 13:29:13 +0000
committerdoko <doko@138bc75d-0d04-0410-961f-82ee72b054a4>2008-06-28 13:29:13 +0000
commit1020ce5944edde4364baef4d371cd4f9b0dae721 (patch)
tree602cd7aa7c947386134690d8e0f6b53abcdeacb9 /libjava/classpath/gnu/java/awt/java2d
parent9f41ce98ce6f4f7c8ac5e2c4b6e5d27e10201015 (diff)
downloadppe42-gcc-1020ce5944edde4364baef4d371cd4f9b0dae721.tar.gz
ppe42-gcc-1020ce5944edde4364baef4d371cd4f9b0dae721.zip
libjava/
2008-06-28 Matthias Klose <doko@ubuntu.com> Import GNU Classpath (classpath-0_97_2-release). * Regenerate class and header files. * Regenerate auto* files. * gcj/javaprims.h: Define jobjectRefType. * jni.cc (_Jv_JNI_GetObjectRefType): New (stub only). (_Jv_JNIFunctions): Initialize GetObjectRefType. * gnu/classpath/jdwp/VMVirtualMachine.java, java/security/VMSecureRandom.java: Merge from classpath. * HACKING: Fix typo. * ChangeLog-2007: New file. * configure.ac: Set JAVAC, pass --disable-regen-headers to classpath. libjava/classpath/ 2008-06-28 Matthias Klose <doko@ubuntu.com> * m4/ac_prog_javac.m4: Disable check for JAVAC, when not configured with --enable-java-maintainer-mode. * aclocal.m4, configure: Regenerate. * native/jni/gstreamer-peer/Makefile.am: Do not link with libclasspathnative. * native/jni/gstreamer-peer/Makefile.in: Regenerate. * tools/Makefile.am, lib/Makefile.am: Use JAVAC for setting JCOMPILER, drop flags not understood by gcj. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@137223 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/gnu/java/awt/java2d')
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java165
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java132
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java29
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java2
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java119
-rw-r--r--libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java153
6 files changed, 522 insertions, 78 deletions
diff --git a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java
index 15ec90da1c0..36ba0f4304c 100644
--- a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java
+++ b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java
@@ -37,6 +37,8 @@ exception statement from your version. */
package gnu.java.awt.java2d;
+import gnu.java.util.LRUCache;
+
import java.awt.AWTError;
import java.awt.AlphaComposite;
import java.awt.AWTPermission;
@@ -80,7 +82,9 @@ import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.Map;
/**
@@ -152,22 +156,46 @@ public abstract class AbstractGraphics2D
{
/**
+ * Wether we use anti aliasing for rendering text by default or not.
+ */
+ private static final boolean DEFAULT_TEXT_AA =
+ Boolean.getBoolean("gnu.java2d.default_text_aa");
+
+ /**
* The default font to use on the graphics object.
*/
private static final Font FONT = new Font("SansSerif", Font.PLAIN, 12);
/**
+ * The size of the LRU cache used for caching GlyphVectors.
+ */
+ private static final int GV_CACHE_SIZE = 50;
+
+ /**
* Caches certain shapes to avoid massive creation of such Shapes in
* the various draw* and fill* methods.
*/
- private static final ThreadLocal<ShapeCache> shapeCache =
- new ThreadLocal<ShapeCache>();
+ private static final ShapeCache shapeCache = new ShapeCache();
+
+ /**
+ * A pool of scanline converters. It is important to reuse scanline
+ * converters because they keep their datastructures in place. We pool them
+ * for use in multiple threads.
+ */
+ private static final LinkedList<ScanlineConverter> scanlineConverters =
+ new LinkedList<ScanlineConverter>();
+
+ /**
+ * Caches glyph vectors for better drawing performance.
+ */
+ private static final Map<TextCacheKey,GlyphVector> gvCache =
+ Collections.synchronizedMap(new LRUCache<TextCacheKey,GlyphVector>(GV_CACHE_SIZE));
/**
- * The scanline converters by thread.
+ * This key is used to search in the gvCache without allocating a new
+ * key each time.
*/
- private static final ThreadLocal<ScanlineConverter> scanlineConverters =
- new ThreadLocal<ScanlineConverter>();
+ private static final TextCacheKey searchTextKey = new TextCacheKey();
/**
* The transformation for this Graphics2D instance
@@ -484,14 +512,25 @@ public abstract class AbstractGraphics2D
*/
public void drawString(String text, int x, int y)
{
- if (isOptimized)
- rawDrawString(text, x, y);
- else
+ GlyphVector gv;
+ synchronized (searchTextKey)
{
- FontRenderContext ctx = getFontRenderContext();
- GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
- drawGlyphVector(gv, x, y);
+ TextCacheKey tck = searchTextKey;
+ FontRenderContext frc = getFontRenderContext();
+ tck.setString(text);
+ tck.setFont(font);
+ tck.setFontRenderContext(frc);
+ if (gvCache.containsKey(tck))
+ {
+ gv = gvCache.get(tck);
+ }
+ else
+ {
+ gv = font.createGlyphVector(frc, text.toCharArray());
+ gvCache.put(new TextCacheKey(text, font, frc), gv);
+ }
}
+ drawGlyphVector(gv, x, y);
}
/**
@@ -949,7 +988,10 @@ public abstract class AbstractGraphics2D
public FontRenderContext getFontRenderContext()
{
- return new FontRenderContext(transform, false, true);
+ // Protect our own transform from beeing modified.
+ AffineTransform tf = new AffineTransform(transform);
+ // TODO: Determine antialias and fractionalmetrics parameters correctly.
+ return new FontRenderContext(tf, false, true);
}
/**
@@ -992,8 +1034,10 @@ public abstract class AbstractGraphics2D
// Copy the clip. If it's a Rectangle, preserve that for optimization.
if (clip instanceof Rectangle)
copy.clip = new Rectangle((Rectangle) clip);
- else
+ else if (clip != null)
copy.clip = new GeneralPath(clip);
+ else
+ copy.clip = null;
copy.renderingHints = new RenderingHints(null);
copy.renderingHints.putAll(renderingHints);
@@ -1163,7 +1207,7 @@ public abstract class AbstractGraphics2D
}
else
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.line == null)
sc.line = new Line2D.Float();
sc.line.setLine(x1, y1, x2, y2);
@@ -1175,11 +1219,13 @@ public abstract class AbstractGraphics2D
{
if (isOptimized)
{
- rawDrawRect(x, y, w, h);
+ int tx = (int) transform.getTranslateX();
+ int ty = (int) transform.getTranslateY();
+ rawDrawRect(x + tx, y + ty, w, h);
}
else
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.rect == null)
sc.rect = new Rectangle();
sc.rect.setBounds(x, y, w, h);
@@ -1204,7 +1250,7 @@ public abstract class AbstractGraphics2D
}
else
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.rect == null)
sc.rect = new Rectangle();
sc.rect.setBounds(x, y, width, height);
@@ -1249,7 +1295,7 @@ public abstract class AbstractGraphics2D
public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
int arcHeight)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.roundRect == null)
sc.roundRect = new RoundRectangle2D.Float();
sc.roundRect.setRoundRect(x, y, width, height, arcWidth, arcHeight);
@@ -1269,7 +1315,7 @@ public abstract class AbstractGraphics2D
public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
int arcHeight)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.roundRect == null)
sc.roundRect = new RoundRectangle2D.Float();
sc.roundRect.setRoundRect(x, y, width, height, arcWidth, arcHeight);
@@ -1286,7 +1332,7 @@ public abstract class AbstractGraphics2D
*/
public void drawOval(int x, int y, int width, int height)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.ellipse == null)
sc.ellipse = new Ellipse2D.Float();
sc.ellipse.setFrame(x, y, width, height);
@@ -1303,7 +1349,7 @@ public abstract class AbstractGraphics2D
*/
public void fillOval(int x, int y, int width, int height)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.ellipse == null)
sc.ellipse = new Ellipse2D.Float();
sc.ellipse.setFrame(x, y, width, height);
@@ -1316,7 +1362,7 @@ public abstract class AbstractGraphics2D
public void drawArc(int x, int y, int width, int height, int arcStart,
int arcAngle)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.arc == null)
sc.arc = new Arc2D.Float();
sc.arc.setArc(x, y, width, height, arcStart, arcAngle, Arc2D.OPEN);
@@ -1329,7 +1375,7 @@ public abstract class AbstractGraphics2D
public void fillArc(int x, int y, int width, int height, int arcStart,
int arcAngle)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.arc == null)
sc.arc = new Arc2D.Float();
sc.arc.setArc(x, y, width, height, arcStart, arcAngle, Arc2D.PIE);
@@ -1338,7 +1384,7 @@ public abstract class AbstractGraphics2D
public void drawPolyline(int[] xPoints, int[] yPoints, int npoints)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.polyline == null)
sc.polyline = new GeneralPath();
GeneralPath p = sc.polyline;
@@ -1355,7 +1401,7 @@ public abstract class AbstractGraphics2D
*/
public void drawPolygon(int[] xPoints, int[] yPoints, int npoints)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.polygon == null)
sc.polygon = new Polygon();
sc.polygon.reset();
@@ -1370,7 +1416,7 @@ public abstract class AbstractGraphics2D
*/
public void fillPolygon(int[] xPoints, int[] yPoints, int npoints)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.polygon == null)
sc.polygon = new Polygon();
sc.polygon.reset();
@@ -1559,8 +1605,9 @@ public abstract class AbstractGraphics2D
{
Object v = renderingHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
// We default to antialiasing for text rendering.
- antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON
- || v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
+ antialias = v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON
+ || (v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT
+ && DEFAULT_TEXT_AA);
}
else
{
@@ -1569,12 +1616,15 @@ public abstract class AbstractGraphics2D
}
ScanlineConverter sc = getScanlineConverter();
int resolution = 0;
+ int yRes = 0;
if (antialias)
{
// Adjust resolution according to rendering hints.
resolution = 2;
+ yRes = 4;
}
- sc.renderShape(this, s, clip, transform, resolution, renderingHints);
+ sc.renderShape(this, s, clip, transform, resolution, yRes, renderingHints);
+ freeScanlineConverter(sc);
}
/**
@@ -1606,7 +1656,7 @@ public abstract class AbstractGraphics2D
*/
protected void rawDrawLine(int x0, int y0, int x1, int y1)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.line == null)
sc.line = new Line2D.Float();
sc.line.setLine(x0, y0, x1, y1);
@@ -1615,7 +1665,7 @@ public abstract class AbstractGraphics2D
protected void rawDrawRect(int x, int y, int w, int h)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.rect == null)
sc.rect = new Rectangle();
sc.rect.setBounds(x, y, w, h);
@@ -1623,22 +1673,6 @@ public abstract class AbstractGraphics2D
}
/**
- * Draws a string in optimization mode. The implementation should respect the
- * clip and translation. It can assume that the clip is a rectangle and that
- * the transform is only a translating transform.
- *
- * @param text the string to be drawn
- * @param x the start of the baseline, X coordinate
- * @param y the start of the baseline, Y coordinate
- */
- protected void rawDrawString(String text, int x, int y)
- {
- FontRenderContext ctx = getFontRenderContext();
- GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
- drawGlyphVector(gv, x, y);
- }
-
- /**
* Clears a rectangle in optimization mode. The implementation should respect the
* clip and translation. It can assume that the clip is a rectangle and that
* the transform is only a translating transform.
@@ -1667,7 +1701,7 @@ public abstract class AbstractGraphics2D
*/
protected void rawFillRect(int x, int y, int w, int h)
{
- ShapeCache sc = getShapeCache();
+ ShapeCache sc = shapeCache;
if (sc.rect == null)
sc.rect = new Rectangle();
sc.rect.setBounds(x, y, w, h);
@@ -1918,35 +1952,38 @@ public abstract class AbstractGraphics2D
}
/**
- * Returns the ShapeCache for the calling thread.
+ * Returns a free scanline converter from the pool.
*
- * @return the ShapeCache for the calling thread
+ * @return a scanline converter
*/
- private ShapeCache getShapeCache()
+ private ScanlineConverter getScanlineConverter()
{
- ShapeCache sc = shapeCache.get();
- if (sc == null)
+ synchronized (scanlineConverters)
{
- sc = new ShapeCache();
- shapeCache.set(sc);
+ ScanlineConverter sc;
+ if (scanlineConverters.size() > 0)
+ {
+ sc = scanlineConverters.removeFirst();
+ }
+ else
+ {
+ sc = new ScanlineConverter();
+ }
+ return sc;
}
- return sc;
}
/**
- * Returns the scanline converter for this thread.
+ * Puts a scanline converter back in the pool.
*
- * @return the scanline converter for this thread
+ * @param sc
*/
- private ScanlineConverter getScanlineConverter()
+ private void freeScanlineConverter(ScanlineConverter sc)
{
- ScanlineConverter sc = scanlineConverters.get();
- if (sc == null)
+ synchronized (scanlineConverters)
{
- sc = new ScanlineConverter();
- scanlineConverters.set(sc);
+ scanlineConverters.addLast(sc);
}
- return sc;
}
}
diff --git a/libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java b/libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java
new file mode 100644
index 00000000000..c83ad1fff8f
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java
@@ -0,0 +1,132 @@
+package gnu.java.awt.java2d;
+
+/**
+ * Stores and handles the pixel converage for a scanline. The pixel coverage
+ * is stored as sorted list of buckets, each of which holds information about
+ * the coverage for the X and Y axis. This is utilized to compute the actual
+ * coverage for each pixel on the scanline and finding chunks of pixels with
+ * equal coverage.
+ */
+final class PixelCoverage
+{
+
+ /**
+ * One bucket in the list.
+ */
+ private static final class Bucket
+ {
+ /**
+ * The X coordinate on the scanline to which this bucket belongs.
+ */
+ int xPos;
+
+ /**
+ * The X coverage.
+ */
+ int xCov;
+
+ /**
+ * The Y coverage.
+ */
+ int yCov;
+
+ /**
+ * Implements a linked list. This points to the next element of the list.
+ */
+ Bucket next;
+
+ /**
+ * Implements a linked list. This points to the previous element of the
+ * list.
+ */
+ Bucket prev;
+ }
+
+ /**
+ * The head of the sorted list of buckets.
+ */
+ private Bucket head;
+
+ /**
+ * The current bucket. We make use of the fact that the scanline converter
+ * always scans the scanline (and thus this list) from left to right to
+ * quickly find buckets or insertion points.
+ */
+ private Bucket current;
+
+ /**
+ * The bucket after the last valid bucket. Unused buckets are not thrown
+ * away and garbage collected. Instead, we keep them at the tail of the list
+ * and reuse them when necessary.
+ */
+ private Bucket last;
+
+ /**
+ * Indicates the the next scan of the scanline begins and that the next
+ * request will be at the beginning of this list. This makes searching and
+ * sorting of this list very quick.
+ */
+ void rewind()
+ {
+ current = head;
+ }
+
+ /**
+ * Clears the list. This does not throw away the old buckets but only
+ * resets the end-pointer of the list to the first element. All buckets are
+ * then unused and are reused when the list is filled again.
+ */
+ void clear()
+ {
+ last = head;
+ }
+
+ /**
+ * This adds the specified x and y coverage to the pixel at the specified
+ * X position.
+ *
+ * @param x the X position
+ * @param xc the x coverage
+ * @param yc the y coverage
+ */
+ void add(int x, int xc, int yc)
+ {
+ Bucket bucket = findOrInsert(x);
+ bucket.xCov += xc;
+ bucket.yCov += yc;
+ }
+
+ /**
+ * Finds the bucket in the list with the specified X coordinate.
+ * If no such bucket is found, then a new one is fetched (either a cached
+ * bucket from the end of the list or a newly allocated one) inserted at the
+ * correct position and returned.
+ *
+ * @param x the X coordinate
+ *
+ * @return a bucket to hold the coverage data
+ */
+ private Bucket findOrInsert(int x)
+ {
+ // First search for a matching bucket.
+ if (head == null)
+ {
+ // Special case: the list is still empty.
+ head = new Bucket();
+ current = head;
+ return head;
+ }
+
+ // This performs a linear search, starting from the current bucket.
+ // This is reasonably efficient because access to this list is always done
+ // in a linear fashion and we are not more then 1 or 2 buckets away from
+ // the one we're looking for.
+ Bucket match = current;
+ while (match != null && match.xPos != x)
+ {
+
+ }
+
+ return match;
+ }
+}
diff --git a/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java b/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
index 2693a0b70c7..cc4bbef28c0 100644
--- a/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
+++ b/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java
@@ -62,11 +62,6 @@ public final class ScanlineConverter
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;
@@ -94,6 +89,11 @@ public final class ScanlineConverter
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.
*/
@@ -145,14 +145,15 @@ public final class ScanlineConverter
* @param trans the transform
*/
public void renderShape(Pixelizer p, Shape shape, Shape clip,
- AffineTransform trans, int res, RenderingHints hints)
+ 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);
+ setResolution(res, yRes);
boolean haveClip = clip != null;
@@ -278,10 +279,10 @@ public final class ScanlineConverter
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);
+ 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;
@@ -306,14 +307,16 @@ public final class ScanlineConverter
*
* @param res the resolution
*/
- private void setResolution(int res)
+ 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 << Y_RESOLUTION);
+ scanlineCoverage.setMaxCoverage(scanlinesPerPixel << yResolution);
+
+ yResolution = yRes;
}
/**
diff --git a/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java b/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java
index 6db7fb01988..deb603bcb51 100644
--- a/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java
+++ b/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java
@@ -157,7 +157,7 @@ public final class ScanlineCoverage
* A data object that carries information about pixel coverage on a scanline.
* The data consists of a starting X position on the scanline, the
* length of the range in pixels and the actual coverage value.
-ยด */
+ **/
public static final class Range
{
/**
diff --git a/libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java b/libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java
new file mode 100644
index 00000000000..f4e77f450d0
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java
@@ -0,0 +1,119 @@
+/* ShapeWrapper.java -- Protects shapes by wrapping them
+ Copyright (C) 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 java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Protects any other shape from beeing modified by wrapping it.
+ */
+public class ShapeWrapper
+ implements Shape
+{
+
+ /**
+ * The shape to be protected.
+ */
+ private Shape shape;
+
+ /**
+ * Creates a new ShapeWrapper.
+ *
+ * @param other the shape to be protected
+ */
+ public ShapeWrapper(Shape other)
+ {
+ shape = other;
+ }
+
+ public boolean contains(double x, double y)
+ {
+ return shape.contains(x, y);
+ }
+
+ public boolean contains(Point2D p)
+ {
+ return shape.contains(p);
+ }
+
+ public boolean contains(double x, double y, double w, double h)
+ {
+ return shape.contains(x, y, w, h);
+ }
+
+ public boolean contains(Rectangle2D r)
+ {
+ return shape.contains(r);
+ }
+
+ public Rectangle getBounds()
+ {
+ return shape.getBounds();
+ }
+
+ public Rectangle2D getBounds2D()
+ {
+ return shape.getBounds2D();
+ }
+
+ public PathIterator getPathIterator(AffineTransform transform)
+ {
+ return shape.getPathIterator(transform);
+ }
+
+ public PathIterator getPathIterator(AffineTransform transform, double flatness)
+ {
+ return shape.getPathIterator(transform, flatness);
+ }
+
+ public boolean intersects(double x, double y, double w, double h)
+ {
+ return shape.intersects(x, y, w, h);
+ }
+
+ public boolean intersects(Rectangle2D r)
+ {
+ return shape.intersects(r);
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java b/libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java
new file mode 100644
index 00000000000..0a60c622676
--- /dev/null
+++ b/libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java
@@ -0,0 +1,153 @@
+/* TextCacheKey.java -- Key to use for caching texts with their rendered layout
+ Copyright (C) 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 java.awt.Font;
+import java.awt.font.FontRenderContext;
+
+/**
+ * A key object to be used when caching pre-rendered text.
+ */
+public class TextCacheKey
+{
+
+ /**
+ * The actual string.
+ */
+ private String string;
+
+ /**
+ * The font render context.
+ */
+ private FontRenderContext fontRenderContext;
+
+ /**
+ * The font.
+ */
+ private Font font;
+
+ /**
+ * Creates a new TextCacheKey.
+ *
+ * This is intended to be used as search key. It is important to initialize
+ * the values using the setter methods before using this key, otherwise
+ * it will throw NPEs.
+ */
+ public TextCacheKey()
+ {
+ // No-arg constructor.
+ }
+
+ /**
+ * Creates a new TextCacheKey with initial values.
+ *
+ * @param s the string
+ * @param f the font
+ * @param frc the font render context
+ */
+ public TextCacheKey(String s, Font f, FontRenderContext frc)
+ {
+ string = s;
+ font = f;
+ fontRenderContext = frc;
+ }
+
+ /**
+ * Re-sets the string. This is intented to be used in search keys only.
+ *
+ * @param s the string to set
+ */
+ public void setString(String s)
+ {
+ string = s;
+ }
+
+ /**
+ * Sets the font render context.
+ * This is intented to be used in search keys only.
+ *
+ * @param frc the new font render context
+ */
+ public void setFontRenderContext(FontRenderContext frc)
+ {
+ fontRenderContext = frc;
+ }
+
+ /**
+ * Sets the font.
+ * This is intented to be used in search keys only.
+ *
+ * @param f the font to set
+ */
+ public void setFont(Font f)
+ {
+ font = f;
+ }
+
+ /**
+ * Determines if two objects are equal.
+ *
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object o)
+ {
+ boolean eq;
+ if (o instanceof TextCacheKey)
+ {
+ TextCacheKey other = (TextCacheKey) o;
+ eq = other.string.equals(string)
+ && other.font.equals(font)
+ && other.fontRenderContext.equals(fontRenderContext);
+ }
+ else
+ {
+ eq = false;
+ }
+ return eq;
+ }
+
+ /**
+ * Computes a hashcode for this key.
+ *
+ * @see Object#hashCode()
+ */
+ public int hashCode()
+ {
+ return string.hashCode() ^ font.hashCode() ^ fontRenderContext.hashCode();
+ }
+}
OpenPOWER on IntegriCloud