Unembed a font
unembedfont
JAVA
/**
* Example written by Bruno Lowagie in answer to a question by a customer.
*/
package sandbox.fonts;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import sandbox.WrapToTest;
@WrapToTest
public class UnembedFont {
public static final String SRC = "results/fonts/withSerifFont.pdf";
public static final String DEST = "results/fonts/withoutSerifFont.pdf";
public static void main(String[] args) throws DocumentException, IOException {
UnembedFont app = new UnembedFont();
app.manipulatePdf(SRC, DEST);
}
/**
* Creates a PDF with an embedded font.
*/
public void createPdf(String file) throws DocumentException, IOException {
// step 1
Document document = new Document();
// step 2
OutputStream os = new FileOutputStream(file);
PdfWriter.getInstance(document, os);
// step 3
document.open();
// step 4
BaseFont bf = BaseFont.createFont("resources/fonts/PT_Serif-Web-Regular.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
Font f = new Font(bf, 12);
document.add(new Paragraph("This is a test with Times New Roman.", f));
// step 5
document.close();
}
/**
* Removes the embedded font
*/
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
createPdf(src);
// we create a reader instance
PdfReader reader = new PdfReader(src);
// we loop over all objects
PdfObject obj;
for (int i = 1; i < reader.getXrefSize(); i++) {
obj = reader.getPdfObject(i);
// we skip all objects that aren't a dictionary
if (obj == null || !obj.isDictionary())
continue;
// we process all dictionaries
unembedTTF((PdfDictionary)obj);
}
// removing unused objects will remove unused font file streams
reader.removeUnusedObjects();
// we persist the altered document
OutputStream os = new FileOutputStream(dest);
PdfStamper stamper = new PdfStamper(reader, os);
stamper.close();
}
/**
* Processes a dictionary.
* In case of font dictionaries, the dictionary is processed.
*/
public void unembedTTF(PdfDictionary dict) {
// we ignore all dictionaries that aren't font dictionaries
if (!dict.isFont())
return;
// we only remove TTF fonts
if (dict.getAsDict(PdfName.FONTFILE2) != null) {
return;
}
// check if a subset was used (in which case we remove the prefix)
PdfName baseFont = dict.getAsName(PdfName.BASEFONT);
if (baseFont.getBytes()[7] == '+') {
baseFont = new PdfName(baseFont.toString().substring(8));
dict.put(PdfName.BASEFONT, baseFont);
}
// we check if there's a font descriptor
PdfDictionary fontDescriptor = dict.getAsDict(PdfName.FONTDESCRIPTOR);
if (fontDescriptor == null)
return;
// is there is, we replace the fontname and remove the font file
fontDescriptor.put(PdfName.FONTNAME, baseFont);
fontDescriptor.remove(PdfName.FONTFILE2);
}
}