Merge branch 'RED-8800-bp' into 'release/0.142.x'

Red 8800 bp

See merge request fforesight/layout-parser!180
This commit is contained in:
Kilian Schüttler 2024-07-15 17:58:59 +02:00
commit c3d24393ea
2 changed files with 54 additions and 12 deletions

View File

@ -82,6 +82,7 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine {
private int pageRotation; private int pageRotation;
private PDRectangle pageSize; private PDRectangle pageSize;
private Matrix translateMatrix;
private final GlyphList glyphList; private final GlyphList glyphList;
private final Map<COSDictionary, Float> fontHeightMap = new WeakHashMap<COSDictionary, Float>(); private final Map<COSDictionary, Float> fontHeightMap = new WeakHashMap<COSDictionary, Float>();
@ -133,6 +134,12 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine {
this.pageRotation = page.getRotation(); this.pageRotation = page.getRotation();
this.pageSize = page.getCropBox(); 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); super.processPage(page);
} }
@ -257,13 +264,22 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine {
return; 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 // This is a hack for unicode letter with 2 chars e.g. RA see unicodeProblem.pdf
if (unicodeMapping.length() == 2) { if (unicodeMapping.length() == 2) {
processTextPosition(new TextPosition(pageRotation, processTextPosition(new TextPosition(pageRotation,
pageSize.getWidth(), pageSize.getWidth(),
pageSize.getHeight(), pageSize.getHeight(),
textRenderingMatrix, translatedTextRenderingMatrix,
nextX, nextX,
nextY, nextY,
Math.abs(dyDisplay), Math.abs(dyDisplay),
@ -277,7 +293,7 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine {
processTextPosition(new TextPosition(pageRotation, processTextPosition(new TextPosition(pageRotation,
pageSize.getWidth(), pageSize.getWidth(),
pageSize.getHeight(), pageSize.getHeight(),
textRenderingMatrix, translatedTextRenderingMatrix,
nextX, nextX,
nextY, nextY,
Math.abs(dyDisplay), Math.abs(dyDisplay),
@ -293,7 +309,7 @@ public class LegacyPDFStreamEngine extends PDFStreamEngine {
processTextPosition(new TextPosition(pageRotation, processTextPosition(new TextPosition(pageRotation,
pageSize.getWidth(), pageSize.getWidth(),
pageSize.getHeight(), pageSize.getHeight(),
textRenderingMatrix, translatedTextRenderingMatrix,
nextX, nextX,
nextY, nextY,
Math.abs(dyDisplay), Math.abs(dyDisplay),

View File

@ -1,6 +1,7 @@
package com.knecon.fforesight.service.viewerdoc.service; package com.knecon.fforesight.service.viewerdoc.service;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -84,6 +85,7 @@ public class ViewerDocumentService {
pdPage.setContents(ContentStreamUtility.removeLayerFromContentStreams(allLayers, classifiers)); pdPage.setContents(ContentStreamUtility.removeLayerFromContentStreams(allLayers, classifiers));
AffineTransform textDeRotationMatrix = getTextDeRotationTransform(pdPage); AffineTransform textDeRotationMatrix = getTextDeRotationTransform(pdPage);
AffineTransform pageTransformationMatrix = getPageTransformationMatrix(pdPage);
if (!ContentStreamClassifier.areAllContentStreamsEscaped(classifiers)) { 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, // 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(); contentStream.saveGraphicsState();
drawVisualizationsToContentStream(pdDocument, visualization.getVisualizationsOnPages().get(pageNumber), contentStream, textDeRotationMatrix); drawVisualizationsToContentStream(pdDocument,
visualization.getVisualizationsOnPages().get(pageNumber),
contentStream,
textDeRotationMatrix,
pageTransformationMatrix);
contentStream.restoreGraphicsState(); 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<ContentStreams.Identifier, PDOptionalContentGroup> addLayersToDocument(List<Visualizations> visualizations, PDDocument pdDocument) { private static Map<ContentStreams.Identifier, PDOptionalContentGroup> addLayersToDocument(List<Visualizations> visualizations, PDDocument pdDocument) {
Map<ContentStreams.Identifier, PDOptionalContentGroup> optionalContentGroupMap = new HashMap<>(); Map<ContentStreams.Identifier, PDOptionalContentGroup> optionalContentGroupMap = new HashMap<>();
@ -147,7 +159,8 @@ public class ViewerDocumentService {
private static void drawVisualizationsToContentStream(PDDocument pdDocument, private static void drawVisualizationsToContentStream(PDDocument pdDocument,
VisualizationsOnPage visualizationsOnPage, VisualizationsOnPage visualizationsOnPage,
PDPageContentStream contentStream, PDPageContentStream contentStream,
AffineTransform textDeRotationMatrix) throws IOException { AffineTransform textDeRotationMatrix,
AffineTransform pageTransformationMatrix) throws IOException {
if (visualizationsOnPage.isMakePathsInvisible()) { if (visualizationsOnPage.isMakePathsInvisible()) {
contentStream.addRect(0, 0, 1, 1); contentStream.addRect(0, 0, 1, 1);
@ -155,17 +168,18 @@ public class ViewerDocumentService {
} }
for (ColoredLine coloredLine : visualizationsOnPage.getColoredLines()) { for (ColoredLine coloredLine : visualizationsOnPage.getColoredLines()) {
Line2D line = transformLine(coloredLine.line(), pageTransformationMatrix);
contentStream.setLineWidth(coloredLine.lineWidth()); contentStream.setLineWidth(coloredLine.lineWidth());
contentStream.setStrokingColor(coloredLine.color()); contentStream.setStrokingColor(coloredLine.color());
contentStream.moveTo((float) coloredLine.line().getX1(), (float) coloredLine.line().getY1()); contentStream.moveTo((float) line.getX1(), (float) line.getY1());
contentStream.lineTo((float) coloredLine.line().getX2(), (float) coloredLine.line().getY2()); contentStream.lineTo((float) line.getX2(), (float) line.getY2());
contentStream.stroke(); contentStream.stroke();
} }
for (ColoredRectangle coloredRectangle : visualizationsOnPage.getColoredRectangles()) { for (ColoredRectangle coloredRectangle : visualizationsOnPage.getColoredRectangles()) {
contentStream.setLineWidth(coloredRectangle.lineWidth()); contentStream.setLineWidth(coloredRectangle.lineWidth());
contentStream.setStrokingColor(coloredRectangle.color()); 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.addRect((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight());
contentStream.stroke(); contentStream.stroke();
} }
@ -175,7 +189,7 @@ public class ViewerDocumentService {
PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState(); PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
graphicsState.setNonStrokingAlphaConstant(filledRectangle.alpha()); graphicsState.setNonStrokingAlphaConstant(filledRectangle.alpha());
contentStream.setGraphicsStateParameters(graphicsState); 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.addRect((float) r.getX(), (float) r.getY(), (float) r.getWidth(), (float) r.getHeight());
contentStream.fill(); contentStream.fill();
} }
@ -190,7 +204,7 @@ public class ViewerDocumentService {
} else { } else {
contentStream.setRenderingMode(RenderingMode.FILL); contentStream.setRenderingMode(RenderingMode.FILL);
} }
Matrix textMatrix = getTextMatrix(placedText, textDeRotationMatrix); Matrix textMatrix = getTextMatrix(placedText, textDeRotationMatrix, pageTransformationMatrix);
contentStream.setTextMatrix(textMatrix); contentStream.setTextMatrix(textMatrix);
contentStream.showText(placedText.text()); contentStream.showText(placedText.text());
contentStream.endText(); 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; Matrix textMatrix;
if (placedText.textMatrix().isEmpty()) { if (placedText.textMatrix().isEmpty()) {
@ -236,7 +250,7 @@ public class ViewerDocumentService {
} else { } else {
textMatrix = placedText.textMatrix().get(); 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();
}
} }