private void transformClippingPath(Matrix newCtm) { Path path = new Path(); for (Subpath subpath : clippingPath.getSubpaths()) { Subpath transformedSubpath = transformSubpath(subpath, newCtm); path.addSubpath(transformedSubpath); } clippingPath = path; }
public Path(Path path) { addSubpaths(path.getSubpaths()); }
/** * Sets the current clipping path to the specified path. * * <strong>Note:</strong>This method doesn't modify existing clipping path, * it simply replaces it with the new one instead. * @param clippingPath New clipping path. */ public void setClippingPath(Path clippingPath) { Path pathCopy = new Path(clippingPath); pathCopy.closeAllSubpaths(); this.clippingPath = pathCopy; }
/** * Appends a rectangle to the current path as a complete subpath. */ public void rectangle(float x, float y, float w, float h) { moveTo(x, y); lineTo(x + w, y); lineTo(x + w, y + h); lineTo(x, y + h); closeSubpath(); }
/** * Closes the current subpath. */ public void closeSubpath() { if (!isEmpty()) { Subpath lastSubpath = getLastSubpath(); lastSubpath.setClosed(true); Point startPoint = lastSubpath.getStartPoint(); moveTo((float) startPoint.getX(), (float) startPoint.getY()); } }
/** * Intersects the current clipping path with the given path. * * <strong>Note:</strong> Coordinates of the given path should be in * the transformed user space. * @param path The path to be intersected with the current clipping path. * @param fillingRule The filling rule which should be applied to the given path. * It should be either {@link FillingRule#EVEN_ODD} or * {@link FillingRule#NONZERO_WINDING} */ public void clip(Path path, int fillingRule) { if (clippingPath == null || clippingPath.isEmpty()) { return; } Path pathCopy = new Path(path); pathCopy.closeAllSubpaths(); IClipper clipper = new DefaultClipper(); ClipperBridge.addPath(clipper, clippingPath, IClipper.PolyType.SUBJECT); ClipperBridge.addPath(clipper, pathCopy, IClipper.PolyType.CLIP); PolyTree resultTree = new PolyTree(); clipper.execute(IClipper.ClipType.INTERSECTION, resultTree, IClipper.PolyFillType.NON_ZERO, ClipperBridge.getFillType(fillingRule)); clippingPath = ClipperBridge.convertToPath(resultTree); }
/** * Copy constructor. * @param source the Graphics State to copy from */ ParserGraphicsState(ParserGraphicsState source) { super(source); if (source.clippingPath != null) { clippingPath = new Path(source.clippingPath); } }
/** * Appends a cubic Bezier curve to the current path. The curve shall extend from * the current point to the point <CODE>(x3, y3)</CODE> with the note that the (x3, y3) * point represents two control points. */ public void curveFromTo(float x1, float y1, float x3, float y3) { if (currentPoint == null) { throw new RuntimeException(START_PATH_ERR_MSG); } curveTo(x1, y1, x3, y3, x3, y3); }
/** * {@inheritDoc} */ public void invoke(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands) { processor.currentPath.closeSubpath(); } }
/** * Appends a straight line segment from the current point to the point <CODE>(x, y)</CODE>. * @param x x-coordinate of the new point * @param y y-coordinate of the new point */ public void lineTo(float x, float y) { if (currentPoint == null) { throw new RuntimeException(START_PATH_ERR_MSG); } Point targetPoint = new Point(x, y); getLastSubpath().addSegment(new Line(currentPoint, targetPoint)); currentPoint = targetPoint; }
/** * Adds all iText {@link Subpath}s of the iText {@link Path} to the {@link ClipperOffset} object with one * note: it doesn't add degenerate subpaths. * * @return {@link java.util.List} consisting of all degenerate iText {@link Subpath}s of the path. */ public static List<Subpath> addPath(ClipperOffset offset, com.itextpdf.kernel.geom.Path path, IClipper.JoinType joinType, IClipper.EndType endType) { List<Subpath> degenerateSubpaths = new ArrayList<>(); for (Subpath subpath : path.getSubpaths()) { if (subpath.isDegenerate()) { degenerateSubpaths.add(subpath); continue; } if (!subpath.isSinglePointClosed() && !subpath.isSinglePointOpen()) { IClipper.EndType et; if (subpath.isClosed()) { // Offsetting is never used for path being filled et = IClipper.EndType.CLOSED_LINE; } else { et = endType; } List<com.itextpdf.kernel.geom.Point> linearApproxPoints = subpath.getPiecewiseLinearApproximation(); offset.addPath(new Path(convertToLongPoints(linearApproxPoints)), joinType, et); } } return degenerateSubpaths; }
public Path(List<? extends Subpath> subpaths) { addSubpaths(subpaths); }
/** * {@inheritDoc} */ public void invoke(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands) { float x1 = ((PdfNumber) operands.get(0)).floatValue(); float y1 = ((PdfNumber) operands.get(1)).floatValue(); float x3 = ((PdfNumber) operands.get(2)).floatValue(); float y3 = ((PdfNumber) operands.get(3)).floatValue(); processor.currentPath.curveFromTo(x1, y1, x3, y3); } }
static void addContour(com.itextpdf.kernel.geom.Path path, List<Point.LongPoint> contour, boolean close) { List<com.itextpdf.kernel.geom.Point> floatContour = convertToFloatPoints(contour); com.itextpdf.kernel.geom.Point point = floatContour.get(0); path.moveTo((float) point.getX(), (float) point.getY()); for (int i = 1; i < floatContour.size(); i++) { point = floatContour.get(i); path.lineTo((float) point.getX(), (float) point.getY()); } if (close) { path.closeSubpath(); } }
/** * Resets the graphics state stack, matrices and resources. */ public void reset() { gsStack.removeAllElements(); gsStack.push(new ParserGraphicsState()); textMatrix = null; textLineMatrix = null; resourcesStack = new Stack<>(); isClip = false; currentPath = new Path(); }
/** * Appends a cubic Bezier curve to the current path. The curve shall extend from * the current point to the point <CODE>(x3, y3)</CODE> with the note that the current * point represents two control points. */ public void curveTo(float x2, float y2, float x3, float y3) { if (currentPoint == null) { throw new RuntimeException(START_PATH_ERR_MSG); } curveTo((float) currentPoint.getX(), (float) currentPoint.getY(), x2, y2, x3, y3); }
/** * {@inheritDoc} */ public void invoke(PdfCanvasProcessor processor, PdfLiteral operator, List<PdfObject> operands) { if (close) { processor.currentPath.closeSubpath(); } processor.paintPath(operation, rule); } }
/** * Appends a cubic Bezier curve to the current path. The curve shall extend from * the current point to the point <CODE>(x3, y3)</CODE>. * @param x1 x-coordinate of the first control point * @param y1 y-coordinate of the first control point * @param x2 x-coordinate of the second control point * @param y2 y-coordinate of the second control point * @param x3 x-coordinate of the third control point * @param y3 y-coordinate of the third control point */ public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) { if (currentPoint == null) { throw new RuntimeException(START_PATH_ERR_MSG); } // Numbered in natural order Point secondPoint = new Point(x1, y1); Point thirdPoint = new Point(x2, y2); Point fourthPoint = new Point(x3, y3); List<Point> controlPoints = new ArrayList<>(Arrays.asList(currentPoint, secondPoint, thirdPoint, fourthPoint)); getLastSubpath().addSegment(new BezierCurve(controlPoints)); currentPoint = fourthPoint; }
/** * Adds iText {@link Path} to the given {@link IClipper} object. * @param clipper The {@link IClipper} object. * @param path The {@link com.itextpdf.kernel.geom.Path} object to be added to the {@link IClipper}. * @param polyType See {@link IClipper.PolyType}. */ public static void addPath(IClipper clipper, com.itextpdf.kernel.geom.Path path, IClipper.PolyType polyType) { for (Subpath subpath : path.getSubpaths()) { if (!subpath.isSinglePointClosed() && !subpath.isSinglePointOpen()) { List<com.itextpdf.kernel.geom.Point> linearApproxPoints = subpath.getPiecewiseLinearApproximation(); clipper.addPath(new Path(convertToLongPoints(linearApproxPoints)), polyType, subpath.isClosed()); } } }