All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.lowagie.text.pdf.PdfCopy Maven / Gradle / Ivy

There is a newer version: 1.3.27-jsign3
Show newest version
/*
 * $Id: PdfCopy.java 3912 2009-04-26 08:38:15Z blowagie $
 *
 * Copyright (C) 2002 Mark Thompson
 *
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the License.
 *
 * The Original Code is 'iText, a free JAVA-PDF library'.
 *
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
 * All Rights Reserved.
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
 *
 * Contributor(s): all the names of the contributors are added in the source code
 * where applicable.
 *
 * Alternatively, the contents of this file may be used under the terms of the
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
 * provisions of LGPL are applicable instead of those above.  If you wish to
 * allow use of your version of this file only under the terms of the LGPL
 * License and not to allow others to use your version of this file under
 * the MPL, indicate your decision by deleting the provisions above and
 * replace them with the notice and other provisions required by the LGPL.
 * If you do not delete the provisions above, a recipient may use your version
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the MPL as stated above or under the terms of the GNU
 * Library General Public License as published by the Free Software Foundation;
 * either version 2 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
 * details.
 *
 * If you didn't download this code from the following link, you should check if
 * you aren't using an obsolete version:
 * https://github.com/LibrePDF/OpenPDF
 */
package com.lowagie.text.pdf;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.ExceptionConverter;
import com.lowagie.text.Rectangle;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Make copies of PDF documents. Documents can be edited after reading and before writing them out.
 *
 * @author Mark Thompson
 */

public class PdfCopy extends PdfWriter {

  /**
   * This class holds information about indirect references, since they are renumbered by iText.
   */
  static class IndirectReferences {

    PdfIndirectReference theRef;
    boolean hasCopied;

    IndirectReferences(PdfIndirectReference ref) {
      theRef = ref;
      hasCopied = false;
    }

    void setCopied() {
      hasCopied = true;
    }

    boolean getCopied() {
      return hasCopied;
    }

    PdfIndirectReference getRef() {
      return theRef;
    }
  }

  protected HashMap indirects;
  protected HashMap> indirectMap;
  protected PdfReader reader;
  protected PdfIndirectReference acroForm;
  protected int[] namePtr = {0};
  /**
   * Holds value of property rotateContents.
   */
  private boolean rotateContents = true;
  protected PdfArray fieldArray;
  protected HashMap fieldTemplates;

  /**
   * A key to allow us to hash indirect references
   */
  protected static class RefKey {

    int num;
    int gen;

    RefKey(int num, int gen) {
      this.num = num;
      this.gen = gen;
    }

    RefKey(PdfIndirectReference ref) {
      num = ref.getNumber();
      gen = ref.getGeneration();
    }

    RefKey(PRIndirectReference ref) {
      num = ref.getNumber();
      gen = ref.getGeneration();
    }

    public int hashCode() {
      return (gen << 16) + num;
    }

    public boolean equals(Object o) {
      if (!(o instanceof RefKey)) {
        return false;
      }
      RefKey other = (RefKey) o;
      return this.gen == other.gen && this.num == other.num;
    }

    public String toString() {
      return Integer.toString(num) + ' ' + gen;
    }
  }

  /**
   * Constructor
   *
   * @param os outputstream
   * @param document document
   */
  public PdfCopy(Document document, OutputStream os) throws DocumentException {
    super(new PdfDocument(), os);
    this.document.setDocumentLanguage(document.getDocumentLanguage());
    document.addDocListener(pdf);
    pdf.addWriter(this);
    indirectMap = new HashMap<>();
  }

  /**
   * Getter for property rotateContents.
   *
   * @return Value of property rotateContents.
   */
  public boolean isRotateContents() {
    return this.rotateContents;
  }

  /**
   * Setter for property rotateContents.
   *
   * @param rotateContents New value of property rotateContents.
   */
  public void setRotateContents(boolean rotateContents) {
    this.rotateContents = rotateContents;
  }

