]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugfix: support justified text in AFP Renderer (already working in AFP Painter)
authorChris Bowditch <cbowditch@apache.org>
Fri, 10 Jul 2009 10:32:23 +0000 (10:32 +0000)
committerChris Bowditch <cbowditch@apache.org>
Fri, 10 Jul 2009 10:32:23 +0000 (10:32 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@792873 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/afp/DataStream.java
src/java/org/apache/fop/afp/modca/AbstractPageObject.java
src/java/org/apache/fop/render/afp/AFPRenderer.java
status.xml

index b1ff96859fa0eedbe063fcdb1a74319d1c115469..cb68af94ed71121f9f44b1fb1faaf62acba5f4ba 100644 (file)
@@ -30,8 +30,9 @@ import java.util.Map;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import org.apache.fop.afp.fonts.AFPFont;
 import org.apache.fop.afp.fonts.AFPFontAttributes;
+import org.apache.fop.afp.fonts.AFPFont;
+import org.apache.fop.afp.fonts.CharacterSet;
 import org.apache.fop.afp.modca.AbstractPageObject;
 import org.apache.fop.afp.modca.Document;
 import org.apache.fop.afp.modca.InterchangeSet;
@@ -41,6 +42,10 @@ import org.apache.fop.afp.modca.PageObject;
 import org.apache.fop.afp.modca.ResourceGroup;
 import org.apache.fop.afp.modca.TagLogicalElementBean;
 import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
+import org.apache.fop.afp.ptoca.PtocaProducer;
+import org.apache.fop.afp.ptoca.PtocaBuilder;
+import org.apache.fop.util.CharUtilities;
+import org.apache.fop.fonts.Font;
 
 /**
  * A data stream is a continuous ordered stream of data elements and objects
@@ -347,11 +352,15 @@ public class DataStream {
      * Helper method to create text on the current page, this method delegates
      * to the current presentation text object in order to construct the text.
      *
-     * @param textDataInfo
-     *            the afp text data
+     * @param textDataInfo the afp text data
+     * @param letterSpacing letter spacing to draw text with
+     * @param wordSpacing word Spacing to draw text with
+     * @param font is the font to draw text with
+     * @param charSet is the AFP Character Set to use with the text 
      * @throws UnsupportedEncodingException thrown if character encoding is not supported
      */
-    public void createText(AFPTextDataInfo textDataInfo) throws UnsupportedEncodingException {
+    public void createText(final AFPTextDataInfo textDataInfo, final int letterSpacing, final int wordSpacing,
+                           final Font font, final CharacterSet charSet) throws UnsupportedEncodingException {
         int rotation = paintingState.getRotation();
         if (rotation != 0) {
             textDataInfo.setRotation(rotation);
@@ -359,7 +368,86 @@ public class DataStream {
             textDataInfo.setX(p.x);
             textDataInfo.setY(p.y);
         }
-        currentPage.createText(textDataInfo);
+        // use PtocaProducer to create PTX records
+        PtocaProducer producer = new PtocaProducer() {
+
+            public void produce(PtocaBuilder builder) throws IOException {
+                builder.setTextOrientation(textDataInfo.getRotation());
+                builder.absoluteMoveBaseline(textDataInfo.getY());
+                builder.absoluteMoveInline(textDataInfo.getX());
+
+                builder.setExtendedTextColor(textDataInfo.getColor());
+                builder.setCodedFont((byte)textDataInfo.getFontReference());
+
+                int l = textDataInfo.getString().length();
+                StringBuffer sb = new StringBuffer();
+
+                int interCharacterAdjustment = 0;
+                AFPUnitConverter unitConv = paintingState.getUnitConverter();
+                if (letterSpacing != 0) {
+                    interCharacterAdjustment = Math.round(unitConv.mpt2units(letterSpacing));
+                }
+                builder.setInterCharacterAdjustment(interCharacterAdjustment);
+
+                int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
+                int spacing = spaceWidth + letterSpacing;
+                int fixedSpaceCharacterIncrement = Math.round(unitConv.mpt2units(spacing));
+                int varSpaceCharacterIncrement = fixedSpaceCharacterIncrement;
+                if (wordSpacing != 0) {
+                    varSpaceCharacterIncrement = Math.round(unitConv.mpt2units(
+                            spaceWidth + wordSpacing + letterSpacing));
+                }
+                builder.setVariableSpaceCharacterIncrement(varSpaceCharacterIncrement);
+
+                boolean fixedSpaceMode = false;
+
+                for (int i = 0; i < l; i++) {
+                    char orgChar = textDataInfo.getString().charAt(i);
+                    float glyphAdjust = 0;
+                    if (CharUtilities.isFixedWidthSpace(orgChar)) {
+                        flushText(builder, sb, charSet);
+                        builder.setVariableSpaceCharacterIncrement(
+                                fixedSpaceCharacterIncrement);
+                        fixedSpaceMode = true;
+                        sb.append(CharUtilities.SPACE);
+                        int charWidth = font.getCharWidth(orgChar);
+                        glyphAdjust += (charWidth - spaceWidth);
+                    } else {
+                        if (fixedSpaceMode) {
+                            flushText(builder, sb, charSet);
+                            builder.setVariableSpaceCharacterIncrement(
+                                    varSpaceCharacterIncrement);
+                            fixedSpaceMode = false;
+                        }
+                        char ch;
+                        if (orgChar == CharUtilities.NBSPACE) {
+                            ch = ' '; //converted to normal space to allow word spacing
+                        } else {
+                            ch = orgChar;
+                        }
+                        sb.append(ch);
+                    }
+
+                    if (glyphAdjust != 0) {
+                        flushText(builder, sb, charSet);
+                        int increment = Math.round(unitConv.mpt2units(glyphAdjust));
+                        builder.relativeMoveInline(increment);
+                    }
+                }
+                flushText(builder, sb, charSet);
+            }
+
+            private void flushText(PtocaBuilder builder, StringBuffer sb,
+                    final CharacterSet charSet) throws IOException {
+                if (sb.length() > 0) {
+                    builder.addTransparentData(charSet.encodeChars(sb));
+                    sb.setLength(0);
+                }
+            }
+
+        };
+
+        currentPage.createText(producer);
     }
 
     /**
index cd8c44b5eca2aaa18c8e0207e91fd6b30fd79d42..af676410f08a2c48d940dd2d92775007d8398752 100644 (file)
@@ -25,9 +25,9 @@ import java.io.UnsupportedEncodingException;
 import java.util.List;
 
 import org.apache.fop.afp.AFPLineDataInfo;
-import org.apache.fop.afp.AFPTextDataInfo;
 import org.apache.fop.afp.Completable;
 import org.apache.fop.afp.Factory;
+import org.apache.fop.afp.ptoca.PtocaProducer;
 import org.apache.fop.afp.fonts.AFPFont;
 
 /**
@@ -170,8 +170,10 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen
      *            the afp text data
      * @throws UnsupportedEncodingException thrown if character encoding is not supported
      */
-    public void createText(AFPTextDataInfo textDataInfo) throws UnsupportedEncodingException {
-        getPresentationTextObject().createTextData(textDataInfo);
+    public void createText(PtocaProducer producer) throws UnsupportedEncodingException {
+        //getPresentationTextObject().createTextData(textDataInfo);
+        getPresentationTextObject().createControlSequences(producer);
+
     }
 
     /**
index 5024fa7b62ed78c6496ac1c4c419ada721304f2d..b9eb345b7056f324248440b564348a0053bc33c1 100644 (file)
@@ -75,6 +75,7 @@ import org.apache.fop.area.inline.TextArea;
 import org.apache.fop.datatypes.URISpecification;
 import org.apache.fop.events.ResourceEventProducer;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontCollection;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontManager;
@@ -563,6 +564,8 @@ public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCust
         AFPFont font = (AFPFont)fontMetricMap.get(internalFontName);
         AFPPageFonts pageFonts = paintingState.getPageFonts();
         AFPFontAttributes fontAttributes = pageFonts.registerFont(internalFontName, font, fontSize);
+        Font fnt = getFontFromArea(text);
+
 
         // create text data info
         AFPTextDataInfo textDataInfo = new AFPTextDataInfo();
@@ -603,7 +606,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCust
         textDataInfo.setString(textString);
 
         try {
-            dataStream.createText(textDataInfo);
+            dataStream.createText(textDataInfo, textLetterSpaceAdjust, textWordSpaceAdjust, fnt, charSet);
         } catch (UnsupportedEncodingException e) {
             AFPEventProducer eventProducer
                 = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster());
index d46bbb06cb05c61924938d4e2f081a01ea8b8670..3b7e3bac9cf8c1a77e964a8824eeadc0fc7fd64d 100644 (file)
@@ -58,6 +58,9 @@
       documents. Example: the fix of marks layering will be such a case when it's done.
     -->
     <release version="FOP Trunk" date="TBD">
+      <action context="Renderers" dev="CB" type="fix">
+        Bugfix: support justified text in AFP Renderer (already working in AFP Painter)
+      </action>
       <action context="Renderers" dev="AD" type="add">
         AFP Renderer Raster Fonts:
         <ul>