Selaa lähdekoodia

Bugzill#51530: Improved support for EBCDIC encoded double byte fonts fo AFP.

Submitted by: Mehdi Houshmand <med1985.at.gmail.com>


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1165223 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_1rc1old
Peter Hancock 12 vuotta sitten
vanhempi
commit
de056bce77

+ 6
- 0
src/documentation/content/xdocs/trunk/output.xml Näytä tiedosto

<a href="fonts.html#embedding"><code>referenced-fonts</code> section of the configuration file</a>. <a href="fonts.html#embedding"><code>referenced-fonts</code> section of the configuration file</a>.
However, the default fonts shown above will not be embedded. However, the default fonts shown above will not be embedded.
</p> </p>
<p>
For double byte EBCDIC encoded character sets, there is an optional tag that must be set to prevent
characters from being miscoded. This defaults to "false" if not specified.</p>
<source><![CDATA[
<afp-font type="CIDKeyed" codepage="T10835 " encoding="Cp937" characterset="CZTKAI" ebcdic-dbcs="true"/>]]>
</source>
</section> </section>
<section id="afp-renderer-resolution-config"> <section id="afp-renderer-resolution-config">
<title>Output Resolution</title> <title>Output Resolution</title>

+ 15
- 50
src/java/org/apache/fop/afp/fonts/CharacterSet.java Näytä tiedosto



import java.io.File; import java.io.File;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException; import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Map; import java.util.Map;


import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;

import org.apache.fop.afp.AFPConstants; import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
import org.apache.fop.afp.util.ResourceAccessor; import org.apache.fop.afp.util.ResourceAccessor;
import org.apache.fop.afp.util.SimpleResourceAccessor; import org.apache.fop.afp.util.SimpleResourceAccessor;
import org.apache.fop.afp.util.StringUtils; import org.apache.fop.afp.util.StringUtils;




/** The code page to which the character set relates */ /** The code page to which the character set relates */
protected String codePage;
protected final String codePage;


/** The encoding used for the code page */ /** The encoding used for the code page */
protected String encoding;
protected final String encoding;


/** The charset encoder corresponding to this encoding */
private CharsetEncoder encoder;
/** The characterset encoder corresponding to this encoding */
private final CharactersetEncoder encoder;


/** The character set relating to the font */ /** The character set relating to the font */
protected String name;
protected final String name;


