2015-08-24 2 views
-1

Я хотел бы проверить PDF, если все шрифты встроены или нет. Я следил за кодированием, как упоминалось в How to check that all used fonts are embedded in PDF with Java iText?, но я до сих пор не могу получить правильный список используемых шрифтов.Itext: Как получить список не встроенных шрифтов pdf

См. Мой пример pdf: https://www.dropbox.com/s/anvm49vh87d8yqs/000024944.pdf?dl=0, кодировка не содержит никаких шрифтов, кроме свойств документа в акробате, упоминание Helvetica + Verdana (встроенное подмножество) + Verdana-Bold (встроенное подмножество). Для других PDF-файлов я получаю подмножество Verdana Embedded, только для такого типа PDF-файлов я не могу получить список шрифтов.

Поскольку нам приходится иметь дело с огромным количеством pdf-файлов из внутренних источников, мы должны иметь возможность внедрять шрифты, чтобы их печатать. Поскольку встраивание всех шрифтов практически невозможно, мы просто хотим вставлять общие шрифты, для экзотических шрифтов мы будем игнорировать printrequest.

Может ли кто-нибудь помочь мне решить эту проблему? Спасибо

+0

правильный ссылку на PDF по протоколу HTTPS://www.dropbox.com/s/anvm49vh87d8yqs/000024944.pdf?dl=0 –

+0

Я проверил ваш файл с помощью callas pdfToolbox (осторожно, я связан с этим инструментом), и в нем говорится, что Verdana и Verdana bold встроены (и подмножество), но Helvetica НЕ встроен; что совпадает с отчетами Adobe Acrobat. –

+0

И несколько комментарий «рядом с темой» - вы понимаете, что вложение даже стандартных шрифтов - опасная вещь, чтобы делать правильно? Нет никакой гарантии, что ваша копия шрифта будет такой же, как у оригинального создателя файла PDF, и вы можете столкнуться с разной шириной или проблемами с кодировкой при встраивании шрифтов. –

ответ

0

Мне удалось получить некоторые результаты, объединив кодировку от How to check that all used fonts are embedded in PDF with Java iText? и http://itextpdf.com/examples/iia.php?id=288. Первоначально он не работал как font.getAsName (PdfName.BASEFONT) .toString(); не работает в моем случае, но я сделал небольшое изменение и получил некоторые результаты.

Ниже мое кодирование:

/** 
* Creates a Set containing information about the fonts in the src PDF file. 
* @param src the path to a PDF file 
* @throws IOException 
*/ 
public void listFonts(PdfReader reader, Set<String> set) throws IOException { 

    int n = reader.getXrefSize(); 
    PdfObject object; 
    PdfDictionary font; 

    for (int i = 0; i < n; i++) { 
     object = reader.getPdfObject(i); 
     if (object == null || !object.isDictionary()) { 
      continue; 
     } 

     font = (PdfDictionary)object; 

     if (font.get(PdfName.FONTNAME) != null) { 

      System.out.println("fontname " + font.get(PdfName.FONTNAME)); 
      processFont(font,set); 

     } 
    } 
} 

/** 
* Finds out if the font is an embedded subset font 
* @param font name 
* @return true if the name denotes an embedded subset font 
*/ 
private boolean isEmbeddedSubset(String name) { 
    //name = String.format("%s subset (%s)", name.substring(8), name.substring(1, 7)); 
    return name != null && name.length() > 8 && name.charAt(7) == '+'; 
} 

private void processFont(PdfDictionary font, Set<String> set) { 

    String name = font.get(PdfName.FONTNAME).toString(); 

    if(isEmbeddedSubset(name)) { 
     return; 
    } 

    PdfDictionary desc = font.getAsDict(PdfName.FONTDESCRIPTOR); 

    //nofontdescriptor 
    if (desc == null) { 
     System.out.println("desc null "); 
     PdfArray descendant = font.getAsArray(PdfName.DESCENDANTFONTS); 

     if (descendant == null) { 
      System.out.println("descendant null "); 
      set.add(name.substring(1));    
     } 
     else { 
      System.out.println("descendant not null "); 
      for (int i = 0; i < descendant.size(); i++) { 
       PdfDictionary dic = descendant.getAsDict(i); 
       processFont(dic, set);      
      }    
     }    
    } 
    /** 
     * (Type 1) embedded 
    */ 
    else if (desc.get(PdfName.FONTFILE) != null) { 
     System.out.println("(TrueType) embedded "); 
    } 

    /** 
     * (TrueType) embedded 
    */ 
    else if (desc.get(PdfName.FONTFILE2) != null) { 
     System.out.println("(FONTFILE2) embedded "); 
    } 

    /** 
    * " (" + font.getAsName(PdfName.SUBTYPE).toString().substring(1) + ") embedded" 
    */  
    else if (desc.get(PdfName.FONTFILE3) != null) { 
     System.out.println("(FONTFILE3) "); 
    } 

    else { 
     set.add(name.substring(1));   
    } 
} 

}

