JDK-8064833 : [macosx] Native font lookup uses family+style, not full name/postscript name
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 7u4
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: os_x
  • Submitted: 2014-11-13
  • Updated: 2015-10-22
  • Resolved: 2015-01-26
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.
JDK 8 JDK 9
8u60Fixed 9 b52Fixed
Related Reports
Duplicate :  
Relates :  
Description
There was an FX bug report that text was printed incorrectly
https://javafx-jira.kenai.com/browse/RT-38198.
It wasn't clear if it was a locale problem but the symptom looked like
a bad char->glyph mapping.

This was seen only on later OS X systems. Some debugging revealed that
Helvetica-LightOblique was in use and this helped identify the problem.

FX printing is using an interface to Java 2D. This prints text by passing
the font information and glyphs to draw to the 2D pipeline.

It was eventually determined that the glyph codes passed from FX were the
correct ones for the font that was specified and that the problem was in
the 2D side where the wrong font was found. This is not at all specific to
printing. The same happens on screen. And once you know the font to
use you can see the problem on 10.7.x too.

The OS X specific font code correctly registers Helvetica-LightOblique for lookup
However when it comes to be used it needs to get a pointer to a native font
resource. It does this by passing the family name - in this case 'Helvetica' - and
style information.
            nativeFontPtr = createNativeFont(nativeFontName, style, isFakeItalic);

This is under-specified and as a result the underlying native font
that is mapped from the Java CFont is actually Helvetica-Oblique and thus we
get the glyph ids mapped into that font which is different.

Note: this is NOT a regression in Oracle JDK for OS X.
I can reproduce the problem on Apple JDK 6. Its likely been a bug forever ...

That can be resolved as thus :-
hg diff CFont.java
diff --git a/src/java.desktop/macosx/classes/sun/font/CFont.java b/src/java.desktop/macosx/classes/sun/font/CFont.java
--- a/src/java.desktop/macosx/classes/sun/font/CFont.java
+++ b/src/java.desktop/macosx/classes/sun/font/CFont.java
@@ -94,7 +94,7 @@
         handle = new Font2DHandle(this);
         fullName = name;
         familyName = inFamilyName;
-        nativeFontName = inFamilyName;
+        nativeFontName = fullName;
         setStyle();
     }

The two things I am not sure about - that I can think of - are
1) That this lookup by full name will work reliably - and note this is PSName which is
how the Apple implementation has always worked, but that is for another day
2) Since we specify full name we should find the right style, so I am unsure if
the native code to 'add' that trait is a) always a no-op, b) sometimes a no-op
but occasionally helpful, or c) harmful in at least some cases.

The test program below demonstrates the problem - if it finds this font it ought to
draw "Big red italic font" but instead draws garbage text.

import javax.swing.*;
import java.awt.*;
import java.awt.font.*;

public class DrawHelveticaGV extends JComponent {

    public static void main(String[] args) throws Exception {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        DrawHelveticaGV dgv = new DrawHelveticaGV();
        f.add("Center", dgv);
        f.pack();
        f.setVisible(true);
    }

    public Dimension getPreferredSize() {
      return new Dimension(400,400);
    }

    int[] codes = { 0x23, 0x4a, 0x48, 0x3, 0x4a, 0x55, 0x42, 0x4d,
                    0x4a, 0x44, 0x3,
                    0x53, 0x46, 0x45, 0x3, 0x55, 0x46, 0x59, 0x55, };

    public void paintComponent(Graphics g) {
       super.paintComponent(g);
       Graphics2D g2 = (Graphics2D)g;
       FontRenderContext frc = new FontRenderContext(null, true, true);
       Font f = new Font("Helvetica-LightOblique", Font.PLAIN, 40);
       System.out.println("font = " +f.getFontName());
       GlyphVector gv = f.createGlyphVector(frc, codes);
       g.setFont(f);
       g.setColor(Color.white);
       g.fillRect(0,0,400,400);
       g.setColor(Color.black);
       g2.drawGlyphVector(gv, 5,200);
    }
}


Comments
What are the chances of getting a back port to 8u60 or some near-term 8u release? I think I'm having this issue with my JavaFX application and the closest matching JavaFX issue (https://javafx-jira.kenai.com/browse/RT-38198) points to this as the culprit. Basically all my text printing on OS X is coming out with grabbed characters and character advances.
02-06-2015

> I can reproduce the problem on Apple JDK 6. Its likely been a bug forever ... I thought I had something even earlier to try but Apple made what looked 1.4.2 in fact just a symlink to 1.6
14-11-2014

I am not too surprised to find that the change above causes some failures with lookups that involve a family+style Needs a more sophisticated fix. Also AWTFont.m unconditionally defines "DEBUG". That is a leftover from the initial port or perhaps even earlier.
13-11-2014