-
Bug
-
Resolution: Cannot Reproduce
-
P4
-
None
-
1.4.2
-
itanium
-
windows_xp
FULL PRODUCT VERSION :
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
There seems to be a pretty serious bug in FontMetrics.getStringBounds() whereby the font width will keep on increasing as the font size grows but then all of a sudden on larger values it'll shrink. I'm expecting the font width to always get bigger as the font size increases. Here are two data points that show what I'm seeing...
java.awt.Font[family=Georgia,name=Georgia,style=bold,size=268435488]
\-> width("SAMPLE")=145
java.awt.Font[family=Georgia,name=Georgia,style=bold,size=134217776]
\-> width("SAMPLE")=218
Notice how the text width grows as the font size shrinks.
This is a serious problem for me because I'm trying to programmatically detect what font size (in point units) will produce a certain text width (in pixel units). I can't use a binary search algorithm with the above bug.
REPRODUCIBILITY :
This bug can be reproduced always.
The submitter provided this additional information
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame;
public class FontMetricsBug
{
public static void main(String[] args)
{
Font bigFont = new Font("Times New Roman", Font.PLAIN, 268435488);
Font smallFont = new Font("Times New Roman", Font.PLAIN, 134217776);
JFrame frame = new JFrame();
frame.setVisible(true);
Graphics graphics = frame.getGraphics();
final String text = "test";
int bigWidth = graphics.getFontMetrics(bigFont).stringWidth(text);
int smallWidth = graphics.getFontMetrics(smallFont).stringWidth(text);
assert(bigWidth >= smallWidth): "bigWidth=" + bigWidth + ",
smallWidth=" +
smallWidth;
}
}
I get an output of "bigWidth=43, smallWidth=66" on my end which clearly
indicates a problem :) Also, on a related note, I noticed that
FontMetrics.getStringBounds() returns a Rectangle2D and then you can
invoke Rectangle2D.getBounds() to cast the bounds from float/double into
an int. I looked at the underlying code and there is no checking for
overflow. Isn't it possible for an overflow to occur if the original
coordinates were double and were being cast to an int? Should I file a
separate issue for this? (it is somewhat related to FontMetrics and
overflow problems)
I also see problems with the following test case:
import java.awt.*;
import java.awt.image.*;
public class FM {
public static void main(String args[]) {
BufferedImage bi = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D)bi.getGraphics();
double sf = 1;
//double sf = 0.0000001;
//double sf = 10000;
g.scale(sf, sf);
for (int i=0;i<31;i++){
int sz = (int)Math.pow(2, i);
Font f = new Font("Arial", Font.PLAIN, sz);
g.setFont(f);
FontMetrics fm = g.getFontMetrics();
System.out.println(f.getSize() + " " + fm.stringWidth("SAMPLE") +
" " + fm.getStringBounds("SAMPLE", g));
}
}
}
% java FM
1 6 java.awt.geom.Rectangle2D$Float[x=0.0,y=-0.92163086,w=6.0,h=1.1499023]
2 7 java.awt.geom.Rectangle2D$Float[x=0.0,y=-1.8432617,w=7.0,h=2.2998047]
4 17 java.awt.geom.Rectangle2D$Float[x=0.0,y=-3.6865234,w=17.0,h=4.5996094]
8 31 java.awt.geom.Rectangle2D$Float[x=0.0,y=-7.373047,w=31.0,h=9.199219]
16 66 java.awt.geom.Rectangle2D$Float[x=0.0,y=-14.746094,w=66.0,h=18.398438]
32 129 java.awt.geom.Rectangle2D$Float[x=0.0,y=-29.492188,w=129.0,h=36.796875]
64 261 java.awt.geom.Rectangle2D$Float[x=0.0,y=-58.984375,w=261.0,h=73.59375]
128 516 java.awt.geom.Rectangle2D$Float[x=0.0,y=-117.96875,w=516.0,h=147.1875]
256 1039 java.awt.geom.Rectangle2D$Float[x=0.0,y=-235.9375,w=1039.0,h=294.375]
512 2080 java.awt.geom.Rectangle2D$Float[x=0.0,y=-471.875,w=2080.0,h=588.75]
1024 4155 java.awt.geom.Rectangle2D$Float[x=0.0,y=-943.75,w=4155.0,h=1177.5]
2048 8310 java.awt.geom.Rectangle2D$Float[x=0.0,y=-1887.5,w=8310.0,h=2355.0]
4096 16619 java.awt.geom.Rectangle2D$Float[x=0.0,y=-3775.0,w=16619.0,h=4710.0]
8192 33237 java.awt.geom.Rectangle2D$Float[x=0.0,y=-7550.0,w=33237.0,h=9420.0]
16384 66473 java.awt.geom.Rectangle2D$Float[x=0.0,y=-15100.0,w=66473.0,h=18840.0]
32768 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
65536 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
131072 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
262144 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
524288 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
1048576 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
2097152 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
4194304 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
8388608 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
16777216 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
33554432 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
67108864 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
134217728 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
268435456 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
536870912 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
1073741824 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
java version "1.5.0_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05)
Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
There seems to be a pretty serious bug in FontMetrics.getStringBounds() whereby the font width will keep on increasing as the font size grows but then all of a sudden on larger values it'll shrink. I'm expecting the font width to always get bigger as the font size increases. Here are two data points that show what I'm seeing...
java.awt.Font[family=Georgia,name=Georgia,style=bold,size=268435488]
\-> width("SAMPLE")=145
java.awt.Font[family=Georgia,name=Georgia,style=bold,size=134217776]
\-> width("SAMPLE")=218
Notice how the text width grows as the font size shrinks.
This is a serious problem for me because I'm trying to programmatically detect what font size (in point units) will produce a certain text width (in pixel units). I can't use a binary search algorithm with the above bug.
REPRODUCIBILITY :
This bug can be reproduced always.
The submitter provided this additional information
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame;
public class FontMetricsBug
{
public static void main(String[] args)
{
Font bigFont = new Font("Times New Roman", Font.PLAIN, 268435488);
Font smallFont = new Font("Times New Roman", Font.PLAIN, 134217776);
JFrame frame = new JFrame();
frame.setVisible(true);
Graphics graphics = frame.getGraphics();
final String text = "test";
int bigWidth = graphics.getFontMetrics(bigFont).stringWidth(text);
int smallWidth = graphics.getFontMetrics(smallFont).stringWidth(text);
assert(bigWidth >= smallWidth): "bigWidth=" + bigWidth + ",
smallWidth=" +
smallWidth;
}
}
I get an output of "bigWidth=43, smallWidth=66" on my end which clearly
indicates a problem :) Also, on a related note, I noticed that
FontMetrics.getStringBounds() returns a Rectangle2D and then you can
invoke Rectangle2D.getBounds() to cast the bounds from float/double into
an int. I looked at the underlying code and there is no checking for
overflow. Isn't it possible for an overflow to occur if the original
coordinates were double and were being cast to an int? Should I file a
separate issue for this? (it is somewhat related to FontMetrics and
overflow problems)
I also see problems with the following test case:
import java.awt.*;
import java.awt.image.*;
public class FM {
public static void main(String args[]) {
BufferedImage bi = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D)bi.getGraphics();
double sf = 1;
//double sf = 0.0000001;
//double sf = 10000;
g.scale(sf, sf);
for (int i=0;i<31;i++){
int sz = (int)Math.pow(2, i);
Font f = new Font("Arial", Font.PLAIN, sz);
g.setFont(f);
FontMetrics fm = g.getFontMetrics();
System.out.println(f.getSize() + " " + fm.stringWidth("SAMPLE") +
" " + fm.getStringBounds("SAMPLE", g));
}
}
}
% java FM
1 6 java.awt.geom.Rectangle2D$Float[x=0.0,y=-0.92163086,w=6.0,h=1.1499023]
2 7 java.awt.geom.Rectangle2D$Float[x=0.0,y=-1.8432617,w=7.0,h=2.2998047]
4 17 java.awt.geom.Rectangle2D$Float[x=0.0,y=-3.6865234,w=17.0,h=4.5996094]
8 31 java.awt.geom.Rectangle2D$Float[x=0.0,y=-7.373047,w=31.0,h=9.199219]
16 66 java.awt.geom.Rectangle2D$Float[x=0.0,y=-14.746094,w=66.0,h=18.398438]
32 129 java.awt.geom.Rectangle2D$Float[x=0.0,y=-29.492188,w=129.0,h=36.796875]
64 261 java.awt.geom.Rectangle2D$Float[x=0.0,y=-58.984375,w=261.0,h=73.59375]
128 516 java.awt.geom.Rectangle2D$Float[x=0.0,y=-117.96875,w=516.0,h=147.1875]
256 1039 java.awt.geom.Rectangle2D$Float[x=0.0,y=-235.9375,w=1039.0,h=294.375]
512 2080 java.awt.geom.Rectangle2D$Float[x=0.0,y=-471.875,w=2080.0,h=588.75]
1024 4155 java.awt.geom.Rectangle2D$Float[x=0.0,y=-943.75,w=4155.0,h=1177.5]
2048 8310 java.awt.geom.Rectangle2D$Float[x=0.0,y=-1887.5,w=8310.0,h=2355.0]
4096 16619 java.awt.geom.Rectangle2D$Float[x=0.0,y=-3775.0,w=16619.0,h=4710.0]
8192 33237 java.awt.geom.Rectangle2D$Float[x=0.0,y=-7550.0,w=33237.0,h=9420.0]
16384 66473 java.awt.geom.Rectangle2D$Float[x=0.0,y=-15100.0,w=66473.0,h=18840.0]
32768 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
65536 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
131072 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
262144 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
524288 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
1048576 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
2097152 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
4194304 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
8388608 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
16777216 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
33554432 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
67108864 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
134217728 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
268435456 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
536870912 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
1073741824 0 java.awt.geom.Rectangle2D$Float[x=0.0,y=0.0,w=0.0,h=0.0]
- relates to
-
JDK-4522900 Bad Font Metrics returned (ascent, descent) when using scaled fonts in Java2D
-
- Open
-
-
JDK-6568541 Very large font size causes SIGSEGV when FontMetrics.stringWidth() invoked
-
- Closed
-