United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6517861 Java2D : Installing font of family "Times" on Windows hides "Times New Roman"
JDK-6517861 : Java2D : Installing font of family "Times" on Windows hides "Times New Roman"

Submit Date:
Updated Date:
Project Name:
Resolved Date:
Affected Versions:
Fixed Versions:

Related Reports

Sub Tasks

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 =
     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.



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.

Remove the other fonts from the system.

Hardware and Software, Engineered to Work Together