8189809: Large performance regression in Swing text layout
authorprr
Mon, 11 Dec 2017 15:17:03 -0800
changeset 48285 7e8a0c4ee95e
parent 48284 fd7fbc929001
child 48286 745ea7d5039a
8189809: Large performance regression in Swing text layout Reviewed-by: serb, pnarayanan
src/java.desktop/share/classes/java/awt/Font.java
src/java.desktop/share/classes/sun/font/FontDesignMetrics.java
src/java.desktop/share/classes/sun/swing/SwingUtilities2.java
--- a/src/java.desktop/share/classes/java/awt/Font.java	Mon Dec 11 21:14:43 2017 +0100
+++ b/src/java.desktop/share/classes/java/awt/Font.java	Mon Dec 11 15:17:03 2017 -0800
@@ -56,6 +56,7 @@
 import sun.font.Font2D;
 import sun.font.Font2DHandle;
 import sun.font.FontAccess;
+import sun.font.FontDesignMetrics;
 import sun.font.FontManager;
 import sun.font.FontManagerFactory;
 import sun.font.FontUtilities;
@@ -2603,9 +2604,8 @@
         }
 
         if (simple) {
-            GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex,
-                                                     limit - beginIndex, frc);
-            return gv.getLogicalBounds();
+            FontDesignMetrics metrics = FontDesignMetrics.getMetrics(this, frc);
+            return metrics.getSimpleBounds(chars, beginIndex, limit-beginIndex);
         } else {
             // need char array constructor on textlayout
             String str = new String(chars, beginIndex, limit - beginIndex);
--- a/src/java.desktop/share/classes/sun/font/FontDesignMetrics.java	Mon Dec 11 21:14:43 2017 +0100
+++ b/src/java.desktop/share/classes/sun/font/FontDesignMetrics.java	Mon Dec 11 15:17:03 2017 -0800
@@ -33,6 +33,7 @@
 import java.awt.GraphicsEnvironment;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
 import java.awt.font.FontRenderContext;
 import java.awt.font.TextLayout;
 
@@ -519,6 +520,28 @@
     }
 
     /**
+     * This method is called from java.awt.Font only after verifying
+     * the arguments and that the text is simple and there are no
+     * layout attributes, font transform etc.
+     */
+    public Rectangle2D getSimpleBounds(char data[], int off, int len) {
+
+        float width = 0;
+        int limit = off + len;
+        for (int i=off; i < limit; i++) {
+            char ch = data[i];
+            if (ch < 0x100) {
+                width += getLatinCharWidth(ch);
+            } else {
+                width += handleCharWidth(ch);
+            }
+        }
+
+        float height = ascent + descent + leading;
+        return new Rectangle2D.Float(0f, -ascent, width, height);
+     }
+
+    /**
      * Gets the advance widths of the first 256 characters in the
      * {@code Font}.  The advance is the
      * distance from the leftmost point to the rightmost point on the
--- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java	Mon Dec 11 21:14:43 2017 +0100
+++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java	Mon Dec 11 15:17:03 2017 -0800
@@ -890,8 +890,17 @@
                                           FontMetrics fm,
                                           boolean useFPAPI)
     {
-        return len == 0 ? 0 : getFontStringWidth(new String(data, offset, len),
-                                                 fm, useFPAPI);
+        if (len == 0) {
+           return 0;
+        }
+        if (useFPAPI) {
+            Rectangle2D bounds = fm.getFont().
+                                     getStringBounds(data, offset, offset + len,
+                                                     fm.getFontRenderContext());
+            return (float) bounds.getWidth();
+        } else {
+            return fm.charsWidth(data, offset, len);
+        }
     }
 
     public static float getFontStringWidth(String data, FontMetrics fm,