  /**
   * Grabs a page from the input document
   *
   * @param reader the reader of the document
   * @param pageNumber which page to get
   * @return the page
   */
  public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) {
    if (currentPdfReaderInstance != null) {
      if (currentPdfReaderInstance.getReader() != reader) {
        try {
          currentPdfReaderInstance.getReader().close();
          currentPdfReaderInstance.getReaderFile().close();
        } catch (IOException ioe) {
          // empty on purpose
        }
        currentPdfReaderInstance = reader.getPdfReaderInstance(this);
      }
    } else {
      currentPdfReaderInstance = reader.getPdfReaderInstance(this);
    }
    return currentPdfReaderInstance.getImportedPage(pageNumber);
  }


  /**
   * Translate a PRIndirectReference to a PdfIndirectReference In addition, translates the object numbers, and copies the referenced object
   * to the output file. NB: PRIndirectReferences (and PRIndirectObjects) really need to know what file they came from, because each file
   * has its own namespace. The translation we do from their namespace to ours is *at best* heuristic, and guaranteed to fail under some
   * circumstances.
   * @param in the PRIndirectReference to translate
   * @return the translated PRIndirectReference
   * @throws IOException on error
   * @throws BadPdfFormatException on error with the Pdf format
   */
  protected PdfIndirectReference copyIndirect(PRIndirectReference in) throws IOException, BadPdfFormatException {
    PdfIndirectReference theRef;
    RefKey key = new RefKey(in);
    IndirectReferences iRef = indirects.get(key);
    if (iRef != null) {
      theRef = iRef.getRef();
      if (iRef.getCopied()) {
        return theRef;
      }
    } else {
      theRef = body.getPdfIndirectReference();
      iRef = new IndirectReferences(theRef);
      indirects.put(key, iRef);
    }
    PdfObject obj = PdfReader.getPdfObjectRelease(in);
    if (obj != null && obj.isDictionary()) {
      PdfObject type = PdfReader.getPdfObjectRelease(((PdfDictionary) obj).get(PdfName.TYPE));
      if (PdfName.PAGE.equals(type)) {
        return theRef;
      }
    }
    iRef.setCopied();
    obj = copyObject(obj);
    addToBody(obj, theRef);
    return theRef;
  }

  /**
   * Translate a PRDictionary to a PdfDictionary. Also translate all of the objects contained in it.
   * @param in the PRDictionary to translate
   * @return  the translated PRDictionary
   * @throws IOException on error
   * @throws BadPdfFormatException on error with the Pdf format
   */
  protected PdfDictionary copyDictionary(PdfDictionary in)
      throws IOException, BadPdfFormatException {
    PdfDictionary out = new PdfDictionary();
    PdfObject type = PdfReader.getPdfObjectRelease(in.get(PdfName.TYPE));

      for (PdfName key : in.getKeys()) {
          PdfObject value = in.get(key);
          //        System.out.println("Copy " + key);
          if (PdfName.PAGE.equals(type)) {
              if (!key.equals(PdfName.B) && !key.equals(PdfName.PARENT)) {
                  out.put(key, copyObject(value));
              }
          } else {
              out.put(key, copyObject(value));
          }
      }
    return out;
  }

  /**
   * Translate a PRStream to a PdfStream. The data part copies itself.
   * @param in the PRStream to translate
   * @return the translated PRStream
   * @throws IOException on error
   * @throws BadPdfFormatException on error with the Pdf format
   */
  protected PdfStream copyStream(PRStream in) throws IOException, BadPdfFormatException {
    PRStream out = new PRStream(in, null);

    for (PdfName key : in.getKeys()) {
      PdfObject value = in.get(key);
      out.put(key, copyObject(value));
    }

    return out;
  }


  /**
   * Translate a PRArray to a PdfArray. Also translate all of the objects contained in it
   * @param in the PdfArray to copy
   * @return the newly generate PdfArray
   * @throws IOException on error
   */
  protected PdfArray copyArray(PdfArray in) throws IOException, BadPdfFormatException {
    PdfArray out = new PdfArray();

    for (PdfObject value : in.getElements()) {
      out.add(copyObject(value));
    }
    return out;
  }

  /**
   * Translate a PR-object to a Pdf-object
   * @param in the PdfObject to translate
   * @throws IOException on error
   * @throws BadPdfFormatException on error with the Pdf format
   * @return the PdfObject
   */
  protected PdfObject copyObject(PdfObject in) throws IOException, BadPdfFormatException {
    if (in == null) {
      return PdfNull.PDFNULL;
    }
    switch (in.type) {
      case PdfObject.DICTIONARY:
        //            System.out.println("Dictionary: " + in.toString());
        return copyDictionary((PdfDictionary) in);
      case PdfObject.INDIRECT:
        PdfObject obj =  copyIndirect((PRIndirectReference) in);
        if (obj == null) {
            return PdfNull.PDFNULL;
        }
        return obj;
      case PdfObject.ARRAY:
        return copyArray((PdfArray) in);
      case PdfObject.NUMBER:
      case PdfObject.NAME:
      case PdfObject.STRING:
      case PdfObject.NULL:
      case PdfObject.BOOLEAN:
      case 0:
        return in;
      case PdfObject.STREAM:
        return copyStream((PRStream) in);
      //                return in;
      default:
        if (in.type < 0) {
          String lit = in.toString();
          if (lit.equals("true") || lit.equals("false")) {
            return new PdfBoolean(lit);
          }
          return new PdfLiteral(lit);
        }
        System.out.println("CANNOT COPY type " + in.type);
        return null;
    }
  }

  /**
   * convenience method. Given an imported page, set our "globals"
   * @param iPage  the imported page
   * @return the page number
   */
  protected int setFromIPage(PdfImportedPage iPage) {
    int pageNum = iPage.getPageNumber();
    PdfReaderInstance inst = currentPdfReaderInstance = iPage.getPdfReaderInstance();
    reader = inst.getReader();
    setFromReader(reader);
    return pageNum;
  }

  /**
   * convenience method. Given a reader, set our "globals"
   * @param reader  the PdfReader
   */
  protected void setFromReader(PdfReader reader) {
    this.reader = reader;
    indirects = indirectMap.get(reader);
    if (indirects == null) {
      indirects = new HashMap<>();
      indirectMap.put(reader, indirects);
      PdfDictionary catalog = reader.getCatalog();
      PRIndirectReference ref;
      PdfObject o = catalog.get(PdfName.ACROFORM);
      if (o == null || o.type() != PdfObject.INDIRECT) {
        return;
      }
      ref = (PRIndirectReference) o;
      if (acroForm == null) {
        acroForm = body.getPdfIndirectReference();
      }
      indirects.put(new RefKey(ref), new IndirectReferences(acroForm));
    }
  }

  /**
   * Add an imported page to our output
   *
   * @param iPage an imported page
   * @throws IOException on error
   * @throws BadPdfFormatException on error
   */
  public void addPage(PdfImportedPage iPage) throws IOException, BadPdfFormatException {
    int pageNum = setFromIPage(iPage);

    PdfDictionary thePage = reader.getPageN(pageNum);
    PRIndirectReference origRef = reader.getPageOrigRef(pageNum);
    reader.releasePage(pageNum);
    RefKey key = new RefKey(origRef);
    PdfIndirectReference pageRef;
    IndirectReferences iRef = indirects.get(key);
    if (iRef != null && !iRef.getCopied()) {
      pageReferences.add(iRef.getRef());
      iRef.setCopied();
    }
    pageRef = getCurrentPage();
    if (iRef == null) {
      iRef = new IndirectReferences(pageRef);
      indirects.put(key, iRef);
    }
    iRef.setCopied();
    PdfDictionary newPage = copyDictionary(thePage);
    root.addPage(newPage);
    ++currentPageNumber;
  }

  /**
   * Adds a blank page.
   *
   * @param  rect The page dimension
   * @param  rotation The rotation angle in degrees
   * @since 2.1.5
   */
  public void addPage(Rectangle rect, int rotation) {
    PdfRectangle mediabox = new PdfRectangle(rect, rotation);
    PageResources resources = new PageResources();
    PdfPage page = new PdfPage(mediabox, new HashMap<>(),
            resources.getResources(), 0);
    page.put(PdfName.TABS, getTabs());
    root.addPage(page);
    ++currentPageNumber;
  }

  /**
   * Copy the acroform for an input document. Note that you can only have one, we make no effort to merge them.
   *
   * @param reader The reader of the input file that is being copied
   * @throws IOException on error
   * @throws BadPdfFormatException on error
   */
  public void copyAcroForm(PdfReader reader) throws IOException, BadPdfFormatException {
    setFromReader(reader);

    PdfDictionary catalog = reader.getCatalog();
    PRIndirectReference hisRef = null;
    PdfObject o = catalog.get(PdfName.ACROFORM);
    if (o != null && o.type() == PdfObject.INDIRECT) {
      hisRef = (PRIndirectReference) o;
    }
    if (hisRef == null) {
      return; // bugfix by John Englar
    }
    RefKey key = new RefKey(hisRef);
    PdfIndirectReference myRef;
    IndirectReferences iRef = indirects.get(key);
    if (iRef != null) {
      acroForm = myRef = iRef.getRef();
    } else {
      acroForm = myRef = body.getPdfIndirectReference();
      iRef = new IndirectReferences(myRef);
      indirects.put(key, iRef);
    }
    if (!iRef.getCopied()) {
      iRef.setCopied();
      PdfDictionary theForm = copyDictionary((PdfDictionary) PdfReader.getPdfObject(hisRef));
      addToBody(theForm, myRef);
    }
  }

  /*
   * the getCatalog method is part of PdfWriter.
   * we wrap this so that we can extend it
   */
  protected PdfDictionary getCatalog(PdfIndirectReference rootObj) {
    try {
      PdfDictionary theCat = pdf.getCatalog(rootObj);
      if (fieldArray == null) {
        if (acroForm != null) {
          theCat.put(PdfName.ACROFORM, acroForm);
        }
      } else {
        addFieldResources(theCat);
      }
      return theCat;
    } catch (IOException e) {
      throw new ExceptionConverter(e);
    }
  }

  private void addFieldResources(PdfDictionary catalog) throws IOException {
    if (fieldArray == null) {
      return;
    }
    PdfDictionary acroForm = new PdfDictionary();
    catalog.put(PdfName.ACROFORM, acroForm);
    acroForm.put(PdfName.FIELDS, fieldArray);
    acroForm.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
    if (fieldTemplates.isEmpty()) {
      return;
    }
    PdfDictionary dr = new PdfDictionary();
    acroForm.put(PdfName.DR, dr);
    for (Object o : fieldTemplates.keySet()) {
      PdfTemplate template = (PdfTemplate) o;
      PdfFormField.mergeResources(dr, (PdfDictionary) template.getResources());
    }
    // if (dr.get(PdfName.ENCODING) == null) dr.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
    PdfDictionary fonts = dr.getAsDict(PdfName.FONT);
    if (fonts == null) {
      fonts = new PdfDictionary();
      dr.put(PdfName.FONT, fonts);
    }
    if (!fonts.contains(PdfName.HELV)) {
      PdfDictionary dic = new PdfDictionary(PdfName.FONT);
      dic.put(PdfName.BASEFONT, PdfName.HELVETICA);
      dic.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
      dic.put(PdfName.NAME, PdfName.HELV);
      dic.put(PdfName.SUBTYPE, PdfName.TYPE1);
      fonts.put(PdfName.HELV, addToBody(dic).getIndirectReference());
    }
    if (!fonts.contains(PdfName.ZADB)) {
      PdfDictionary dic = new PdfDictionary(PdfName.FONT);
      dic.put(PdfName.BASEFONT, PdfName.ZAPFDINGBATS);
      dic.put(PdfName.NAME, PdfName.ZADB);
      dic.put(PdfName.SUBTYPE, PdfName.TYPE1);
      fonts.put(PdfName.ZADB, addToBody(dic).getIndirectReference());
    }
  }

  /**
   * Signals that the Document was closed and that no other
   * Elements will be added.
   * 

* The pages-tree is built and written to the outputstream. A Catalog is constructed, as well as an Info-object, the reference table is * composed and everything is written to the outputstream embedded in a Trailer. */ public void close() { if (open) { PdfReaderInstance ri = currentPdfReaderInstance; pdf.close(); super.close(); if (ri != null) { try { ri.getReader().close(); ri.getReaderFile().close(); } catch (IOException ioe) { // empty on purpose } } } } public PdfIndirectReference add(PdfOutline outline) { return null; } public void addAnnotation(PdfAnnotation annot) { } PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException { return null; } public void freeReader(PdfReader reader) throws IOException { indirectMap.remove(reader); if (currentPdfReaderInstance != null) { if (currentPdfReaderInstance.getReader() == reader) { try { currentPdfReaderInstance.getReader().close(); currentPdfReaderInstance.getReaderFile().close(); } catch (IOException ioe) { // empty on purpose } currentPdfReaderInstance = null; } } } /** * Create a page stamp. New content and annotations, including new fields, are allowed. The fields added cannot have parents in another * pages. This method modifies the PdfReader instance. *

The general usage to stamp something in a page is:

*
   * PdfImportedPage page = copy.getImportedPage(reader, 1);
   * PdfCopy.PageStamp ps = copy.createPageStamp(page);
   * ps.addAnnotation(PdfAnnotation.createText(copy, new Rectangle(50, 180, 70, 200), "Hello", "No Thanks", true, "Comment"));
   * PdfContentByte under = ps.getUnderContent();
   * under.addImage(img);
   * PdfContentByte over = ps.getOverContent();
   * over.beginText();
   * over.setFontAndSize(bf, 18);
   * over.setTextMatrix(30, 30);
   * over.showText("total page " + totalPage);
   * over.endText();
   * ps.alterContents();
   * copy.addPage(page);
   * 
* * @param iPage an imported page * @return the PageStamp */ public PageStamp createPageStamp(PdfImportedPage iPage) { int pageNum = iPage.getPageNumber(); PdfReader reader = iPage.getPdfReaderInstance().getReader(); PdfDictionary pageN = reader.getPageN(pageNum); return new PageStamp(reader, pageN, this); } public static class PageStamp { PdfDictionary pageN; PdfCopy.StampContent under; PdfCopy.StampContent over; PageResources pageResources; PdfReader reader; PdfCopy cstp; PageStamp(PdfReader reader, PdfDictionary pageN, PdfCopy cstp) { this.pageN = pageN; this.reader = reader; this.cstp = cstp; } public PdfContentByte getUnderContent() { if (under == null) { if (pageResources == null) { pageResources = new PageResources(); PdfDictionary resources = pageN.getAsDict(PdfName.RESOURCES); pageResources.setOriginalResources(resources, cstp.namePtr); } under = new PdfCopy.StampContent(cstp, pageResources); } return under; } public PdfContentByte getOverContent() { if (over == null) { if (pageResources == null) { pageResources = new PageResources(); PdfDictionary resources = pageN.getAsDict(PdfName.RESOURCES); pageResources.setOriginalResources(resources, cstp.namePtr); } over = new PdfCopy.StampContent(cstp, pageResources); } return over; } public void alterContents() throws IOException { if (over == null && under == null) { return; } PdfArray ar = null; PdfObject content = PdfReader.getPdfObject(pageN.get(PdfName.CONTENTS), pageN); if (content == null) { ar = new PdfArray(); pageN.put(PdfName.CONTENTS, ar); } else if (content.isArray()) { ar = (PdfArray) content; } else if (content.isStream()) { ar = new PdfArray(); ar.add(pageN.get(PdfName.CONTENTS)); pageN.put(PdfName.CONTENTS, ar); } else { ar = new PdfArray(); pageN.put(PdfName.CONTENTS, ar); } ByteBuffer out = new ByteBuffer(); if (under != null) { out.append(PdfContents.SAVESTATE); applyRotation(pageN, out); out.append(under.getInternalBuffer()); out.append(PdfContents.RESTORESTATE); } if (over != null) { out.append(PdfContents.SAVESTATE); } PdfStream stream = new PdfStream(out.toByteArray()); stream.flateCompress(cstp.getCompressionLevel()); PdfIndirectReference ref1 = cstp.addToBody(stream).getIndirectReference(); ar.addFirst(ref1); out.reset(); if (over != null) { out.append(' '); out.append(PdfContents.RESTORESTATE); out.append(PdfContents.SAVESTATE); applyRotation(pageN, out); out.append(over.getInternalBuffer()); out.append(PdfContents.RESTORESTATE); stream = new PdfStream(out.toByteArray()); stream.flateCompress(cstp.getCompressionLevel()); ar.add(cstp.addToBody(stream).getIndirectReference()); } pageN.put(PdfName.RESOURCES, pageResources.getResources()); } void applyRotation(PdfDictionary pageN, ByteBuffer out) { if (!cstp.rotateContents) { return; } Rectangle page = reader.getPageSizeWithRotation(pageN); int rotation = page.getRotation(); switch (rotation) { case 90: out.append(PdfContents.ROTATE90); out.append(page.getTop()); out.append(' ').append('0').append(PdfContents.ROTATEFINAL); break; case 180: out.append(PdfContents.ROTATE180); out.append(page.getRight()); out.append(' '); out.append(page.getTop()); out.append(PdfContents.ROTATEFINAL); break; case 270: out.append(PdfContents.ROTATE270); out.append('0').append(' '); out.append(page.getRight()); out.append(PdfContents.ROTATEFINAL); break; } } private void addDocumentField(PdfIndirectReference ref) { if (cstp.fieldArray == null) { cstp.fieldArray = new PdfArray(); } cstp.fieldArray.add(ref); } private void expandFields(PdfFormField field, List allAnnots) { allAnnots.add(field); List kids = field.getKidFields(); if (kids != null) { for (PdfFormField kid : kids) { expandFields(kid, allAnnots); } } } public void addAnnotation(PdfAnnotation annot) { try { List allAnnots = new ArrayList<>(); if (annot.isForm()) { PdfFormField field = (PdfFormField) annot; if (field.getParent() != null) { return; } expandFields(field, allAnnots); if (cstp.fieldTemplates == null) { cstp.fieldTemplates = new HashMap<>(); } } else { allAnnots.add(annot); } for (PdfAnnotation allAnnot : allAnnots) { annot = allAnnot; if (annot.isForm()) { if (!annot.isUsed()) { Map templates = annot.getTemplates(); if (templates != null) { cstp.fieldTemplates.putAll(templates); } } PdfFormField field = (PdfFormField) annot; if (field.getParent() == null) { addDocumentField(field.getIndirectReference()); } } if (annot.isAnnotation()) { PdfObject pdfobj = PdfReader.getPdfObject(pageN.get(PdfName.ANNOTS), pageN); PdfArray annots; if (pdfobj == null || !pdfobj.isArray()) { annots = new PdfArray(); pageN.put(PdfName.ANNOTS, annots); } else { annots = (PdfArray) pdfobj; } annots.add(annot.getIndirectReference()); if (!annot.isUsed()) { PdfRectangle rect = (PdfRectangle) annot.get(PdfName.RECT); if (rect != null && (rect.left() != 0 || rect.right() != 0 || rect.top() != 0 || rect.bottom() != 0)) { int rotation = reader.getPageRotation(pageN); Rectangle pageSize = reader.getPageSizeWithRotation(pageN); switch (rotation) { case 90: annot.put(PdfName.RECT, new PdfRectangle( pageSize.getTop() - rect.bottom(), rect.left(), pageSize.getTop() - rect.top(), rect.right())); break; case 180: annot.put(PdfName.RECT, new PdfRectangle( pageSize.getRight() - rect.left(), pageSize.getTop() - rect.bottom(), pageSize.getRight() - rect.right(), pageSize.getTop() - rect.top())); break; case 270: annot.put(PdfName.RECT, new PdfRectangle( rect.bottom(), pageSize.getRight() - rect.left(), rect.top(), pageSize.getRight() - rect.right())); break; } } } } if (!annot.isUsed()) { annot.setUsed(); cstp.addToBody(annot, annot.getIndirectReference()); } } } catch (IOException e) { throw new ExceptionConverter(e); } } } public static class StampContent extends PdfContentByte { PageResources pageResources; /** * Creates a new instance of StampContent */ StampContent(PdfWriter writer, PageResources pageResources) { super(writer); this.pageResources = pageResources; } /** * Gets a duplicate of this PdfContentByte. All the members are copied by reference but the buffer stays different. * * @return a copy of this PdfContentByte */ public PdfContentByte getDuplicate() { return new PdfCopy.StampContent(writer, pageResources); } PageResources getPageResources() { return pageResources; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy