简体   繁体   中英

Replace fonts in a PDF using iText (Java)

I'd like to convert all the fonts, embedded or otherwise, of a PDF to another font using iText. I understand that line-height, kerning and a bunch of other things would be bungled up, but this I truly don't mind how ugly the output is.

I have seen how to embed fonts into existing pdfs here , but I don't know how to set ALL EXISTING text in the document to that font.

I understand that this isn't as straightforward as I make it out to be. Perhaps it would be easier just to take all the raw text from the document, and create a new document using the new font (again, layout/readability is a non-issue to me)

The example EmbedFontPostFacto.java from chapter 16 of iText in Action — 2nd Edition shows how to embed an originally not embedded font. The central method is this:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
    // the font file
    RandomAccessFile raf = new RandomAccessFile(FONT, "r");
    byte fontfile[] = new byte[(int)raf.length()];
    raf.readFully(fontfile);
    raf.close();
    // create a new stream for the font file
    PdfStream stream = new PdfStream(fontfile);
    stream.flateCompress();
    stream.put(PdfName.LENGTH1, new PdfNumber(fontfile.length));
    // create a reader object
    PdfReader reader = new PdfReader(RESULT1);
    int n = reader.getXrefSize();
    PdfObject object;
    PdfDictionary font;
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT2));
    PdfName fontname = new PdfName(FONTNAME);
    for (int i = 0; i < n; i++) {
        object = reader.getPdfObject(i);
        if (object == null || !object.isDictionary())
            continue;
        font = (PdfDictionary)object;
        if (PdfName.FONTDESCRIPTOR.equals(font.get(PdfName.TYPE))
            && fontname.equals(font.get(PdfName.FONTNAME))) {
            PdfIndirectObject objref = stamper.getWriter().addToBody(stream);
            font.put(PdfName.FONTFILE2, objref.getIndirectReference());
        }
    }
    stamper.close();
    reader.close();
}

This (without the fontname.equals(font.get(PdfName.FONTNAME)) test) may be a starting point for the simple cases of your task.

You'll have to do quite a lot of tests concerning encoding and add some individual translations for a more generic solution. You may want to study section 9 Text of the PDF specification ISO 32000-1 for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM