2017-03-03 1 views
3

J'utilise la bibliothèque PDFBox d'Apache pour écrire une classe PdfDocumentBuilder. J'utilise currentFont.hasGlyph(character) pour vérifier si un personnage a un glyphe avant d'essayer de l'écrire dans le fichier. Le problème est que lorsque le caractère est un caractère de contrôle Unicode comme '\u001f', hasGlyph() renvoie true, provoquant une exception à être levée par encode() lors de l'écriture (voir le code PdfDocumentBuilder et la trace de la pile ci-dessous pour référence).PDFBox hasGlyph() renvoie true pour les caractères de contrôle Unicode non pris en charge

J'ai fait quelques recherches et il semble que ces caractères de contrôle Unicode ne sont pas supportés pour la police que j'utilise (Courier Prime).

Alors pourquoi hasGlyph() renvoie-t-il la valeur true pour les caractères de contrôle Unicode lorsqu'ils ne sont pas pris en charge? Bien sûr, je peux supprimer les caractères de contrôle de la ligne avec un simple replaceAll avant d'entrer dans la méthode writeTextWithSymbol(), mais si la méthode hasGlyph() ne fonctionne pas comme je le souhaite, j'ai un plus gros problème.

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()); 
    } 
} 

Trace de la pile:

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

Quelle version utilisez-vous? Le dernier en date est 2.0.4, alors s'il vous plaît réessayez avec cela juste pour être sûr. Est-ce que cet effet se produit également avec des polices ordinaires comme Arial? Comment avez-vous créé l'objet police? –

+0

@TilmanHausherr J'utilise 2.0.4. J'ai testé avec quelques autres polices standard et le problème persiste. J'ai ajouté le code qui crée l'objet currentFont. –

+0

J'ai créé un test simple et oui ça arrive aussi avec Arial. Je suppose que le bogue est dans hasGlyph, ou que le paramètre dans hasGlyph n'est pas ce que l'on pourrait penser. Pour vous, le mieux serait d'appeler font.encode() avec chaque caractère et d'attraper l'exception IllegalArgumentException, pour savoir si le caractère est supporté ou non. De cette façon, vous le savez à coup sûr. Je vais créer un problème dans JIRA plus tard. –

Répondre

3

Comme expliqué dans les commentaires ci-dessus, hasGlyph() ne vise pas à accepter les caractères unicode comme paramètre. Donc, si vous devez vérifier si un caractère peut être encodé avant de l'écrire, vous pouvez faire quelque chose comme ceci:

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

Vous observez 'IOException' dans' isCharacterEncodeable() '. Ne devriez-vous pas attraper 'IllegalArgumentException'? –

+0

@TilmanHausherr bonne prise –