Search in sources :

Example 1 with PathRenderInfo

use of com.itextpdf.kernel.pdf.canvas.parser.data.PathRenderInfo in project i7j-pdfsweep by itext.

the class PdfCleanUpEventListener method getEncounteredPath.

/**
 * Get the last encountered PathRenderInfo, then clears the internal buffer
 *
 * @return the PathRenderInfo object that was encountered when processing the last path rendering operation
 */
PathRenderInfo getEncounteredPath() {
    if (content.size() == 0) {
        throw new PdfException(pathDataExpected);
    }
    IEventData eventData = content.get(0);
    if (!(eventData instanceof PathRenderInfo)) {
        throw new PdfException(pathDataExpected);
    }
    content.clear();
    return (PathRenderInfo) eventData;
}
Also used : IEventData(com.itextpdf.kernel.pdf.canvas.parser.data.IEventData) PdfException(com.itextpdf.kernel.exceptions.PdfException) PathRenderInfo(com.itextpdf.kernel.pdf.canvas.parser.data.PathRenderInfo)

Example 2 with PathRenderInfo

use of com.itextpdf.kernel.pdf.canvas.parser.data.PathRenderInfo in project i7j-pdfsweep by itext.

the class PdfCleanUpProcessor method writePath.

private void writePath() {
    PathRenderInfo path = ((PdfCleanUpEventListener) getEventListener()).getEncounteredPath();
    boolean stroke = (path.getOperation() & PathRenderInfo.STROKE) == PathRenderInfo.STROKE;
    boolean fill = (path.getOperation() & PathRenderInfo.FILL) == PathRenderInfo.FILL;
    boolean clip = path.isPathModifiesClippingPath();
    // Here we intentionally draw all three paths separately and not combining them in any way:
    // First of all, stroke converted to fill paths, therefore it could not be combined with fill (if it is
    // stroke-fill operation) or clip paths, and also it should be drawn after the fill, because in case it's
    // stroke-fill operation stroke should be "on top" of the filled area.
    // Secondly, current clipping path modifying happens AFTER the path painting. So if it is drawn separately, clip
    // path should be the last one.
    // So consider the situation when it is stroke-fill operation and also this path is marked as clip path.
    // And here we have it: fill path is the first, stroke path is the second and clip path is the last. And
    // stroke path could not be combined with neither fill nor clip paths.
    // Some improved logic could be applied to distinguish the cases when some paths actually could be drawn as one,
    // but this is the only generic solution.
    Path fillPath = null;
    PdfCanvas canvas = getCanvas();
    if (fill) {
        fillPath = filter.filterFillPath(path, path.getRule());
        if (!fillPath.isEmpty()) {
            writeNotAppliedGsParams(true, false);
            openNotWrittenTags();
            writePath(fillPath);
            if (path.getRule() == FillingRule.NONZERO_WINDING) {
                canvas.fill();
            } else {
                // FillingRule.EVEN_ODD
                canvas.eoFill();
            }
        }
    }
    if (stroke) {
        Path strokePath = filter.filterStrokePath(path);
        if (!strokePath.isEmpty()) {
            // we pass stroke here as false, because stroke is transformed into fill. we don't need to set stroke color
            writeNotAppliedGsParams(false, false);
            openNotWrittenTags();
            writeStrokePath(strokePath, path.getStrokeColor());
        }
    }
    if (clip) {
        Path clippingPath;
        if (fill && path.getClippingRule() == path.getRule()) {
            clippingPath = fillPath;
        } else {
            clippingPath = filter.filterFillPath(path, path.getClippingRule());
        }
        if (!clippingPath.isEmpty()) {
            writeNotAppliedGsParams(false, false);
            openNotWrittenTags();
            writePath(clippingPath);
            if (path.getClippingRule() == FillingRule.NONZERO_WINDING) {
                canvas.clip();
            } else {
                // FillingRule.EVEN_ODD
                canvas.eoClip();
            }
        } else {
            // If the clipping path from the source document is cleaned (it happens when reduction
            // area covers the path completely), then you should treat it as an empty set (no points
            // are included in the path). Then the current clipping path (which is the intersection
            // between previous clipping path and the new one) is also empty set, which means that
            // there is no visible content at all. But at the same time as we removed the clipping
            // path, the invisible content would become visible. So, to emulate the correct result,
            // we would simply put a degenerate clipping path which consists of a single point at (0, 0).
            // we still need to open all q operators
            writeNotAppliedGsParams(false, false);
            canvas.moveTo(0, 0).clip();
        }
        canvas.endPath();
    }
}
Also used : Path(com.itextpdf.kernel.geom.Path) PdfCanvas(com.itextpdf.kernel.pdf.canvas.PdfCanvas) PathRenderInfo(com.itextpdf.kernel.pdf.canvas.parser.data.PathRenderInfo)

Aggregations

PathRenderInfo (com.itextpdf.kernel.pdf.canvas.parser.data.PathRenderInfo)2 PdfException (com.itextpdf.kernel.exceptions.PdfException)1 Path (com.itextpdf.kernel.geom.Path)1 PdfCanvas (com.itextpdf.kernel.pdf.canvas.PdfCanvas)1 IEventData (com.itextpdf.kernel.pdf.canvas.parser.data.IEventData)1