How to use iText to add a watermark using an embedded font

I have several pdf / a documents with some built-in fonts, now I have to send these documents using iText to add a watermark.

I know that you can embed a font with iText:

BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);

but I would like to use a font that is already embedded in the document to add a text watermark (something like "SAMPLE COPY").

How can i do this?

+3
source share
3 answers

You want to DocumentFont. You cannot create them directly, the constructor is a private package, but it BaseFont.createFont(PRIndirectReference)will do the trick.

, PRIndirectReference , . "PR" PdfReader. :

1) PdfReader, , PRStream, , /Type /Font, .

public PRIndirectReference findNamedFont( PdfReader myReader, String desiredFontName) {
  int objNum = 0;
  PdfObject curObj;
  do {
    //The "Release" version doesn't keep a reference 
    //to the object so it can be GC'd later.  Quite Handy 
    //when dealing with Really Big PDFs.
    curObj = myReader.getPdfObjectRelease( objNum++ );
    if (curObj instanceof PRStream) {
      PRStream stream = (PRStream)curObj;
      PdfName type = stream.getAsName(PdfName.TYPE);
      if (PdfName.FONT.equals(type)) {
        PdfString fontName = stream.getAsString(PdfName.BASEFONT);
        if (desiredFontName.equals(fontName.toString())) {
          return curObj.getIndRef();
        }
      }
    }
  } while (curObj != null);
return null;
}  

2) /Font <<>> dicts, . , XObject Form , :

public PRIndirectReference findFontInPage(PdfReader reader, String desiredName, int i) {

  PdfDictionary page = reader.getPageN(i); 
  return findFontInResources(page.getAsDict(PdfName.RESOURCES), desiredName);
}   

public PRIndirectReference findFontInResources(PdfDictionary resources, String desiredName) {
  if (resources != null) {
    PdfDictionary fonts = resources.getAsDict(PdfName.FONTS);
    if (fonts != null) {
      for (PdfName curFontName : fonts.keySet()) {
        PRStream curFont (PRStream)= fonts.getAsStream(curFontName);
        if (desiredName.equals(curFont.getAsString(PdfName.BASEFONT).toString()) {
          return (PRIndirectReference) curFont.getIndirectReference();
        }
      }
    }
    PdfDictionary xobjs = resources.getAsDict(PdfName.XOBJECTS);
    if (xobjs != null) {
      for (PdfName curXObjName : xobjs.keySet()) {
        PRStream curXObj = (PRStream)xobjs.getAsStream(curXObjName);
        if (curXObj != null && PdfName.FORM.equals(curXObj.getAsName(PdfName.SUBTYPE)) {
          PdfDictionary resources = curXObj.getAsDict(PdfName.RESOURCES);
          PRIndirectReference ref = findFontInResources(resources, desiredName);
          if (ref != null) {
            return ref;
          }
        }
      }
    }
  }
  return null;
}

PRIndirectReference, . BaseFont.createFont(myPRRef), DocumentFont. PDF, , .

, "6-random-letters-plus-sign", . . , , , , "arry ole". , : " " , , Moons Ago.

PS: , . .

" ", , , . .;)

+2

: " " "".

PdfGraphics2D " " overContent, AWT . , PDF .

PdfContentByte overcontent = stamper.getOverContent(1);
Graphics2D g2d = overcontent.createGraphicsShapes(pageWid, pageHei);

drawStuffToTheGraphic(g2d);

g2d.dispose();

"", . , .. , .

+1

Using a simple jPod (BSD, SourceForge), you can use the Watermark example. WITH

PDFontTools.getFonts(doc)

you can list the fonts and then use one of them in the "createForm" method ...

0
source

Source: https://habr.com/ru/post/1789726/


All Articles