/** The path to the installed fonts */ /** The path to the installed fonts */
private ResourceAccessor accessor; private ResourceAccessor accessor;
* {@link #CharacterSet(String, String, String, ResourceAccessor)} instead. * {@link #CharacterSet(String, String, String, ResourceAccessor)} instead.
*/ */
public CharacterSet(String codePage, String encoding, String name, String path) { public CharacterSet(String codePage, String encoding, String name, String path) {
this(codePage, encoding, name,
this(codePage, encoding, false, name,
new SimpleResourceAccessor(path != null ? new File(path) : null)); new SimpleResourceAccessor(path != null ? new File(path) : null));
} }


/** /**
* Constructor for the CharacterSetMetric object, the character set is used
* to load the font information from the actual AFP font.
* Constructor for the CharacterSetMetric object, the character set is used to load the font
* information from the actual AFP font.
* *
* @param codePage the code page identifier * @param codePage the code page identifier
* @param encoding the encoding of the font * @param encoding the encoding of the font
* @param isEBDCS if this is an EBCDIC double byte character set.
* @param name the character set name * @param name the character set name
* @param accessor the resource accessor to load resource with * @param accessor the resource accessor to load resource with
*/ */
CharacterSet(String codePage, String encoding, String name, ResourceAccessor accessor) {
CharacterSet(String codePage, String encoding, boolean isEBDCS, String name,
ResourceAccessor accessor) {
if (name.length() > MAX_NAME_LEN) { if (name.length() > MAX_NAME_LEN) {
String msg = "Character set name '" + name + "' must be a maximum of " String msg = "Character set name '" + name + "' must be a maximum of "
+ MAX_NAME_LEN + " characters"; + MAX_NAME_LEN + " characters";
} }
this.codePage = codePage; this.codePage = codePage;
this.encoding = encoding; this.encoding = encoding;
try {
this.encoder = Charset.forName(encoding).newEncoder();
this.encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
} catch (UnsupportedCharsetException uce) {
//No nio-capable encoder available
//This may happen with "Cp500" on Sun Java 1.4.2
this.encoder = null;
}
this.encoder = CharactersetEncoder.newInstance(encoding, isEBDCS);
this.accessor = accessor; this.accessor = accessor;


this.characterSetOrientations = new java.util.HashMap(4); this.characterSetOrientations = new java.util.HashMap(4);
* @return the encoded characters * @return the encoded characters
* @throws CharacterCodingException if the encoding operation fails * @throws CharacterCodingException if the encoding operation fails
*/ */
public byte[] encodeChars(CharSequence chars) throws CharacterCodingException {
if (encoder != null) {
ByteBuffer bb;
// encode method is not thread safe
synchronized (encoder) {
bb = encoder.encode(CharBuffer.wrap(chars));
}
if (bb.hasArray()) {
return bb.array();
} else {
bb.rewind();
byte[] bytes = new byte[bb.remaining()];
bb.get(bytes);
return bytes;
}
} else {
//Sun Java 1.4.2 compatibility
byte[] bytes;
try {
bytes = chars.toString().getBytes(this.encoding);
return bytes;
} catch (UnsupportedEncodingException uee) {
throw new UnsupportedOperationException(
"Unsupported encoding: " + uee.getMessage());
}
}
public EncodedChars encodeChars(CharSequence chars) throws CharacterCodingException {
return encoder.encode(chars);
} }


/** /**

+ 46
- 27
src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java Näytä tiedosto



import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.image.loader.util.SoftMapCache;

import org.apache.fop.afp.AFPConstants; import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.util.ResourceAccessor; import org.apache.fop.afp.util.ResourceAccessor;
import org.apache.fop.afp.util.StructuredFieldReader; import org.apache.fop.afp.util.StructuredFieldReader;
import org.apache.fop.fonts.Typeface; import org.apache.fop.fonts.Typeface;
import org.apache.xmlgraphics.image.loader.util.SoftMapCache;


/** /**
* The CharacterSetBuilder is responsible building the a CharacterSet instance that holds * The CharacterSetBuilder is responsible building the a CharacterSet instance that holds
} }


/** /**
* Load the font details and metrics into the CharacterSetMetric object,
* this will use the actual afp code page and character set files to load
* the object with the necessary metrics.
* Load the font details and metrics into the CharacterSetMetric object, this will use the
* actual afp code page and character set files to load the object with the necessary metrics.
*
* @param characterSetName name of the characterset * @param characterSetName name of the characterset
* @param codePageName name of the code page file * @param codePageName name of the code page file
* @param encoding encoding name * @param encoding encoding name
* @return CharacterSet object * @return CharacterSet object
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
*/ */
public CharacterSet build(String characterSetName, String codePageName,
String encoding, ResourceAccessor accessor) throws IOException {
public CharacterSet build(String characterSetName, String codePageName, String encoding,
ResourceAccessor accessor) throws IOException {
return processFont(characterSetName, codePageName, encoding, false, accessor);
}


/**
* Load the font details and metrics into the CharacterSetMetric object, this will use the
* actual afp code page and character set files to load the object with the necessary metrics.
* This method is to be used for double byte character sets (DBCS).
*
* @param characterSetName name of the characterset
* @param codePageName name of the code page file
* @param encoding encoding name
* @param isEDBCS if this is an EBCDIC double byte character set (DBCS)
* @param accessor used to load codepage and characterset
* @return CharacterSet object
* @throws IOException if an I/O error occurs
*/
public CharacterSet buildDBCS(String characterSetName, String codePageName, String encoding,
boolean isEDBCS, ResourceAccessor accessor) throws IOException {
return processFont(characterSetName, codePageName, encoding, isEDBCS, accessor);
}

/**
* Load the font details and metrics into the CharacterSetMetric object, this will use the
* actual afp code page and character set files to load the object with the necessary metrics.
*
* @param characterSetName the CharacterSetMetric object to populate
* @param codePageName the name of the code page to use
* @param encoding name of the encoding in use
* @param typeface base14 font name
* @return CharacterSet object
* @throws IOException if an I/O error occurs
*/
public CharacterSet build(String characterSetName, String codePageName, String encoding,
Typeface typeface) throws IOException {
return new FopCharacterSet(codePageName, encoding, characterSetName, typeface);
}

private CharacterSet processFont(String characterSetName, String codePageName, String encoding,
boolean isEDBCS, ResourceAccessor accessor) throws IOException {
// check for cached version of the characterset // check for cached version of the characterset
String descriptor = characterSetName + "_" + encoding + "_" + codePageName; String descriptor = characterSetName + "_" + encoding + "_" + codePageName;
CharacterSet characterSet = (CharacterSet)characterSetsCache.get(descriptor); CharacterSet characterSet = (CharacterSet)characterSetsCache.get(descriptor);
} }


// characterset not in the cache, so recreating // characterset not in the cache, so recreating
characterSet = new CharacterSet(
codePageName, encoding, characterSetName, accessor);
characterSet = new CharacterSet(codePageName, encoding, isEDBCS, characterSetName,
accessor);


InputStream inputStream = null; InputStream inputStream = null;


} }
characterSetsCache.put(descriptor, characterSet); characterSetsCache.put(descriptor, characterSet);
return characterSet; return characterSet;

}

