All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.fop.afp.fonts.CharacterSet Maven / Gradle / Ivy

Go to download

Apache FOP (Formatting Objects Processor) is the world's first print formatter driven by XSL formatting objects (XSL-FO) and the world's first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PCL, PS, AFP, TIFF, PNG, SVG, XML (area tree representation), Print, AWT and TXT. The primary output target is PDF.

There is a newer version: 2.9
Show newest version
/*
 * 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: CharacterSet.java 946585 2010-05-20 09:52:27Z jeremias $ */

package org.apache.fop.afp.fonts;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URI;
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;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Map;

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

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

/**
 * The IBM Font Object Content Architecture (FOCA) supports presentation
 * of character shapes by defining their characteristics, which include
 * font description information for identifying the characters, font metric
 * information for positioning the characters, and character shape information
 * for presenting the character images.
 * 

* Presenting a graphic character on a presentation surface requires * information on the rotation and position of character on the physical * or logical page. *

* This class proivdes font metric information for a particular font * as identified by the character set name. This information is obtained * directly from the AFP font files which must be installed in the path * specified in the afp-fonts xml definition file. *

*/ public class CharacterSet { /** Static logging instance */ protected static final Log LOG = LogFactory.getLog(CharacterSet.class.getName()); /** default codepage */ public static final String DEFAULT_CODEPAGE = "T1V10500"; /** default encoding */ public static final String DEFAULT_ENCODING = "Cp500"; private static final int MAX_NAME_LEN = 8; /** The code page to which the character set relates */ protected String codePage; /** The encoding used for the code page */ protected String encoding; /** The charset encoder corresponding to this encoding */ private CharsetEncoder encoder; /** The character set relating to the font */ protected String name; /** The path to the installed fonts */ private ResourceAccessor accessor; /** The current orientation (currently only 0 is supported by FOP) */ private final String currentOrientation = "0"; /** The collection of objects for each orientation */ private Map characterSetOrientations = null; /** The nominal vertical size (in millipoints) for bitmap fonts. 0 for outline fonts. */ private int nominalVerticalSize = 0; /** * 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 encoding the encoding of the font * @param name the character set name * @param path the path to the installed afp fonts * @deprecated Please use {@link #CharacterSet(String, String, String, URI)} instead. */ public CharacterSet(String codePage, String encoding, String name, String path) { this(codePage, encoding, name, 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. * * @param codePage the code page identifier * @param encoding the encoding of the font * @param name the character set name * @param accessor the resource accessor to load resource with */ CharacterSet(String codePage, String encoding, String name, ResourceAccessor accessor) { if (name.length() > MAX_NAME_LEN) { String msg = "Character set name '" + name + "' must be a maximum of " + MAX_NAME_LEN + " characters"; LOG.error("Constructor:: " + msg); throw new IllegalArgumentException(msg); } if (name.length() < MAX_NAME_LEN) { this.name = StringUtils.rpad(name, ' ', MAX_NAME_LEN); } else { this.name = name; } this.codePage = codePage; 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.accessor = accessor; this.characterSetOrientations = new java.util.HashMap(4); } /** * Add character set metric information for the different orientations * * @param cso the metrics for the orientation */ public void addCharacterSetOrientation(CharacterSetOrientation cso) { characterSetOrientations.put( String.valueOf(cso.getOrientation()), cso); } /** * Sets the nominal vertical size of the font in the case of bitmap fonts. * @param nominalVerticalSize the nominal vertical size (in millipoints) */ public void setNominalVerticalSize(int nominalVerticalSize) { this.nominalVerticalSize = nominalVerticalSize; } /** * Returns the nominal vertical size of the font in the case of bitmap fonts. For outline fonts, * zero is returned, because these are scalable fonts. * @return the nominal vertical size (in millipoints) for bitmap fonts, or 0 for outline fonts. */ public int getNominalVerticalSize() { return this.nominalVerticalSize; } /** * Ascender height is the distance from the character baseline to the * top of the character box. A negative ascender height signifies that * all of the graphic character is below the character baseline. For * a character rotation other than 0, ascender height loses its * meaning when the character is lying on its side or is upside down * with respect to normal viewing orientation. For the general case, * Ascender Height is the characters most positive y-axis value. * For bounded character boxes, for a given character having an * ascender, ascender height and baseline offset are equal. * * @return the ascender value in millipoints */ public int getAscender() { return getCharacterSetOrientation().getAscender(); } /** * Cap height is the average height of the uppercase characters in * a font. This value is specified by the designer of a font and is * usually the height of the uppercase M. * * @return the cap height value in millipoints */ public int getCapHeight() { return getCharacterSetOrientation().getCapHeight(); } /** * Descender depth is the distance from the character baseline to * the bottom of a character box. A negative descender depth signifies * that all of the graphic character is above the character baseline. * * @return the descender value in millipoints */ public int getDescender() { return getCharacterSetOrientation().getDescender(); } /** * Returns the first character in the character set * * @return the first character in the character set (Unicode codepoint) */ public char getFirstChar() { return getCharacterSetOrientation().getFirstChar(); } /** * Returns the last character in the character set * * @return the last character in the character set (Unicode codepoint) */ public char getLastChar() { return getCharacterSetOrientation().getLastChar(); } /** * Returns the resource accessor to load the font resources with. * @return the resource accessor to load the font resources with */ public ResourceAccessor getResourceAccessor() { return this.accessor; } /** * Get the width (in 1/1000ths of a point size) of all characters * * @return the widths of all characters */ public int[] getWidths() { return getCharacterSetOrientation().getWidths(); } /** * XHeight refers to the height of the lower case letters above the baseline. * * @return the typical height of characters */ public int getXHeight() { return getCharacterSetOrientation().getXHeight(); } /** * Get the width (in 1/1000ths of a point size) of the character * identified by the parameter passed. * * @param character the Unicode character from which the width will be calculated * @return the width of the character */ public int getWidth(char character) { return getCharacterSetOrientation().getWidth(character); } /** * Returns the AFP character set identifier * * @return the AFP character set identifier */ public String getName() { return name; } /** * Returns the AFP character set identifier as a byte array * * @return the AFP character set identifier as a byte array */ public byte[] getNameBytes() { byte[] nameBytes = null; try { nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING); } catch (UnsupportedEncodingException usee) { nameBytes = name.getBytes(); LOG.warn( "UnsupportedEncodingException translating the name " + name); } return nameBytes; } /** * Returns the AFP code page identifier * * @return the AFP code page identifier */ public String getCodePage() { return codePage; } /** * Returns the AFP code page encoding * * @return the AFP code page encoding */ public String getEncoding() { return encoding; } /** * Helper method to return the current CharacterSetOrientation, note * that FOP does not yet implement the "reference-orientation" * attribute therefore we always use the orientation zero degrees, * Other orientation information is captured for use by a future * implementation (whenever FOP implement the mechanism). This is also * the case for landscape prints which use an orientation of 270 degrees, * in 99.9% of cases the font metrics will be the same as the 0 degrees * therefore the implementation currently will always use 0 degrees. * * @return characterSetOrentation The current orientation metrics. */ private CharacterSetOrientation getCharacterSetOrientation() { CharacterSetOrientation c = (CharacterSetOrientation) characterSetOrientations.get(currentOrientation); return c; } /** * Indicates whether the given char in the character set. * @param c the character to check * @return true if the character is in the character set */ public boolean hasChar(char c) { if (encoder != null) { return encoder.canEncode(c); } else { //Sun Java 1.4.2 compatibility return true; } } /** * Encodes a character sequence to a byte array. * @param chars the characters * @return the encoded characters * @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()); } } } /** * Map a Unicode character to a code point in the font. * The code tables are already converted to Unicode therefore * we can use the identity mapping. * * @param c the Unicode character to map * @return the mapped character */ public char mapChar(char c) { //TODO This is not strictly correct but we'll let it be for the moment return c; } /** * Returns the increment for an space. * @return the space increment */ public int getSpaceIncrement() { return getCharacterSetOrientation().getSpaceIncrement(); } /** * Returns the increment for an em space. * @return the em space increment */ public int getEmSpaceIncrement() { return getCharacterSetOrientation().getEmSpaceIncrement(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy