]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla #51209:
authorChris Bowditch <cbowditch@apache.org>
Wed, 18 Jan 2012 11:54:36 +0000 (11:54 +0000)
committerChris Bowditch <cbowditch@apache.org>
Wed, 18 Jan 2012 11:54:36 +0000 (11:54 +0000)
SVG text in AFP creates miscoded GOCA text
Submitted by: Luis Bernardo

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

src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
src/java/org/apache/fop/afp/modca/GraphicsObject.java
src/java/org/apache/fop/afp/svg/AFPTextHandler.java
status.xml
test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java [new file with mode: 0644]

index 19ad8751c254348f32515e8b0c14f2ad584d674b..17d1acda170dd1e7d0efb4db2b721b674f4ff375 100644 (file)
@@ -209,5 +209,17 @@ public abstract class CharactersetEncoder {
         public int getLength() {
             return length;
         }
+
+        /**
+         * The bytes
+         * 
+         * @return the bytes
+         */
+        public byte[] getBytes() {
+            // return copy just in case
+            byte[] copy = new byte[bytes.length];
+            System.arraycopy(bytes, 0, copy, 0, bytes.length);
+            return copy;
+        }
     }
 }
index dc61f1034349f8aac604a817398e8ca81c28f060..a70aeb74f4b6605cb5febdacafff84bc70929451 100644 (file)
@@ -22,8 +22,9 @@ package org.apache.fop.afp.goca;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.CharacterCodingException;
 
-import org.apache.fop.afp.AFPConstants;
+import org.apache.fop.afp.fonts.CharacterSet;
 
 /**
  * A GOCA graphics string
@@ -34,7 +35,12 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
     protected static final int MAX_STR_LEN = 255;
 
     /** the string to draw */
-    protected final String str;
+    private final String str;
+
+    /**
+     * The character set encoding to use
+     */
+    private final CharacterSet charSet;
 
     /**
      * Constructor (absolute positioning)
@@ -42,20 +48,12 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
      * @param str the character string
      * @param x the x coordinate
      * @param y the y coordinate
+     * @param charSet the character set
      */
