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
This commit is contained in:
Scott Gilbertson 2003-04-19 17:59:40 +00:00 committed by Tom Tromey
parent 3b2288059d
commit 1230b94d56
2 changed files with 153 additions and 26 deletions

View File

@ -1,3 +1,12 @@
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

View File

@ -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)