summaryrefslogtreecommitdiff
path: root/gnu/java/awt/peer/gtk/GdkFontPeer.java
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/java/awt/peer/gtk/GdkFontPeer.java')
-rw-r--r--gnu/java/awt/peer/gtk/GdkFontPeer.java217
1 files changed, 178 insertions, 39 deletions
diff --git a/gnu/java/awt/peer/gtk/GdkFontPeer.java b/gnu/java/awt/peer/gtk/GdkFontPeer.java
index 40b234984..5f5126ac5 100644
--- a/gnu/java/awt/peer/gtk/GdkFontPeer.java
+++ b/gnu/java/awt/peer/gtk/GdkFontPeer.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
+import gnu.java.awt.ClasspathToolkit;
import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.java.awt.font.opentype.NameDecoder;
@@ -48,39 +49,125 @@ import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.GlyphMetrics;
import java.awt.font.LineMetrics;
+import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.text.CharacterIterator;
import java.util.Locale;
import java.util.Map;
-import java.util.ResourceBundle;
import java.nio.ByteBuffer;
import java.util.HashMap;
public class GdkFontPeer extends ClasspathFontPeer
{
+ static final FontRenderContext DEFAULT_CTX =
+ new FontRenderContext(null, false, false);
+
+ /**
+ * Caches TextLayout instances for use in charsWidth() and drawString().
+ * The size of the cache has been chosen so that relativly large GUIs with
+ * text documents are still efficient.
+ */
+ HashMap textLayoutCache = new GtkToolkit.LRUCache(500);
+
+ private class GdkFontMetrics extends FontMetrics
+ {
+
+ public GdkFontMetrics (Font font)
+ {
+ super(initFont(font));
+ }
+
+ public int stringWidth (String str)
+ {
+ TextLayout tl = (TextLayout) textLayoutCache.get(str);
+ if (tl == null)
+ {
+ tl = new TextLayout(str, font, DEFAULT_CTX);
+ textLayoutCache.put(str, tl);
+ }
+ return (int) tl.getAdvance();
+ }
+
+ public int charWidth (char ch)
+ {
+ return stringWidth (new String (new char[] { ch }));
+ }
+
+ public int charsWidth (char data[], int off, int len)
+ {
+ return stringWidth (new String (data, off, len));
+ }
+
+ public int getHeight()
+ {
+ return (int) height;
+ }
+
+ public int getLeading ()
+ {
+ return (int) (height - (ascent + descent));
+ }
+
+ public int getAscent ()
+ {
+ return (int) ascent;
+ }
+
+ public int getMaxAscent ()
+ {
+ return (int) ascent;
+ }
+
+ public int getDescent ()
+ {
+ return (int) descent;
+ }
+
+ public int getMaxDescent ()
+ {
+ return (int) maxDescent;
+ }
+
+ public int getMaxAdvance ()
+ {
+ return (int) maxAdvance;
+ }
+ }
+
static native void initStaticState();
private final int native_state = GtkGenericPeer.getUniqueInteger ();
- private static ResourceBundle bundle;
/**
* Cache GlyphMetrics objects.
*/
private HashMap metricsCache;
-
+
+ private static final int FONT_METRICS_ASCENT = 0;
+ private static final int FONT_METRICS_MAX_ASCENT = 1;
+ private static final int FONT_METRICS_DESCENT = 2;
+ private static final int FONT_METRICS_MAX_DESCENT = 3;
+ private static final int FONT_METRICS_MAX_ADVANCE = 4;
+ private static final int FONT_METRICS_HEIGHT = 5;
+ private static final int FONT_METRICS_UNDERLINE_OFFSET = 6;
+ private static final int FONT_METRICS_UNDERLINE_THICKNESS = 7;
+
+ float ascent;
+ float descent;
+ float maxAscent;
+ float maxDescent;
+ float maxAdvance;
+ float height;
+ float underlineOffset;
+ float underlineThickness;
+
+ GdkFontMetrics metrics;
+
static
{
System.loadLibrary("gtkpeer");
initStaticState ();
- try
- {
- bundle = ResourceBundle.getBundle ("gnu.java.awt.peer.gtk.font");
- }
- catch (Throwable ignored)
- {
- bundle = null;
- }
}
private ByteBuffer nameTable = null;
@@ -89,8 +176,8 @@ public class GdkFontPeer extends ClasspathFontPeer
private native void dispose ();
private native void setFont (String family, int style, int size);
- native void getFontMetrics(double [] metrics);
- native void getTextMetrics(String str, double [] metrics);
+ native synchronized void getFontMetrics(double [] metrics);
+ native synchronized void getTextMetrics(String str, double [] metrics);
native void releasePeerGraphicsResource();
@@ -149,6 +236,7 @@ public class GdkFontPeer extends ClasspathFontPeer
initState ();
setFont (this.familyName, this.style, (int)this.size);
metricsCache = new HashMap();
+ setupMetrics();
}
public GdkFontPeer (String name, Map attributes)
@@ -157,6 +245,40 @@ public class GdkFontPeer extends ClasspathFontPeer
initState ();
setFont (this.familyName, this.style, (int)this.size);
metricsCache = new HashMap();
+ setupMetrics();
+ }
+
+
+ /**
+ * Makes sure to return a Font based on the given Font that has as
+ * peer a GdkFontPeer. Used in the initializer.
+ */
+ static Font initFont(Font font)
+ {
+ if (font == null)
+ return new Font("Dialog", Font.PLAIN, 12);
+ else if (font.getPeer() instanceof GdkFontPeer)
+ return font;
+ else
+ {
+ ClasspathToolkit toolkit;
+ toolkit = (ClasspathToolkit) Toolkit.getDefaultToolkit();
+ return toolkit.getFont(font.getName(), font.getAttributes());
+ }
+ }
+
+ private void setupMetrics()
+ {
+ double [] hires = new double[8];
+ getFontMetrics(hires);
+ ascent = (float) hires[FONT_METRICS_ASCENT];
+ maxAscent = (float) hires[FONT_METRICS_MAX_ASCENT];
+ descent = (float) hires[FONT_METRICS_DESCENT];
+ maxDescent = (float) hires[FONT_METRICS_MAX_DESCENT];
+ maxAdvance = (float) hires[FONT_METRICS_MAX_ADVANCE];
+ height = (float) hires[FONT_METRICS_HEIGHT];
+ underlineOffset = (float) hires[FONT_METRICS_UNDERLINE_OFFSET];
+ underlineThickness = (float) hires[FONT_METRICS_UNDERLINE_THICKNESS];
}
/**
@@ -261,26 +383,17 @@ public class GdkFontPeer extends ClasspathFontPeer
return Font.ROMAN_BASELINE;
}
- private static class GdkFontLineMetrics extends LineMetrics
+ private class GdkFontLineMetrics extends LineMetrics
{
- private FontMetrics fm;
- private int nchars;
- private float strikethroughOffset, strikethroughThickness,
- underlineOffset, underlineThickness;
-
- public GdkFontLineMetrics (GdkFontPeer fp, FontMetrics m, int n)
+ private int nchars;
+ public GdkFontLineMetrics (GdkFontPeer fp, int n)
{
- fm = m;
nchars = n;
- strikethroughOffset = 0f;
- underlineOffset = 0f;
- strikethroughThickness = ((float)fp.getSize(null)) / 12f;
- underlineThickness = strikethroughThickness;
}
public float getAscent()
{
- return (float) fm.getAscent ();
+ return ascent;
}
public int getBaselineIndex()
@@ -296,27 +409,52 @@ public class GdkFontPeer extends ClasspathFontPeer
public float getDescent()
{
- return (float) fm.getDescent ();
+ return descent;
}
public float getHeight()
{
- return (float) fm.getHeight ();
+ return height;
}
- public float getLeading() { return 0.f; }
- public int getNumChars() { return nchars; }
- public float getStrikethroughOffset() { return 0.f; }
- public float getStrikethroughThickness() { return 0.f; }
- public float getUnderlineOffset() { return 0.f; }
- public float getUnderlineThickness() { return 0.f; }
+ public float getLeading()
+ {
+ return height - (ascent + descent);
+ }
+
+ public int getNumChars()
+ {
+ return nchars;
+ }
+
+ public float getStrikethroughOffset()
+ {
+ // FreeType doesn't seem to provide a value here.
+ return ascent / 2;
+ }
+
+ public float getStrikethroughThickness()
+ {
+ // FreeType doesn't seem to provide a value here.
+ return 1.f;
+ }
+
+ public float getUnderlineOffset()
+ {
+ return underlineOffset;
+ }
+
+ public float getUnderlineThickness()
+ {
+ return underlineThickness;
+ }
}
public LineMetrics getLineMetrics (Font font, CharacterIterator ci,
int begin, int limit, FontRenderContext rc)
{
- return new GdkFontLineMetrics (this, getFontMetrics (font), limit - begin);
+ return new GdkFontLineMetrics (this, limit - begin);
}
public Rectangle2D getMaxCharBounds (Font font, FontRenderContext rc)
@@ -361,14 +499,14 @@ public class GdkFontPeer extends ClasspathFontPeer
public LineMetrics getLineMetrics (Font font, String str,
FontRenderContext frc)
{
- return new GdkFontLineMetrics (this, getFontMetrics (font), str.length ());
+ return new GdkFontLineMetrics (this, str.length ());
}
public FontMetrics getFontMetrics (Font font)
{
- // Get the font metrics through GtkToolkit to take advantage of
- // the metrics cache.
- return Toolkit.getDefaultToolkit().getFontMetrics (font);
+ if (metrics == null)
+ metrics = new GdkFontMetrics(font);
+ return metrics;
}
/**
@@ -387,4 +525,5 @@ public class GdkFontPeer extends ClasspathFontPeer
{
metricsCache.put( new Integer( glyphCode ), metrics );
}
+
}