From d4500b879bd6199ce8ceadf2b9d15c222a241dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kilian=20Sch=C3=BCttler?= Date: Mon, 15 Jul 2024 17:58:59 +0200 Subject: [PATCH] Red 8800 bp --- .../parsing/LegacyPDFStreamEngine.java | 22 ++++++++-- .../service/ViewerDocumentService.java | 44 +++++++++++++++---- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/parsing/LegacyPDFStreamEngine.java b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/parsing/LegacyPDFStreamEngine.java index 326746d..560ea93 100644 --- a/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/parsing/LegacyPDFStreamEngine.java +++ b/layoutparser-service/layoutparser-service-processor/src/main/java/com/knecon/fforesight/service/layoutparser/processor/services/parsing/LegacyPDFStreamEngine.java @@ -82,6 +82,7 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine { private int pageRotation; private PDRectangle pageSize; + private Matrix translateMatrix; private final GlyphList glyphList; private final Map fontHeightMap = new WeakHashMap(); @@ -133,6 +134,12 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine { this.pageRotation = page.getRotation(); this.pageSize = page.getCropBox(); + if (pageSize.getLowerLeftX() == 0 && pageSize.getLowerLeftY() == 0) { + translateMatrix = null; + } else { + // translation matrix for cropbox + translateMatrix = Matrix.getTranslateInstance(-pageSize.getLowerLeftX(), -pageSize.getLowerLeftY()); + } super.processPage(page); } @@ -257,13 +264,22 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine { return; } } + // adjust for cropbox if needed + Matrix translatedTextRenderingMatrix; + if (translateMatrix == null) { + translatedTextRenderingMatrix = textRenderingMatrix; + } else { + translatedTextRenderingMatrix = Matrix.concatenate(translateMatrix, textRenderingMatrix); + nextX -= pageSize.getLowerLeftX(); + nextY -= pageSize.getLowerLeftY(); + } // This is a hack for unicode letter with 2 chars e.g. RA see unicodeProblem.pdf if (unicodeMapping.length() == 2) { processTextPosition(new TextPosition(pageRotation, pageSize.getWidth(), pageSize.getHeight(), - textRenderingMatrix, + translatedTextRenderingMatrix, nextX, nextY, Math.abs(dyDisplay), @@ -277,7 +293,7 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine { processTextPosition(new TextPosition(pageRotation, pageSize.getWidth(), pageSize.getHeight(), - textRenderingMatrix, + translatedTextRenderingMatrix, nextX, nextY, Math.abs(dyDisplay), @@ -293,7 +309,7 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine { processTextPosition(new TextPosition(pageRotation, pageSize.getWidth(), pageSize.getHeight(), - textRenderingMatrix, + translatedTextRenderingMatrix, nextX, nextY, Math.abs(dyDisplay), diff --git a/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java b/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java index 04233da..570900b 100644 --- a/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java +++ b/layoutparser-service/viewer-doc-processor/src/main/java/com/knecon/fforesight/service/viewerdoc/service/ViewerDocumentService.java @@ -1,6 +1,7 @@ package com.knecon.fforesight.service.viewerdoc.service; import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.FileOutputStream; @@ -84,6 +85,7 @@ public class ViewerDocumentService { pdPage.setContents(ContentStreamUtility.removeLayerFromContentStreams(allLayers, classifiers)); AffineTransform textDeRotationMatrix = getTextDeRotationTransform(pdPage); + AffineTransform pageTransformationMatrix = getPageTransformationMatrix(pdPage); if (!ContentStreamClassifier.areAllContentStreamsEscaped(classifiers)) { // We need to save the graphics state before, such that our appended content cannot be affected by previous content streams with side effects, @@ -106,7 +108,11 @@ public class ViewerDocumentService { contentStream.saveGraphicsState(); - drawVisualizationsToContentStream(pdDocument, visualization.getVisualizationsOnPages().get(pageNumber), contentStream, textDeRotationMatrix); + drawVisualizationsToContentStream(pdDocument, + visualization.getVisualizationsOnPages().get(pageNumber), + contentStream, + textDeRotationMatrix, + pageTransformationMatrix); contentStream.restoreGraphicsState(); @@ -133,6 +139,12 @@ public class ViewerDocumentService { } + private AffineTransform getPageTransformationMatrix(PDPage pdPage) { + + return new AffineTransform(1, 0, 0, 1, pdPage.getCropBox().getLowerLeftX(), pdPage.getCropBox().getLowerLeftY()); + } + + private static Map addLayersToDocument(List visualizations, PDDocument pdDocument) { Map optionalContentGroupMap = new HashMap<>(); @@ -147,7 +159,8 @@ public class ViewerDocumentService { private static void drawVisualizationsToContentStream(PDDocument pdDocument, VisualizationsOnPage visualizationsOnPage, PDPageContentStream contentStream, - AffineTransform textDeRotationMatrix) throws IOException { + AffineTransform textDeRotationMatrix, + AffineTransform pageTransformationMatrix) throws IOException { if (visualizationsOnPage.isMakePathsInvisible()) { contentStream.addRect(0, 0, 1, 1); @@ -155,17 +168,18 @@ public class ViewerDocumentService { } for (ColoredLine coloredLine : visualizationsOnPage.getColoredLines()) { + Line2D line = transformLine(coloredLine.line(), pageTransformationMatrix); contentStream.setLineWidth(coloredLine.lineWidth()); contentStream.setStrokingColor(coloredLine.color()); - contentStream.moveTo((float) coloredLine.line().getX1(), (float) coloredLine.line().getY1()); - contentStream.lineTo((float) coloredLine.line().getX2(), (float) coloredLine.line().getY2()); + contentStream.moveTo((float) line.getX1(), (float) line.getY1()); + contentStream.lineTo((float) line.getX2(), (float) line.getY2()); contentStream.stroke(); } for (ColoredRectangle coloredRectangle : visualizationsOnPage.getColoredRectangles()) { contentStream.setLineWidth(coloredRectangle.lineWidth()); contentStream.setStrokingColor(coloredRectangle.color()); - Rectangle2D r = coloredRectangle.rectangle2D(); + Rectangle2D r = transformRect(coloredRectangle.rectangle2D(), pageTransformationMatrix); contentStream.addRect((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight()); contentStream.stroke(); } @@ -175,7 +189,7 @@ public class ViewerDocumentService { PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState(); graphicsState.setNonStrokingAlphaConstant(filledRectangle.alpha()); contentStream.setGraphicsStateParameters(graphicsState); - Rectangle2D r = filledRectangle.rectangle2D(); + Rectangle2D r = transformRect(filledRectangle.rectangle2D(), pageTransformationMatrix); contentStream.addRect((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight()); contentStream.fill(); } @@ -190,7 +204,7 @@ public class ViewerDocumentService { } else { contentStream.setRenderingMode(RenderingMode.FILL); } - Matrix textMatrix = getTextMatrix(placedText, textDeRotationMatrix); + Matrix textMatrix = getTextMatrix(placedText, textDeRotationMatrix, pageTransformationMatrix); contentStream.setTextMatrix(textMatrix); contentStream.showText(placedText.text()); contentStream.endText(); @@ -223,7 +237,7 @@ public class ViewerDocumentService { } - private static Matrix getTextMatrix(PlacedText placedText, AffineTransform textDeRotationMatrix) { + private static Matrix getTextMatrix(PlacedText placedText, AffineTransform textDeRotationMatrix, AffineTransform pageTransformationMatrix) { Matrix textMatrix; if (placedText.textMatrix().isEmpty()) { @@ -236,7 +250,7 @@ public class ViewerDocumentService { } else { textMatrix = placedText.textMatrix().get(); } - return textMatrix; + return new Matrix(pageTransformationMatrix).multiply(textMatrix); } @@ -313,4 +327,16 @@ public class ViewerDocumentService { }); } + + private static Line2D transformLine(Line2D line, AffineTransform pageTransformation) { + + return new Line2D.Double(pageTransformation.transform(line.getP1(), null), pageTransformation.transform(line.getP2(), null)); + } + + + private static Rectangle2D transformRect(Rectangle2D r, AffineTransform pageTransformation) { + + return pageTransformation.createTransformedShape(r).getBounds2D(); + } + }