Loading some TrueType Font from TTF file in Java causes FontFormatException: Font name not found

后端 未结 2 1564
别跟我提以往
别跟我提以往 2021-01-14 02:33

I am attempting to create a java.awt.Font instance from a TTF file on my system, but only some fonts are able to load without error. The code below is some test code I found

相关标签:
2条回答
  • 2021-01-14 03:12

    This is an Oracle JDK/OpenJDK feature (bug).

    The problem is caused by sun.font.TrueTypeFont and its lack of support for Mac TrueType font names.

    TrueTypeFont.java contains a check for reading the name table of a TrueType font to only read the Microsoft platform ID name (platformID == 3) and not the Mac platform ID (platformID == 1). In many cases, truetype fonts included on OSX only have names with a platformID of 1. Because of this, the initNames() method does not set a value for either familyName or fullName and the code after initNames() runs checks to see if they are null (which they are of course) and throws the Font name not found exception.

    On Apple JDK (1.6 and maybe 1.5?), Apple didn't use TrueTypeFont as the FontHandler. They had their own implementation which is called sun.font.AppleNativeFont. You can't even use sun.font.TrueTypeFont on Apple JDK because it will always use the sun.font.AppleNativeFont handler, which has support for both Mac and Microsoft platform IDs.

    It appears that sun.font.AppleNativeFont doesn't exist in OpenJDK or Oracle JDK, even though Apple "donated" the code to Oracle.

    It would be handy from a continuity point of view to include sun.font.AppleNativeFont in OpenJDK/Oracle JDK. It would be even better if TrueTypeFont.java was improved to include support for Mac TrueType fonts.

    UPDATE: WORKAROUND SOLUTION.

    One of the patches in the comments below was submitted to the OpenJDK repository. If you clone the repository with the right revision, you can get the patched files.

    hg clone -r 8b05f9b91765 http://hg.openjdk.java.net/jdk7/jdk7/jdk

    Copy these following files from jdk/src/shared/classes/sun/font:

    TrueTypeFont.java
    LCIDMap.java
    AppleLangID.java
    

    To the same directory in the trunk of a current JDK (I used jdk8-b132), compile it and you will have Mac font support. You may also want to apply this patch which was made after the Mac font patch:

    http://hg.openjdk.java.net/jdk7/jdk7/jdk/rev/3dabb2f78e73

    Voila!

    0 讨论(0)
  • 2021-01-14 03:15

    OK, so after some digging, it turns out that this problem is due to a bug (feature!) in the java.awt implementation. Namely, loading a physical TrueType font fails if the font file's name table does not include family name and full name records.

    To identify the problem, I used GrepCode to trace backward from the relevant exception in OpenJDK's AWT implementation. Once I had discovered the name table issue, I used ttx, a no-frills TrueType metadata editor to add the name entries Java looks for. Ex:

    <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
      American Typewriter
    </namerecord>
    <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
      American Typewriter
    </namerecord>
    

    The new TTF files generated by ttx could now be opened by Java. Yay!

    0 讨论(0)
提交回复
热议问题