FULL PRODUCT VERSION :
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b86, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
Results produced from the shear() operation do not match results produced in JDK 1.2 thru 1.5. shear() was used to produce a "inverted, slanted" font which looked like a shadow to the original font. The original font was flipped, then sheared which produced the shadow affect.
fontTransform = AffineTransform.getScaleInstance(1.0, -1.0);
fontTransform.shear(-1.0, 0.0);
reflectionFont = textFont.deriveFont(fontTransform);
Up through JDK 1.5, this produced a "shadow" of the original font, In JDK 1.6B2, the shear inverts the font across the Y axis instead of slanting the original font.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The following code was used to illustrate affine transforms and rendering hints in a class I teach. This code worked correctly until JDK 6.
Sample code is included below that shows this behavior.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The generated font should appear below the original font, not to the left of the font.
ACTUAL -
The new "shadow" font is no longer correct. If you just scale the font, you get the correct results, if you just shear the font, you get the correct results, if you scale the font, then shear it, it appears as though axis values are flipped.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class Affine1 extends JPanel{
// our arrow shape
GeneralPath arrow = new GeneralPath();
// rotate transform
AffineTransform arrowRotate;
// shadow transform
AffineTransform shadowScale;
// shear transform
AffineTransform shadowShear;
// font transform
AffineTransform fontTransform;
Shape rotatedArrow;
Shape scaledArrow;
Shape skewedArrow;
static RenderingHints hints1;
static RenderingHints hints2;
Font textFont = new Font("Arial", Font.PLAIN, 40);
// derived fonts...
Font reflectionFont;
Font reflectionFont2;
public Affine1 () {
super();
setLayout(null);
// get the graphics environment
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
env.getAvailableFontFamilyNames();
hints1 = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
hints2 = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
// build our arrow, but it is pointing to the right
arrow.moveTo(0f, -10f);
arrow.lineTo(20f, -10f);
arrow.lineTo(20f, 0f);
arrow.lineTo(40, -20f);
arrow.lineTo(20f, -40f);
arrow.lineTo(20f, -30f);
arrow.lineTo(0f, -30f);
arrow.closePath();
// rotate the arrow -90 around its center
arrowRotate = AffineTransform.getRotateInstance(- Math.PI/2, 20, -20);
shadowScale = AffineTransform.getScaleInstance(1.0, 0.4);
shadowShear = AffineTransform.getShearInstance(-1.25, 0.0);
rotatedArrow = arrowRotate.createTransformedShape(arrow);
scaledArrow = shadowScale.createTransformedShape(rotatedArrow);
skewedArrow = shadowShear.createTransformedShape(scaledArrow);
// This is the code that no longer works
fontTransform = AffineTransform.getScaleInstance(1.0, -1.0);
fontTransform.shear(-1.0, 0.0);
// if you try to just shear the font, it works, if you just scaled
// it above it works as well.
// fontTransform = AffineTransform.getShearInstance(-1.0, 0.0);
reflectionFont = textFont.deriveFont(fontTransform);
shadowScale.shear(-1.25, 0.0);
reflectionFont2 = textFont.deriveFont(shadowScale);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
// draw Java2D with shadow in back
g2d.translate(100, 80);
g2d.setFont(reflectionFont2);
g2d.setPaint(Color.gray);
g2d.drawString("Aliased", 0, 0);
g2d.setPaint(Color.blue);
g2d.setFont(textFont);
g2d.drawString("Aliased", 0, 0);
// draw Java2D with shadow in back
g2d.translate(300, 0);
g2d.setRenderingHints(hints1);
g2d.setPaint(Color.gray);
g2d.setFont(reflectionFont2);
g2d.drawString("Anti-Aliased", 0, 0);
g2d.setPaint(Color.blue);
g2d.setFont(textFont);
g2d.drawString("Anti-Aliased", 0, 0);
// Now draw arrow with shadow
g2d.translate(-260, 80);
g2d.setColor(Color.gray);
g2d.fill(skewedArrow);
g2d.setColor(Color.blue);
g2d.fill(rotatedArrow);
// arrow with shadow and anti-aliasing
g2d.setRenderingHints(hints1);
g2d.translate(350, 0);
g2d.setColor(Color.gray);
g2d.fill(skewedArrow);
g2d.setColor(Color.blue);
g2d.fill(rotatedArrow);
g2d.setRenderingHints(hints2);
g2d.translate(-400, 0);
// Now draw Java2D with shadow in front
g2d.translate(-80, 60);
g2d.setFont(textFont);
g2d.drawString("Java 2D 1 2 3 4 5", 0, 0);
g2d.setPaint(Color.gray);
// note the use of using the transformed font like any other
// font. Its transformation placed its 0,0 location at the top
// left of its bounds
g2d.setFont(reflectionFont);
g2d.drawString("Java 2D 1 2 3 4 5", 0, 0);
// Now draw Java2D with shadow in front and anti-aliasing
g2d.translate(350, 0);
g2d.setColor(Color.blue);
g2d.setRenderingHints(hints1);
g2d.setFont(textFont);
g2d.drawString("Java 2D 1 2 3 4 5", 0, 0);
g2d.setPaint(Color.gray);
g2d.setFont(reflectionFont);
g2d.drawString("Java 2D 1 2 3 4 5", 0, 0);
g2d.setRenderingHints(hints2);
g2d.translate(-200, 0);
}
public static void main(String argv[]) {
JFrame j = new JFrame("Affine1.java");
j.setContentPane(new Affine1());
j.setSize(500, 400);
j.setVisible(true);
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None known
Release Regression From : mustang
The above release value was the last known release where this
bug was not reproducible. Since then there has been a regression.