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/09/04 20:43:38 UTC

svn commit: r1622529 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: rendering/PageDrawer.java util/PDFStreamEngine.java util/operator/text/ShowText.java util/operator/text/ShowTextGlyph.java

Author: jahewson
Date: Thu Sep  4 18:43:38 2014
New Revision: 1622529

URL: http://svn.apache.org/r1622529
Log:
PDFBOX-2262/PDFBOX-2315: Fix refactored text positioning to handle glyph spacing correctly

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowText.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowTextGlyph.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java?rev=1622529&r1=1622528&r2=1622529&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/rendering/PageDrawer.java Thu Sep  4 18:43:38 2014
@@ -328,7 +328,7 @@ public class PageDrawer extends PDFGraph
     }
 
     @Override
-    protected void showText(byte[] string, float adjustment) throws IOException
+    protected void showText(byte[] string) throws IOException
     {
         PDGraphicsState state = getGraphicsState();
         RenderingMode renderingMode = state.getTextState().getRenderingMode();
@@ -339,7 +339,7 @@ public class PageDrawer extends PDFGraph
             textClippingArea = new Area();
         }
 
-        super.showText(string, adjustment);
+        super.showText(string);
 
         // apply the buffered clip as one area
         if (renderingMode.isClip())

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java?rev=1622529&r1=1622528&r2=1622529&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/PDFStreamEngine.java Thu Sep  4 18:43:38 2014
@@ -35,9 +35,12 @@ import java.util.Stack;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSArray;
 import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSNumber;
 import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.cos.COSString;
 import org.apache.pdfbox.pdfparser.PDFStreamParser;
 import org.apache.pdfbox.pdmodel.PDResources;
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
@@ -313,23 +316,56 @@ public class PDFStreamEngine
      * @param string the encoded text
      * @throws IOException if there was an error showing the text
      */
-    public void showText(byte[] string) throws IOException
+    public void showTextString(byte[] string) throws IOException
     {
-        showText(string, 0);
+        showText(string);
     }
 
     /**
      * Called when a string of text with spacing adjustments is to be shown.
      *
-     * @param strings list of the encoded text
-     * @param adjustments spacing adjustment for each string
+     * @param array array of encoded text strings and adjustments
      * @throws IOException if there was an error showing the text
      */
-    public void showAdjustedText(List<byte[]> strings, List<Float> adjustments) throws IOException
+    public void showTextStrings(COSArray array) throws IOException
     {
-        for (int i = 0, len = strings.size(); i < len; i++)
+        PDTextState textState = getGraphicsState().getTextState();
+        float fontSize = textState.getFontSize();
+        float horizontalScaling = textState.getHorizontalScaling() / 100f;
+        float charSpacing = textState.getCharacterSpacing();
+        boolean isVertical = textState.getFont().isVertical();
+
+        for (COSBase obj : array)
         {
-            showText(strings.get(i), adjustments.get(i));
+            if (obj instanceof COSNumber)
+            {
+                float tj = ((COSNumber)obj).floatValue();
+
+                // calculate the combined displacements
+                float tx, ty;
+                if (isVertical)
+                {
+                    tx = 0;
+                    ty = -tj / 1000 * fontSize + charSpacing;
+                }
+                else
+                {
+                    tx = (-tj / 1000 * fontSize + charSpacing) * horizontalScaling;
+                    ty = 0;
+                }
+
+                // update the text matrix
+                textMatrix.concatenate(Matrix.getTranslatingInstance(tx, ty));
+            }
+            else if(obj instanceof COSString)
+            {
+                byte[] string = ((COSString)obj).getBytes();
+                showText(string);
+            }
+            else
+            {
+                throw new IOException("Unknown type in array for TJ operation:" + obj);
+            }
         }
     }
 
@@ -338,10 +374,9 @@ public class PDFStreamEngine
      * perform an action when encoded text is being processed.
      *
      * @param string the encoded text
