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);
}
}