United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6591278 Wrong rendering of transformed fonts on Windows with Java 6
JDK-6591278 : Wrong rendering of transformed fonts on Windows with Java 6

Details
Type:
Bug
Submit Date:
2007-08-09
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
client-libs
OS:
windows_xp
Sub-Component:
2d
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
Java 1.6.0_01-b06

ADDITIONAL OS VERSION INFORMATION :
Windows XP sp2

A DESCRIPTION OF THE PROBLEM :
Wrong rendering of transformed fonts on Windows with Java 6.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the example, with real transformation matrix (which was obtained after some transformation in real program). Note, that it doesn't appear with Java 1.4.2, only with Java 6.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Normal string "3 500"
ACTUAL -
Expected string with skewed numbers.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import java.awt.*;

import java.awt.event.*;
import java.awt.geom.AffineTransform;

class DrawStringTest extends Frame
{  
	DrawStringTest(String s)
	{
		super(s);
		setBounds(0, 0, 500, 300);
		setVisible(true);
	}

	public void paint(Graphics g)
	{
		Font f = new Font("Dialog", Font.PLAIN, 12);
		
		String s1 = "3 500";
        
        AffineTransform tr = new AffineTransform();
        double[] m = new double[6];
        tr.getMatrix(m);
        //m00 m10 m01 m11 m02 m12
        m[0] = 0.8749999999999999;
        m[1] = 0.0;
        m[2] = 0.0;
        m[3] = 0.875;
        m[4] = 5.675000000000001;
        m[5] = 107.11192516891774;
        /*m[0] = 0.875;
        m[1] = 0.0;
        m[2] = 0.0;
        m[3] = 0.875;
        m[4] = 7.0;
        m[5] = 107.11192516891774;*/
        tr = new AffineTransform(m);
        g.setFont(f);
        ((Graphics2D)g).transform(tr);
		g.drawString(s1, 0, 0);
}  

	public static void main(String[] args)
	{
		DrawStringTest f = new DrawStringTest("DrawStringTest");
		
		f.addWindowListener(new WindowAdapter(){
		
		public void windowClosing(WindowEvent ev){
			System.exit(0);}
		});
	}
} 

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
"Rounding" of transformation matrix, like:

double[] m = new double[6];
_graphics.getTransform().getMatrix(m);
for (int i = 0; i < 6; i ++)
m[i] = (double)Math.round(m[i]*1000000000)/1000000000;
_graphics.setTransform(new AffineTransform(m));

Release Regression From : 5
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

                                    

Comments
EVALUATION

Transformation matrix is not pure scale transform. 
T2K is performing hinting with different x and y point sizes.
(and difference is getting beiiger because t2k uses fixed math internally)

I am not sure why exaclty difference is that noticeable. Looks like hinting was 
disabled for some reason.

To avoid this we can update logic of preparation of transformation matrix for hinting engine to be more tolerant to small differences and rounding errors.
In particular we can consider x/y sizes of point to be the same if they differ 
by 1 (i.e. in last bit of fixed math representation).
                                     
2007-08-18
EVALUATION

This problem is not reproducible with latest 6u10 and 7 builds.
First, fix for 6656651 make it difficult to observe because t2k is not default rasterizer in many cases. Morover fix for 6223022 changed rounding logic (in uril.c) and this 
prevents discrepancy in this particular case.

The root reason is still there, rasterizer uses fixed math and input transform may 
be not identity due to float point math.  Converstion from float to fixed increases 
discrepancy and this may eventually lead to very noticeable changes in the glyph appearance (because hinting code was not supposed to work with all different transforms). 

However, importance of this issue for 6u10 seems to have decreased significantly.
                                     
2008-05-20
EVALUATION

If scale factors are almost the same then process them as identical.
This resolves the problem when identity is lost due to precision loss.

Note that explicitly setting transformation matrix that is close to identity but 
exceeds this threshold will still lead to noticeable change in rasterization result.
                                     
2008-05-28



Hardware and Software, Engineered to Work Together