diff options
| author | doko <doko@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-06-28 13:29:13 +0000 |
|---|---|---|
| committer | doko <doko@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-06-28 13:29:13 +0000 |
| commit | 1020ce5944edde4364baef4d371cd4f9b0dae721 (patch) | |
| tree | 602cd7aa7c947386134690d8e0f6b53abcdeacb9 /libjava/classpath/gnu/java/awt/java2d | |
| parent | 9f41ce98ce6f4f7c8ac5e2c4b6e5d27e10201015 (diff) | |
| download | ppe42-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')
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(); + } +} |