-     * @param adjustment a position adjustment from a TJ array to be applied after the glyph
      * @throws IOException if there is an error processing the string
      */
-    protected void showText(byte[] string, float adjustment) throws IOException
+    protected void showText(byte[] string) throws IOException
     {
         PDGraphicsState state = getGraphicsState();
         PDTextState textState = state.getTextState();
@@ -378,12 +413,9 @@ public class PDFStreamEngine
             // 32 in a string when using a simple font or a composite font that defines code 32 as
             // a single-byte code.
             float wordSpacing = 0;
-            if (codeLength == 1)
+            if (codeLength == 1 && code == 32)
             {
-                if (code == 32)
-                {
-                    wordSpacing += textState.getWordSpacing();
-                }
+                wordSpacing += textState.getWordSpacing();
             }
 
             // text rendering matrix (text space -> device space)
@@ -407,24 +439,16 @@ public class PDFStreamEngine
             // process the decoded glyph
             showGlyph(textRenderingMatrix, font, code, unicode, w);
 
-            // TJ adjustment after final glyph
-            float tj = 0;
-            if (in.available() == 0)
-            {
-                tj = adjustment;
-            }
-
             // calculate the combined displacements
             float tx, ty;
             if (font.isVertical())
             {
                 tx = 0;
-                ty = (w.getY() - tj / 1000) * fontSize + charSpacing + wordSpacing;
+                ty = w.getY() * fontSize + charSpacing + wordSpacing;
             }
             else
             {
-                tx = ((w.getX() - tj / 1000) * fontSize + charSpacing + wordSpacing) *
-                        horizontalScaling;
+                tx = (w.getX() * fontSize + charSpacing + wordSpacing) * horizontalScaling;
                 ty = 0;
             }
 

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowText.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowText.java?rev=1622529&r1=1622528&r2=1622529&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowText.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowText.java Thu Sep  4 18:43:38 2014
@@ -36,6 +36,6 @@ public class ShowText extends OperatorPr
     public void process(Operator operator, List<COSBase> arguments) throws IOException
     {
         COSString string = (COSString)arguments.get( 0 );
-        context.showText(string.getBytes());
+        context.showTextString(string.getBytes());
     }
 }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowTextGlyph.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowTextGlyph.java?rev=1622529&r1=1622528&r2=1622529&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowTextGlyph.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/text/ShowTextGlyph.java Thu Sep  4 18:43:38 2014
@@ -16,14 +16,11 @@
  */
 package org.apache.pdfbox.util.operator.text;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.pdfbox.cos.COSArray;
 import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.cos.COSNumber;
 import java.io.IOException;
-import org.apache.pdfbox.cos.COSString;
 import org.apache.pdfbox.util.operator.Operator;
 import org.apache.pdfbox.util.operator.OperatorProcessor;
 
@@ -38,40 +35,6 @@ public class ShowTextGlyph extends Opera
     public void process(Operator operator, List<COSBase> arguments) throws IOException
     {
         COSArray array = (COSArray)arguments.get(0);
-
-        List<Float> adjustments = new ArrayList<Float>();
-        List<byte[]> strings = new ArrayList<byte[]>();
-        boolean lastWasString = false;
-
-        for(int i = 0, len = array.size(); i < len; i++)
-        {
-            COSBase next = array.get(i);
-            if (next instanceof COSNumber)
-            {
-                adjustments.add(((COSNumber)next).floatValue());
-                lastWasString = false;
-            }
-            else if(next instanceof COSString)
-            {
-                if (lastWasString)
-                {
-                    adjustments.add(0f); // adjustment for previous string
-                }
-                strings.add(((COSString)next).getBytes());
-                lastWasString = true;
-            }
-            else
-            {
-                throw new IOException("Unknown type in array for TJ operation:" + next);
-            }
-        }
-
-        // adjustment for final string
-        if (lastWasString)
-        {
-            adjustments.add(0f);
-        }
-
-        context.showAdjustedText(strings, adjustments);
+        context.showTextStrings(array);
     }
 }