summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--gnu/java/awt/peer/gtk/FreetypeGlyphVector.java72
-rw-r--r--gnu/java/awt/peer/gtk/GdkFontPeer.java25
-rw-r--r--include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h2
-rw-r--r--java/awt/geom/AffineTransform.java4
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c26
6 files changed, 112 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index cd0ea9c8f..1461c2cc3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);