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 2020/11/23 16:41:10 UTC
svn commit: r1883754 - in
/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane:
DebugPDFRenderer.java DebugPageDrawer.java DebugTextOverlay.java
PagePane.java
Author: tilman
Date: Mon Nov 23 16:41:10 2020
New Revision: 1883754
URL: http://svn.apache.org/viewvc?rev=1883754&view=rev
Log:
PDFBOX-5021: move the drawing of the cyan bounds from DebugPageDrawer into DebugTextOverlay because they would be overwritten by a later drawn image
implement type3 fonts (from DrawPrintTextLocations)
fix bug that caused wrong rectangles for rotated glyphs (e.g. file from issue 4228)
Removed:
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/DebugPDFRenderer.java
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/DebugPageDrawer.java
Modified:
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/DebugTextOverlay.java
pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/PagePane.java
Modified: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/DebugTextOverlay.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/DebugTextOverlay.java?rev=1883754&r1=1883753&r2=1883754&view=diff
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/DebugTextOverlay.java (original)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/DebugTextOverlay.java Mon Nov 23 16:41:10 2020
@@ -20,6 +20,7 @@ import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
+import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
@@ -33,11 +34,14 @@ import org.apache.pdfbox.pdmodel.PDDocum
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType3CharProc;
import org.apache.pdfbox.pdmodel.font.PDType3Font;
+import org.apache.pdfbox.pdmodel.font.PDVectorFont;
import org.apache.pdfbox.pdmodel.interactive.pagenavigation.PDThreadBead;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import org.apache.pdfbox.util.Matrix;
+import org.apache.pdfbox.util.Vector;
/**
* Draws an overlay showing the locations of text found by PDFTextStripper and another heuristic.
@@ -54,7 +58,8 @@ final class DebugTextOverlay
private final boolean showTextStripper;
private final boolean showTextStripperBeads;
private final boolean showFontBBox;
-
+ private final boolean showGlyphBounds;
+
private class DebugTextStripper extends PDFTextStripper
{
private final Graphics2D graphics;
@@ -189,11 +194,96 @@ final class DebugTextOverlay
}
}
}
+
+ @Override
+ protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, Vector displacement) throws IOException
+ {
+ super.showGlyph(textRenderingMatrix, font, code, displacement);
+
+ if (!DebugTextOverlay.this.showGlyphBounds)
+ {
+ return;
+ }
+
+ AffineTransform at = textRenderingMatrix.createAffineTransform();
+ at.concatenate(font.getFontMatrix().createAffineTransform());
+
+ // compute glyph path
+ GeneralPath path;
+ if (font instanceof PDType3Font)
+ {
+ // It is difficult to calculate the real individual glyph bounds for type 3 fonts
+ // because these are not vector fonts, the content stream could contain almost anything
+ // that is found in page content streams.
+ PDType3Font t3Font = (PDType3Font) font;
+ PDType3CharProc charProc = t3Font.getCharProc(code);
+ if (charProc == null)
+ {
+ return;
+ }
+
+ BoundingBox fontBBox = t3Font.getBoundingBox();
+ PDRectangle glyphBBox = charProc.getGlyphBBox();
+ if (glyphBBox == null)
+ {
+ return;
+ }
+
+ // PDFBOX-3850: glyph bbox could be larger than the font bbox
+ glyphBBox.setLowerLeftX(Math.max(fontBBox.getLowerLeftX(), glyphBBox.getLowerLeftX()));
+ glyphBBox.setLowerLeftY(Math.max(fontBBox.getLowerLeftY(), glyphBBox.getLowerLeftY()));
+ glyphBBox.setUpperRightX(Math.min(fontBBox.getUpperRightX(), glyphBBox.getUpperRightX()));
+ glyphBBox.setUpperRightY(Math.min(fontBBox.getUpperRightY(), glyphBBox.getUpperRightY()));
+ path = glyphBBox.toGeneralPath();
+ }
+ else
+ {
+ PDVectorFont vectorFont = (PDVectorFont) font;
+ path = vectorFont.getNormalizedPath(code);
+
+ if (path == null)
+ {
+ return;
+ }
+
+ // stretch non-embedded glyph if it does not match the width contained in the PDF
+ if (!font.isEmbedded() && !font.isVertical() && !font.isStandard14() && font.hasExplicitWidth(code))
+ {
+ float fontWidth = font.getWidthFromFont(code);
+ if (fontWidth > 0 && // ignore spaces
+ Math.abs(fontWidth - displacement.getX() * 1000) > 0.0001)
+ {
+ float pdfWidth = displacement.getX() * 1000;
+ at.scale(pdfWidth / fontWidth, 1);
+ }
+ }
+ }
+
+ // compute visual bounds
+ Shape bbox = at.createTransformedShape(path.getBounds2D());
+ Shape transformedBBox = flip.createTransformedShape(bbox);
+
+ // save
+ Color color = graphics.getColor();
+ Stroke stroke = graphics.getStroke();
+ Shape clip = graphics.getClip();
+
+ // draw
+ graphics.setClip(graphics.getDeviceConfiguration().getBounds());
+ graphics.setColor(Color.cyan);
+ graphics.setStroke(new BasicStroke(.5f));
+ graphics.draw(transformedBBox);
+
+ // restore
+ graphics.setStroke(stroke);
+ graphics.setColor(color);
+ graphics.setClip(clip);
+ }
}
DebugTextOverlay(PDDocument document, int pageIndex, float scale,
- boolean showTextStripper, boolean showTextStripperBeads,
- boolean showFontBBox)
+ boolean showTextStripper, boolean showTextStripperBeads,
+ boolean showFontBBox, boolean showGlyphBounds)
{
this.document = document;
this.pageIndex = pageIndex;
@@ -201,6 +291,7 @@ final class DebugTextOverlay
this.showTextStripper = showTextStripper;
this.showTextStripperBeads = showTextStripperBeads;
this.showFontBBox = showFontBBox;
+ this.showGlyphBounds = showGlyphBounds;
}
public void renderTo(Graphics2D graphics) throws IOException
Modified: pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/PagePane.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/PagePane.java?rev=1883754&r1=1883753&r2=1883754&view=diff
==============================================================================
--- pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/PagePane.java (original)
+++ pdfbox/trunk/debugger/src/main/java/org/apache/pdfbox/debugger/pagepane/PagePane.java Mon Nov 23 16:41:10 2020
@@ -473,7 +473,7 @@ public class PagePane implements ActionL
label.setText(labelText);
statuslabel.setText(labelText);
- PDFRenderer renderer = new DebugPDFRenderer(document, ViewMenu.isShowGlyphBounds());
+ PDFRenderer renderer = new PDFRenderer(document);
renderer.setSubsamplingAllowed(ViewMenu.isAllowSubsampling());
long t0 = System.nanoTime();
@@ -487,7 +487,7 @@ public class PagePane implements ActionL
// debug overlays
DebugTextOverlay debugText = new DebugTextOverlay(document, pageIndex, scale,
showTextStripper, showTextStripperBeads,
- showFontBBox);
+ showFontBBox, ViewMenu.isShowGlyphBounds());
Graphics2D g = image.createGraphics();
debugText.renderTo(g);
g.dispose();