diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/FreetypeGlyphVector.java | 72 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GdkFontPeer.java | 25 | ||||
-rw-r--r-- | include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h | 2 | ||||
-rw-r--r-- | java/awt/geom/AffineTransform.java | 4 | ||||
-rw-r--r-- | native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c | 26 |
6 files changed, 112 insertions, 31 deletions
@@ -1,3 +1,17 @@ +2006-06-11 Sven de Marothy <sven@physto.se> + + * gnu/java/awt/peer/gtk/FreetypeGlyphVector.java + (setupGlyphMetrics): New method. Add glyphmetrics caching. + (getOutline): Operate on the shape directly. + * gnu/java/awt/peer/gtk/GdkFontPeer.java + (getGlyphMetrics,putGlyphMetrics): Add GlyphMetrics caching. + * include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h + (getGlyph renamed getGlyphs) + * java/awt/geom/AffineTransform.java + (getTranslateInstance): Set fields directly. + * native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c + (getGlyphs): Get all glyph codes at once. + 2006-06-11 Raif S. Naffah <raif@swiftdsl.com.au> PR Classpath/27853 diff --git a/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java b/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java index 1f5c455dd..4978c6a45 100644 --- a/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java +++ b/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java @@ -84,11 +84,7 @@ public class FreetypeGlyphVector extends GlyphVector */ private AffineTransform[] glyphTransforms; - /** - * Keep track of which glyphs are whitespace, since we don't have - * reporting from the peers yet. TextLayout needs this for justification. - */ - private boolean[] whiteSpace; + private GlyphMetrics[] metricsCache; /** * Create a glyphvector from a given (Freetype) font and a String. @@ -147,21 +143,25 @@ public class FreetypeGlyphVector extends GlyphVector { nGlyphs = s.codePointCount( 0, s.length() ); glyphCodes = new int[ nGlyphs ]; + int[] codePoints = new int[ nGlyphs ]; int stringIndex = 0; + for(int i = 0; i < nGlyphs; i++) { - glyphCodes[i] = getGlyph( s.codePointAt(stringIndex) ); + codePoints[i] = s.codePointAt( stringIndex ); // UTF32 surrogate handling - if( s.codePointAt( stringIndex ) != (int)s.charAt( stringIndex ) ) + if( codePoints[i] != (int)s.charAt( stringIndex ) ) stringIndex ++; stringIndex ++; } + + glyphCodes = getGlyphs( codePoints ); } /** * Returns the glyph code within the font for a given character */ - public native int getGlyph(int codepoint); + public native int[] getGlyphs(int[] codepoints); /** * Returns the kerning of a glyph pair @@ -209,14 +209,12 @@ public class FreetypeGlyphVector extends GlyphVector logicalBounds = null; // invalidate caches. glyphPositions = null; - whiteSpace = new boolean[ nGlyphs ]; glyphTransforms = new AffineTransform[ nGlyphs ]; double x = 0; + for(int i = 0; i < nGlyphs; i++) { - whiteSpace[i] = Character.isWhitespace( glyphCodes[ i ] ); GlyphMetrics gm = getGlyphMetrics( i ); - Rectangle2D r = gm.getBounds2D(); glyphTransforms[ i ] = AffineTransform.getTranslateInstance(x, 0); x += gm.getAdvanceX(); if( i > 0 ) @@ -266,22 +264,48 @@ public class FreetypeGlyphVector extends GlyphVector gm.getAdvanceX(), r.getHeight() ); } + /* + * FIXME: Not all glyph types are supported. + * (The JDK doesn't really seem to do so either) + */ + public void setupGlyphMetrics() + { + metricsCache = new GlyphMetrics[ nGlyphs ]; + + for(int i = 0; i < nGlyphs; i++) + { + GlyphMetrics gm = (GlyphMetrics) + peer.getGlyphMetrics( glyphCodes[ i ] ); + if( gm == null ) + { + double[] val = getMetricsNative( glyphCodes[ i ] ); + if( val == null ) + gm = null; + else + { + gm = new GlyphMetrics( true, + (float)val[1], + (float)val[2], + new Rectangle2D.Double + ( val[3], val[4], + val[5], val[6] ), + GlyphMetrics.STANDARD ); + peer.putGlyphMetrics( glyphCodes[ i ], gm ); + } + } + metricsCache[ i ] = gm; + } + } + /** * Returns the metrics of a single glyph. - * FIXME: Not all glyph types are supported. */ public GlyphMetrics getGlyphMetrics(int glyphIndex) { - double[] val = getMetricsNative( glyphCodes[ glyphIndex ] ); - if( val == null ) - return null; - byte type = whiteSpace[ glyphIndex ] ? - GlyphMetrics.WHITESPACE : GlyphMetrics.STANDARD; - - return new GlyphMetrics( true, (float)val[1], (float)val[2], - new Rectangle2D.Double( val[3], val[4], - val[5], val[6] ), - type ); + if( metricsCache == null ) + setupGlyphMetrics(); + + return metricsCache[ glyphIndex ]; } /** @@ -406,7 +430,9 @@ public class FreetypeGlyphVector extends GlyphVector public Shape getOutline(float x, float y) { AffineTransform tx = AffineTransform.getTranslateInstance( x, y ); - return tx.createTransformedShape( getOutline() ); + GeneralPath gp = (GeneralPath)getOutline(); + gp.transform( tx ); + return gp; } /** diff --git a/gnu/java/awt/peer/gtk/GdkFontPeer.java b/gnu/java/awt/peer/gtk/GdkFontPeer.java index f126e01fc..f5ed8a710 100644 --- a/gnu/java/awt/peer/gtk/GdkFontPeer.java +++ b/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -57,12 +57,18 @@ 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 native void initStaticState(); private final int native_state = GtkGenericPeer.getUniqueInteger (); private static ResourceBundle bundle; + + /** + * Cache GlyphMetrics objects. + */ + private HashMap metricsCache; static { @@ -145,6 +151,7 @@ public class GdkFontPeer extends ClasspathFontPeer super(name, style, size); initState (); setFont (this.familyName, this.style, (int)this.size); + metricsCache = new HashMap(); } public GdkFontPeer (String name, Map attributes) @@ -152,6 +159,7 @@ public class GdkFontPeer extends ClasspathFontPeer super(name, attributes); initState (); setFont (this.familyName, this.style, (int)this.size); + metricsCache = new HashMap(); } /** @@ -375,4 +383,21 @@ public class GdkFontPeer extends ClasspathFontPeer // the metrics cache. return Toolkit.getDefaultToolkit().getFontMetrics (font); } + + /** + * Returns a cached GlyphMetrics object for a given glyphcode, + * or null if it doesn't exist in the cache. + */ + GlyphMetrics getGlyphMetrics( int glyphCode ) + { + return (GlyphMetrics)metricsCache.get( new Integer( glyphCode ) ); + } + + /** + * Put a GlyphMetrics object in the cache. + */ + void putGlyphMetrics( int glyphCode, Object metrics ) + { + metricsCache.put( new Integer( glyphCode ), metrics ); + } } diff --git a/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h b/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h index 8c8434b6e..10a4ea5e5 100644 --- a/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h +++ b/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h @@ -10,7 +10,7 @@ extern "C" { #endif -JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyph (JNIEnv *env, jobject, jint); +JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphs (JNIEnv *env, jobject, jintArray); JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getKerning (JNIEnv *env, jobject, jint, jint); JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative (JNIEnv *env, jobject, jint); JNIEXPORT jobject JNICALL Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative (JNIEnv *env, jobject, jint); diff --git a/java/awt/geom/AffineTransform.java b/java/awt/geom/AffineTransform.java index 4d1a4d6d5..55b688355 100644 --- a/java/awt/geom/AffineTransform.java +++ b/java/awt/geom/AffineTransform.java @@ -414,7 +414,9 @@ public class AffineTransform implements Cloneable, Serializable public static AffineTransform getTranslateInstance(double tx, double ty) { AffineTransform t = new AffineTransform(); - t.setToTranslation(tx, ty); + t.m02 = tx; + t.m12 = ty; + t.type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION; return t; } diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c index 42abd983c..361b67746 100644 --- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c +++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c @@ -81,24 +81,38 @@ getFont(JNIEnv *env, jobject obj) return (PangoFcFont *)pfont->font; } -JNIEXPORT jint JNICALL -Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyph - (JNIEnv *env, jobject obj, jint codepoint) +JNIEXPORT jintArray JNICALL +Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphs + (JNIEnv *env, jobject obj, jintArray codepoints) { FT_Face ft_face; jint glyph_index; + jintArray retArray; PangoFcFont *font; + jint *values, *cpvals; + jint length; + int i; font = getFont(env, obj); ft_face = pango_fc_font_lock_face( font ); g_assert (ft_face != NULL); - glyph_index = FT_Get_Char_Index( ft_face, codepoint ); + length = (*env)->GetArrayLength (env, codepoints); + cpvals = (*env)->GetIntArrayElements (env, codepoints, NULL); + + retArray = (*env)->NewIntArray (env, length); + values = (*env)->GetIntArrayElements (env, retArray, NULL); + + for( i = 0; i < length; i++ ) + values[i] = FT_Get_Char_Index( ft_face, cpvals[i] ); + + (*env)->ReleaseIntArrayElements (env, retArray, values, 0); + (*env)->ReleaseIntArrayElements (env, codepoints, cpvals, 0); pango_fc_font_unlock_face (font); - return glyph_index; + return retArray; } JNIEXPORT jobject JNICALL @@ -143,7 +157,7 @@ Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative FT_Set_Transform( ft_face, NULL, NULL ); - if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_DEFAULT ) != 0 ) + if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_NO_BITMAP ) != 0 ) { pango_fc_font_unlock_face( font ); printf("Couldn't load glyph %i\n", glyphIndex); |