Author: tilman Date: Fri Jul 10 07:58:24 2020 New Revision: 1879751 URL: http://svn.apache.org/viewvc?rev=1879751&view=rev Log: PDFBOX-4909: don't calculate font height again for every glyph and isolate calculations, by Alfred Faltiska
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/LegacyPDFStreamEngine.java Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/LegacyPDFStreamEngine.java URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/LegacyPDFStreamEngine.java?rev=1879751&r1=1879750&r2=1879751&view=diff ============================================================================== --- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/LegacyPDFStreamEngine.java (original) +++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/text/LegacyPDFStreamEngine.java Fri Jul 10 07:58:24 2020 @@ -33,12 +33,14 @@ import org.apache.pdfbox.pdmodel.font.PD import org.apache.pdfbox.pdmodel.graphics.state.PDGraphicsState; import java.io.IOException; +import java.util.List; import org.apache.fontbox.ttf.TrueTypeFont; import org.apache.fontbox.util.BoundingBox; import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.Vector; import org.apache.pdfbox.contentstream.operator.DrawObject; +import org.apache.pdfbox.contentstream.operator.Operator; import org.apache.pdfbox.contentstream.operator.state.Concatenate; import org.apache.pdfbox.contentstream.operator.state.Restore; import org.apache.pdfbox.contentstream.operator.state.Save; @@ -60,6 +62,7 @@ import org.apache.pdfbox.contentstream.o import org.apache.pdfbox.contentstream.operator.text.SetTextRise; import org.apache.pdfbox.contentstream.operator.text.SetWordSpacing; import org.apache.pdfbox.contentstream.operator.text.ShowText; +import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.pdmodel.font.PDFontDescriptor; /** @@ -81,6 +84,8 @@ class LegacyPDFStreamEngine extends PDFS private Matrix translateMatrix; private final GlyphList glyphList; + float currentFontHeight = -1; + /** * Constructor. */ @@ -97,7 +102,7 @@ class LegacyPDFStreamEngine extends PDFS addOperator(new SetCharSpacing()); addOperator(new MoveText()); addOperator(new MoveTextSetLeading()); - addOperator(new SetFontAndSize()); + addOperator(new CapturingSetFontAndSize()); addOperator(new ShowText()); addOperator(new ShowTextAdjusted()); addOperator(new SetTextLeading()); @@ -162,48 +167,6 @@ class LegacyPDFStreamEngine extends PDFS float horizontalScaling = state.getTextState().getHorizontalScaling() / 100f; Matrix textMatrix = getTextMatrix(); - BoundingBox bbox = font.getBoundingBox(); - if (bbox.getLowerLeftY() < Short.MIN_VALUE) - { - // PDFBOX-2158 and PDFBOX-3130 - // files by Salmat eSolutions / ClibPDF Library - bbox.setLowerLeftY(- (bbox.getLowerLeftY() + 65536)); - } - // 1/2 the bbox is used as the height todo: why? - float glyphHeight = bbox.getHeight() / 2; - - // sometimes the bbox has very high values, but CapHeight is OK - PDFontDescriptor fontDescriptor = font.getFontDescriptor(); - if (fontDescriptor != null) - { - float capHeight = fontDescriptor.getCapHeight(); - if (Float.compare(capHeight, 0) != 0 && - (capHeight < glyphHeight || Float.compare(glyphHeight, 0) == 0)) - { - glyphHeight = capHeight; - } - // PDFBOX-3464, PDFBOX-4480, PDFBOX-4553: - // sometimes even CapHeight has very high value, but Ascent and Descent are ok - float ascent = fontDescriptor.getAscent(); - float descent = fontDescriptor.getDescent(); - if (capHeight > ascent && ascent > 0 && descent < 0 && - ((ascent - descent) / 2 < glyphHeight || Float.compare(glyphHeight, 0) == 0)) - { - glyphHeight = (ascent - descent) / 2; - } - } - - // transformPoint from glyph space -> text space - float height; - if (font instanceof PDType3Font) - { - height = font.getFontMatrix().transformPoint(0, glyphHeight).y; - } - else - { - height = glyphHeight / 1000; - } - float displacementX = displacement.getX(); // the sorting algorithm is based on the width of the character. As the displacement // for vertical characters doesn't provide any suitable value for it, we have to @@ -253,7 +216,7 @@ class LegacyPDFStreamEngine extends PDFS // (modified) width and height calculations float dxDisplay = nextX - textRenderingMatrix.getTranslateX(); - float dyDisplay = height * textRenderingMatrix.getScalingFactorY(); + float dyDisplay = currentFontHeight * textRenderingMatrix.getScalingFactorY(); // // start of the original method @@ -339,6 +302,61 @@ class LegacyPDFStreamEngine extends PDFS } /** + * Compute the font height. Override this if you want to use own calculations. + * + * @param font the font. + * @return the font height. + * + * @throws IOException if there is an error while getting the font bounding box. + */ + protected float computeFontHeight(PDFont font) throws IOException + { + BoundingBox bbox = font.getBoundingBox(); + if (bbox.getLowerLeftY() < Short.MIN_VALUE) + { + // PDFBOX-2158 and PDFBOX-3130 + // files by Salmat eSolutions / ClibPDF Library + bbox.setLowerLeftY(- (bbox.getLowerLeftY() + 65536)); + } + // 1/2 the bbox is used as the height todo: why? + float glyphHeight = bbox.getHeight() / 2; + + // sometimes the bbox has very high values, but CapHeight is OK + PDFontDescriptor fontDescriptor = font.getFontDescriptor(); + if (fontDescriptor != null) + { + float capHeight = fontDescriptor.getCapHeight(); + if (Float.compare(capHeight, 0) != 0 && + (capHeight < glyphHeight || Float.compare(glyphHeight, 0) == 0)) + { + glyphHeight = capHeight; + } + // PDFBOX-3464, PDFBOX-4480, PDFBOX-4553: + // sometimes even CapHeight has very high value, but Ascent and Descent are ok + float ascent = fontDescriptor.getAscent(); + float descent = fontDescriptor.getDescent(); + if (capHeight > ascent && ascent > 0 && descent < 0 && + ((ascent - descent) / 2 < glyphHeight || Float.compare(glyphHeight, 0) == 0)) + { + glyphHeight = (ascent - descent) / 2; + } + } + + // transformPoint from glyph space -> text space + float height; + if (font instanceof PDType3Font) + { + height = font.getFontMatrix().transformPoint(0, glyphHeight).y; + } + else + { + height = glyphHeight / 1000; + } + + return height; + } + + /** * A method provided as an event interface to allow a subclass to perform some specific * functionality when text needs to be processed. * @@ -349,4 +367,13 @@ class LegacyPDFStreamEngine extends PDFS // subclasses can override to provide specific functionality } + private class CapturingSetFontAndSize extends SetFontAndSize + { + public void process(Operator operator, List<COSBase> arguments) throws IOException + { + super.process(operator, arguments); + PDFont font = context.getGraphicsState().getTextState().getFont(); + currentFontHeight = computeFontHeight(font); + } + } }