6904962: GlyphVector.getVisualBounds should not be affected by leading or trailing white space.
Reviewed-by: igor, dougfelt
--- a/jdk/src/share/classes/sun/font/StandardGlyphVector.java Mon Nov 09 14:23:49 2009 -0800
+++ b/jdk/src/share/classes/sun/font/StandardGlyphVector.java Mon Nov 30 14:39:35 2009 -0800
@@ -396,12 +396,19 @@
// !!! not cached, assume TextLayout will cache if necessary
public Rectangle2D getVisualBounds() {
- if (glyphs.length == 0) {
- return new Rectangle2D.Float(0, 0, 0, 0);
+ Rectangle2D result = null;
+ for (int i = 0; i < glyphs.length; ++i) {
+ Rectangle2D glyphVB = getGlyphVisualBounds(i).getBounds2D();
+ if (!glyphVB.isEmpty()) {
+ if (result == null) {
+ result = glyphVB;
+ } else {
+ Rectangle2D.union(result, glyphVB, result);
+ }
+ }
}
- Rectangle2D result = getGlyphVisualBounds(0).getBounds2D();
- for (int i = 1; i < glyphs.length; ++i) {
- Rectangle2D.union(result, getGlyphVisualBounds(i).getBounds2D(), result);
+ if (result == null) {
+ result = new Rectangle2D.Float(0, 0, 0, 0);
}
return result;
}
@@ -1787,8 +1794,19 @@
gp.transform(sgv.invdtx);
result = gp.getBounds2D();
}
- result.setRect(result.getMinX() + x + dx, result.getMinY() + y + dy,
- result.getWidth(), result.getHeight());
+ /* Since x is the logical advance of the glyph to this point.
+ * Because of the way that Rectangle.union is specified, this
+ * means that subsequent unioning of a rect including that
+ * will be affected, even if the glyph is empty. So skip such
+ * cases. This alone isn't a complete solution since x==0
+ * may also not be what is wanted. The code that does the
+ * unioning also needs to be aware to ignore empty glyphs.
+ */
+ if (!result.isEmpty()) {
+ result.setRect(result.getMinX() + x + dx,
+ result.getMinY() + y + dy,
+ result.getWidth(), result.getHeight());
+ }
return result;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/GlyphVector/VisualBounds.java Mon Nov 30 14:39:35 2009 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @summary leading and trailing spaces must not affect visual bounds
+ * @bug 6904962
+ */
+
+
+import java.awt.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+
+public class VisualBounds {
+
+ public static void main(String args[]) {
+
+ String s1 = "a";
+ String s2 = s1+" ";
+ String s3 = " "+s1;
+ Font f = new Font("Dialog", Font.PLAIN, 12);
+ FontRenderContext frc = new FontRenderContext(null, false, false);
+ GlyphVector gv1 = f.createGlyphVector(frc, s1);
+ GlyphVector gv2 = f.createGlyphVector(frc, s2);
+ GlyphVector gv3 = f.createGlyphVector(frc, s3);
+ Rectangle2D bds1 = gv1.getVisualBounds();
+ Rectangle2D bds2 = gv2.getVisualBounds();
+ Rectangle2D bds3 = gv3.getVisualBounds();
+ GlyphVector gv4 = f.createGlyphVector(frc, " ");
+ Rectangle2D bds4 = gv4.getVisualBounds();
+ System.out.println(bds1);
+ System.out.println(bds2);
+ System.out.println(bds3);
+ System.out.println(bds4);
+
+ if (!bds1.equals(bds2)) {
+ throw new RuntimeException("Trailing space: Visual bounds differ");
+ }
+ if (bds2.getWidth() != bds3.getWidth()) {
+ throw new RuntimeException("Leading space: Visual widths differ");
+ }
+ if (!bds4.isEmpty()) {
+ throw new RuntimeException("Non empty bounds for space");
+ }
+ }
+}