use of com.itextpdf.kernel.pdf.canvas.PdfCanvas 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();
}
}
use of com.itextpdf.kernel.pdf.canvas.PdfCanvas in project i7j-pdfsweep by itext.
the class PdfCleanUpProcessor method popCanvasIfFormXObject.
private void popCanvasIfFormXObject(String operator, List<PdfObject> operands) {
if ("Do".equals(operator)) {
PdfStream formStream = getXObjectStream((PdfName) operands.get(0));
if (PdfName.Form.equals(formStream.getAsName(PdfName.Subtype))) {
PdfCanvas cleanedCanvas = popCleanedCanvas();
PdfFormXObject newFormXObject = new PdfFormXObject((Rectangle) null);
newFormXObject.getPdfObject().putAll(formStream);
if (formStream.containsKey(PdfName.Resources)) {
newFormXObject.put(PdfName.Resources, cleanedCanvas.getResources().getPdfObject());
}
newFormXObject.getPdfObject().setData(cleanedCanvas.getContentStream().getBytes());
PdfName name = getCanvas().getResources().addForm(newFormXObject);
getCanvas().getContentStream().getOutputStream().write(name).writeSpace().writeBytes(ByteUtils.getIsoBytes("Do\n"));
}
}
}
use of com.itextpdf.kernel.pdf.canvas.PdfCanvas in project i7j-pdfsweep by itext.
the class PdfCleanUpTool method removeRedactAnnots.
/**
* Remove the redaction annotations.
* This method is called after the annotations are processed.
*
* @throws IOException
*/
private void removeRedactAnnots() throws IOException {
for (PdfRedactAnnotation annotation : redactAnnotations.keySet()) {
PdfPage page = annotation.getPage();
if (page != null) {
page.removeAnnotation(annotation);
PdfPopupAnnotation popup = annotation.getPopup();
if (popup != null) {
page.removeAnnotation(popup);
}
}
PdfCanvas canvas = new PdfCanvas(page);
PdfStream redactRolloverAppearance = annotation.getRedactRolloverAppearance();
PdfString overlayText = annotation.getOverlayText();
Rectangle annotRect = annotation.getRectangle().toRectangle();
if (redactRolloverAppearance != null) {
drawRolloverAppearance(canvas, redactRolloverAppearance, annotRect, redactAnnotations.get(annotation));
} else if (overlayText != null && !overlayText.toUnicodeString().isEmpty()) {
drawOverlayText(canvas, overlayText.toUnicodeString(), annotRect, annotation.getRepeat(), annotation.getDefaultAppearance(), annotation.getJustification());
}
}
}
use of com.itextpdf.kernel.pdf.canvas.PdfCanvas in project i7j-pdfsweep by itext.
the class PdfAutoSweepTools method highlight.
/**
* Highlight areas of interest in a given {@link PdfPage}
*
* @param pdfPage the {@link PdfPage} to be highlighted
*/
public void highlight(PdfPage pdfPage) {
List<PdfCleanUpLocation> cleanUpLocations = getPdfCleanUpLocations(pdfPage);
for (PdfCleanUpLocation loc : cleanUpLocations) {
PdfCanvas canvas = new PdfCanvas(pdfPage);
canvas.setColor(loc.getCleanUpColor(), true);
canvas.rectangle(loc.getRegion());
canvas.fill();
}
}
Aggregations