blob: 3cb4b334349b4a02ae3411a239bdde6ac195b530 [file] [log] [blame]
/*
* 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.fonts.type1;
import java.awt.geom.Dimension2D;
import java.awt.geom.RectangularShape;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.xmlgraphics.java2d.Dimension2DDouble;
/**
* Represents the contents of a Type 1 AFM font metrics file.
*/
public class AFMFile {
private String fontName;
private String fullName;
private String familyName;
private String weight;
private RectangularShape fontBBox;
private String encodingScheme;
private String characterSet;
private Number capHeight;
private Number xHeight;
private Number ascender;
private Number descender;
private Number stdHW;
private Number stdVW;
private AFMWritingDirectionMetrics[] writingDirectionMetrics
= new AFMWritingDirectionMetrics[3];
private List charMetrics = new java.util.ArrayList();
//List<AFMCharMetrics>
private Map charNameToMetrics = new java.util.HashMap();
//Map<String, AFMCharMetrics>
private int firstChar = -1;
private int lastChar = -1;
private Map kerningMap;
//Map<String, Map<String, Dimension2D>>
/**
* Default constructor.
*/
public AFMFile() {
//nop
}
/**
* Returns the FontName value.
* @return the font name
*/
public String getFontName() {
return fontName;
}
/**
* Sets the FontName value.
* @param fontName the font name to set
*/
public void setFontName(String fontName) {
this.fontName = fontName;
}
/**
* Returns the FullName value.
* @return the full name of the font
*/
public String getFullName() {
return fullName;
}
/**
* Sets the FullName value.
* @param fullName the full name to set
*/
public void setFullName(String fullName) {
this.fullName = fullName;
}
/**
* Returns the FamilyName value.
* @return the family name of the font
*/
public String getFamilyName() {
return familyName;
}
/**
* Sets the FamilyName value.
* @param familyName the family name to set
*/
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
/**
* Returns the Weight value.
* @return the weight
*/
public String getWeight() {
return weight;
}
/**
* Sets the Weight value.
* @param weight the weight to set
*/
public void setWeight(String weight) {
this.weight = weight;
}
/**
* Returns the FontBBox value.
* @return the font's bounding box
*/
public RectangularShape getFontBBox() {
return fontBBox;
}
/**
* Returns the FontBBox value as integer array.
* @return the font's bounding box
*/
public int[] getFontBBoxAsIntArray() {
RectangularShape rect = getFontBBox();
return new int[] {
(int)Math.floor(rect.getMinX()), (int)Math.floor(rect.getMinY()),
(int)Math.ceil(rect.getMaxX()), (int)Math.ceil(rect.getMaxY())};
}
/**
* Sets the FontBBox value.
* @param fontBBox the fontBBox to set
*/
public void setFontBBox(RectangularShape fontBBox) {
this.fontBBox = fontBBox;
}
/**
* Returns the EncodingScheme value.
* @return the encoding scheme
*/
public String getEncodingScheme() {
return encodingScheme;
}
/**
* Sets the EncodingScheme value
* @param encodingScheme the encodingScheme to set
*/
public void setEncodingScheme(String encodingScheme) {
this.encodingScheme = encodingScheme;
}
/**
* Returns the CharacterSet value.
* @return the characterSet
*/
public String getCharacterSet() {
return characterSet;
}
/**
* Sets the CharacterSet value.
* @param characterSet the characterSet to set
*/
public void setCharacterSet(String characterSet) {
this.characterSet = characterSet;
}
/**
* Returns the CapHeight value.
* @return the capHeight
*/
public Number getCapHeight() {
return capHeight;
}
/**
* Sets the CapHeight value.
* @param capHeight the capHeight to set
*/
public void setCapHeight(Number capHeight) {
this.capHeight = capHeight;
}
/**
* Returns the XHeight value.
* @return the xHeight
*/
public Number getXHeight() {
return xHeight;
}
/**
* Sets the XHeight value.
* @param height the xHeight to set
*/
public void setXHeight(Number height) {
xHeight = height;
}
/**
* Returns the Ascender value.
* @return the ascender
*/
public Number getAscender() {
return ascender;
}
/**
* Sets the Ascender value.
* @param ascender the ascender to set
*/
public void setAscender(Number ascender) {
this.ascender = ascender;
}
/**
* Returns the Descender value.
* @return the descender
*/
public Number getDescender() {
return descender;
}
/**
* Sets the Descender value.
* @param descender the descender to set
*/
public void setDescender(Number descender) {
this.descender = descender;
}
/**
* Returns the StdHW value.
* @return the descender
*/
public Number getStdHW() {
return stdHW;
}
/**
* Sets the StdHW value.
* @param stdHW the StdHW to set
*/
public void setStdHW(Number stdHW) {
this.stdHW = stdHW;
}
/**
* Returns the StdVW value.
* @return the descender
*/
public Number getStdVW() {
return stdVW;
}
/**
* Sets the StdVW value.
* @param stdVW the StdVW to set
*/
public void setStdVW(Number stdVW) {
this.stdVW = stdVW;
}
/**
* Gets writing direction metrics.
* @param index the writing direction (0, 1 or 2)
* @return the writing direction metrics
*/
public AFMWritingDirectionMetrics getWritingDirectionMetrics(int index) {
return this.writingDirectionMetrics[index];
}
/**
* Sets writing direction metrics.
* @param index the writing direction (0, 1 or 2)
* @param metrics the writing direction metrics
*/
public void setWritingDirectionMetrics(int index, AFMWritingDirectionMetrics metrics) {
this.writingDirectionMetrics[index] = metrics;
}
/**
* Adds new character metrics.
* @param metrics the character metrics
*/
public void addCharMetrics(AFMCharMetrics metrics) {
String name = metrics.getCharName();
if (metrics.getUnicodeSequence() == null) {
//Ignore as no Unicode assignment is possible
return;
}
this.charMetrics.add(metrics);
if (name != null) {
this.charNameToMetrics.put(name, metrics);
}
int idx = metrics.getCharCode();
if (idx >= 0) { //Only if the character is part of the encoding
if (firstChar < 0 || idx < firstChar) {
firstChar = idx;
}
if (lastChar < 0 || idx > lastChar) {
lastChar = idx;
}
}
}
/**
* Returns the number of character available for this font.
* @return the number of character
*/
public int getCharCount() {
return this.charMetrics.size();
}
/**
* Returns the first character index in the encoding that has a glyph.
* @return the first character index with a glyph
*/
public int getFirstChar() {
return this.firstChar;
}
/**
* Returns the last character index in the encoding that has a glyph.
* @return the last character index with a glyph
*/
public int getLastChar() {
return this.lastChar;
}
/**
* Returns the character metrics associated with the character name.
* @param name the character name
* @return the character metrics or null if there's no such character
*/
public AFMCharMetrics getChar(String name) {
return (AFMCharMetrics)this.charNameToMetrics.get(name);
}
/**
* Returns the list of AFMCharMetrics instances representing all the available characters.
* @return a List of AFMCharMetrics instances
*/
public List getCharMetrics() {
return Collections.unmodifiableList(this.charMetrics);
}
/**
* Adds a X-kerning entry.
* @param name1 the name of the first character
* @param name2 the name of the second character
* @param kx kerning value in x-direction
*/
public void addXKerning(String name1, String name2, double kx) {
if (this.kerningMap == null) {
this.kerningMap = new java.util.HashMap();
}
Map entries = (Map)this.kerningMap.get(name1);
if (entries == null) {
entries = new java.util.HashMap();
this.kerningMap.put(name1, entries);
}
entries.put(name2, new Dimension2DDouble(kx, 0));
}
/**
* Indicates whether the font has kerning information.
* @return true if there is kerning information
*/
public boolean hasKerning() {
return this.kerningMap != null;
}
/**
* Creates and returns a kerning map for writing mode 0 (ltr) with character codes.
* @return the kerning map or null if there is no kerning information.
*/
public Map createXKerningMapEncoded() {
if (!hasKerning()) {
return null;
}
Map m = new java.util.HashMap();
Iterator iterFrom = this.kerningMap.entrySet().iterator();
while (iterFrom.hasNext()) {
Map.Entry entryFrom = (Map.Entry)iterFrom.next();
String name1 = (String)entryFrom.getKey();
AFMCharMetrics chm1 = getChar(name1);
if (chm1 == null || !chm1.hasCharCode()) {
continue;
}
Map container = null;
Map entriesTo = (Map)entryFrom.getValue();
Iterator iterTo = entriesTo.entrySet().iterator();
while (iterTo.hasNext()) {
Map.Entry entryTo = (Map.Entry)iterTo.next();
String name2 = (String)entryTo.getKey();
AFMCharMetrics chm2 = getChar(name2);
if (chm2 == null || !chm2.hasCharCode()) {
continue;
}
if (container == null) {
Integer k1 = new Integer(chm1.getCharCode());
container = (Map)m.get(k1);
if (container == null) {
container = new java.util.HashMap();
m.put(k1, container);
}
}
Dimension2D dim = (Dimension2D)entryTo.getValue();
container.put(new Integer(chm2.getCharCode()),
new Integer((int)Math.round(dim.getWidth())));
}
}
return m;
}
/** {@inheritDoc} */
public String toString() {
return "AFM: " + getFullName();
}
}