You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2024/12/16 16:57:09 UTC
svn commit: r1922536 - in /pdfbox/branches/2.0/pdfbox/src: main/java/org/apache/pdfbox/text/PDFTextStripper.java test/java/org/apache/pdfbox/text/TestTextStripper.java
Author: tilman
Date: Mon Dec 16 16:57:08 2024
New Revision: 1922536
URL: http://svn.apache.org/viewvc?rev=1922536&view=rev
Log:
PDFBOX-3774: conditionally ignore spaces from the content stream; add setting + getter/setter + test + code simplification by Kevin Day
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/PDFTextStripper.java
pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/text/TestTextStripper.java
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/PDFTextStripper.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/PDFTextStripper.java?rev=1922536&r1=1922535&r2=1922536&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/PDFTextStripper.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/PDFTextStripper.java Mon Dec 16 16:57:08 2024
@@ -146,6 +146,7 @@ public class PDFTextStripper extends Leg
private boolean shouldSeparateByBeads = true;
private boolean sortByPosition = false;
private boolean addMoreFormatting = false;
+ private boolean ignoreContentStreamSpaceGlyphs = false;
private float indentThreshold = defaultIndentThreshold;
private float dropThreshold = defaultDropThreshold;
@@ -526,11 +527,8 @@ public class PDFTextStripper extends Leg
{
IterativeMergeSort.sort(textList, comparator);
}
- finally
- {
- // PDFBOX-5487: Remove all space characters if contained within the adjacent letters
- removeContainedSpaces(textList);
- }
+ // PDFBOX-5487: Remove all space characters if contained within the adjacent letters
+ removeContainedSpaces(textList);
}
startArticle();
@@ -558,6 +556,12 @@ public class PDFTextStripper extends Leg
PositionWrapper current = new PositionWrapper(position);
String characterValue = position.getUnicode();
+ // PDFBOX-3774: conditionally ignore spaces from the content stream
+ if (" ".equals(characterValue) && getIgnoreContentStreamSpaceGlyphs())
+ {
+ continue;
+ }
+
// Resets the average character width when we see a change in font
// or a change in the font size
if (lastPosition != null && (position.getFont() != lastPosition.getTextPosition()
@@ -1286,6 +1290,32 @@ public class PDFTextStripper extends Leg
}
/**
+ * Determines whether spaces in the content stream text rendering instructions will be ignored
+ * during text extraction.
+ *
+ * @return true is space glyphs in the content stream text rendering instructions will be
+ * ignored - default is false
+ */
+ public boolean getIgnoreContentStreamSpaceGlyphs()
+ {
+ return ignoreContentStreamSpaceGlyphs;
+ }
+
+ /**
+ * Instruct the algorithm to ignore any spaces in the text rendering instructions in the content
+ * stream, and instead rely purely on the algorithm to determine where word breaks are.
+ *
+ * This can improve text extraction results where the content stream is sorted by position and
+ * has text overlapping spaces, but could cause some word breaks to not be added to the output
+ *
+ * @param newIgnoreContentStreamSpaceGlyphs whether PDF Box should ignore context stream spaces
+ */
+ public void setIgnoreContentStreamSpaceGlyphs(boolean newIgnoreContentStreamSpaceGlyphs)
+ {
+ ignoreContentStreamSpaceGlyphs = newIgnoreContentStreamSpaceGlyphs;
+ }
+
+ /**
* Get the current space width-based tolerance value that is being used to estimate where spaces in text should be
* added. Note that the default value for this has been determined from trial and error.
*
Modified: pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/text/TestTextStripper.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/text/TestTextStripper.java?rev=1922536&r1=1922535&r2=1922536&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/text/TestTextStripper.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/text/TestTextStripper.java Mon Dec 16 16:57:08 2024
@@ -48,9 +48,12 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.TestPDPageTree;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDFontDescriptor;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.PDType3Font;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
@@ -743,4 +746,49 @@ public class TestTextStripper extends Te
assertEquals(1378, text.replaceAll("\r", "").length());
doc.close();
}
+
+ /**
+ * PDFBOX-3774: test the IgnoreContentStreamSpaceGlyphs option.
+ *
+ * @throws Exception
+ */
+ public void testIgnoreContentStreamSpaceGlyphs() throws Exception
+ {
+ PDDocument doc = new PDDocument();
+ PDPage page = new PDPage();
+ PDPageContentStream cs = new PDPageContentStream(doc, page);
+
+ float fontHeight = 8;
+ float x = 50;
+ float y = page.getMediaBox().getHeight() - 50;
+ PDFont font = PDType1Font.HELVETICA;
+ cs.beginText();
+ cs.setFont(font, fontHeight);
+ cs.newLineAtOffset(x, y);
+ cs.showText("( )");
+ cs.endText();
+
+ int indent = 6;
+ float overlapX = x + indent * font.getAverageFontWidth() / 1000f * fontHeight;
+ PDFont overlapFont = PDType1Font.TIMES_ROMAN;
+ cs.beginText();
+ cs.setFont(overlapFont, fontHeight * 2f);
+ cs.newLineAtOffset(overlapX, y);
+ cs.showText("overlap");
+ cs.endText();
+ cs.close();
+ doc.addPage(page);
+
+ PDFTextStripper localStripper = new PDFTextStripper();
+ localStripper.setLineSeparator("\n");
+ localStripper.setPageEnd("\n");
+ localStripper.setStartPage(1);
+ localStripper.setEndPage(1);
+ localStripper.setSortByPosition(true);
+
+ localStripper.setIgnoreContentStreamSpaceGlyphs(true);
+ String text = localStripper.getText(doc);
+ assertEquals("( overlap )\n", text);
+ doc.close();
+ }
}