Author: jahewson Date: Sat Aug 30 00:32:34 2014 New Revision: 1621405 URL: http://svn.apache.org/r1621405 Log: PDFBOX-2262: encapsulate text positioning
Removed: pdfbox/branches/no-awt/pdfbox/src/main/resources/META-INF/services/ Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java pdfbox/branches/no-awt/pdfbox/src/test/java/org/apache/pdfbox/ParallelParameterized.java Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDCIDFont.java Sat Aug 30 00:32:34 2014 @@ -261,7 +261,7 @@ public abstract class PDCIDFont implemen } /** - * Returns the position vector (v) for the given character code. + * Returns the position vector (v) in 1/1000 text space, for the given character code. * * @param code character code * @return position vector (v) Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDFont.java Sat Aug 30 00:32:34 2014 @@ -35,6 +35,7 @@ import org.apache.pdfbox.io.IOUtils; import org.apache.pdfbox.pdmodel.common.COSArrayList; import org.apache.pdfbox.pdmodel.common.COSObjectable; import org.apache.pdfbox.util.Matrix; +import org.apache.pdfbox.util.Vector; /** * This is the base class for all PDF fonts. @@ -157,6 +158,31 @@ public abstract class PDFont implements } /** + * Returns the position vector (v), in text space, for the given character. + * This represents the position of vertical origin relative to horizontal origin, for + * horizontal writing it will always be (0, 0). For vertical writing both x and y are set. + * + * @param code character code + * @return position vector + */ + public Vector getPositionVector(int code) + { + throw new UnsupportedOperationException("Horizontal fonts have no position vector"); + } + + /** + * Returns the displacement vector (w0, w1) in text space, for the given character. + * For horizontal text only the x component is used, for vertical text only the y component. + * + * @param code character code + * @return displacement vector + */ + public Vector getDisplacement(int code) throws IOException + { + return new Vector(getWidth(code) / 1000, 0); + } + + /** * Returns the advance width of the given character, in glyph space. * * @param code character code Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType0Font.java Sat Aug 30 00:32:34 2014 @@ -30,6 +30,7 @@ import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.encoding.GlyphList; import org.apache.pdfbox.encoding.StandardEncoding; import org.apache.pdfbox.util.Matrix; +import org.apache.pdfbox.util.Vector; /** * A Composite (Type 0) font. @@ -199,6 +200,26 @@ public class PDType0Font extends PDFont } @Override + public Vector getPositionVector(int code) + { + // units are always 1/1000 text space, font matrix is not used, see FOP-2252 + return descendantFont.getPositionVector(code).scale(-1 / 1000f); + } + + @Override + public Vector getDisplacement(int code) throws IOException + { + if (isVertical()) + { + return new Vector(0, descendantFont.getVerticalDisplacementVectorY(code) / 1000f); + } + else + { + return super.getDisplacement(code); + } + } + + @Override public float getWidth(int code) throws IOException { return descendantFont.getWidth(code); Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/font/PDType3Font.java Sat Aug 30 00:32:34 2014 @@ -30,6 +30,7 @@ import org.apache.pdfbox.encoding.Encodi import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.util.Matrix; +import org.apache.pdfbox.util.Vector; /** * A PostScript Type 3 Font. @@ -74,6 +75,12 @@ public class PDType3Font extends PDSimpl } @Override + public Vector getDisplacement(int code) throws IOException + { + return getFontMatrix().transform(new Vector(getWidth(code), 0)); + } + + @Override public float getWidth(int code) throws IOException { int firstChar = dict.getInt(COSName.FIRST_CHAR, -1); Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java Sat Aug 30 00:32:34 2014 @@ -73,6 +73,7 @@ import org.apache.pdfbox.pdmodel.interac import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream; import org.apache.pdfbox.util.Matrix; import org.apache.pdfbox.util.PDFGraphicsStreamEngine; +import org.apache.pdfbox.util.Vector; /** * Paints a page in a PDF document to a Graphics context. @@ -214,7 +215,7 @@ public class PageDrawer extends PDFGraph initStream(pageDimension); - // transform ctm + // transformPoint ctm Matrix concat = matrix.multiply(getGraphicsState().getCurrentTransformationMatrix()); getGraphicsState().setCurrentTransformationMatrix(concat); @@ -272,31 +273,21 @@ public class PageDrawer extends PDFGraph @Override protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, String unicode, - float dx, float dy) throws IOException + Vector displacement) throws IOException { - try - { - AffineTransform at = textRenderingMatrix.createAffineTransform(); - Matrix fontMatrix = font.getFontMatrix(); + AffineTransform at = textRenderingMatrix.createAffineTransform(); + at.concatenate(font.getFontMatrix().createAffineTransform()); - // use different methods to draw the string - if (font instanceof PDType3Font) - { - // Type3 fonts don't use the same units within the font matrix as the other fonts - at.scale(fontMatrix.getValue(0, 0), fontMatrix.getValue(1, 1)); - // Type3 fonts are using streams for each character - drawType3String((PDType3Font) font, code, at); - } - else - { - Glyph2D glyph2D = createGlyph2D(font); - at.concatenate(fontMatrix.createAffineTransform()); - drawGlyph2D(glyph2D, code, at); - } + if (font instanceof PDType3Font) + { + // Type3 fonts use PDF streams for each character + drawType3String((PDType3Font) font, code, at); } - catch (IOException e) + else { - LOG.error(e.getMessage(), e); // todo: really? + // all other fonts use vectors + Glyph2D glyph2D = createGlyph2D(font); + drawGlyph2D(glyph2D, code, at); } } Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/Matrix.java Sat Aug 30 00:32:34 2014 @@ -301,14 +301,14 @@ public class Matrix implements Cloneable * @param point point to transform */ public void transform(Point2D point) { - double x = point.getX(); - double y = point.getY(); - double a = single[0]; - double b = single[1]; - double c = single[3]; - double d = single[4]; - double e = single[6]; - double f = single[7]; + float x = (float)point.getX(); + float y = (float)point.getY(); + float a = single[0]; + float b = single[1]; + float c = single[3]; + float d = single[4]; + float e = single[6]; + float f = single[7]; point.setLocation(x * a + y * c + e, x * b + y * d + f); } @@ -318,17 +318,34 @@ public class Matrix implements Cloneable * @param x x-coordinate * @param y y-coordinate */ - public Point2D transform(double x, double y) { - double a = single[0]; - double b = single[1]; - double c = single[3]; - double d = single[4]; - double e = single[6]; - double f = single[7]; + public Point2D transformPoint(double x, double y) { + float a = single[0]; + float b = single[1]; + float c = single[3]; + float d = single[4]; + float e = single[6]; + float f = single[7]; return new Point2D.Double(x * a + y * c + e, x * b + y * d + f); } /** + * Transforms the given point by this matrix. + * + * @param vector @2D vector + */ + public Vector transform(Vector vector) { + float a = single[0]; + float b = single[1]; + float c = single[3]; + float d = single[4]; + float e = single[6]; + float f = single[7]; + float x = vector.getX(); + float y = vector.getY(); + return new Vector(x * a + y * c + e, x * b + y * d + f); + } + + /** * Create a new matrix with just the scaling operators. * * @return A new matrix with just the scaling operators. Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java Sat Aug 30 00:32:34 2014 @@ -388,43 +388,22 @@ public class PDFStreamEngine Matrix ctm = state.getCurrentTransformationMatrix(); Matrix textRenderingMatrix = parameters.multiply(textMatrix).multiply(ctm); - // get glyph's horizontal and vertical displacements (glyph space -> text space) - // todo: it would be nice to encapsulate the code below - float w0, w1; - if (font instanceof PDType3Font) - { - // Type 3 fonts specify a custom matrix - Matrix fontMatrix = font.getFontMatrix(); - Point2D adv = fontMatrix.transform(font.getWidth(code), font.getHeight(code)); - w0 = (float)adv.getX(); - w1 = (float)adv.getY(); - } - else + // get glyph's position vector if this is vertical text + // changes to vertical text should be tested with PDFBOX-2294 and PDFBOX-1422 + if (font.isVertical()) { - // all other fonts use 1:1000 for widths, even those with a FontMatrix, see FOP-2252 - if (font.isVertical()) - { - // changes to vertical text should be tested with PDFBOX-2294 and PDFBOX-1422 - PDType0Font type0 = (PDType0Font)font; + // position vector, in text space + Vector v = font.getPositionVector(code); - // position vector (position of vertical origin relative to horizontal origin) - Vector v = type0.getDescendantFont().getPositionVector(code); - textRenderingMatrix.translate(v.scale(-1 / 1000f)); - - // displacement vector - w0 = 0; - w1 = type0.getDescendantFont().getVerticalDisplacementVectorY(code) / 1000; - } - else - { - // displacement vector - w0 = font.getWidth(code) / 1000f; - w1 = 0; - } + // apply the position vector to the horizontal origin to get the vertical origin + textRenderingMatrix.translate(v); } + // get glyph's horizontal and vertical displacements, in text space + Vector w = font.getDisplacement(code); + // process the decoded glyph - showGlyph(textRenderingMatrix, font, code, unicode, w0, w1); + showGlyph(textRenderingMatrix, font, code, unicode, w); // TJ adjustment after final glyph float tj = 0; @@ -438,11 +417,12 @@ public class PDFStreamEngine if (font.isVertical()) { tx = 0; - ty = (w1 - tj / 1000) * fontSize + charSpacing + wordSpacing; + ty = (w.getY() - tj / 1000) * fontSize + charSpacing + wordSpacing; } else { - tx = ((w0 - tj / 1000) * fontSize + charSpacing + wordSpacing) * horizontalScaling; + tx = ((w.getX() - tj / 1000) * fontSize + charSpacing + wordSpacing) * + horizontalScaling; ty = 0; } @@ -459,12 +439,11 @@ public class PDFStreamEngine * @param font the current font * @param code internal PDF character code for the glyph * @param unicode the Unicode text for this glyph, or null if the PDF does provide it - * @param dx the x-advance of the glyph in text space - * @param dy the y-advance of the glyph in text space + * @param displacement the displacement (i.e. advance) of the glyph in text space * @throws IOException if the glyph cannot be processed */ protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, String unicode, - float dx, float dy) throws IOException + Vector displacement) throws IOException { // overridden in subclasses } @@ -628,10 +607,10 @@ public class PDFStreamEngine } /** - * use the current transformation matrix to transform a single point. + * use the current transformation matrix to transformPoint a single point. * - * @param x x-coordinate of the point to be transform - * @param y y-coordinate of the point to be transform + * @param x x-coordinate of the point to be transformPoint + * @param y y-coordinate of the point to be transformPoint * @return the transformed coordinates as Point2D.Double */ public Point2D.Double transformedPoint(double x, double y) @@ -643,9 +622,9 @@ public class PDFStreamEngine } /** - * use the current transformation matrix to transform a PDRectangle. + * use the current transformation matrix to transformPoint a PDRectangle. * - * @param rect the PDRectangle to transform + * @param rect the PDRectangle to transformPoint * @return the transformed coordinates as a GeneralPath */ public GeneralPath transformedPDRectanglePath(PDRectangle rect) Modified: pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/main/java/org/apache/pdfbox/util/PDFTextStreamEngine.java Sat Aug 30 00:32:34 2014 @@ -82,7 +82,7 @@ public class PDFTextStreamEngine extends */ @Override protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, String unicode, - float dx, float dy) throws IOException + Vector displacement) throws IOException { // // legacy calculations which were previously in PDFStreamEngine @@ -97,12 +97,12 @@ public class PDFTextStreamEngine extends // 1/2 the bbox is used as the height todo: why? float glyphHeight = font.getBoundingBox().getHeight() / 2; - // transform from glyph space -> text space - float height = (float)font.getFontMatrix().transform(0, glyphHeight).getY(); + // transformPoint from glyph space -> text space + float height = (float)font.getFontMatrix().transformPoint(0, glyphHeight).getY(); // (modified) combined displacement, this is calculated *without* taking the character // spacing and word spacing into account, due to legacy code in TextStripper - float tx = dx * fontSize * horizontalScaling; + float tx = displacement.getX() * fontSize * horizontalScaling; float ty = 0; // todo: support vertical writing mode // (modified) combined displacement matrix Modified: pdfbox/branches/no-awt/pdfbox/src/test/java/org/apache/pdfbox/ParallelParameterized.java URL: http://svn.apache.org/viewvc/pdfbox/branches/no-awt/pdfbox/src/test/java/org/apache/pdfbox/ParallelParameterized.java?rev=1621405&r1=1621404&r2=1621405&view=diff ============================================================================== --- pdfbox/branches/no-awt/pdfbox/src/test/java/org/apache/pdfbox/ParallelParameterized.java (original) +++ pdfbox/branches/no-awt/pdfbox/src/test/java/org/apache/pdfbox/ParallelParameterized.java Sat Aug 30 00:32:34 2014 @@ -31,7 +31,7 @@ import java.util.concurrent.TimeUnit; */ public class ParallelParameterized extends Parameterized { - static final long TIMEOUT_SECS = 60; + static final long TIMEOUT_SECS = 120; private static class FixedThreadPoolScheduler implements RunnerScheduler {