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

com.itextpdf.kernel.pdf.xobject.PdfFormXObject Maven / Gradle / Ivy

There is a newer version: 9.0.0
Show newest version
/*

    This file is part of the iText (R) project.
    Copyright (c) 1998-2022 iText Group NV
    Authors: Bruno Lowagie, Paulo Soares, et al.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
    as published by the Free Software Foundation with the addition of the
    following permission added to Section 15 as permitted in Section 7(a):
    FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
    ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
    OF THIRD PARTY RIGHTS

    This program 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 Affero General Public License for more details.
    You should have received a copy of the GNU Affero General Public License
    along with this program; if not, see http://www.gnu.org/licenses or write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA, 02110-1301 USA, or download the license from the following URL:
    http://itextpdf.com/terms-of-use/

    The interactive user interfaces in modified source and object code versions
    of this program must display Appropriate Legal Notices, as required under
    Section 5 of the GNU Affero General Public License.

    In accordance with Section 7(b) of the GNU Affero General Public License,
    a covered work must retain the producer line in every PDF that is created
    or manipulated using iText.

    You can be released from the requirements of the license by purchasing
    a commercial license. Buying such a license is mandatory as soon as you
    develop commercial activities involving the iText software without
    disclosing the source code of your own applications.
    These activities include: offering paid services to customers as an ASP,
    serving PDFs on the fly in a web application, shipping iText with a closed
    source product.

    For more information, please contact iText Software Corp. at this
    address: [email protected]
 */
package com.itextpdf.kernel.pdf.xobject;

import com.itextpdf.kernel.exceptions.PdfException;
import com.itextpdf.kernel.geom.Matrix;
import com.itextpdf.kernel.exceptions.KernelExceptionMessageConstant;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.geom.Vector;
import com.itextpdf.kernel.pdf.PdfArray;
import com.itextpdf.kernel.pdf.PdfDictionary;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfObject;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfResources;
import com.itextpdf.kernel.pdf.PdfStream;
import com.itextpdf.kernel.pdf.PdfString;
import com.itextpdf.kernel.pdf.canvas.wmf.WmfImageData;
import com.itextpdf.kernel.pdf.canvas.wmf.WmfImageHelper;

/**
 * A wrapper for Form XObject. ISO 32000-1, 8.10 FormXObjects.
 */
public class PdfFormXObject extends PdfXObject {

    protected PdfResources resources = null;

    /**
     * Creates a new instance of Form XObject.
     *
     * @param bBox the form XObject’s bounding box.
     */
    public PdfFormXObject(Rectangle bBox) {
        super(new PdfStream());
        getPdfObject().put(PdfName.Type, PdfName.XObject);
        getPdfObject().put(PdfName.Subtype, PdfName.Form);
        if (bBox != null) {
            getPdfObject().put(PdfName.BBox, new PdfArray(bBox));
        }
    }

    /**
     * Create {@link PdfFormXObject} instance by {@link PdfStream}.
     * Note, this constructor doesn't perform any additional checks
     *
     * @param pdfStream {@link PdfStream} with Form XObject.
     * @see PdfXObject#makeXObject(PdfStream)
     */
    public PdfFormXObject(PdfStream pdfStream) {
        super(pdfStream);
        if (!getPdfObject().containsKey(PdfName.Subtype)) {
            getPdfObject().put(PdfName.Subtype, PdfName.Form);
        }
    }

    /**
     * Creates form XObject from page content.
     * The page shall be from the document, to which FormXObject will be added.
     *
     * @param page an instance of {@link PdfPage}
     */
    public PdfFormXObject(PdfPage page) {
        this(page.getCropBox());
        getPdfObject().getOutputStream().writeBytes(page.getContentBytes());
        resources = new PdfResources((PdfDictionary) page.getResources().getPdfObject().clone());
        getPdfObject().put(PdfName.Resources, resources.getPdfObject());
    }

    /**
     * Creates a form XObject from {@link com.itextpdf.kernel.pdf.canvas.wmf.WmfImageData}.
     * Unlike other images, {@link com.itextpdf.kernel.pdf.canvas.wmf.WmfImageData} images are represented as {@link PdfFormXObject}, not as
     * {@link PdfImageXObject}.
     *
     * @param image       image to create form object from
     * @param pdfDocument document instance which is needed for writing form stream contents
     */
    public PdfFormXObject(WmfImageData image, PdfDocument pdfDocument) {
        this(new WmfImageHelper(image).createFormXObject(pdfDocument).getPdfObject());
    }

