diff --git a/src/main/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalService.java b/src/main/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalService.java index fe7ba36..6d99256 100644 --- a/src/main/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalService.java +++ b/src/main/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalService.java @@ -8,6 +8,7 @@ import java.awt.geom.Rectangle2D; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -46,6 +47,7 @@ public class InvisibleElementRemovalService { * handled cases: * -Text which is transparent or is set to not render * -Elements outside of clipping path + * -Elements outside of Form XObjects * -Elements that have been painted over by visible and filled Paths * -Elements with the same color as background * unhandled cases: @@ -235,6 +237,8 @@ public class InvisibleElementRemovalService { // writer needs to be newly initialized when entering a new content stream // see ElementEditTest in PDFTron (https://www.pdftron.com/documentation/samples/android/java/ElementEditTest) ElementWriter formWriter = new ElementWriter(); + context.clippingPathStack().enterNewGState(); + context.clippingPathStack().intersectClippingPath(new GeneralPath(Converter.toRectangle2D(formElement.getBBox()))); context.reader().formBegin(); formWriter.begin(formObj); @@ -245,6 +249,7 @@ public class InvisibleElementRemovalService { formWriter.end(); formWriter.destroy(); context.reader().end(); + context.clippingPathStack().leaveGState(); } } diff --git a/src/test/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalServiceTest.java b/src/test/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalServiceTest.java index 556546c..d817678 100644 --- a/src/test/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalServiceTest.java +++ b/src/test/java/com/iqser/red/pdftronlogic/commons/InvisibleElementRemovalServiceTest.java @@ -53,6 +53,34 @@ class InvisibleElementRemovalServiceTest { } + @Test + @SneakyThrows + void removeInvisibleTextClippedByFormObjects() { + + String fileName = "files/invisibleTextInNestedFormObjects.pdf"; + String resultFileName = OsUtils.createTmpFileName(fileName, "INVISIBLE_REMOVAL"); + String deltaResultFileName = OsUtils.createTmpFileName(fileName, "INVISIBLE_REMOVAL_DELTA"); + try (var in = this.getClass().getClassLoader().getResourceAsStream(fileName); var out = new FileOutputStream(resultFileName)) { + invisibleElementRemovalService.removeInvisibleElements(in, out, false); + } + + try (var in = this.getClass().getClassLoader().getResourceAsStream(fileName); var out = new FileOutputStream(deltaResultFileName)) { + invisibleElementRemovalService.removeInvisibleElements(in, out, true); + } + try (var in = new FileInputStream(resultFileName)) { + String text = extractAllTextFromDocument(in); + assertThat(text).isBlank(); + } + try (var in = new FileInputStream(deltaResultFileName)) { + String[] text = extractAllTextFromDocument(in).split("\n"); + assertThat(text).contains(":Bold S-enantiomer form if two codes are supplied", + "Red : Only observed in laboratory soil studies", + "Green : Observed in both laboratory soil studies and lysimeter leachate", + "Blue : Only observed in lysimeter leachate"); + } + } + + @Test @SneakyThrows void removeInvisibleElementsWithColoredBackground() { diff --git a/src/test/resources/files/invisibleTextInNestedFormObjects.pdf b/src/test/resources/files/invisibleTextInNestedFormObjects.pdf new file mode 100644 index 0000000..a655b3a Binary files /dev/null and b/src/test/resources/files/invisibleTextInNestedFormObjects.pdf differ