/**
* Load the font details and metrics into the CharacterSetMetric object,
* this will use the actual afp code page and character set files to load
* the object with the necessary metrics.
*
* @param characterSetName the CharacterSetMetric object to populate
* @param codePageName the name of the code page to use
* @param encoding name of the encoding in use
* @param typeface base14 font name
* @return CharacterSet object
*/
public CharacterSet build(String characterSetName, String codePageName,
String encoding, Typeface typeface) {
return new FopCharacterSet(codePageName, encoding, characterSetName, typeface);
} }


/** /**

+ 199
- 0
src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java Näytä tiedosto

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.afp.fonts;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;

/**
* An abstraction that wraps the encoding mechanism for encoding a Unicode character sequence into a
* specified format.
*/
public abstract class CharactersetEncoder {

private final CharsetEncoder encoder;

private CharactersetEncoder(String encoding) {
this.encoder = Charset.forName(encoding).newEncoder();
this.encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
}

/**
* Tells whether or not this encoder can encode the given character.
*
* @param c the character
* @return true if, and only if, this encoder can encode the given character
* @throws IllegalStateException - If an encoding operation is already in progress
*/
final boolean canEncode(char c) {
return encoder.canEncode(c);
}

/**
* Encodes a character sequence to a byte array.
*
* @param chars the character sequence
* @return the encoded character sequence
* @throws CharacterCodingException if the encoding operation fails
*/
final EncodedChars encode(CharSequence chars) throws CharacterCodingException {
ByteBuffer bb;
// encode method is not thread safe
synchronized (encoder) {
bb = encoder.encode(CharBuffer.wrap(chars));
}
if (bb.hasArray()) {
return getEncodedChars(bb.array(), bb.limit());
} else {
bb.rewind();
byte[] bytes = new byte[bb.remaining()];
bb.get(bytes);
return getEncodedChars(bytes, bytes.length);
}
}

abstract EncodedChars getEncodedChars(byte[] byteArray, int length);

/**
* Encodes <code>chars</code> into a format specified by <code>encoding</code>.
*
* @param chars the character sequence
* @param encoding the encoding type
* @param isEDBCS if this encoding represents a double-byte character set
* @return encoded data
* @throws CharacterCodingException if encoding fails
*/
public static EncodedChars encodeSBCS(CharSequence chars, String encoding, boolean isEDBCS)
throws CharacterCodingException {
CharactersetEncoder encoder = newInstance(encoding, isEDBCS);
return encoder.encode(chars);
}

/**
* The EBCDIC double byte encoder is used for encoding IBM format DBCS (double byte character
* sets) with an EBCDIC code-page. Given a double byte EBCDIC code page and a Unicode character
* sequence it will return its EBCDIC code-point, however, the "Shift In - Shift Out" operators
* are removed from the sequence of bytes. These are only used in Line Data.
*/
private final static class EbcdicDoubleByteEncoder extends CharactersetEncoder {
private EbcdicDoubleByteEncoder(String encoding) {
super(encoding);
}
@Override
EncodedChars getEncodedChars(byte[] byteArray, int length) {
if (byteArray[0] == 0x0E && byteArray[length - 1] == 0x0F) {
return new EncodedChars(byteArray, 1, length - 2);
}
return new EncodedChars(byteArray);
}
}

/**
* The default encoder is used for encoding IBM format SBCS (single byte character sets), this
* the primary format for most Latin character sets. This can also be used for Unicode double-
* byte character sets (DBCS).
*/
private final static class DefaultEncoder extends CharactersetEncoder {
private DefaultEncoder(String encoding) {
super(encoding);
}

@Override
EncodedChars getEncodedChars(byte[] byteArray, int length) {
return new EncodedChars(byteArray);
}
}

/**
* Returns an new instance of a {@link CharactersetEncoder}.
*
* @param encoding the encoding for the underlying character encoder
* @param isEbcdicDBCS whether or not this wraps a double-byte EBCDIC code page.
* @return the CharactersetEncoder
*/
static CharactersetEncoder newInstance(String encoding, boolean isEbcdicDBCS) {
if (isEbcdicDBCS) {
return new EbcdicDoubleByteEncoder(encoding);
} else {
return new DefaultEncoder(encoding);
}
}

/**
* A container for encoded character bytes
*/
public static class EncodedChars {

final private byte[] bytes;

final private int offset;

final private int length;

private EncodedChars(byte[] bytes, int offset, int length) {
if (offset < 0) throw new IllegalArgumentException();

if (length < 0) throw new IllegalArgumentException();

if (offset + length > bytes.length) throw new IllegalArgumentException();

this.bytes = bytes;

this.offset = offset;

this.length = length;
}

private EncodedChars(byte[] bytes) {
this(bytes, 0, bytes.length);
}

/**
* write <code>length</code> bytes from <code>offset</code> to the output stream
*
* @param out output to write the bytes to
* @throws IOException if an I/O error occurs
*/
public void writeTo(OutputStream out, int offset, int length) throws IOException {
if (offset < 0) throw new IllegalArgumentException();

if (length < 0) throw new IllegalArgumentException();

if (offset + length > this.length) throw new IllegalArgumentException();

out.write(bytes, this.offset + offset, length);
}

/**
* The number of containing bytes.
*
* @return
*/
public int getLength() {
return length;
}
}
}

