And this is part two of the fix: optimized drawing is disabled in CairoGraphics2D if any glyphs have been transformed. The fallback code path respects transformations, while the optimized code doesn't.

Cheers,
Francis


2007-04-12  Francis Kung  <[EMAIL PROTECTED]>

        PR 23887
        * gnu/java/awt/peer/gtk/CairoGraphics2D.java
        (drawGlyphVector): Check for transforms before using optimized path.
        * gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
(FreetypeGlyphVector(FreetypeGlyphVector)): Initialize glyphTransforms array
        to null and check for nulls in copied array.
        (hasTransforms): New method.
        (performDefaultLayout): Check for identity transform.
        (setGlyphTransform): Check for equality before making changes.
Index: gnu/java/awt/peer/gtk/CairoGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,v
retrieving revision 1.69
diff -u -r1.69 CairoGraphics2D.java
--- gnu/java/awt/peer/gtk/CairoGraphics2D.java	4 Apr 2007 19:20:33 -0000	1.69
+++ gnu/java/awt/peer/gtk/CairoGraphics2D.java	12 Apr 2007 20:13:37 -0000
@@ -1726,7 +1726,8 @@
                        .equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF));
     ignoreAA = true;
     
-    if (gv instanceof FreetypeGlyphVector && alpha == 1.0)
+    if (gv instanceof FreetypeGlyphVector && alpha == 1.0
+        && !((FreetypeGlyphVector)gv).hasTransforms())
       {
         int n = gv.getNumGlyphs ();
         int[] codes = gv.getGlyphCodes (0, n, null);
Index: gnu/java/awt/peer/gtk/FreetypeGlyphVector.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java,v
retrieving revision 1.20
diff -u -r1.20 FreetypeGlyphVector.java
--- gnu/java/awt/peer/gtk/FreetypeGlyphVector.java	12 Apr 2007 19:27:46 -0000	1.20
+++ gnu/java/awt/peer/gtk/FreetypeGlyphVector.java	12 Apr 2007 20:13:37 -0000
@@ -88,7 +88,10 @@
   private long[] fontSet = null;
 
   /**
-   * Glyph transforms. (de facto only the translation is used)
+   * Glyph transforms.  Supports all transform operations.
+   * 
+   * The identity transform should not be stored in this array; use a null
+   * instead (will result in performance improvements).
    */
   private AffineTransform[] glyphTransforms;
 
@@ -187,9 +190,12 @@
     fontSet = new long[nGlyphs];
     glyphPositions = new float[(nGlyphs + 1) * 2];
     glyphTransforms = new AffineTransform[ nGlyphs ];
+    Arrays.fill(glyphTransforms, null);
+    
     for(int i = 0; i < nGlyphs; i++ )
       {
-        glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] );
+        if (gv.glyphTransforms[i] != null)
+          glyphTransforms[ i ] = new AffineTransform(gv.glyphTransforms[i]);
         glyphCodes[i] = gv.glyphCodes[ i ];
       }
     System.arraycopy(gv.glyphPositions, 0, glyphPositions, 0,
@@ -331,7 +337,8 @@
         double[] matrix = new double[4];
         tx.getMatrix(matrix);
         AffineTransform deltaTx = new AffineTransform(matrix);
-        Arrays.fill(glyphTransforms, deltaTx);
+        if (!deltaTx.isIdentity())
+          Arrays.fill(glyphTransforms, deltaTx);
       }
   }
 
@@ -493,7 +500,19 @@
   {
     return glyphTransforms[glyphIndex];
   }
-
+  
+  /**
+   * Checks whether any transform has been set on any glyphs.
+   */
+  protected boolean hasTransforms()
+  {
+    for (int i = 0; i < glyphTransforms.length; i++)
+      if (glyphTransforms[i] != null)
+        return true;
+    
+    return false;
+  }
+  
   /**
    * Returns the visual bounds of a glyph
    * May be off by a pixel or two due to hinting/rasterization.
@@ -590,6 +609,19 @@
    */
   public void setGlyphTransform(int glyphIndex, AffineTransform newTX)
   {
+    // The identity transform should never be in the glyphTransforms array;
+    // using and checking for nulls can be much faster.
+    if (newTX != null && newTX.isIdentity())
+      newTX = null;
+    
+    // If the old and new transforms are identical, bail
+    if (glyphTransforms[glyphIndex] == null && newTX == null)
+      return;
+    
+    if (newTX != null && newTX.equals(glyphTransforms[glyphIndex]))
+      return;
+    
+    // Invalidate bounds cache and set new transform
     logicalBounds = null;
     glyphTransforms[glyphIndex] = newTX;
   }

Reply via email to