2017-03-03 48 views
3

私はApacheのPDFBoxライブラリを使用してPdfDocumentBuilderクラスを作成しています。私はcurrentFont.hasGlyph(character)を使って、ファイルに書き込む前に文字にグリフがあるかどうかを確認しています。問題は、文字が'\u001f'のようなUnicode制御文字の場合、hasGlyph()がtrueを返し、書き込み時に例外がスローされる(参照のためにPdfDocumentBuilderコードとスタックトレースを参照)。PDFBox hasGlyph()は、サポートされていないUnicode制御文字の場合は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()がパラメータとしてUnicode文字を受け入れるためのものではありません。

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良いキャッチ –

関連する問題