RED-6369: Rules Refactor
* fixed AnnotationService with new Coordinates * fixed bug in split boundary function
This commit is contained in:
parent
59827eab81
commit
9d8e544d0c
@ -92,6 +92,11 @@ public class Boundary implements Comparable<Boundary> {
|
|||||||
List<Boundary> splitBoundaries = new LinkedList<>();
|
List<Boundary> splitBoundaries = new LinkedList<>();
|
||||||
int previousIndex = start;
|
int previousIndex = start;
|
||||||
for (int splitIndex : splitIndices) {
|
for (int splitIndex : splitIndices) {
|
||||||
|
|
||||||
|
// skip split if it would produce a boundary of length 0
|
||||||
|
if (splitIndex == previousIndex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
splitBoundaries.add(new Boundary(previousIndex, splitIndex));
|
splitBoundaries.add(new Boundary(previousIndex, splitIndex));
|
||||||
previousIndex = splitIndex;
|
previousIndex = splitIndex;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,8 @@ import java.util.function.Function;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collector;
|
import java.util.stream.Collector;
|
||||||
|
|
||||||
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
|
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Point;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Point;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Rectangle;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.AtomicTextBlock;
|
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.AtomicTextBlock;
|
||||||
@ -39,6 +41,12 @@ public class RectangleTransformations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Rectangle2D bBoxUnionRectangle(List<Rectangle> rectangles) {
|
||||||
|
|
||||||
|
return rectangles.stream().map(RectangleTransformations::toRectangle2D).collect(new Rectangle2DUnion());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Rectangle2D rectangleUnion(List<Rectangle2D> rectangle2DList) {
|
public static Rectangle2D rectangleUnion(List<Rectangle2D> rectangle2DList) {
|
||||||
|
|
||||||
return rectangle2DList.stream().collect(new Rectangle2DUnion());
|
return rectangle2DList.stream().collect(new Rectangle2DUnion());
|
||||||
@ -57,6 +65,34 @@ public class RectangleTransformations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Rectangle2D toRectangle2D(Rectangle rectangle) {
|
||||||
|
|
||||||
|
return new Rectangle2D.Double(rectangle.getTopLeft().getX() - rectangle.getWidth(),
|
||||||
|
rectangle.getTopLeft().getY() - rectangle.getHeight(),
|
||||||
|
rectangle.getWidth(),
|
||||||
|
rectangle.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Rectangle2D toRectangle2D(PDRectangle rectangle) {
|
||||||
|
|
||||||
|
return new Rectangle2D.Double(rectangle.getLowerLeftX(), rectangle.getLowerLeftY(), rectangle.getWidth(), rectangle.getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static PDRectangle toPDRectangleUnion(List<Rectangle> rectangles) {
|
||||||
|
|
||||||
|
Rectangle2D rectangle2D = RectangleTransformations.bBoxUnionRectangle(rectangles);
|
||||||
|
|
||||||
|
PDRectangle annotationPosition = new PDRectangle();
|
||||||
|
annotationPosition.setLowerLeftX((float) rectangle2D.getMinX());
|
||||||
|
annotationPosition.setLowerLeftY((float) rectangle2D.getMinY());
|
||||||
|
annotationPosition.setUpperRightX((float) rectangle2D.getMaxX());
|
||||||
|
annotationPosition.setUpperRightY((float) rectangle2D.getMaxY());
|
||||||
|
return annotationPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Rectangle toRectangle(Rectangle2D rectangle2D, int pageNumber) {
|
public static Rectangle toRectangle(Rectangle2D rectangle2D, int pageNumber) {
|
||||||
|
|
||||||
return new Rectangle(new Point((float) rectangle2D.getMaxX(), (float) rectangle2D.getMaxY()), (float) rectangle2D.getWidth(), (float) rectangle2D.getHeight(), pageNumber);
|
return new Rectangle(new Point((float) rectangle2D.getMaxX(), (float) rectangle2D.getMaxY()), (float) rectangle2D.getWidth(), (float) rectangle2D.getHeight(), pageNumber);
|
||||||
|
|||||||
@ -76,7 +76,7 @@ public class DocumentDataMapper {
|
|||||||
.tocId(toPrimitiveIntArray(entry.tocId()))
|
.tocId(toPrimitiveIntArray(entry.tocId()))
|
||||||
.subEntries(entry.children().stream().map(this::toEntryData).toList())
|
.subEntries(entry.children().stream().map(this::toEntryData).toList())
|
||||||
.type(entry.type())
|
.type(entry.type())
|
||||||
.atomicTextBlocks(atomicTextBlocks)
|
.atomicBlocks(atomicTextBlocks)
|
||||||
.pages(entry.node().getPages().stream().map(PageNode::getNumber).map(Integer::longValue).toArray(Long[]::new))
|
.pages(entry.node().getPages().stream().map(PageNode::getNumber).map(Integer::longValue).toArray(Long[]::new))
|
||||||
.properties(properties)
|
.properties(properties)
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
@ -1,22 +1,24 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.utils;
|
package com.iqser.red.service.redaction.v1.server.visualization.service;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||||
|
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.DocumentGraph;
|
import com.iqser.red.service.redaction.v1.server.document.graph.DocumentGraph;
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.PageNode;
|
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.TableOfContents;
|
import com.iqser.red.service.redaction.v1.server.document.graph.TableOfContents;
|
||||||
|
import com.iqser.red.service.redaction.v1.server.document.graph.factory.RectangleTransformations;
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.NodeType;
|
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.NodeType;
|
||||||
|
import com.iqser.red.service.redaction.v1.server.document.graph.nodes.PageNode;
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.AtomicTextBlock;
|
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.AtomicTextBlock;
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.TextBlock;
|
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.TextBlock;
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.factory.RectangleTransformations;
|
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@ -80,6 +82,12 @@ public class PdfDraw {
|
|||||||
public static void drawRectangle2DList(PDDocument document, int pageNumber, List<Rectangle2D> rectCollection, Options options) {
|
public static void drawRectangle2DList(PDDocument document, int pageNumber, List<Rectangle2D> rectCollection, Options options) {
|
||||||
|
|
||||||
var pdPage = document.getPage(pageNumber - 1);
|
var pdPage = document.getPage(pageNumber - 1);
|
||||||
|
drawRectangle2DList(document, rectCollection, options, pdPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void drawRectangle2DList(PDDocument document, List<Rectangle2D> rectCollection, Options options, PDPage pdPage) throws IOException {
|
||||||
|
|
||||||
var contentStream = new PDPageContentStream(document, pdPage, PDPageContentStream.AppendMode.APPEND, true);
|
var contentStream = new PDPageContentStream(document, pdPage, PDPageContentStream.AppendMode.APPEND, true);
|
||||||
|
|
||||||
contentStream.setStrokingColor(options.getStrokeColor());
|
contentStream.setStrokingColor(options.getStrokeColor());
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server;
|
package com.iqser.red.service.redaction.v1.server;
|
||||||
|
|
||||||
import static com.iqser.red.service.redaction.v1.server.redaction.utils.SeparatorUtils.boundaryIsSurroundedBySeparators;
|
import static com.iqser.red.service.redaction.v1.server.redaction.utils.SeparatorUtils.boundaryIsSurroundedBySeparators;
|
||||||
import static com.iqser.red.service.redaction.v1.server.utils.PdfDraw.drawRectangle2DList;
|
import static com.iqser.red.service.redaction.v1.server.visualization.service.PdfDraw.drawRectangle2DList;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
@ -35,7 +35,7 @@ import com.iqser.red.service.redaction.v1.server.redaction.service.DictionarySer
|
|||||||
import com.iqser.red.service.redaction.v1.server.redaction.service.RedactionLogCreatorService;
|
import com.iqser.red.service.redaction.v1.server.redaction.service.RedactionLogCreatorService;
|
||||||
import com.iqser.red.service.redaction.v1.server.redaction.utils.SearchImplementation;
|
import com.iqser.red.service.redaction.v1.server.redaction.utils.SearchImplementation;
|
||||||
import com.iqser.red.service.redaction.v1.server.segmentation.PdfSegmentationService;
|
import com.iqser.red.service.redaction.v1.server.segmentation.PdfSegmentationService;
|
||||||
import com.iqser.red.service.redaction.v1.server.utils.PdfDraw;
|
import com.iqser.red.service.redaction.v1.server.visualization.service.PdfDraw;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.annotate;
|
package com.iqser.red.service.redaction.v1.server.annotate;
|
||||||
|
|
||||||
|
import static com.iqser.red.service.redaction.v1.server.document.graph.factory.RectangleTransformations.toPDRectangleUnion;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -9,6 +12,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.pdfbox.io.MemoryUsageSetting;
|
import org.apache.pdfbox.io.MemoryUsageSetting;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
@ -22,13 +26,17 @@ import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
|
|||||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationText;
|
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationText;
|
||||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup;
|
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationTextMarkup;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.*;
|
|
||||||
|
import com.google.common.primitives.Floats;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Rectangle;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLog;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLogComment;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLogComment;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLogEntry;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLogEntry;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.CellRectangle;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.CellRectangle;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionGrid;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionGrid;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionRectangle;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionRectangle;
|
||||||
|
import com.iqser.red.service.redaction.v1.server.document.graph.factory.RectangleTransformations;
|
||||||
import com.iqser.red.service.redaction.v1.server.exception.RedactionException;
|
import com.iqser.red.service.redaction.v1.server.exception.RedactionException;
|
||||||
import com.iqser.red.service.redaction.v1.server.redaction.service.DictionaryService;
|
import com.iqser.red.service.redaction.v1.server.redaction.service.DictionaryService;
|
||||||
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
||||||
@ -43,7 +51,20 @@ public class AnnotationService {
|
|||||||
private final DictionaryService dictionaryService;
|
private final DictionaryService dictionaryService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method draws a PDF Text Markup Annotation for each RedactionLogEntry and the section grid.
|
||||||
|
* A Text Markup Annotation has two main functionalities.
|
||||||
|
* First, it highlights text with a color and second, when hovered over in a PDF Viewer it displays a popup message.
|
||||||
|
* Where the Popup message appears is defined by the Rectangle provided to the Annotation.
|
||||||
|
* Further, the highlighted text regions are identified by multiple quad points which are represented by 8 floats each, which identify the four corners.
|
||||||
|
* According to the PDF specification, these points should be provided in counterclockwise fashion.
|
||||||
|
* Experiments have shown, PDFBox requires them to be provided in Z-like fashion as such: top-left, top-right, bottom-left, bottom-right
|
||||||
|
* If multiple regions should be highlighted per annotation, the quad points need to be concatenated
|
||||||
|
* For a more detailed information look in the PDF Specification 12.5.6.10
|
||||||
|
*
|
||||||
|
* @param annotateRequest containing the SectionGrid, RedactionLog, ManualRedactions and the colors for the highlights
|
||||||
|
* @return the annotated PDFDoc
|
||||||
|
*/
|
||||||
public AnnotateResponse annotate(AnnotateRequest annotateRequest) {
|
public AnnotateResponse annotate(AnnotateRequest annotateRequest) {
|
||||||
|
|
||||||
var storedObjectStream = redactionStorageService.getStoredObject(RedactionStorageService.StorageIdUtils.getStorageId(annotateRequest.getDossierId(),
|
var storedObjectStream = redactionStorageService.getStoredObject(RedactionStorageService.StorageIdUtils.getStorageId(annotateRequest.getDossierId(),
|
||||||
@ -96,12 +117,12 @@ public class AnnotationService {
|
|||||||
List<PDAnnotation> annotations = pdPage.getAnnotations();
|
List<PDAnnotation> annotations = pdPage.getAnnotations();
|
||||||
|
|
||||||
for (RedactionLogEntry entry : logEntries) {
|
for (RedactionLogEntry entry : logEntries) {
|
||||||
annotations.addAll(createAnnotation(entry, page, pdPage.getMediaBox(), pdPage.getCropBox()));
|
annotations.addAll(createAnnotation(entry, page, pdPage.getRotation(), pdPage.getCropBox()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<PDAnnotation> createAnnotation(RedactionLogEntry redactionLogEntry, int page, PDRectangle mediaBox, PDRectangle cropBox) {
|
private List<PDAnnotation> createAnnotation(RedactionLogEntry redactionLogEntry, int page, int rotation, PDRectangle cropBox) {
|
||||||
|
|
||||||
List<PDAnnotation> annotations = new ArrayList<>();
|
List<PDAnnotation> annotations = new ArrayList<>();
|
||||||
|
|
||||||
@ -113,9 +134,9 @@ public class AnnotationService {
|
|||||||
|
|
||||||
PDAnnotationTextMarkup annotation = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
|
PDAnnotationTextMarkup annotation = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT);
|
||||||
annotation.constructAppearances();
|
annotation.constructAppearances();
|
||||||
PDRectangle pdRectangle = toPDRectangle(rectangles, mediaBox, cropBox);
|
PDRectangle pdRectangle = toPDRectangleUnion(rectangles);
|
||||||
annotation.setRectangle(pdRectangle);
|
annotation.setRectangle(pdRectangle);
|
||||||
annotation.setQuadPoints(toQuadPoints(rectangles, mediaBox, cropBox));
|
annotation.setQuadPoints(Floats.toArray(toQuadPoints(rectangles)));
|
||||||
if (!redactionLogEntry.isHint()) {
|
if (!redactionLogEntry.isHint()) {
|
||||||
annotation.setContents(redactionLogEntry.getValue() + " " + createAnnotationContent(redactionLogEntry));
|
annotation.setContents(redactionLogEntry.getValue() + " " + createAnnotationContent(redactionLogEntry));
|
||||||
}
|
}
|
||||||
@ -151,72 +172,26 @@ public class AnnotationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private PDRectangle toPDRectangle(List<Rectangle> rectangles, PDRectangle mediaBox, PDRectangle cropBox) {
|
public static List<Double> toQuadPoints(List<Rectangle> rectangles) {
|
||||||
|
|
||||||
float lowerLeftX = Float.MAX_VALUE;
|
return rectangles.stream().map(RectangleTransformations::toRectangle2D).flatMap(AnnotationService::toQuadPoints).toList();
|
||||||
float upperRightX = 0;
|
|
||||||
float lowerLeftY = 0;
|
|
||||||
float upperRightY = Float.MAX_VALUE;
|
|
||||||
|
|
||||||
for (Rectangle rectangle : rectangles) {
|
|
||||||
if (rectangle.getTopLeft().getX() < lowerLeftX) {
|
|
||||||
lowerLeftX = rectangle.getTopLeft().getX();
|
|
||||||
}
|
|
||||||
if (rectangle.getTopLeft().getX() + rectangle.getWidth() > upperRightX) {
|
|
||||||
upperRightX = rectangle.getTopLeft().getX() + rectangle.getWidth();
|
|
||||||
}
|
|
||||||
if (rectangle.getTopLeft().getY() + rectangle.getHeight() > lowerLeftY) {
|
|
||||||
lowerLeftY = rectangle.getTopLeft().getY() + rectangle.getHeight();
|
|
||||||
}
|
|
||||||
if (rectangle.getTopLeft().getY() < upperRightY) {
|
|
||||||
upperRightY = rectangle.getTopLeft().getY();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var x1 = lowerLeftX + cropBox.getLowerLeftX() - mediaBox.getLowerLeftY();
|
|
||||||
var y1 = lowerLeftY + (mediaBox.getLowerLeftY() - cropBox.getLowerLeftY());
|
|
||||||
var x2 = upperRightX + cropBox.getLowerLeftX() - mediaBox.getLowerLeftY();
|
|
||||||
var y2 = upperRightY - (mediaBox.getLowerLeftY() - cropBox.getLowerLeftY());
|
|
||||||
|
|
||||||
PDRectangle annotationPosition = new PDRectangle();
|
|
||||||
annotationPosition.setLowerLeftX(x1);
|
|
||||||
annotationPosition.setLowerLeftY(y1);
|
|
||||||
annotationPosition.setUpperRightX(x2);
|
|
||||||
annotationPosition.setUpperRightY(y2);
|
|
||||||
return annotationPosition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private float[] toQuadPoints(List<Rectangle> rectangles, PDRectangle mediaBox, PDRectangle cropBox) {
|
public static Stream<Double> toQuadPoints(Rectangle2D rectangle) {
|
||||||
|
|
||||||
float[] quadPoints = new float[rectangles.size() * 8];
|
double x1 = rectangle.getMinX();
|
||||||
int i = 0;
|
double y1 = rectangle.getMinY();
|
||||||
|
|
||||||
for (Rectangle rectangle : rectangles) {
|
double x2 = rectangle.getMaxX();
|
||||||
float[] quadPoint = toQuadPoint(rectangle, mediaBox, cropBox);
|
double y2 = rectangle.getMinY();
|
||||||
for (int j = 0; j <= 7; j++) {
|
|
||||||
quadPoints[i + j] = quadPoint[j];
|
|
||||||
}
|
|
||||||
i += 8;
|
|
||||||
}
|
|
||||||
return quadPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
double x3 = rectangle.getMaxX();
|
||||||
|
double y3 = rectangle.getMaxY();
|
||||||
|
|
||||||
private float[] toQuadPoint(Rectangle rectangle, PDRectangle mediaBox, PDRectangle cropBox) {
|
double x4 = rectangle.getMinX();
|
||||||
|
double y4 = rectangle.getMaxY();
|
||||||
var x1 = rectangle.getTopLeft().getX() + cropBox.getLowerLeftX() - mediaBox.getLowerLeftX() + (cropBox.toString()
|
return Stream.of(x4, y4, x3, y3, x1, y1, x2, y2);
|
||||||
.equals(mediaBox.toString()) ? cropBox.getLowerLeftX() : 0f);
|
|
||||||
var y1 = rectangle.getTopLeft().getY() + (mediaBox.getLowerLeftY() - cropBox.getLowerLeftY()) + (cropBox.toString()
|
|
||||||
.equals(mediaBox.toString()) ? cropBox.getLowerLeftY() : 0f);
|
|
||||||
var x2 = rectangle.getTopLeft().getX() + rectangle.getWidth() + cropBox.getLowerLeftX() - mediaBox.getLowerLeftX() + (cropBox.toString()
|
|
||||||
.equals(mediaBox.toString()) ? cropBox.getLowerLeftX() : 0f);
|
|
||||||
var y2 = rectangle.getTopLeft().getY() + rectangle.getHeight() - (mediaBox.getLowerLeftY() - cropBox.getLowerLeftY()) + (cropBox.toString()
|
|
||||||
.equals(mediaBox.toString()) ? cropBox.getLowerLeftY() : 0f);
|
|
||||||
|
|
||||||
// quadPoints is array of x,y coordinates in Z-like order (top-left, top-right, bottom-left,bottom-right)
|
|
||||||
// of the area to be highlighted
|
|
||||||
return new float[]{x1, y1, x2, y2, x1, y2 - rectangle.getHeight(), x2, y1 - rectangle.getHeight()};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,7 @@ class BoundaryTest {
|
|||||||
assertEquals(List.of(new Boundary(10, 12), new Boundary(12, 40), new Boundary(40, 90), new Boundary(90, 100)), startBoundary.split(List.of(12, 40, 90)));
|
assertEquals(List.of(new Boundary(10, 12), new Boundary(12, 40), new Boundary(40, 90), new Boundary(90, 100)), startBoundary.split(List.of(12, 40, 90)));
|
||||||
assertEquals(List.of(new Boundary(10, 40), new Boundary(40, 100)), startBoundary.split(List.of(40)));
|
assertEquals(List.of(new Boundary(10, 40), new Boundary(40, 100)), startBoundary.split(List.of(40)));
|
||||||
assertEquals(1, startBoundary.split(Collections.emptyList()).size());
|
assertEquals(1, startBoundary.split(Collections.emptyList()).size());
|
||||||
|
assertEquals(1, startBoundary.split(List.of(startBoundary.start())).size());
|
||||||
assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(Collections.singletonList(0)));
|
assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(Collections.singletonList(0)));
|
||||||
assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(Collections.singletonList(100)));
|
assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(Collections.singletonList(100)));
|
||||||
assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(List.of(12, 40, 100)));
|
assertThrows(IndexOutOfBoundsException.class, () -> startBoundary.split(List.of(12, 40, 100)));
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.TextBlock;
|
import com.iqser.red.service.redaction.v1.server.document.graph.textblock.TextBlock;
|
||||||
import com.iqser.red.service.redaction.v1.server.utils.PdfDraw;
|
import com.iqser.red.service.redaction.v1.server.visualization.service.PdfDraw;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user