+ 1
- 1
src/java/org/apache/fop/afp/fonts/FopCharacterSet.java Näytä tiedosto

String name, String name,
Typeface charSet) { Typeface charSet) {


super(codePage, encoding, name, (ResourceAccessor)null);
super(codePage, encoding, false, name, (ResourceAccessor) null);
this.charSet = charSet; this.charSet = charSet;
} }



+ 15
- 24
src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java Näytä tiedosto

import java.io.OutputStream; import java.io.OutputStream;


import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
import org.apache.xmlgraphics.java2d.color.CIELabColorSpace; import org.apache.xmlgraphics.java2d.color.CIELabColorSpace;
import org.apache.xmlgraphics.java2d.color.ColorUtil; import org.apache.xmlgraphics.java2d.color.ColorUtil;
import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives; import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
* @param data The text data to add. * @param data The text data to add.
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
*/ */
public void addTransparentData(byte[] data) throws IOException {
if (data.length <= TRANSPARENT_DATA_MAX_SIZE) {
addTransparentDataChunk(data);
} else {
// data size greater than TRANSPARENT_MAX_SIZE, so slice
int numTransData = data.length / TRANSPARENT_DATA_MAX_SIZE;
int currIndex = 0;
for (int transDataCnt = 0; transDataCnt < numTransData; transDataCnt++) {
addTransparentDataChunk(data, currIndex, TRANSPARENT_DATA_MAX_SIZE);
currIndex += TRANSPARENT_DATA_MAX_SIZE;
}
int left = data.length - currIndex;
addTransparentDataChunk(data, currIndex, left);
public void addTransparentData(EncodedChars encodedChars) throws IOException {

// data size greater than TRANSPARENT_MAX_SIZE, so slice
int numTransData = encodedChars.getLength() / TRANSPARENT_DATA_MAX_SIZE;
int currIndex = 0;
for (int transDataCnt = 0; transDataCnt < numTransData; transDataCnt++) {
addTransparentDataChunk(encodedChars, currIndex, TRANSPARENT_DATA_MAX_SIZE);
currIndex += TRANSPARENT_DATA_MAX_SIZE;
} }
}
int left = encodedChars.getLength() - currIndex;
addTransparentDataChunk(encodedChars, currIndex, left);


private void addTransparentDataChunk(byte[] data) throws IOException {
addTransparentDataChunk(data, 0, data.length);
} }


private void addTransparentDataChunk(byte[] data, int offset, int length) throws IOException {
if (length > TRANSPARENT_MAX_SIZE) {
// Check that we are not exceeding the maximum length
throw new IllegalArgumentException(
"Transparent data is longer than " + TRANSPARENT_MAX_SIZE + " bytes");
}


private void addTransparentDataChunk(EncodedChars encodedChars, int offset, int length) throws IOException {
newControlSequence(); newControlSequence();
write(data, offset, length);
encodedChars.writeTo(baout, offset, length);
commit(chained(TRN)); commit(chained(TRN));
} }