Таким образом, вместо того, чтобы использовать имя String = font.getAsName (PdfName.BASEFONT) .ToString(); Я изменил его на String name = font.get (PdfName.FONTNAME) .toString();

Это определенно дает лучшие результаты, поскольку это дает мне разные шрифты. Однако я не получаю результаты для fontdescriptor и descendantfonts. Или они просто недоступны в моих pdf-файлах или потому, что я изменил кодировку, я никогда не окажусь там. Могу ли я предположить, обнаружено ли подмножество, что шрифт встроен, если нет подмножества availbale в имени шрифта, я могу предположить, что шрифт не внедрен?

+0

Это не ответ, не так ли? Вы можете использовать кнопку ** Edit **, чтобы изменить начальную запись. Я не уверен, что ваши * новые * вопросы внизу логически следуют из того, что вы спрашиваете выше, или лучше должны быть размещены как совершенно новые вопросы. – usr2564301

+0

Это был отчасти ответ, так как я получил некоторые лучшие результаты. Однако все еще были некоторые сомнения в основном потому, что я не полностью понимаю использование подмножеств и шрифтов. –

1

Понял работать после того, как все, ссылаясь на BASEFONT вместо FONT:

/** 
* Creates a Set containing information about the fonts in the src PDF file. 
* @param src the path to a PDF file 
* @throws IOException 
*/ 
public void listFonts(PdfReader reader, Set<String> set) throws IOException { 

    try { 

     int n = reader.getXrefSize(); 
     PdfObject object; 
     PdfDictionary font; 

     for (int i = 0; i < n; i++) { 
      object = reader.getPdfObject(i); 
      if (object == null || !object.isDictionary()) { 
       continue; 
      } 

      font = (PdfDictionary)object; 

      if (font.get(PdfName.BASEFONT) != null) { 
       System.out.println("fontname " + font.getAsName(PdfName.BASEFONT).toString()); 
       processFont(font,set); 

      } 

     } 


    } catch (Exception e) { 
     System.out.println("error " + e.getMessage()); 
    } 


} 

/** 
* Finds out if the font is an embedded subset font 
* @param font name 
* @return true if the name denotes an embedded subset font 
*/ 
private boolean isEmbeddedSubset(String name) { 
    //name = String.format("%s subset (%s)", name.substring(8), name.substring(1, 7)); 
    return name != null && name.length() > 8 && name.charAt(7) == '+'; 
} 

private void processFont(PdfDictionary font, Set<String> set) { 

     **String name = font.getAsName(PdfName.BASEFONT).toString();** 

     if(isEmbeddedSubset(name)) { 
      return; 
     } 

     PdfDictionary desc = font.getAsDict(PdfName.FONTDESCRIPTOR); 

     //nofontdescriptor 
     if (desc == null) { 
      System.out.println("desc null "); 
      PdfArray descendant = font.getAsArray(PdfName.DESCENDANTFONTS); 

      if (descendant == null) { 
       System.out.println("descendant null "); 
       set.add(name.substring(1));    
      } 
      else { 
       System.out.println("descendant not null "); 
       for (int i = 0; i < descendant.size(); i++) { 
        PdfDictionary dic = descendant.getAsDict(i); 
        processFont(dic, set);      
        }    
      }    
     } 
     /** 
     * (Type 1) embedded 
     */ 
     else if (desc.get(PdfName.FONTFILE) != null) { 
      System.out.println("(TrueType) embedded "); 
     } 

     /** 
     * (TrueType) embedded 
     */ 
     else if (desc.get(PdfName.FONTFILE2) != null) { 
      System.out.println("(FONTFILE2) embedded "); 
     } 

     /** 
     * " (" + font.getAsName(PdfName.SUBTYPE).toString().substring(1) + ") embedded" 
     */  
     else if (desc.get(PdfName.FONTFILE3) != null) { 
      System.out.println("(FONTFILE3) "); 
     } 

     else { 
      set.add(name.substring(1));   
     } 


} 

Это дает мне те же результаты, что и список шрифтов читателя акробата> свойства

Смежные вопросы