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;
+ }
}
}
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
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)
* @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} */
* 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} */
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;
*/
public void setCharacterSet(int characterSet) {
if (characterSet != graphicsState.characterSet) {
- addObject(new GraphicsSetCharacterSet(characterSet));
graphicsState.characterSet = characterSet;
}
+ addObject(new GraphicsSetCharacterSet(characterSet));
}
/**
* @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));
}
/**
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);
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>
--- /dev/null
+/*\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