Hi,

The following patch (committed) fixes the getGlyphPosition and
getGlyphPositions methods in the gtk peers for
java.awt.font.GlyphVector, as well as adding support for vertical fonts
and cleaning up the implementation a bit.

Regards,
Francis


2006-09-20  Francis Kung  <[EMAIL PROTECTED]>

        * gnu/java/awt/peer/gtk/FreetypeGlyphVector.java:
        (constructor): Expanded glyphPositions array to accomodate
Y-coordinates.
        (getGlyphOutline): Call getGylphTransform to generate transform.
        (getGylphPosition): Read position directly out of array.
        (getGlyphPositions): Read positions directly out of array.
        (getGlyphTransform): Generate transform based on gylphPositions array.
        (performDefaultLayout): Populate glyphPositions array instead of
transforms.
        (setGlyphPosition): Set position directly into array.
        (setGlyphTransform): Update positions array as well.

Index: gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java,v
retrieving revision 1.7
diff -u -r1.7 FreetypeGlyphVector.java
--- gnu/java/awt/peer/gtk/FreetypeGlyphVector.java	18 Jun 2006 00:54:47 -0000	1.7
+++ gnu/java/awt/peer/gtk/FreetypeGlyphVector.java	19 Sep 2006 19:06:57 -0000
@@ -39,14 +39,14 @@
 
 import java.awt.Font;
 import java.awt.Shape;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.GeneralPath;
+import java.awt.font.FontRenderContext;
 import java.awt.font.GlyphJustificationInfo;
 import java.awt.font.GlyphMetrics;
 import java.awt.font.GlyphVector;
-import java.awt.font.FontRenderContext;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 
 public class FreetypeGlyphVector extends GlyphVector
 {
@@ -155,14 +155,15 @@
       }
 
     glyphCodes = new int[ nGlyphs ];
-    glyphPositions = new float[ nGlyphs ];
+    glyphPositions = new float[(nGlyphs + 1) * 2];
     glyphTransforms = new AffineTransform[ nGlyphs ];
     for(int i = 0; i < nGlyphs; i++ )
       {
-	glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] );
-	glyphCodes[i] = gv.glyphCodes[ i ];
-	glyphPositions[i] = gv.glyphPositions[ i ];
+        glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] );
+        glyphCodes[i] = gv.glyphCodes[ i ];
       }
+    System.arraycopy(gv.glyphPositions, 0, glyphPositions, 0,
+                     glyphPositions.length);
   }
 
   /**
@@ -242,22 +243,26 @@
   public void performDefaultLayout()
   {
     logicalBounds = null; // invalidate caches.
-    glyphPositions = null;
-
-    glyphTransforms = new AffineTransform[ nGlyphs ]; 
-    double x = 0;
+    glyphPositions = new float[(nGlyphs + 1) * 2];
+    glyphTransforms = new AffineTransform[nGlyphs];
 
+    GlyphMetrics gm = null;
     for(int i = 0; i < nGlyphs; i++)
       {
-	GlyphMetrics gm = getGlyphMetrics( i );
-	glyphTransforms[ i ] = AffineTransform.getTranslateInstance(x, 0);
-	x += gm.getAdvanceX();
-	if( i > 0 )
-	  {
-	    Point2D p = getKerning( glyphCodes[ i - 1 ], glyphCodes[ i ] );
-	    x += p.getX();
-	  }
+        gm = getGlyphMetrics( i );
+        glyphPositions[i*2] += gm.getAdvanceX();
+        glyphPositions[i*2 + 1] += gm.getAdvanceY();
+        glyphTransforms[i] = null;
+        
+        if (i != 0 && i != (nGlyphs + 1))
+          {
+            Point2D p = getKerning(glyphCodes[i - 1], glyphCodes[i]);
+            glyphPositions[i * 2] += p.getX();
+            glyphPositions[i * 2 + 1] += p.getY();
+          }
       }
+    glyphPositions[nGlyphs * 2] = gm.getAdvanceX();
+    glyphPositions[nGlyphs * 2 + 1] = gm.getAdvanceY();
   }
 
   /**
@@ -352,7 +357,7 @@
   public Shape getGlyphOutline(int glyphIndex)
   {
     GeneralPath gp = getGlyphOutlineNative( glyphCodes[ glyphIndex ] );
-    gp.transform( glyphTransforms[ glyphIndex ] );
+    gp.transform( getGlyphTransform(glyphIndex));
     return gp;
   }
 
@@ -361,8 +366,8 @@
    */
   public Point2D getGlyphPosition(int glyphIndex)
   {
-    return glyphTransforms[ glyphIndex ].transform( new Point2D.Double(0, 0),
-						   null );
+    return new Point2D.Float(glyphPositions[glyphIndex*2],
+                             glyphPositions[glyphIndex*2 + 1]);
   }
 
   /**
@@ -371,25 +376,12 @@
   public float[] getGlyphPositions(int beginGlyphIndex, int numEntries, 
 				   float[] positionReturn)
   {
-    if( glyphPositions != null )
-      return glyphPositions;
-
-    float[] rval;
-
-    if( positionReturn == null )
-      rval = new float[2 * numEntries];
-    else
-      rval = positionReturn;
-
-    for( int i = beginGlyphIndex; i < numEntries; i++ )
-      {
-	Point2D p = getGlyphPosition( i );
-	rval[i * 2] = (float)p.getX();
-	rval[i * 2 + 1] = (float)p.getY();
-      }
-
-    glyphPositions = rval;
-    return rval;
+    if (positionReturn == null)
+      positionReturn = new float[numEntries*2];
+    
+    System.arraycopy(glyphPositions, beginGlyphIndex*2, positionReturn, 0,
+                     numEntries*2);
+    return positionReturn;
   }
 
   /**
@@ -397,7 +389,11 @@
    */
   public AffineTransform getGlyphTransform(int glyphIndex)
   {
-    return new AffineTransform( glyphTransforms[ glyphIndex ] );
+    if (glyphTransforms[glyphIndex] == null)
+      glyphTransforms[glyphIndex] = AffineTransform.getScaleInstance(glyphPositions[glyphIndex*2],
+                                                                     glyphPositions[glyphIndex*2 + 1]);
+    
+    return glyphTransforms[glyphIndex];
   }
 
   /**
@@ -486,10 +482,12 @@
   public void setGlyphPosition(int glyphIndex, Point2D newPos)
   {
     // FIXME: Scaling, etc.?
-    glyphTransforms[ glyphIndex ].setToTranslation( newPos.getX(), 
-						    newPos.getY() );
+    glyphPositions[glyphIndex*2] = (float)(newPos.getX());
+    glyphPositions[glyphIndex*2 + 1] = (float)(newPos.getY());
     logicalBounds = null;
-    glyphPositions = null;
+    
+    if (glyphIndex != nGlyphs)
+      glyphTransforms[glyphIndex] = null;
   }
 
   /**
@@ -497,8 +495,11 @@
    */
   public void setGlyphTransform(int glyphIndex, AffineTransform newTX)
   {
-    glyphTransforms[ glyphIndex ].setTransform( newTX );
+    // FIXME: Scaling, etc.?
     logicalBounds = null;
-    glyphPositions = null;
+    Point2D pt = newTX.transform(new Point2D.Double(0, 0), null);
+    glyphPositions[glyphIndex*2] = (float)(pt.getX());
+    glyphPositions[glyphIndex*2 + 1] = (float)(pt.getY());
+    glyphTransforms[glyphIndex] = newTX;
   }
 }

Reply via email to