    /**
     * Calculates the coordinates of the xObject BBox multiplied by the Matrix field.
     *
     * 

* For mor information see paragraph 8.10.1 in ISO-32000-1. * * @param form the object for which calculate the coordinates of the bBox * @return the bBox {@link Rectangle} */ public static Rectangle calculateBBoxMultipliedByMatrix(PdfFormXObject form) { PdfArray pdfArrayBBox = form.getPdfObject().getAsArray(PdfName.BBox); if (pdfArrayBBox == null) { throw new PdfException(KernelExceptionMessageConstant.PDF_FORM_XOBJECT_HAS_INVALID_BBOX); } float[] bBoxArray = pdfArrayBBox.toFloatArray(); PdfArray pdfArrayMatrix = form.getPdfObject().getAsArray(PdfName.Matrix); float[] matrixArray; if (pdfArrayMatrix == null) { matrixArray = new float[] {1, 0, 0, 1, 0, 0}; } else { matrixArray = pdfArrayMatrix.toFloatArray(); } Matrix matrix = new Matrix(matrixArray[0], matrixArray[1], matrixArray[2], matrixArray[3], matrixArray[4], matrixArray[5]); Vector bBoxMin = new Vector(bBoxArray[0], bBoxArray[1], 1); Vector bBoxMax = new Vector(bBoxArray[2], bBoxArray[3], 1); Vector bBoxMinByMatrix = bBoxMin.cross(matrix); Vector bBoxMaxByMatrix = bBoxMax.cross(matrix); float width = bBoxMaxByMatrix.get(Vector.I1) - bBoxMinByMatrix.get(Vector.I1); float height = bBoxMaxByMatrix.get(Vector.I2) - bBoxMinByMatrix.get(Vector.I2); return new Rectangle(bBoxMinByMatrix.get(Vector.I1), bBoxMinByMatrix.get(Vector.I2), width, height); } /** * Gets {@link PdfResources} of the Form XObject. * Note, if there is no resources, a new instance will be created. * * @return not null instance of {@link PdfResources}. */ public PdfResources getResources() { if (this.resources == null) { PdfDictionary resourcesDict = getPdfObject().getAsDictionary(PdfName.Resources); if (resourcesDict == null) { resourcesDict = new PdfDictionary(); getPdfObject().put(PdfName.Resources, resourcesDict); } this.resources = new PdfResources(resourcesDict); } return resources; } /** * Gets Form XObject's BBox, {@link PdfName#BBox} key. * * @return a {@link PdfArray}, that represents {@link Rectangle}. */ public PdfArray getBBox() { return getPdfObject().getAsArray(PdfName.BBox); } /** * Sets Form XObject's BBox, {@link PdfName#BBox} key. * * @param bBox a {@link PdfArray}, that represents {@link Rectangle}. * @return object itself. */ public PdfFormXObject setBBox(PdfArray bBox) { return put(PdfName.BBox, bBox); } /** * Sets a group attributes dictionary indicating that the contents of the form XObject * shall be treated as a group and specifying the attributes of that group. * {@link PdfName#Group} key. * * @param transparency instance of {@link PdfTransparencyGroup}. * @return object itself. * @see PdfTransparencyGroup */ public PdfFormXObject setGroup(PdfTransparencyGroup transparency) { return put(PdfName.Group, transparency.getPdfObject()); } /** * Gets width based on XObject's BBox. * * @return float value. */ @Override public float getWidth() { return getBBox() == null ? 0 : getBBox().getAsNumber(2).floatValue() - getBBox().getAsNumber(0).floatValue(); } /** * Gets height based on XObject's BBox. * * @return float value. */ @Override public float getHeight() { return getBBox() == null ? 0 : getBBox().getAsNumber(3).floatValue() - getBBox().getAsNumber(1).floatValue(); } /** * To manually flush a {@code PdfObject} behind this wrapper, you have to ensure * that this object is added to the document, i.e. it has an indirect reference. * Basically this means that before flushing you need to explicitly call {@link #makeIndirect(PdfDocument)}. * For example: wrapperInstance.makeIndirect(document).flush(); * Note that not every wrapper require this, only those that have such warning in documentation. */ @Override public void flush() { resources = null; if (getPdfObject().get(PdfName.BBox) == null) { throw new PdfException(KernelExceptionMessageConstant.FORM_XOBJECT_MUST_HAVE_BBOX); } super.flush(); } //-----Additional entries in form dictionary for Trap Network annotation /** * Sets process color model for trap network appearance, {@link PdfName#PCM} key. * * @param model shall be one of the valid values: {@link PdfName#DeviceGray}, * {@link PdfName#DeviceRGB}, {@link PdfName#DeviceCMYK}, {@link PdfName#DeviceCMY}, * {@link PdfName#DeviceRGBK}, and {@link PdfName#DeviceN}. * @return object itself. */ public PdfFormXObject setProcessColorModel(PdfName model) { return put(PdfName.PCM, model); } /** * Gets process color model of trap network appearance, {@link PdfName#PCM} key. * * @return a {@link PdfName} instance, possible values: {@link PdfName#DeviceGray}, * {@link PdfName#DeviceRGB}, {@link PdfName#DeviceCMYK}, {@link PdfName#DeviceCMY}, * {@link PdfName#DeviceRGBK}, and {@link PdfName#DeviceN}. */ public PdfName getProcessColorModel() { return getPdfObject().getAsName(PdfName.PCM); } /** * Sets separation color names for the trap network appearance, {@link PdfName#SeparationColorNames} key. * * @param colorNames an array of names identifying the colorants that were assumed * when the trap network appearance was created. * @return object itself. */ public PdfFormXObject setSeparationColorNames(PdfArray colorNames) { return put(PdfName.SeparationColorNames, colorNames); } /** * Gets separation color names of trap network appearance, {@link PdfName#SeparationColorNames} key. * * @return an {@link PdfArray} of names identifying the colorants. */ public PdfArray getSeparationColorNames() { return getPdfObject().getAsArray(PdfName.SeparationColorNames); } /** * Sets an array of TrapRegion objects defining the page’s trapping zones * and the associated trapping parameters, as described in Adobe Technical Note #5620, * Portable Job Ticket Format. {@link PdfName#TrapRegions} key. * * @param regions A {@link PdfArray} of indirect references to TrapRegion objects. * @return object itself. */ public PdfFormXObject setTrapRegions(PdfArray regions) { return put(PdfName.TrapRegions, regions); } /** * Gets an array of TrapRegion objects defining the page’s trapping zones * and the associated trapping parameters, as described in Adobe Technical Note #5620, * Portable Job Ticket Format. {@link PdfName#TrapRegions} key. * * @return A {@link PdfArray} of indirect references to TrapRegion objects. */ public PdfArray getTrapRegions() { return getPdfObject().getAsArray(PdfName.TrapRegions); } /** * Sets a human-readable text string that described this trap network to the user. * {@link PdfName#TrapStyles} key. * * @param trapStyles a {@link PdfString} value. * @return object itself. */ public PdfFormXObject setTrapStyles(PdfString trapStyles) { return put(PdfName.TrapStyles, trapStyles); } /** * Gets a human-readable text string that described this trap network to the user. * {@link PdfName#TrapStyles} key. * * @return a {@link PdfString} value. */ public PdfString getTrapStyles() { return getPdfObject().getAsString(PdfName.TrapStyles); } //-----Additional entries in form dictionary for Printer Mark annotation /** * Sets a text string representing the printer’s mark in human-readable form. * * @param markStyle a string value. * @return object itself. */ public PdfFormXObject setMarkStyle(PdfString markStyle) { return put(PdfName.MarkStyle, markStyle); } /** * Gets a text string representing the printer’s mark in human-readable form. * * @return a string value. */ public PdfString getMarkStyle() { return getPdfObject().getAsString(PdfName.MarkStyle); } /** * Puts the value into Image XObject dictionary and associates it with the specified key. * If the key is already present, it will override the old value with the specified one. * * @param key key to insert or to override * @param value the value to associate with the specified key * @return object itself. */ public PdfFormXObject put(PdfName key, PdfObject value) { getPdfObject().put(key, value); setModified(); return this; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy