Unembed a font

This is a code example of iText PDF, discover more.

7th November 2015
admin-marketing

Switch code for this example

UnembedFont.java
  1. /**
  2.  * Example written by Bruno Lowagie in answer to a question by a customer.
  3.  */
  4. package sandbox.fonts;
  5.  
  6. import com.itextpdf.text.Document;
  7. import com.itextpdf.text.DocumentException;
  8. import com.itextpdf.text.Font;
  9. import com.itextpdf.text.Paragraph;
  10. import com.itextpdf.text.pdf.BaseFont;
  11. import com.itextpdf.text.pdf.PdfDictionary;
  12. import com.itextpdf.text.pdf.PdfName;
  13. import com.itextpdf.text.pdf.PdfObject;
  14. import com.itextpdf.text.pdf.PdfReader;
  15. import com.itextpdf.text.pdf.PdfStamper;
  16. import com.itextpdf.text.pdf.PdfWriter;
  17.  
  18. import java.io.FileOutputStream;
  19. import java.io.IOException;
  20. import java.io.OutputStream;
  21.  
  22. import sandbox.WrapToTest;
  23.  
  24. @WrapToTest
  25. public class UnembedFont {
  26.  
  27.     public static final String SRC = "results/fonts/withSerifFont.pdf";
  28.     public static final String DEST = "results/fonts/withoutSerifFont.pdf";
  29.  
  30.     public static void main(String[] args) throws DocumentException, IOException {
  31.         UnembedFont app = new UnembedFont();
  32.         app.manipulatePdf(SRC, DEST);
  33.     }
  34.    
  35.     /**
  36.      * Creates a PDF with an embedded font.
  37.      */
  38.     public void createPdf(String file) throws DocumentException, IOException {
  39.         // step 1
  40.         Document document = new Document();
  41.         // step 2
  42.         OutputStream os = new FileOutputStream(file);
  43.         PdfWriter.getInstance(document, os);
  44.         // step 3
  45.         document.open();
  46.         // step 4
  47.         BaseFont bf = BaseFont.createFont("resources/fonts/PT_Serif-Web-Regular.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
  48.         Font f = new Font(bf, 12);
  49.         document.add(new Paragraph("This is a test with Times New Roman.", f));
  50.         // step 5
  51.         document.close();
  52.     }
  53.    
  54.     /**
  55.      * Removes the embedded font
  56.      */
  57.     public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
  58.         createPdf(src);
  59.         // we create a reader instance
  60.         PdfReader reader = new PdfReader(src);
  61.         // we loop over all objects
  62.         PdfObject obj;
  63.         for (int i = 1; i < reader.getXrefSize(); i++) {
  64.             obj = reader.getPdfObject(i);
  65.             // we skip all objects that aren't a dictionary
  66.             if (obj == null || !obj.isDictionary())
  67.                 continue;
  68.             // we process all dictionaries
  69.             unembedTTF((PdfDictionary)obj);
  70.         }
  71.         // removing unused objects will remove unused font file streams
  72.         reader.removeUnusedObjects();
  73.         // we persist the altered document
  74.         OutputStream os = new FileOutputStream(dest);
  75.         PdfStamper stamper = new PdfStamper(reader, os);
  76.         stamper.close();
  77.     }
  78.    
  79.     /**
  80.      * Processes a dictionary.
  81.      * In case of font dictionaries, the dictionary is processed.
  82.      */
  83.     public void unembedTTF(PdfDictionary dict) {
  84.         // we ignore all dictionaries that aren't font dictionaries
  85.         if (!dict.isFont())
  86.             return;
  87.         // we only remove TTF fonts
  88.         if (dict.getAsDict(PdfName.FONTFILE2) != null) {
  89.             return;
  90.         }
  91.         // check if a subset was used (in which case we remove the prefix)
  92.         PdfName baseFont = dict.getAsName(PdfName.BASEFONT);
  93.         if (baseFont.getBytes()[7] == '+') {
  94.             baseFont = new PdfName(baseFont.toString().substring(8));
  95.             dict.put(PdfName.BASEFONT, baseFont);
  96.         }
  97.         // we check if there's a font descriptor
  98.         PdfDictionary fontDescriptor = dict.getAsDict(PdfName.FONTDESCRIPTOR);
  99.         if (fontDescriptor == null)
  100.             return;
  101.         // is there is, we replace the fontname and remove the font file
  102.         fontDescriptor.put(PdfName.FONTNAME, baseFont);
  103.         fontDescriptor.remove(PdfName.FONTFILE2);
  104.     }
  105. }
Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now