+ 2
- 2
src/java/org/apache/fop/afp/ptoca/TextDataInfoProducer.java Näytä tiedosto

import java.io.IOException; import java.io.IOException;


import org.apache.fop.afp.AFPTextDataInfo; import org.apache.fop.afp.AFPTextDataInfo;
import org.apache.fop.afp.fonts.CharactersetEncoder;


/** /**
* {@link PtocaProducer} implementation that interprets {@link AFPTextDataInfo} objects. * {@link PtocaProducer} implementation that interprets {@link AFPTextDataInfo} objects.
// Add transparent data // Add transparent data
String textString = textDataInfo.getString(); String textString = textDataInfo.getString();
String encoding = textDataInfo.getEncoding(); String encoding = textDataInfo.getEncoding();
byte[] data = textString.getBytes(encoding);
builder.addTransparentData(data);
builder.addTransparentData(CharactersetEncoder.encodeSBCS(textString, encoding, false));
} }


} }

+ 4
- 3
src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java Näytä tiedosto



import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.configuration.ConfigurationException;

import org.apache.fop.afp.AFPResourceLevel; import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.afp.AFPResourceLevelDefaults; import org.apache.fop.afp.AFPResourceLevelDefaults;
import org.apache.fop.afp.fonts.AFPFont; import org.apache.fop.afp.fonts.AFPFont;
} }
String name = afpFontCfg.getAttribute("name", characterset); String name = afpFontCfg.getAttribute("name", characterset);
CharacterSet characterSet = null; CharacterSet characterSet = null;
boolean ebcdicDBCS = afpFontCfg.getAttributeAsBoolean("ebcdic-dbcs", false);

try { try {
characterSet = CharacterSetBuilder.getDoubleByteInstance()
.build(characterset, codepage, encoding, accessor);
characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(characterset,
codepage, encoding, ebcdicDBCS, accessor);
} catch (IOException ioe) { } catch (IOException ioe) {
toConfigurationException(codepage, characterset, ioe); toConfigurationException(codepage, characterset, ioe);
} }

+ 5
- 1
status.xml Näytä tiedosto

documents. Example: the fix of marks layering will be such a case when it's done. documents. Example: the fix of marks layering will be such a case when it's done.
--> -->
<release version="FOP Trunk" date="TBD"> <release version="FOP Trunk" date="TBD">
<action context="Fonts" dev="PH" type="fix" fixes-bug="51530" due-to="Mehdi Houshmand">
Improved support for EBCDIC encoded double byte fonts fo AFP.
</action>
<action context="Fonts" dev="PH" type="fix" fixes-bug="51205" due-to="Mehdi Houshmand"> <action context="Fonts" dev="PH" type="fix" fixes-bug="51205" due-to="Mehdi Houshmand">
Corrected typographical errors in AFPBase12FontCollection.</action>
Corrected typographical errors in AFPBase12FontCollection.
</action>
<action context="Renderers" dev="PH" type="fix" fixes-bug="48062"> <action context="Renderers" dev="PH" type="fix" fixes-bug="48062">
Improved fix of a bug relating to PCL painter thread safetly. Previous fix in rev 895012 Improved fix of a bug relating to PCL painter thread safetly. Previous fix in rev 895012
worked by synchronizing methods of a static instance of Java2DFontMetrics. This fix uses a worked by synchronizing methods of a static instance of Java2DFontMetrics. This fix uses a

+ 3
- 1
test/java/org/apache/fop/StandardTestSuite.java Näytä tiedosto

import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestSuite; import junit.framework.TestSuite;


import org.apache.fop.area.ViewportTestSuite;
import org.apache.fop.afp.fonts.CharactersetEncoderTest;
import org.apache.fop.afp.parser.MODCAParserTestCase; import org.apache.fop.afp.parser.MODCAParserTestCase;
import org.apache.fop.area.ViewportTestSuite;
import org.apache.fop.fonts.DejaVuLGCSerifTest; import org.apache.fop.fonts.DejaVuLGCSerifTest;
import org.apache.fop.fonts.truetype.GlyfTableTestCase; import org.apache.fop.fonts.truetype.GlyfTableTestCase;
import org.apache.fop.image.loader.batik.ImageLoaderTestCase; import org.apache.fop.image.loader.batik.ImageLoaderTestCase;
suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class)); suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class));
suite.addTest(new TestSuite(DejaVuLGCSerifTest.class)); suite.addTest(new TestSuite(DejaVuLGCSerifTest.class));
suite.addTest(new TestSuite(MODCAParserTestCase.class)); suite.addTest(new TestSuite(MODCAParserTestCase.class));
suite.addTest(new TestSuite(CharactersetEncoderTest.class));
suite.addTest(org.apache.fop.render.afp.AFPTestSuite.suite()); suite.addTest(org.apache.fop.render.afp.AFPTestSuite.suite());
suite.addTest(PSTestSuite.suite()); suite.addTest(PSTestSuite.suite());
suite.addTest(new TestSuite(GlyfTableTestCase.class)); suite.addTest(new TestSuite(GlyfTableTestCase.class));

+ 108
- 0
test/java/org/apache/fop/afp/fonts/CharactersetEncoderTest.java Näytä tiedosto

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* $Id$ */

