2017-03-03 5 views
3

Apache의 PDFBox 라이브러리를 사용하여 PdfDocumentBuilder 클래스를 작성하고 있습니다. 편지에 글자를 쓰려고 시도하기 전에 문자에 글리프가 있는지 확인하려면 currentFont.hasGlyph(character)을 사용하고 있습니다. 문제는 문자가 '\u001f'과 같은 유니 코드 제어 문자 인 경우 hasGlyph()이 true를 반환하므로 쓰기시 encode()에 의해 예외가 발생하게됩니다 (참조 용 PdfDocumentBuilder 코드 및 스택 추적 참조).PDFBox hasGlyph()는 지원되지 않는 유니 코드 제어 문자에 대해 true를 반환합니다.

나는 약간의 연구를했으며,이 유니 코드 제어 문자가 내가 사용하고있는 글꼴 (Courier Prime)에 대해 지원되지 않는 것으로 보입니다.

그렇다면 유니 코드 제어 문자가 지원되지 않는데 hasGlyph()이 true를 반환하는 이유는 무엇입니까? 물론 writeTextWithSymbol() 메서드를 입력하기 전에 간단한 replaceAll 줄에서 제어 문자를 제거 할 수 있지만 hasGlyph() 메서드가 예상대로 작동하지 않으면 더 큰 문제가 있습니다.

PdfDocumentBuilder :

private final PDType0Font baseFont; 
private PDType0Font currentFont; 

public PdfDocumentBuilder() { 
    baseFont = PDType0Font.load(doc, this.getClass().getResourceAsStream("/CourierPrime.ttf")); 
    currentFont = baseFont; 
} 

private void writeTextWithSymbol (String text) throws IOException { 
    StringBuilder nonSymbolBuffer = new StringBuilder(); 
    for (char character : text.toCharArray()) { 
     if (currentFont.hasGlyph(character)) { 
      nonSymbolBuffer.append(character); 
     } else { 
      //handling writing line with symbols... 
     } 
    } 
    if (nonSymbolBuffer.length() > 0) { 
     content.showText(nonSymbolBuffer.toString()); 
    } 
} 

스택 추적 :

java.lang.IllegalArgumentException: No glyph for U+001F in font CourierPrime 
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.encode(PDCIDFontType2.java:400) 
at org.apache.pdfbox.pdmodel.font.PDType0Font.encode(PDType0Font.java:351) 
at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:316) 
at org.apache.pdfbox.pdmodel.PDPageContentStream.showText(PDPageContentStream.java:414) 
at org.main.export.PdfDocumentBuilder.writeTextWithSymbol(PdfDocumentBuilder.java:193) 
+1

어떤 버전을 사용하고 있습니까? 최신 버전은 2.0.4이므로 다시 시도해보십시오. 이 효과는 Arial과 같은 일반 글꼴에서도 발생합니까? 어떻게 글꼴 개체를 만들었습니까? –

+0

@TilmanHausherr 2.0.4를 사용 중입니다. 나는 몇 가지 다른 표준 글꼴로 테스트했는데 문제는 여전히 지속됩니다. currentFont 객체를 만드는 코드를 추가했습니다. –

+0

나는 간단한 테스트를 만들었고, 그렇습니다. 버그가 hasGlyph에 있거나 hasGlyph의 매개 변수가 생각하는 바가 아니라고 가정합니다. 가장 좋은 방법은 모든 문자로 font.encode()를 호출하고 문자가 지원되는지 여부를 알기 위해 IllegalArgumentException을 잡는 것입니다. 이렇게하면 확실하게 알 수 있습니다. JIRA에서 나중에 문제를 만들 것입니다. –

답변

3

으로 위의 의견에 설명, hasGlyph() 매개 변수로 유니 코드 문자를 허용하는 것은 아닙니다. 문자를 인코딩하기 전에 인코딩 할 수 있는지 확인해야한다면 다음과 같이 할 수 있습니다.

private void writeTextWithSymbol (String text) throws IOException { 
    StringBuilder nonSymbolBuffer = new StringBuilder(); 
    for (char character : text.toCharArray()) { 
     if (isCharacterEncodeable(character)) { 
      nonSymbolBuffer.append(character); 
     } else { 
      //handle writing line with symbols... 
     } 
    } 
    if (nonSymbolBuffer.length() > 0) { 
     content.showText(nonSymbolBuffer.toString()); 
    } 
} 

private boolean isCharacterEncodeable (char character) throws IOException { 
    try { 
     currentFont.encode(Character.toString(character)); 
     return true; 
    } catch (IllegalArgumentException iae) { 
     LOGGER.trace("Character cannot be encoded", iae); 
     return false; 
    } 
} 
+0

당신은'isCharacterEncodeable()'에서'IOException'을 잡아냅니다. 'IllegalArgumentException'을 잡아서는 안됩니까? –

+0

@TilmanHausherr 좋은 캐치 –