2017-10-11 6 views
0

Comment obtenir la police d'un COSName?En utilisant pdfbox - comment obtenir la police d'un COSName?

La solution que je suis à la recherche d'une certaine façon ressemble à ceci:

COSDictionary dict = new COSDictionary(); 
dict.add(fontname, something); // fontname COSName from below code 
PDFontFactory.createFont(dict); 

Si vous avez besoin de plus de fond, j'ai ajouté toute l'histoire ci-dessous:

J'essaie de remplacer une chaîne dans un fichier PDF. Cela réussit (tant que tout le texte est stocké dans un jeton). Afin de conserver le format, j'aime recentrer le texte. Pour autant que je comprenne, je peux le faire en obtenant la largeur de l'ancienne chaîne et la nouvelle, faire un calcul trivial et définir la nouvelle position.

Je trouve un peu d'inspiration sur stackoverflow pour remplacer https://stackoverflow.com/a/36404377 (oui, il a quelques problèmes, mais fonctionne pour mes simples documents en pdf. Et How to center a text using PDFBox. Malheureusement, cet exemple utilise

une constante police. Donc, en utilisant le code du premier lien que je reçois une manipulation pour l'opérateur « TJ » et un pour «Tj.

PDFStreamParser parser = new PDFStreamParser(page); 
    parser.parse(); 
    java.util.List<Object> tokens = parser.getTokens(); 
    for (int j = 0; j < tokens.size(); j++) 
    { 
    Object next = tokens.get(j); 
    if (next instanceof Operator) 
    { 
     Operator op = (Operator) next; 
     // Tj and TJ are the two operators that display strings in a PDF 
     if (op.getName().equals("Tj")) 
     { 
     // Tj takes one operator and that is the string to display so lets 
     // update that operator 
     COSString previous = (COSString) tokens.get(j - 1); 
     String string = previous.getString(); 
     String replaced = prh.getReplacement(string); 
     if (!string.equals(replaced)) 
     { // if changes are there, replace the content 
      previous.setValue(replaced.getBytes()); 
      float xpos = getPosX(tokens, j); 
      //if (true) // center the text 
      if (6 * xpos > page.getMediaBox().getWidth()) // check if text starts right from 1/xth page width 
      { 
      float fontsize = getFontSize(tokens, j); 
      COSName fontname = getFontName(tokens, j); 
      // TODO 
      PDFont font = ?getFont?(fontname); 
      // TODO 
      float widthnew = getStringWidth(replaced, font, fontsize); 
      setPosX(tokens, j, page.getMediaBox().getWidth()/2F - (widthnew/2F)); 
      } 
      replaceCount++; 
     } 
     } 

Vu le code entre les balises TODO, je vais obtenir les valeurs requises dans la liste symbolique. (oui ce code est terrible, mais pour l'instant il me permet de me concentrer sur le problème principal)

Avoir la chaîne, la taille et la police que je devrais être capable d'appeler la méthode getWidth (..) de l'exemple de code.

Malheureusement, je rencontre des problèmes pour créer une police à partir de la variable COSName.

PDFont ne fournit pas de méthode pour créer une police par son nom. PDFontFactory semble très bien, mais demande un COSDictionary. C'est le point que j'ai abandonné et demander de l'aide de votre part.

Répondre

2

Les noms sont associés à des objets de police dans les ressources de la page.

En supposant que vous utilisez 2.0.x PDFBox et que page est une instance PDPage, vous pouvez résoudre le nom fontname en utilisant:

PDFont font = page.getResources().getFont(fontname); 

Mais l'avertissement des commentaires aux questions que vous faites référence restent: Cette approche ne fonctionne que pour des PDF très simples et pourrait même endommager d'autres.