aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorScott Gilbertson <scottg@mantatest.com>2003-04-19 17:59:40 +0000
committerTom Tromey <tromey@gcc.gnu.org>2003-04-19 17:59:40 +0000
commit1230b94d569c2d914af665a2890d0e841f1c2ae3 (patch)
treee80fc1a431e861eaf074ba267233e9717d2c16ba /libjava
parent3b2288059d786fc6994debbaffeff898746a6921 (diff)
downloadgcc-1230b94d569c2d914af665a2890d0e841f1c2ae3.zip
gcc-1230b94d569c2d914af665a2890d0e841f1c2ae3.tar.gz
gcc-1230b94d569c2d914af665a2890d0e841f1c2ae3.tar.bz2
XGraphicsConfiguration.java (FontMetricsCache): New inner class.
2003-04-19 Scott Gilbertson <scottg@mantatest.com> * gnu/awt/xlib/XGraphicsConfiguration.java (FontMetricsCache): New inner class. (CACHE_SIZE_PER_DISPLAY): New field (fontMetricsCache): New field (getXFontMetrics): Use fontMetricsCache to cache fonts. Prefer loading ISO10646-1 fonts. From-SVN: r65821
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog9
-rw-r--r--libjava/gnu/awt/xlib/XGraphicsConfiguration.java170
2 files changed, 153 insertions, 26 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index d91604b..498a6b0 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,5 +1,14 @@
2003-04-19 Scott Gilbertson <scottg@mantatest.com>
+ * gnu/awt/xlib/XGraphicsConfiguration.java (FontMetricsCache): New
+ inner class.
+ (CACHE_SIZE_PER_DISPLAY): New field
+ (fontMetricsCache): New field
+ (getXFontMetrics): Use fontMetricsCache to cache fonts. Prefer
+ loading ISO10646-1 fonts.
+
+2003-04-19 Scott Gilbertson <scottg@mantatest.com>
+
* libjava/gnu/gcj/xlib/natFont.cc (getStringWidth): Support 16-bit
characters.
* libjava/gnu/gcj/xlib/natGC.cc (drawString): Support 16-bit
diff --git a/libjava/gnu/awt/xlib/XGraphicsConfiguration.java b/libjava/gnu/awt/xlib/XGraphicsConfiguration.java
index 7d7d515..d867bee 100644
--- a/libjava/gnu/awt/xlib/XGraphicsConfiguration.java
+++ b/libjava/gnu/awt/xlib/XGraphicsConfiguration.java
@@ -16,6 +16,7 @@ import java.awt.GraphicsDevice;
import java.awt.Point;
import java.awt.Color;
import java.awt.color.ColorSpace;
+import java.awt.Font;
import java.awt.image.*;
import java.awt.geom.AffineTransform;
import gnu.gcj.xlib.GC;
@@ -27,7 +28,9 @@ import gnu.gcj.xlib.Colormap;
import gnu.gcj.xlib.XColor;
import gnu.gcj.xlib.Screen;
import gnu.gcj.xlib.Display;
+import gnu.gcj.xlib.XException;
import gnu.java.awt.Buffers;
+import java.util.Enumeration;
import java.util.Hashtable;
public class XGraphicsConfiguration extends GraphicsConfiguration
@@ -39,6 +42,104 @@ public class XGraphicsConfiguration extends GraphicsConfiguration
Colormap colormap;
ColorModel imageCM;
ColorModel pixelCM;
+ private static final int CACHE_SIZE_PER_DISPLAY = 10;
+ static FontMetricsCache fontMetricsCache = new FontMetricsCache ();
+
+ /** Font metrics cache class. Caches at most CACHE_SIZE_PER_DISPLAY
+ * XFontMetrics objects for each display device. When a display's cache
+ * gets full, the least-recently used entry is overwritten.
+ * XXX: lruOrder rolls over after a few billion operations, so it might
+ * on very rare occasions misinterpret which is the oldest entry
+ */
+ class FontMetricsCache
+ {
+ private java.util.Hashtable displays = new java.util.Hashtable ();
+
+ /** Font metrics cache for a display device
+ */
+ class PerDisplayCache
+ {
+ private int lruCount = 0;
+ private java.util.Hashtable entries = new java.util.Hashtable ();
+
+ class CacheEntry
+ {
+ int lruOrder;
+ XFontMetrics fm;
+ Font font;
+ }
+
+ /** Get an entry (null if not there) and update LRU ordering
+ */
+ XFontMetrics get (Font font)
+ {
+ CacheEntry entry = (CacheEntry)entries.get (font);
+ if (entry != null)
+ {
+ entry.lruOrder = lruCount++;
+ }
+ return (entry==null) ? null : entry.fm;
+ }
+
+ /** Put an entry in the cache, eliminating the oldest entry if
+ * the cache is at capacity.
+ */
+ void put (Font font, XFontMetrics fontMetrics)
+ {
+ if (entries.size () >= CACHE_SIZE_PER_DISPLAY)
+ {
+ // cache is full -- eliminate the oldest entry
+ // slow operation, but shouldn't happen very often
+ int maxAge = 0;
+ CacheEntry oldestEntry = null;
+ int referenceCount = lruCount;
+ for (Enumeration e = entries.elements (); e.hasMoreElements ();)
+ {
+ CacheEntry entry = (CacheEntry)e.nextElement ();
+ if ((referenceCount-entry.lruOrder) > maxAge)
+ {
+ maxAge = referenceCount-entry.lruOrder;
+ oldestEntry = entry;
+ }
+ }
+ if (oldestEntry != null)
+ entries.remove (oldestEntry.font);
+ }
+ CacheEntry newEntry = new CacheEntry ();
+ newEntry.lruOrder = lruCount++;
+ newEntry.fm = fontMetrics;
+ newEntry.font = font;
+ entries.put (font,newEntry);
+ }
+ }
+
+ /** Get the font metrics for a font, if it is present in the cache.
+ * @param font The AWT font for which to find the font metrics
+ * @param display The display, to select the cached entries for that display
+ * @return The font metrics, or null if not cached
+ */
+ XFontMetrics get (Font font, Display display)
+ {
+ PerDisplayCache cache = (PerDisplayCache)displays.get (display);
+ return (cache==null) ? null : cache.get (font);
+ }
+
+ /** Put a font in the cache
+ * @param font The font
+ * @param display The display
+ * @param fontMetrics The font metrics
+ */
+ void put (Font font, Display display, XFontMetrics fontMetrics)
+ {
+ PerDisplayCache cache = (PerDisplayCache)displays.get (display);
+ if (cache == null)
+ {
+ cache = new PerDisplayCache ();
+ displays.put (display,cache);
+ }
+ cache.put (font,fontMetrics);
+ }
+ }
public XGraphicsConfiguration(Visual visual)
{
@@ -358,33 +459,50 @@ public class XGraphicsConfiguration extends GraphicsConfiguration
}
/* FIXME: This should be moved to XGraphicsDevice... */
- XFontMetrics getXFontMetrics(java.awt.Font awtFont)
+ XFontMetrics getXFontMetrics (java.awt.Font awtFont)
{
- // FIXME: do caching...
-
- String family = "*";
- String name = awtFont.getName();
- String weight = awtFont.isBold() ? "bold" : "medium";
- String slant = awtFont.isItalic() ? "i" : "r";
- String addStyle = "*";
- String pixelSize = "*";
- String pointSize = awtFont.getSize() + "0";
- String xres = "*";
- String yres = "*";
- String spacing = "*";
- String averageWidth = "*";
- String charset = "*";
-
- String logicalFontDescription =
- family + "-" + name + "-" + weight + "-" +
- slant + "-" + addStyle + "-" + pixelSize + "-" +
- pointSize + "-" + xres + "-" + yres + "-" +
- spacing + "-" + averageWidth + "-" + charset;
-
- Display display = visual.getScreen().getDisplay();
- gnu.gcj.xlib.Font xfont =
- new gnu.gcj.xlib.Font(display, logicalFontDescription);
- return new XFontMetrics(xfont, awtFont);
+ // If the metrics object for this font is already cached, use it.
+ // Otherwise create and cache it.
+ Display display = visual.getScreen ().getDisplay ();
+ XFontMetrics fm = fontMetricsCache.get (awtFont,display);
+ if (fm == null)
+ {
+ String foundry = "*";
+ String family = awtFont.getName ();
+ String weight = awtFont.isBold () ? "bold" : "medium";
+ String slant = awtFont.isItalic () ? "i" : "r";
+ String sWidth = "*";
+ String addStyle = "";
+ String pixelSize = "*";
+ String pointSize = awtFont.getSize () + "0";
+ String xres = "*";
+ String yres = "*";
+ String spacing = "*";
+ String averageWidth = "*";
+ String charset = "iso10646-1"; // because we use functions like XDrawString16
+
+ String logicalFontDescription =
+ "-" + // FontNameRegistry prefix
+ foundry + "-" + family + "-" + weight + "-" +
+ slant + "-" + sWidth + "-" + addStyle + "-" +
+ pixelSize + "-" + pointSize + "-" + xres + "-" +
+ yres + "-" + spacing + "-" + averageWidth + "-";
+
+ // Try to load a Unicode font. If that doesn't work, try again, without
+ // specifying the character set.
+ try
+ {
+ gnu.gcj.xlib.Font xfont = new gnu.gcj.xlib.Font (display, logicalFontDescription + charset);
+ fm = new XFontMetrics (xfont, awtFont);
+ }
+ catch (XException e)
+ {
+ gnu.gcj.xlib.Font xfont = new gnu.gcj.xlib.Font (display, logicalFontDescription + "*-*");
+ fm = new XFontMetrics (xfont, awtFont);
+ }
+ fontMetricsCache.put (awtFont,display,fm);
+ }
+ return fm;
}
int getPixel(Color color)