# HG changeset patch # User prr # Date 1513034223 28800 # Node ID 7e8a0c4ee95ed132a17f94e105c58f5a712c36c9 # Parent fd7fbc9290014a672f794b14287c0af3bbacec81 8189809: Large performance regression in Swing text layout Reviewed-by: serb, pnarayanan diff -r fd7fbc929001 -r 7e8a0c4ee95e src/java.desktop/share/classes/java/awt/Font.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); diff -r fd7fbc929001 -r 7e8a0c4ee95e src/java.desktop/share/classes/sun/font/FontDesignMetrics.java --- 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 diff -r fd7fbc929001 -r 7e8a0c4ee95e src/java.desktop/share/classes/sun/swing/SwingUtilities2.java --- 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,