-
Bug
-
Resolution: Fixed
-
P3
-
1.4.1, 1.4.2
-
b77
-
x86
-
windows_xp
Name: jk109818 Date: 08/25/2003
FULL PRODUCT VERSION :
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Adapter Type S3 Savage/IX, S3 Graphics, Inc. compatible
Adapter Description S3 Graphics Savage/IX 103C
Adapter RAM 4.00 MB (4,194,304 bytes)
A DESCRIPTION OF THE PROBLEM :
Some combinations of scaling parameters and font sizes cause severe font distortion when applying a flip transform as well. That is, some values of "xscale" and "yscale" used in the following transformation with some font sizes will cause severe font rendering problems:
| xscale 0 0 |
| 0 -yscale 0 |
where as the "non-flipped" transformation does not cause any problems:
| xscale 0 0 |
| 0 yscale 0 |
Examples are given in the sample program below.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the sample program below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Flipped fonts should look like mirror images of non-flipped fonts when the same (assymetric) scaling is applied to both.
Fonts are severely distorted when flipped for many combinations of scaling factors and font sizes.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.geom.*;
public class TextFlipBug extends Component {
static final float PAD = 15.0f;
static final String STR = "J Q K";
Font font1 = null;
Font font2 = null;
float xscale1, xscale2, yscale1, yscale2;
static final Font IFONT = new Font("Dialog", Font.PLAIN, 12);
TextFlipBug(float xs1, float ys1, int fs1,
float xs2, float ys2, int fs2) {
xscale1 = xs1;
yscale1 = ys1;
font1 = new Font("serif", Font.PLAIN, fs1);
xscale2 = xs2;
yscale2 = ys2;
font2 = new Font("serif", Font.PLAIN, fs2);
}
private void draw_flip(Graphics2D g2,
Font font, // Font to use
String str, // String to point
float xscale, float yscale, // Scale for X and Y
float midx, float midy, // Mid point to draw around
boolean left) // Print to left or right of midx?
{
AffineTransform oldtx = g2.getTransform();
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics();
// If printing left of
float len = xscale * (float) fm.stringWidth(str);
float lshift = PAD;
if (left) {
lshift = -PAD - len;
}
// Scale X and Y and draw string:
g2.translate(midx + lshift, midy - PAD);
g2.scale(xscale, yscale);
g2.drawString(str, 0f, 0f);
// Flip about Y and draw string:
g2.setTransform(oldtx);
g2.translate(midx + lshift, midy + PAD);
g2.scale(xscale, -yscale);
g2.drawString(str, 0f, 0f);
g2.setTransform(oldtx);
g2.setFont(IFONT);
String istr = "(XS=" + xscale + ", YS=" + yscale + ", FS=" + font.getSize() + ")";
fm = g2.getFontMetrics();
lshift = 2*PAD + len;
if (left) {
lshift = - 2*PAD - len - (float) fm.stringWidth(istr);
}
g2.drawString(istr, midx + lshift , midy - PAD);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
// Turning these off/on makes no difference in distortion:
g2.setRenderingHint( RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON );
g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON );
g2.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
Dimension d = this.getSize();
float midx = (float) d.getWidth()/2;
float midy = (float) d.getHeight()/2;
g2.drawLine((int) midx, 0, (int) midx, d.height);
g2.drawLine(0, (int) midy, d.width, (int) midy);
draw_flip(g2, font1, STR, xscale1, yscale1, midx, midy, true);
draw_flip(g2, font2, STR, xscale2, yscale2, midx, midy, false);
}
public static void main(String args[]) {
Frame f;
int loc = 0;
f = new Frame("Yscale under 10.1 is very bad for font size 10 (Xscale closer to 10 helps).");
TextFlipBug tf = new TextFlipBug(2f, 10.1f, 10, 2f, 10.0f, 10);
f.add("Center", tf);
f.pack();
f.setLocation(loc, loc);
f.show();
loc += 50;
f = new Frame("Font size under 26 is bad for Xscale=2 and Yscale=4.");
// Any font size below 26 is bad with xscale=2, yscale=4
tf = new TextFlipBug(2f, 4f, 26, 2f, 4f, 25);
f.add("Center", tf);
f.pack();
f.setLocation(loc, loc);
f.show();
loc += 50;
f = new Frame("Xscale less than 0.9 is bad for Yscale=1.0.");
//
tf = new TextFlipBug(0.9f, 1f, 50, 0.5f, 1f, 50);
f.add("Center", tf);
f.pack();
f.setLocation(loc, loc);
f.show();
loc += 50;
}
public Dimension getPreferredSize() {
return new Dimension (700, 200);
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I couldn't find a satisfactory one. In some cases drawing to a BufferedImage and then flipping the image with a BufferedImageOp might be sufficient, unless you are drawing within the rectangle which bounds the text. I've tried making the image transparent, but this introduces other artifacts.
Release Regression From : 1.3.1_08
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Incident Review ID: 184900)
======================================================================
FULL PRODUCT VERSION :
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
FULL OS VERSION :
Microsoft Windows XP [Version 5.1.2600]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Adapter Type S3 Savage/IX, S3 Graphics, Inc. compatible
Adapter Description S3 Graphics Savage/IX 103C
Adapter RAM 4.00 MB (4,194,304 bytes)
A DESCRIPTION OF THE PROBLEM :
Some combinations of scaling parameters and font sizes cause severe font distortion when applying a flip transform as well. That is, some values of "xscale" and "yscale" used in the following transformation with some font sizes will cause severe font rendering problems:
| xscale 0 0 |
| 0 -yscale 0 |
where as the "non-flipped" transformation does not cause any problems:
| xscale 0 0 |
| 0 yscale 0 |
Examples are given in the sample program below.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the sample program below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Flipped fonts should look like mirror images of non-flipped fonts when the same (assymetric) scaling is applied to both.
Fonts are severely distorted when flipped for many combinations of scaling factors and font sizes.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.geom.*;
public class TextFlipBug extends Component {
static final float PAD = 15.0f;
static final String STR = "J Q K";
Font font1 = null;
Font font2 = null;
float xscale1, xscale2, yscale1, yscale2;
static final Font IFONT = new Font("Dialog", Font.PLAIN, 12);
TextFlipBug(float xs1, float ys1, int fs1,
float xs2, float ys2, int fs2) {
xscale1 = xs1;
yscale1 = ys1;
font1 = new Font("serif", Font.PLAIN, fs1);
xscale2 = xs2;
yscale2 = ys2;
font2 = new Font("serif", Font.PLAIN, fs2);
}
private void draw_flip(Graphics2D g2,
Font font, // Font to use
String str, // String to point
float xscale, float yscale, // Scale for X and Y
float midx, float midy, // Mid point to draw around
boolean left) // Print to left or right of midx?
{
AffineTransform oldtx = g2.getTransform();
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics();
// If printing left of
float len = xscale * (float) fm.stringWidth(str);
float lshift = PAD;
if (left) {
lshift = -PAD - len;
}
// Scale X and Y and draw string:
g2.translate(midx + lshift, midy - PAD);
g2.scale(xscale, yscale);
g2.drawString(str, 0f, 0f);
// Flip about Y and draw string:
g2.setTransform(oldtx);
g2.translate(midx + lshift, midy + PAD);
g2.scale(xscale, -yscale);
g2.drawString(str, 0f, 0f);
g2.setTransform(oldtx);
g2.setFont(IFONT);
String istr = "(XS=" + xscale + ", YS=" + yscale + ", FS=" + font.getSize() + ")";
fm = g2.getFontMetrics();
lshift = 2*PAD + len;
if (left) {
lshift = - 2*PAD - len - (float) fm.stringWidth(istr);
}
g2.drawString(istr, midx + lshift , midy - PAD);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
// Turning these off/on makes no difference in distortion:
g2.setRenderingHint( RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON );
g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON );
g2.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
Dimension d = this.getSize();
float midx = (float) d.getWidth()/2;
float midy = (float) d.getHeight()/2;
g2.drawLine((int) midx, 0, (int) midx, d.height);
g2.drawLine(0, (int) midy, d.width, (int) midy);
draw_flip(g2, font1, STR, xscale1, yscale1, midx, midy, true);
draw_flip(g2, font2, STR, xscale2, yscale2, midx, midy, false);
}
public static void main(String args[]) {
Frame f;
int loc = 0;
f = new Frame("Yscale under 10.1 is very bad for font size 10 (Xscale closer to 10 helps).");
TextFlipBug tf = new TextFlipBug(2f, 10.1f, 10, 2f, 10.0f, 10);
f.add("Center", tf);
f.pack();
f.setLocation(loc, loc);
f.show();
loc += 50;
f = new Frame("Font size under 26 is bad for Xscale=2 and Yscale=4.");
// Any font size below 26 is bad with xscale=2, yscale=4
tf = new TextFlipBug(2f, 4f, 26, 2f, 4f, 25);
f.add("Center", tf);
f.pack();
f.setLocation(loc, loc);
f.show();
loc += 50;
f = new Frame("Xscale less than 0.9 is bad for Yscale=1.0.");
//
tf = new TextFlipBug(0.9f, 1f, 50, 0.5f, 1f, 50);
f.add("Center", tf);
f.pack();
f.setLocation(loc, loc);
f.show();
loc += 50;
}
public Dimension getPreferredSize() {
return new Dimension (700, 200);
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
I couldn't find a satisfactory one. In some cases drawing to a BufferedImage and then flipping the image with a BufferedImageOp might be sufficient, unless you are drawing within the rectangle which bounds the text. I've tried making the image transparent, but this introduces other artifacts.
Release Regression From : 1.3.1_08
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Incident Review ID: 184900)
======================================================================
- relates to
-
JDK-4654540 need hinting support for text rendering with scaled/flipped matrix
-
- Resolved
-