2014-01-21 2 views
3

내 시스템의 TTF 파일에서 java.awt.Font 인스턴스를 만들려고하는데 일부 글꼴 만 오류없이로드 할 수 있습니다. 아래 코드는 온라인에서 찾은 일부 테스트 코드입니다. 내 시스템에서 실행할 때 성공적으로 (예 : Arial.ttf) 285 개의 글꼴을로드 할 수 있지만 83 개의 글꼴 (예 : AmericanTypewriter.ttf)에서는 실패합니다.Java에서 TTF 파일의 일부 트루 타입 글꼴로드 중 FontFormatException : 글꼴 이름을 찾을 수 없음

모든 오류의 원인은없는 FontFormatException: Font name not found입니다.

java.awt.Font 및 형식 호환성에 대해 알려진 문제점이 있습니까? 나는 많은 인터넷 검색 후에 아무것도 찾을 수 없습니다.

public static void main(String[] args) { 
     String rootPath = "/Library/Fonts"; 

     File root = new File(rootPath); 
     if (root.canRead()) { 
      String[] fontFiles = root.list(); 

      Font font = null; 
      for (String fontFile : fontFiles) { 
       try { 
        System.out.println(fontFile); 
        font = Font.createFont(Font.TRUETYPE_FONT, new File(root + "/" + fontFile)); 
        System.out.println(font); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

내 환경은 Java 7, OS X Mavericks (10.9.1)입니다.

java version "1.7.0_40" 
Java(TM) SE Runtime Environment (build 1.7.0_40-b43) 
Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode) 

여기의 도움을 주시면 감사하겠습니다.

답변

4

일부 파고 들자면,이 문제는 java.awt 구현의 버그 (기능!) 때문이라는 것이 밝혀졌습니다. 즉, 글꼴 파일의 이름 테이블에 성 및 전체 이름 레코드가 포함되어 있지 않으면 실제 TrueType 글꼴로드가 실패합니다.

문제를 확인하기 위해 GrepCode를 사용하여 OpenJDK의 AWT 구현에서 관련 예외를 역 추적했습니다. 이름 테이블 문제를 발견하고 나면 ttx이라는 no-frills 트루 타입 메타 데이터 편집기를 사용하여 Java가 찾는 이름 항목을 추가했습니다. 예 :

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

이제 ttx에서 생성 된 새 TTF 파일을 Java에서 열 수 있습니다. 예!

+0

비슷한 문제가 있었지만 글꼴이 Java6 (Eclipse)에서는 제대로로드되었지만 Java7 (터미널)에서는 제대로로드되지 않았습니다. Java6과 7 사이의 구현에는 차이가있는 것 같습니다 ... – britzl

3

이것은 Oracle JDK/OpenJDK 기능 (bug)입니다.

이 문제는 sun.font.TrueTypeFont과 Mac 트루 타입 글꼴 이름에 대한 지원이 부족하여 발생합니다.

TrueTypeFont.java에는 Microsoft 플랫폼 ID 이름 (platformID == 3) 만 읽고 Mac 플랫폼 ID는 (platformID == 1)이 아닌 TrueType 글꼴의 이름 테이블을 읽는 지 확인하는 내용이 포함되어 있습니다. 대부분의 경우 OSX에 포함 된 TrueType 글꼴의 이름은 platformID이고 이름이 initNames() 인 경우 familyName 또는 fullName이 아니며 initNames() 이후의 코드가 실행되면 null인지 확인합니다. 그들은 당연히) Font name not found 예외를 throw합니다.

Apple JDK (1.6 및 1.5?)에서 Apple은 FontHandler로 TrueTypeFont를 사용하지 않았습니다. 그들은 sun.font.AppleNativeFont이라고하는 자체 구현을 가졌습니다. Mac과 Microsoft 플랫폼 ID를 모두 지원하는 sun.font.AppleNativeFont 핸들러를 항상 사용하므로 Apple JDK에서 sun.font.TrueTypeFont을 사용할 수도 없습니다.

Apple이 코드를 Oracle에 기부 했음에도 불구하고 OpenJDK 또는 Oracle JDK에는 sun.font.AppleNativeFont이 존재하지 않는 것처럼 보입니다.

연속성의 관점에서 볼 때 OpenJDK/Oracle JDK에는 sun.font.AppleNativeFont을 포함하면 편리 할 것입니다. TrueTypeFont.java이 개선되어 Mac 트루 타입 글꼴을 지원하는 것이 더 좋을 것입니다.

업데이트 : 해결 방법.

아래 주석의 패치 중 하나가 OpenJDK 저장소에 제출되었습니다. 올바른 버전으로 저장소를 복제하면 패치 된 파일을 얻을 수 있습니다.

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

복사 jdk/src/shared/classes/sun/font에서이 다음과 같은 파일 : 현재 JDK의 트렁크에 같은 디렉토리에

TrueTypeFont.java 
LCIDMap.java 
AppleLangID.java 

는, 컴파일 (나는 jdk8-B132을 사용) 당신은 맥 글꼴이됩니다 지원하다. 또한 맥 폰트 패치 이후에 만들어진이 패치를 적용 할 수 있습니다

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

짜잔를!

+0

2011 년에 몇 명이 포함되지 않았던 패치 백이 게시되었습니다. http://mail.openjdk.java.net/pipermail/2d-dev/2011-March/001922.html http://mail.openjdk.java.net/pipermail/jdk6-dev/2011-January /002230.html 다음은 2014 년에 다시 수정하도록 요청한 사용자입니다. http://mail.openjdk.java.net/pipermail/awt-dev/2014-January/006860.html –