-    public GraphicsCharacterString(String str, int x, int y) {
+    public GraphicsCharacterString(String str, int x, int y, CharacterSet charSet) {
         super(x, y);
         this.str = truncate(str, MAX_STR_LEN);
-    }
-
-    /**
-     * Constructor (relative positioning)
-     *
-     * @param str the character string
-     */
-    public GraphicsCharacterString(String str) {
-        super(null);
-        this.str = truncate(str, MAX_STR_LEN);
+        this.charSet = charSet;
     }
 
     /** {@inheritDoc} */
@@ -84,9 +82,11 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
      * Returns the text string as an encoded byte array
      *
      * @return the text string as an encoded byte array
+     * @throws UnsupportedEncodingException, CharacterCodingException
      */
-    private byte[] getStringAsBytes() throws UnsupportedEncodingException {
-        return str.getBytes(AFPConstants.EBCIDIC_ENCODING);
+    private byte[] getStringAsBytes() throws UnsupportedEncodingException, 
+            CharacterCodingException {
+        return charSet.encodeChars(str).getBytes();
     }
 
     /** {@inheritDoc} */
index 6b2907807889255ca0eca96f7d8dca4255db7c91..66876a5ac53cc41ac5129eff9c0cc92aca1c9f24 100644 (file)
@@ -33,6 +33,7 @@ import org.apache.fop.afp.AFPObjectAreaInfo;
 import org.apache.fop.afp.Completable;
 import org.apache.fop.afp.Factory;
 import org.apache.fop.afp.StructuredData;
+import org.apache.fop.afp.fonts.CharacterSet;
 import org.apache.fop.afp.goca.GraphicsAreaBegin;
 import org.apache.fop.afp.goca.GraphicsAreaEnd;
 import org.apache.fop.afp.goca.GraphicsBox;
@@ -229,9 +230,9 @@ public class GraphicsObject extends AbstractDataObject {
      */
     public void setCharacterSet(int characterSet) {
         if (characterSet != graphicsState.characterSet) {
-            addObject(new GraphicsSetCharacterSet(characterSet));
             graphicsState.characterSet = characterSet;
         }
+        addObject(new GraphicsSetCharacterSet(characterSet));
     }
 
     /**
@@ -325,12 +326,8 @@ public class GraphicsObject extends AbstractDataObject {
      * @param x the x coordinate
      * @param y the y coordinate
      */
-    public void addString(String str, int x, int y) {
-        //Work-around for InfoPrint's AFP which loses character set state over Graphics Data
-        //boundaries.
-        addObject(new GraphicsSetCharacterSet(graphicsState.characterSet));
-
-        addObject(new GraphicsCharacterString(str, x, y));
+    public void addString(String str, int x, int y, CharacterSet charSet) {
+        addObject(new GraphicsCharacterString(str, x, y, charSet));
     }
 
     /**
index eb75e33ffefdb86a8e1dd9b585edf0ccb70d4b4d..2bb4cb60e1bafda7d961ee62ead2d32436159348 100644 (file)
@@ -147,10 +147,15 @@ public class AFPTextHandler extends FOPTextHandlerAdapter {
             fontSize = (int)Math.round(
                     g2d.convertToAbsoluteLength(fontSize));
             fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
+            // TODO: re-think above registerPageFont code...
+            AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
+            final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
+            // Work-around for InfoPrint's AFP which loses character set state
+            // over Graphics Data
+            // boundaries.
             graphicsObj.setCharacterSet(fontReference);
-
             // add the character string
-            graphicsObj.addString(str, Math.round(x), Math.round(y));
+            graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
         } else {
             //Inside Batik's SVG filter operations, you won't get an AFPGraphics2D
             g.drawString(str, x, y);
index df40973f4fba02d50958481b7b60d56f19ad0441..53d1cbdc234d0b66fcdbd511da2bd11fe78c76af 100644 (file)
@@ -61,6 +61,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="Code" dev="CB" type="add" fixes-bug="51209" due-to="Luis Bernardo">
+        SVG text in AFP creates miscoded GOCA text
+      </action>
       <action context="Code" dev="CB" type="add" fixes-bug="50391" due-to="Peter Hancock">
         Add support for different flow-name of fo:region-body in FOP
       </action>
diff --git a/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java b/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java
new file mode 100644 (file)
index 0000000..e986567
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.fop.afp.goca;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
+\r
+import org.apache.fop.afp.fonts.CharacterSet;\r
+import org.apache.fop.afp.fonts.CharacterSetBuilder;\r
+import org.apache.fop.fonts.Typeface;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+\r
+public class GraphicsCharacterStringTestCase {\r
+    private GraphicsCharacterString gcsCp500;\r
+    private GraphicsCharacterString gcsCp1146;\r
+    // consider the EBCDIC code page variants Cp500 and Cp1146\r
+    // the £ corresponds to byte 5B (position 91) in the CCSID 285 and CCSID 1146\r
+    // the $ corresponds to byte 5B (position 91) in the CCSID 500\r
+    private final String poundsText = "££££";\r
+    private final String dollarsText = "$$$$";\r
+    private final byte[] bytesToCheck = {(byte) 0x5b, (byte) 0x5b, (byte) 0x5b, (byte) 0x5b};\r
+\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        CharacterSetBuilder csb = CharacterSetBuilder.getSingleByteInstance();\r
+        CharacterSet cs1146 = csb.build("C0H200B0", "T1V10500", "Cp1146",\r
+                Class.forName("org.apache.fop.fonts.base14.Helvetica").asSubclass(Typeface.class)\r
+                .newInstance(), null);\r
+        gcsCp1146 = new GraphicsCharacterString(poundsText, 0, 0, cs1146);\r
+        CharacterSet cs500 = csb.build("C0H200B0", "T1V10500", "Cp500",\r
+                Class.forName("org.apache.fop.fonts.base14.Helvetica").asSubclass(Typeface.class)\r
+                .newInstance(), null);\r
+        gcsCp500 = new GraphicsCharacterString(dollarsText, 0, 0, cs500);\r
+    }\r
+\r
+    @Test\r
+    public void testWriteToStream() throws IOException {\r
+        // check pounds\r
+        ByteArrayOutputStream baos1146 = new ByteArrayOutputStream();\r
+        gcsCp1146.writeToStream(baos1146);\r
+        byte[] bytes1146 = baos1146.toByteArray();\r
+        for (int i = 0; i < bytesToCheck.length; i++) {\r
+            assertEquals(bytesToCheck[i], bytes1146[6 + i]);\r
+        }\r
+        assertEquals(bytesToCheck.length + 6, bytes1146.length);\r
+        // check dollars\r
+        ByteArrayOutputStream baos500 = new ByteArrayOutputStream();\r
+        gcsCp500.writeToStream(baos500);\r
+        byte[] bytes500 = baos500.toByteArray();\r
+        for (int i = 0; i < bytesToCheck.length; i++) {\r
+            assertEquals(bytesToCheck[i], bytes500[6 + i]);\r
+        }\r
+        assertEquals(bytesToCheck.length + 6, bytes500.length);\r
+    }\r
+}\r