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

com.itextpdf.kernel.pdf.canvas.parser.data.PathRenderInfo Maven / Gradle / Ivy

The newest version!
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2024 Apryse Group NV
    Authors: Apryse Software.

    This program is offered under a commercial and under the AGPL license.
    For commercial licensing, contact us at https://itextpdf.com/sales.  For AGPL licensing, see below.

    AGPL licensing:
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    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 .
 */
package com.itextpdf.kernel.pdf.canvas.parser.data;

import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.geom.Matrix;
import com.itextpdf.kernel.geom.Path;
import com.itextpdf.kernel.pdf.PdfArray;
import com.itextpdf.kernel.pdf.canvas.CanvasGraphicsState;
import com.itextpdf.kernel.pdf.canvas.CanvasTag;
import com.itextpdf.kernel.pdf.canvas.PdfCanvasConstants.FillingRule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

/**
 * Contains information relating to painting current path.
 */
public class PathRenderInfo extends AbstractRenderInfo {

    /**
     * End the path object without filling or stroking it. This operator shall be a path-painting no-op,
     * used primarily for the side effect of changing the current clipping path
     */
    public static final int NO_OP = 0;

    /**
     * Value specifying stroke operation to perform on the current path.
     */
    public static final int STROKE = 1;

    /**
     * Value specifying fill operation to perform on the current path. When the fill operation
     * is performed it should use either nonzero winding or even-odd rule.
     */
    public static final int FILL = 2;

    private Path path;
    private int operation;
    private int rule;
    private boolean isClip;
    private int clippingRule;

    /**
     * Hierarchy of nested canvas tags for the text from the most inner (nearest to text) tag to the most outer.
     */
    private List canvasTagHierarchy;

    /**
     * Creates the new {@link PathRenderInfo} instance.
     *
     * @param canvasTagHierarchy the canvas tag hierarchy
     * @param gs                 the graphics state
     * @param path               the path to be rendered
     * @param operation          one of the possible combinations of {@link #STROKE} and
     *                           {@link #FILL} values or {@link #NO_OP}
     * @param rule               either {@link FillingRule#NONZERO_WINDING} or {@link FillingRule#EVEN_ODD}
     * @param isClip             {@code true} indicates that current path modifies the clipping path
     * @param clipRule           either {@link FillingRule#NONZERO_WINDING} or {@link FillingRule#EVEN_ODD}
     */
    public PathRenderInfo(Stack canvasTagHierarchy, CanvasGraphicsState gs, Path path, int operation, int rule, boolean isClip, int clipRule) {
        super(gs);
        this.canvasTagHierarchy = Collections.unmodifiableList(new ArrayList<>(canvasTagHierarchy));
        this.path = path;
        this.operation = operation;
        this.rule = rule;
        this.isClip = isClip;
        this.clippingRule = clipRule;
    }

    /**
     * If the operation is {@link #NO_OP} then the rule is ignored,
     * otherwise {@link FillingRule#NONZERO_WINDING} is used by default.
     * With this constructor path is considered as not modifying clipping path.
     * 

* See {@link #PathRenderInfo(Stack, CanvasGraphicsState, Path, int, int, boolean, int)} * * @param canvasTagHierarchy the canvas tag hierarchy * @param gs the graphics state * @param path the path to be rendered * @param operation one of the possible combinations of {@link #STROKE} and * {@link #FILL} values or {@link #NO_OP} */ public PathRenderInfo(Stack canvasTagHierarchy, CanvasGraphicsState gs, Path path, int operation) { this(canvasTagHierarchy, gs, path, operation, FillingRule.NONZERO_WINDING, false, FillingRule.NONZERO_WINDING); } /** * Gets the {@link Path} to be rendered * * @return the {@link Path} to be rendered */ public Path getPath() { return path; } /** * Gets the {@code int} value which is either {@link #NO_OP} or one of possible * combinations of {@link #STROKE} and {@link #FILL}. * * @return the operation value */ public int getOperation() { return operation; } /** * Gets either {@link FillingRule#NONZERO_WINDING} or {@link FillingRule#EVEN_ODD}. * * @return the rule value */ public int getRule() { return rule; } /** * Gets the clipping path flag. * * @return {@code true} indicates that current path modifies the clipping path */ public boolean isPathModifiesClippingPath() { return isClip; } /** * Gets either {@link FillingRule#NONZERO_WINDING} or {@link FillingRule#EVEN_ODD}. * * @return the clipping rule value */ public int getClippingRule() { return clippingRule; } /** * Gets the current transformation matrix. * * @return the current transformation {@link Matrix matrix} */ public Matrix getCtm() { checkGraphicsState(); return gs.getCtm(); } /** * Gets the path's line width. * * @return the path's line width */ public float getLineWidth() { checkGraphicsState(); return gs.getLineWidth(); } /** * Gets the line cap style. See {@link com.itextpdf.kernel.pdf.canvas.PdfCanvasConstants.LineCapStyle}. * * @return the line cap style value */ public int getLineCapStyle() { checkGraphicsState(); return gs.getLineCapStyle(); } /** * Gets the line join style. See {@link com.itextpdf.kernel.pdf.canvas.PdfCanvasConstants.LineJoinStyle}. * * @return the line join style value */ public int getLineJoinStyle() { checkGraphicsState(); return gs.getLineJoinStyle(); } /** * Gets the miter limit. * * @return the miter limit */ public float getMiterLimit() { checkGraphicsState(); return gs.getMiterLimit(); } /** * Gets the path's dash pattern. * * @return the path's dash pattern as a {@link PdfArray} */ public PdfArray getLineDashPattern() { checkGraphicsState(); return gs.getDashPattern(); } /** * Gets the path's stroke color. * * @return the path's stroke {@link Color color} */ public Color getStrokeColor() { checkGraphicsState(); return gs.getStrokeColor(); } /** * Gets the path's fill color. * * @return the path's fill {@link Color color} */ public Color getFillColor() { checkGraphicsState(); return gs.getFillColor(); } /** * Gets hierarchy of the canvas tags that wraps given text. * * @return list of the wrapping canvas tags. The first tag is the innermost (nearest to the text) */ public List getCanvasTagHierarchy() { return canvasTagHierarchy; } /** * Gets the marked-content identifier associated with this {@link PathRenderInfo} instance * * @return associated marked-content identifier or -1 in case content is unmarked */ public int getMcid() { for (CanvasTag tag : canvasTagHierarchy) { if (tag.hasMcid()) { return tag.getMcid(); } } return -1; } /** * Checks if this {@link PathRenderInfo} instance belongs to a marked content sequence * with a given mcid. * * @param mcid a marked content id * @return {@code true} if this {@link PathRenderInfo} instance is marked with this id, {@code false} otherwise */ public boolean hasMcid(int mcid) { return hasMcid(mcid, false); } /** * Checks if this {@link PathRenderInfo} instance belongs to a marked content sequence * with a given mcid. * * @param mcid a marked content id * @param checkTheTopmostLevelOnly indicates whether to check the topmost level of marked content stack only * @return {@code true} if this {@link PathRenderInfo} instance is marked with this id, {@code false} otherwise */ public boolean hasMcid(int mcid, boolean checkTheTopmostLevelOnly) { if (checkTheTopmostLevelOnly) { if (canvasTagHierarchy != null) { int infoMcid = getMcid(); return infoMcid != -1 && infoMcid == mcid; } } else { for (CanvasTag tag : canvasTagHierarchy) { if (tag.hasMcid()) if (tag.getMcid() == mcid) return true; } } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy