-
Bug
-
Resolution: Fixed
-
P4
-
7, 9
-
b100
-
x86
-
windows_7
FULL PRODUCT VERSION :
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
public abstract void StandardGlyphVector.setGlyphPosition(int glyphIndex,
Point2D newPos)
throws an ArrayIndexOutOfBoundsException when the glyphIndex parameter is == getNumGlyphs() and the bounds are internally cached inside the StandardGlyphVector implementation.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Obtain a GlyphVector instance from any java.awt.Font instance.
2. Call one of the methods to get any glyphs's bounds from the GlyphVector, such as getLogicalBounds(0). (This causes the bounds to be cached)
3. call setGlyphPosition(glyphIndex, position) where glyphIndex == GlyphVector.getNumGlyphs() and position is any valid position.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The documentation says "If glyphIndex equals the number of glyphs in this GlyphVector, this method sets the position after the last glyph. This position is used to define the advance of the entire GlyphVector."
ACTUAL -
throws ArrayIndexOutOfBoundsException.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at sun.font.StandardGlyphVector.clearCaches(StandardGlyphVector.java:1242)
at sun.font.StandardGlyphVector.setGlyphPosition(StandardGlyphVector.java:454)
at TestStandardGlyphVectorBug.main(TestStandardGlyphVectorBug.java:28)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
public class TestStandardGlyphVectorBug
{
public static void main(String[] args)
{
Font defaultFont = new Font(null);
FontRenderContext defaultFrc = new FontRenderContext(new AffineTransform(), true, true);
GlyphVector gv = defaultFont.createGlyphVector(defaultFrc, "test");
//this causes the bounds to be cached
//which is necessary to trigger the bug
gv.getGlyphLogicalBounds(0);
//this correctly gets the position of the overall advance
Point2D glyphPosition = gv.getGlyphPosition(gv.getNumGlyphs());
// this sets the position of the overall advance,
// but also incorrectly tries to clear the bounds cache
// of a specific glyph indexed by the glyphIndex parameter
// even if the glyphIndex represents the overall advance
// (i.e. if glyphIndex == getNumGlyphs())
gv.setGlyphPosition(gv.getNumGlyphs(), glyphPosition);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
You could call one of the methods of StandardGlyphVector that cause the clearCaches() method to be called before trying to set the advance of the entire GlyhpVector. The private method clearCaches() sets the caches to null. But clearly this is implementation dependent.
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
public abstract void StandardGlyphVector.setGlyphPosition(int glyphIndex,
Point2D newPos)
throws an ArrayIndexOutOfBoundsException when the glyphIndex parameter is == getNumGlyphs() and the bounds are internally cached inside the StandardGlyphVector implementation.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Obtain a GlyphVector instance from any java.awt.Font instance.
2. Call one of the methods to get any glyphs's bounds from the GlyphVector, such as getLogicalBounds(0). (This causes the bounds to be cached)
3. call setGlyphPosition(glyphIndex, position) where glyphIndex == GlyphVector.getNumGlyphs() and position is any valid position.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The documentation says "If glyphIndex equals the number of glyphs in this GlyphVector, this method sets the position after the last glyph. This position is used to define the advance of the entire GlyphVector."
ACTUAL -
throws ArrayIndexOutOfBoundsException.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at sun.font.StandardGlyphVector.clearCaches(StandardGlyphVector.java:1242)
at sun.font.StandardGlyphVector.setGlyphPosition(StandardGlyphVector.java:454)
at TestStandardGlyphVectorBug.main(TestStandardGlyphVectorBug.java:28)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
public class TestStandardGlyphVectorBug
{
public static void main(String[] args)
{
Font defaultFont = new Font(null);
FontRenderContext defaultFrc = new FontRenderContext(new AffineTransform(), true, true);
GlyphVector gv = defaultFont.createGlyphVector(defaultFrc, "test");
//this causes the bounds to be cached
//which is necessary to trigger the bug
gv.getGlyphLogicalBounds(0);
//this correctly gets the position of the overall advance
Point2D glyphPosition = gv.getGlyphPosition(gv.getNumGlyphs());
// this sets the position of the overall advance,
// but also incorrectly tries to clear the bounds cache
// of a specific glyph indexed by the glyphIndex parameter
// even if the glyphIndex represents the overall advance
// (i.e. if glyphIndex == getNumGlyphs())
gv.setGlyphPosition(gv.getNumGlyphs(), glyphPosition);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
You could call one of the methods of StandardGlyphVector that cause the clearCaches() method to be called before trying to set the advance of the entire GlyhpVector. The private method clearCaches() sets the caches to null. But clearly this is implementation dependent.