diff options
Diffstat (limited to 'src/sandbox/org/apache/fop/render/afp/tools')
4 files changed, 457 insertions, 0 deletions
diff --git a/src/sandbox/org/apache/fop/render/afp/tools/BinaryUtils.java b/src/sandbox/org/apache/fop/render/afp/tools/BinaryUtils.java new file mode 100644 index 000000000..4dead37ac --- /dev/null +++ b/src/sandbox/org/apache/fop/render/afp/tools/BinaryUtils.java @@ -0,0 +1,131 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.render.afp.tools; + +import java.io.ByteArrayOutputStream; + +/** + * Library of utility useful conversion methods. + * + */ +public final class BinaryUtils { + + /** + * Convert an int into the corresponding byte array by encoding each + * two hexadecimal digits as a char. This will return a byte array + * to the length specified by bufsize. + * @param integer The int representation. + * @param bufsize The required byte array size. + */ + public static byte[] convert(int integer, int bufsize) { + + StringBuffer buf = new StringBuffer(Integer.toHexString(integer)); + if (buf.length() % 2 == 0) { + // Ignore even number of digits + } else { + // Convert to an even number of digits + buf.insert(0, "0"); + } + int size = buf.length() / 2; + while (size < bufsize) { + buf.insert(0, "00"); + size++; + }; + return convert(buf.toString()); + + } + + /** + * Convert an int into the corresponding byte array by encoding each + * two hexadecimal digits as a char. + * @param integer The int representation + */ + public static byte[] convert(int integer) { + + return convert(Integer.toHexString(integer)); + + } + + /** + * Convert a String of hexadecimal digits into the corresponding + * byte array by encoding each two hexadecimal digits as a byte. + * @param digits The hexadecimal digits representation. + */ + public static byte[] convert(String digits) { + + if (digits.length() % 2 == 0) { + // Even number of digits, so ignore + } else { + // Convert to an even number of digits + digits = "0" + digits; + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + for (int i = 0; i < digits.length(); i += 2) { + char c1 = digits.charAt(i); + char c2 = digits.charAt(i + 1); + byte b = 0; + if ((c1 >= '0') && (c1 <= '9')) + b += ((c1 - '0') * 16); + else if ((c1 >= 'a') && (c1 <= 'f')) + b += ((c1 - 'a' + 10) * 16); + else if ((c1 >= 'A') && (c1 <= 'F')) + b += ((c1 - 'A' + 10) * 16); + else + throw new IllegalArgumentException("Bad hexadecimal digit"); + if ((c2 >= '0') && (c2 <= '9')) + b += (c2 - '0'); + else if ((c2 >= 'a') && (c2 <= 'f')) + b += (c2 - 'a' + 10); + else if ((c2 >= 'A') && (c2 <= 'F')) + b += (c2 - 'A' + 10); + else + throw new IllegalArgumentException("Bad hexadecimal digit"); + baos.write(b); + } + return (baos.toByteArray()); + + } + + /** + * Convert the specified short into a byte array. + * @param value The value to be converted. + * @param array The array to receive the data. + * @param offset The offset into the byte array for the start of the value. + */ + public static void shortToByteArray( + short value, + byte[] array, + int offset) { + array[offset] = (byte) (value >>> 8); + array[offset + 1] = (byte) value; + } + + /** + * Convert the specified short into a byte array. + * @param value The value to be converted. + * @return The byte array + */ + public static byte[] shortToByteArray(short value) { + byte[] serverValue = new byte[2]; + shortToByteArray(value, serverValue, 0); + return serverValue; + } + +} diff --git a/src/sandbox/org/apache/fop/render/afp/tools/DTDEntityResolver.java b/src/sandbox/org/apache/fop/render/afp/tools/DTDEntityResolver.java new file mode 100644 index 000000000..94f4c46bd --- /dev/null +++ b/src/sandbox/org/apache/fop/render/afp/tools/DTDEntityResolver.java @@ -0,0 +1,112 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.render.afp.tools; + +import java.io.IOException; +import java.net.URL; + +import org.apache.fop.render.afp.exceptions.FontRuntimeException; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; + +/** + * An entity resolver for both DOM and SAX models of the SAX document. + * <p> + * The entity resolver only handles queries for the DTD. It will find any URI + * with a recognised public id and return an {@link org.xml.sax.InputSource}. + * <p> + * @author <a href="mailto:joe@exubero.com">Joe Schmetzer</a> + */ +public class DTDEntityResolver implements EntityResolver { + + /** Public ID for the AFP fonts 1.0 DTD. */ + public static final String AFP_DTD_1_0_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.0//EN"; + + /** Resource location for the AFP fonts 1.0 DTD. */ + public static final String AFP_DTD_1_0_RESOURCE = "afp-fonts-1.0.dtd"; + + /** Public ID for the AFP fonts 1.1 DTD. */ + public static final String AFP_DTD_1_1_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.1//EN"; + + /** Resource location for the AFP fonts 1.1 DTD. */ + public static final String AFP_DTD_1_1_RESOURCE = "afp-fonts-1.1.dtd"; + + /** Public ID for the AFP fonts 1.2 DTD. */ + public static final String AFP_DTD_1_2_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.2//EN"; + + /** Resource location for the AFP fonts 1.2 DTD. */ + public static final String AFP_DTD_1_2_RESOURCE = "afp-fonts-1.2.dtd"; + + /** + * Resolve the combination of system and public identifiers. + * If this resolver recognises the publicId, it will handle the resolution + * from the classpath, otherwise it will return null and allow the default + * resolution to occur. + * + * @param publicId the public identifier to use + * @param systemId the system identifier to resolve + * @return An input source to the entity or null if not handled + * @throws IOException an error reading the stream + */ + public InputSource resolveEntity(String publicId, String systemId) + throws IOException { + + URL resource = null; + if( AFP_DTD_1_2_ID.equals(publicId) ) { + resource = getResource( AFP_DTD_1_2_RESOURCE ); + } else if( AFP_DTD_1_1_ID.equals(publicId) ) { + resource = getResource( AFP_DTD_1_1_RESOURCE ); + } else if( AFP_DTD_1_0_ID.equals(publicId) ) { + throw new FontRuntimeException( + "The AFP Installed Font Definition 1.0 DTD is not longer supported" ); + } else if( systemId != null && systemId.indexOf("afp-fonts.dtd") >= 0 ) { + throw new FontRuntimeException( + "The AFP Installed Font Definition DTD must be specified using the public id" ); + } else { + return null; + } + + InputSource inputSource = new InputSource( resource.openStream() ); + inputSource.setPublicId( publicId ); + inputSource.setSystemId( systemId ); + + return inputSource; + } + + /** + * Returns the URL of a resource on the classpath + * @param resourceName the path to the resource relative to the root of the + * classpath. + * @return the URL of the required resource + * @throws FontRuntimeException if the resource could not be found. + */ + private URL getResource( String resourcePath ) { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } + + URL resource = cl.getResource( resourcePath ); + if( resource == null ) { + throw new FontRuntimeException( "Resource " + resourcePath + + " could not be found on the classpath" ); + } + + return resource; + } +} diff --git a/src/sandbox/org/apache/fop/render/afp/tools/StringUtils.java b/src/sandbox/org/apache/fop/render/afp/tools/StringUtils.java new file mode 100644 index 000000000..67b578446 --- /dev/null +++ b/src/sandbox/org/apache/fop/render/afp/tools/StringUtils.java @@ -0,0 +1,80 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.render.afp.tools; + +/** + * Library of utility methods useful in dealing with strings. + * + */ +public class StringUtils { + + /** + * Padds the string to the left with the given character for + * the specified length. + * @param input The input string. + * @param padding The char used for padding. + * @param length The length of the new string. + * @return The padded string. + */ + public static String lpad(String input, char padding, int length) { + + if (input == null) { + input = new String(); + } + + if (input.length() >= length) { + return input; + } else { + StringBuffer result = new StringBuffer(); + int numChars = length - input.length(); + for (int i = 0; i < numChars; i++) { + result.append(padding); + } + result.append(input); + return result.toString(); + } + } + + /** + * Padds the string to the right with the given character for + * the specified length. + * @param input The input string. + * @param padding The char used for padding. + * @param length The length of the new string. + * @return The padded string. + */ + public static String rpad(String input, char padding, int length) { + + if (input == null) { + input = new String(); + } + + if (input.length() >= length) { + return input; + } else { + StringBuffer result = new StringBuffer(input); + int numChars = length - input.length(); + for (int i = 0; i < numChars; i++) { + result.append(padding); + } + return result.toString(); + } + } + +}
\ No newline at end of file diff --git a/src/sandbox/org/apache/fop/render/afp/tools/StructuredFieldReader.java b/src/sandbox/org/apache/fop/render/afp/tools/StructuredFieldReader.java new file mode 100644 index 000000000..7df320c27 --- /dev/null +++ b/src/sandbox/org/apache/fop/render/afp/tools/StructuredFieldReader.java @@ -0,0 +1,134 @@ +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed 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.render.afp.tools; + +import java.io.IOException; +import java.io.InputStream; + +/** + * A helper class to read structured fields from a MO:DCA document. Each + * component of a mixed object document is explicitly defined and delimited + * in the data. This is accomplished through the use of MO:DCA data structures, + * called structured fields. Structured fields are used to envelop document + * components and to provide commands and information to applications using + * the data. Structured fields may contain one or more parameters. Each + * parameter provides one value from a set of values defined by the architecture. + * <p/> + * MO:DCA structured fields consist of two parts: an introducer that identifies + * the length and type of the structured field, and data that provides the + * structured field's effect. The data is contained in a set of parameters, + * which can consist of other data structures and data elements. The maximum + * length of a structured field is 32767 bytes. + * <p/> + */ +public class StructuredFieldReader { + + /** + * The input stream to read + */ + private InputStream _inputStream = null; + + /** + * The constructor for the StructuredFieldReader + * @param inputStream the input stream to process + */ + public StructuredFieldReader(InputStream inputStream) { + + _inputStream = inputStream; + + } + + /** + * Get the next structured field as identified by the identifer + * parameter (this must be a valid MO:DCA structured field. + * @param identifier the three byte identifier + */ + public byte[] getNext(byte[] identifier) throws IOException { + + int bufferPointer = 0; + byte[] bufferData = new byte[identifier.length + 2]; + for (int x = 0; x < identifier.length; x++) { + bufferData[x] = (byte) 0; + } + + int c; + while ((c = _inputStream.read()) > -1) { + + bufferData[bufferPointer] = (byte) c; + + // Check the last characters in the buffer + int index = 0; + boolean found = true; + + for (int i = identifier.length - 1; i > -1; i--) { + + int p = bufferPointer - index; + if (p < 0) { + p = bufferData.length + p; + } + + index++; + + if (identifier[i] != bufferData[p]) { + found = false; + break; + } + + } + + if (found) { + + byte[] length = new byte[2]; + + int a = bufferPointer - identifier.length; + if (a < 0) { + a = bufferData.length + a; + } + + int b = bufferPointer - identifier.length - 1; + if (b < 0) { + b = bufferData.length + b; + } + + length[0] = bufferData[b]; + length[1] = bufferData[a]; + + int reclength = ((length[0] & 0xFF) << 8) + (length[1] & 0xFF) - identifier.length -2; + + byte[] retval = new byte[reclength]; + + _inputStream.read(retval, 0, reclength); + + return retval; + + } + + bufferPointer++; + if (bufferPointer >= bufferData.length) { + bufferPointer = 0; + } + + } + + return new byte[] { + }; + + } + +} |