]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Made the IFRenderer smarter so it combines lines of text into a single text element...
authorJeremias Maerki <jeremias@apache.org>
Fri, 15 Aug 2008 14:19:51 +0000 (14:19 +0000)
committerJeremias Maerki <jeremias@apache.org>
Fri, 15 Aug 2008 14:19:51 +0000 (14:19 +0000)
Fixed problems with letter and word spacing.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@686228 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/render/intermediate/IFRenderer.java
src/java/org/apache/fop/render/pdf/PDFPainter.java

index 529aee4d0e2d676cddbb462ad55f9f445e5a1808..19c616df12e8970741d16a74944c5ac2b00ff9d7 100644 (file)
@@ -27,6 +27,7 @@ import java.awt.geom.AffineTransform;
 import java.awt.geom.Rectangle2D;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
@@ -140,6 +141,8 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
 
     private BookmarkTree bookmarkTree;
 
+    private TextUtil textUtil = new TextUtil();
+
     /**
      * Main constructor
      */
@@ -831,10 +834,13 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
             handleIFException(e);
         }
 
-        super.renderText(text);
-
         int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
         int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
+        textUtil.flush();
+        textUtil.setStartPosition(rx, bl);
+        super.renderText(text);
+
+        textUtil.flush();
         renderTextDecoration(tf, size, text, bl, rx);
     }
 
@@ -859,9 +865,12 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
 
         if (space.isAdjustable()) {
             //Used for justified text, for example
-            int tws = -((TextArea) space.getParentArea()).getTextWordSpaceAdjust()
-                         - 2 * textArea.getTextLetterSpaceAdjust();
-            this.currentIPPosition -= tws;
+            int tws = ((TextArea) space.getParentArea()).getTextWordSpaceAdjust()
+                         + 2 * textArea.getTextLetterSpaceAdjust();
+            if (tws != 0) {
+                float fontSize = font.getFontSize() / 1000f;
+                textUtil.adjust(Math.round(tws / fontSize * 10));
+            }
         }
         super.renderSpace(space);
     }
@@ -876,43 +885,75 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
     protected void renderText(String s,
                            int[] letterAdjust,
                            Font font, AbstractTextArea parentArea) {
-        int curX = currentIPPosition;
         float fontSize = font.getFontSize() / 1000f;
 
         int l = s.length();
 
-        int[] dx = new int[l];
-        boolean hasDX = false;
         for (int i = 0; i < l; i++) {
             char ch = s.charAt(i);
+            textUtil.addChar(ch);
             float glyphAdjust = 0;
             if (font.hasChar(ch)) {
                 int tls = (i < l - 1 ? parentArea.getTextLetterSpaceAdjust() : 0);
-                glyphAdjust -= tls;
+                glyphAdjust += tls;
             }
-            curX += font.getCharWidth(ch);
             if (letterAdjust != null && i < l) {
-                glyphAdjust -= letterAdjust[i];
+                glyphAdjust += letterAdjust[i];
             }
 
             float adjust = glyphAdjust / fontSize;
 
+            textUtil.adjust(Math.round(adjust * 10));
+        }
+    }
+
+    private class TextUtil {
+        private static final int INITIAL_BUFFER_SIZE = 16;
+        private int[] dx = new int[INITIAL_BUFFER_SIZE];
+        private boolean hasDX = false;
+        private StringBuffer text = new StringBuffer();
+        private int startx, starty;
+
+        void addChar(char ch) {
+            text.append(ch);
+        }
+
+        void adjust(int adjust) {
             if (adjust != 0) {
-                dx[i] = Math.round(adjust * -10);
-                if (dx[i] != 0) {
-                    hasDX = true;
+                int idx = text.length();
+                if (idx > dx.length - 1) {
+                    int[] newDX = new int[dx.length + INITIAL_BUFFER_SIZE];
+                    System.arraycopy(dx, 0, newDX, 0, dx.length);
+                    dx = newDX;
                 }
+                dx[idx] += adjust;
+                hasDX = true;
             }
-            curX += adjust;
         }
-        try {
-            int rx = currentIPPosition + parentArea.getBorderAndPaddingWidthStart();
-            int bl = currentBPPosition + parentArea.getOffset() + parentArea.getBaselineOffset();
-            painter.drawText(rx, bl, (hasDX ? dx : null), null, s);
-        } catch (IFException e) {
-            handleIFException(e);
+
+        void reset() {
+            if (text.length() > 0) {
+                text.setLength(0);
+                Arrays.fill(dx, 0);
+                hasDX = false;
+            }
+        }
+
+        void setStartPosition(int x, int y) {
+            this.startx = x;
+            this.starty = y;
+        }
+
+        void flush() {
+            if (text.length() > 0) {
+                try {
+                    painter.drawText(startx, starty, (hasDX ? dx : null), null, text.toString());
+                } catch (IFException e) {
+                    handleIFException(e);
+                }
+                reset();
+            }
         }
-        this.currentIPPosition = curX;
     }
 
     /** {@inheritDoc} */
index cfbc21d35727cc86cb41239664a98daad07691dc..65d3b57a073d9795b2c9ddf077e1c45a3aa3ffeb 100644 (file)
@@ -409,7 +409,7 @@ public class PDFPainter extends AbstractBinaryWritingIFPainter {
         int dxl = (dx != null ? dx.length : 0);
 
         if (dx != null && dxl > 0 && dx[0] != 0) {
-            textutil.adjustGlyphTJ(dx[0]);
+            textutil.adjustGlyphTJ(-dx[0] / 10f);
         }
         for (int i = 0; i < l; i++) {
             char orgChar = text.charAt(i);