JDK-6517861 : Java2D : Installing font of family "Times" on Windows hides "Times New Roman"
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows
  • CPU: generic
  • Submitted: 2007-01-25
  • Updated: 2011-03-08
  • Resolved: 2011-03-08
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 6 JDK 7
6u2Fixed 7 b08Fixed
Description
On a Windows XP SP 2 PC a user reports the following :

on one test system we found a really strange behavious of a little app,
which creates a Font instance for each available font familiy name. The
code looks like this:

     String[] fontFamilyNames =
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
     Font[] fonts = new Font[fontFamilyNames.length];
     int fontCount = 0;
     for (int i = 0; i < fontFamilyNames.length; i++) {
       fonts[i] = new Font(fontFamilyNames[i], Font.PLAIN, 1);
     }

On that particular (WinXP) system, there are two fonts installed: Times
New Roman (file name times.ttf) and Times (file name kycw1_75.ttf). Both
family names ("Times New Roman" and "Times") are returned by the
getAvailableFontFamilyNames() method.

The problem is that the line new Font(fontFamilyNames[i], Font.PLAIN, 1)
creates an instance of the "Times" font for both family names. I tried
using alternative constructors (for example new Font(Map attributes)
with only the FamilyName attribute set), but nothing works. As a result
of this, we simply cannot use Times New Roman on that machine from Java,
which is quite a shame, because it is far better than the Times font
(much more of the Unicode glyphs are covered). If we remove the Times
font from the machine, everything works fine. In non-Java applications
both fonts appear in font choosers (under the names "Times" and "Times
New Roman" as you would expect).

I guess this is a bug in the Java font package, but I have a tiny bit a
hope left that there is a workaround available. Can someone help? The
Times font was installed from a driver CD-ROM for a Kyocera printer.

Comments
WORK AROUND Remove the other fonts from the system.
25-01-2007

EVALUATION This started happening in JDK 6 b03 with the fix for 4795932 : RFE: Java 2D should locate fonts by using the windows registry Prior to that we located fonts just by opening font files directly. Now as we mostly go through GDI, we are subject to its vagaries. It looks as if we are running afoul of some hard-coded "alias" mappings that windows does that seems wrong to me. Wrong because they should not apply when real fonts of those aliased names are installed. What happens is as follows : In order to be able to report all fonts we call into GDI and ask it for 1) All font families 2) All fonts in each of those families. We use the windows GDI call : EnumFontFamiliesExW(..) So in the first case it includes "Times" in its list of families and when we then ask for the fonts in that family it reports 5 fonts (!) Times Roman Times New Roman Times New Roman Bold Times New Roman Bold Italic Times New Roman Italic So it seems a GDI app could also end up picking the wrong font if its unlucky. Looking in the registry I see under HKCU\Software\Microsoft\Shared Tools\Font Mapping several aliases like : Times : Times Roman Times Roman : Times New Roman Times New Roman : Times Its somewhat confusing what GDI actually makes of all that but my guess is that means the two families are considered the same, so it enumerates fonts from both. But I find it difficult to believe this is the intended effect of the aliasing. In the JDK I think that what happens next is that since we see In the family "Times" after seeing the family "Times New Roman" and so GDI's claim that "Times New Roman" is a member of the "Times" family wins. Tnen we pull the "plain" font from that family and that's what ends up being returned. Also there are other aliases in GDI for Helvetica->Arial etc and we could also run afoul of those. May be the submitter has this problem too and just hasn't noticed yet. Since we certainly don't want this behaviour, it seems a (cheap) method needs to be found to verify that we aren't being subjected to such aliasing. The proposed solution is that before accepting the font as a member of the family we make a new call to EnumFontFamiliesExW using just the 'full name' of the font as input to GDI. The hypothesis here is that by disconnecting it from the family, the call back will have filled in the true family name of the font in the LOGFONT part of the structure. If its different than the family under which it was initially enumerated then we know its an alias and can ignore it. Testing using the font identified by the submitter shows that this does successfully identify and skip just the aliased font.
25-01-2007