package org.apache.fop.afp.fonts;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.CharacterCodingException;

import junit.framework.TestCase;

/**
* Test {@link CharactersetEncoder}
*/
public class CharactersetEncoderTest extends TestCase {
private CharactersetEncoder singlebyteEncoder;
private CharactersetEncoder doublebyteEncoder;

public void setUp() {
singlebyteEncoder = CharactersetEncoder.newInstance("cp500", false);
doublebyteEncoder = CharactersetEncoder.newInstance("cp937", true);
}

// This is just an arbitrary CJK string
private final String testCJKText = "\u8ACB\u65BC\u627F\u505A\u65E5\u4E03\u65E5\u5167\u672A\u9054"
+ "\u4E03\u65E5\u4E4B\u5B9A\u5B58\u8005\u4EE5\u5BE6\u969B\u5230\u671F\u65E5\u5167\u78BA"
+ "\u8A8D\u672C\u4EA4\u6613\u5167\u5BB9\u3002\u5982\u672A\u65BC\u4E0A\u8FF0\u671F\u9593"
+ "\u5167\u63D0\u51FA\u7570\u8B70\uFF0C\u8996\u540C\u610F\u627F\u8A8D\u672C\u4EA4\u6613"
+ "\u3002";

private final byte[] test6CJKChars = {
(byte) 0x61, (byte) 0x99,
(byte) 0x50, (byte) 0xf4,
(byte) 0x50, (byte) 0xd4,
(byte) 0x56, (byte) 0x99,
(byte) 0x4c, (byte) 0xc9,
(byte) 0x4c, (byte) 0x44 };

private final String testEngText = "Hello World!";
private final byte[] testEngChars = {
(byte) 0xc8, // H
(byte) 0x85, // e
(byte) 0x93, // l
(byte) 0x93, // l
(byte) 0x96, // o
(byte) 0x40, // " "
(byte) 0xe6, // W
(byte) 0x96, // o
(byte) 0x99, // r
(byte) 0x93, // l
(byte) 0x84, // d
(byte) 0x4f // !
};

/**
* Tests canEncode() - tests that canEncode() responds properly to various input characters.
*/
public void testCanEncode() {
// Both SBCS and DBCS should support Latin characters
for (char c = '!'; c < '~'; c++) {
assertTrue(singlebyteEncoder.canEncode(c));
assertTrue(doublebyteEncoder.canEncode(c));
}
// ONLY the double byte characters can handle CJK text
for (char c : testCJKText.toCharArray()) {
assertFalse(singlebyteEncoder.canEncode(c));
assertTrue(doublebyteEncoder.canEncode(c));
}
// Ensure that double byte encoder doesn't just return true all the time...
assertFalse(doublebyteEncoder.canEncode('\u00BB'));
}

public void testEncode() throws CharacterCodingException, IOException {
CharactersetEncoder.EncodedChars encChars;// = doublebyteEncoder.encode(testCJKText);
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
// JAVA 1.5 has a bug in the JVM in which these err for some reason... JAVA 1.6 no issues
/*encChars.writeTo(bOut, 0, encChars.getLength());
byte[] bytes = bOut.toByteArray();
for (int i = 0; i < 12; i++) {
assertEquals(test6CJKChars[i], bytes[i]);
}
bOut.reset();*/

encChars = singlebyteEncoder.encode(testEngText);
encChars.writeTo(bOut, 0, encChars.getLength());
byte[] engBytes = bOut.toByteArray();
for (int i = 0; i < testEngChars.length; i++) {
assertEquals(testEngChars[i], engBytes[i]);
}
assertEquals(testEngChars.length, engBytes.length);
}
}

Loading…
Peruuta
Tallenna