JDK-6476980 : deriveFont is not working on FontUIResource with a dynamically loaded TTF
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2006-09-29
  • Updated: 2014-02-27
  • Resolved: 2006-11-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0u11 b01Fixed
Description
FULL PRODUCT VERSION :
java version "1.5.0_08"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_08-b03)
Java HotSpot(TM) Client VM (build 1.5.0_08-b03, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

Linux hun129ux 2.6.8-24-smp #1 SMP Wed Oct 6 09:16:23 UTC 2004 i686 i686 i386 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
deriveFont is not working with an instance of FontUIResource, which was instantiated with a dynamically loaded true type font.

PRECONDITION: the custom true type font specified in the createFont method must not be registered at the operating system level!

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a new font object by dynamically loading it from a file.
2. Create a new FontUIResource instance by passing it the font object created in the previous step.
3. Derive a new font object with deriveFont by, for example, changing the size. The deriveFont should be called on the FontUIResource instance created in the previous step.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The expected result should be a new font whose size has been changed as specified. The 'new font' here refers to the TTF loaded from the file.
ACTUAL -
Only the font size has changed, but the font is not what is loaded from the file.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
import java.io.*;

/**
 * An application that demonstrates a JDK bug: deriveFont is not working with an
 * instance of FontUIResource, which was instantiated with a dynamically loaded
 * true type font. The true type font file must be located in the same folder where
 * the compiled class files of this program can be found.
 *
 * PRECONDITION: the custom true type font specified in the createFont method must not
 * be registered at the operating system level!
 */
public class BugDemonstrationPanel extends JPanel {
    static JFrame frame;
    private JLabel testLabel;
    private Font labelFont;
    public BugDemonstrationPanel() {
        InputStream fontStream =
            BugDemonstrationPanel.class.getResourceAsStream("<your TTF file name here>");
        if (fontStream != null) {
            try {
                labelFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
                labelFont = new FontUIResource(labelFont).deriveFont((float) 24);
                // If you use the next line instead of the previous one, everything works!
                // labelFont = labelFont.deriveFont((float) 24);
                System.out.println(labelFont.toString());
                fontStream.close();
            } catch (Exception e) {}
            testLabel = new JLabel();
            testLabel.setText("Only the font size changed, but not the font itself!");
            testLabel.setFont(labelFont);
            setSize(300, 200);
            add(testLabel);
	}
    }

    public static void main(String s[]) {
        BugDemonstrationPanel panel = new BugDemonstrationPanel();
        frame = new JFrame(BugDemonstrationPanel.class.toString());
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}

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

CUSTOMER SUBMITTED WORKAROUND :
By not using the FontUIResource (as the demo code shows) everything works as expected.

Comments
EVALUATION The FontUIResource is not marked as with a special flag which identifies it as one which when being further derived has the effect of ensuring the created font reference is copied into the new derivedFont. Its one missing line in the fix for 6313541 in 5.0u7 The JDK 6 version of this fix is differnet and doesn't have this problem The program exhibiting the problem does this ((paraphrasing the code) labelFont = Font.createFont(Font.TRUETYPE_FONT, fontStream); labelFont = new FontUIResource(labelFont); // this is OK labelFont = deriveFont((float) 24); // this has lost the created font However as well as losing the created font it also isn't a FontUIResource anymore either. A workaround is instead to reverse the order of those latter two lines so the code looks like this : labelFont = Font.createFont(Font.TRUETYPE_FONT, fontStream); labelFont = deriveFont((float) 24); // this keeps the created font labelFont = new FontUIResource(labelFont); // this is OK That way you do in fact have a FontUIResource still Still we should see if we can get this fixed in an update release as its possible that in some cases a deriveFont may happen in code outside the application's control.
29-09-2006