You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/08/30 02:32:35 UTC

svn commit: r1621405 - in /pdfbox/branches/no-awt/pdfbox/src: main/java/org/apache/pdfbox/pdmodel/font/ main/java/org/apache/pdfbox/rendering/ main/java/org/apache/pdfbox/util/ main/resources/META-INF/services/ test/java/org/apache/pdfbox/

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
     {