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;
}