blob: d2e58c7757b3ee7cbbfc670adce4f7a5ee3efc82 [file] [log] [blame]
/*
* Copyright 1999-2004 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.fonts;
import java.util.Map;
/**
* This class holds font state information and provides access to the font
* metrics.
*/
public class Font {
/** Default fallback key */
public static final String DEFAULT_FONT = "any,normal,400";
/** Normal font weight */
public static final int NORMAL = 400;
/** Bold font weight */
public static final int BOLD = 700;
private String fontName;
private int fontSize;
//private String fontFamily;
//private String fontStyle;
//private int fontWeight;
/**
* normal or small-caps font
*/
//private int fontVariant;
private FontMetrics metric;
/**
* Main constructor
* @param key key of the font
* @param met font metrics
* @param fontSize font size
*/
public Font(String key, FontMetrics met, int fontSize) {
this.fontName = key;
this.metric = met;
this.fontSize = fontSize;
}
/**
* Returns the font's ascender.
* @return the ascender
*/
public int getAscender() {
return metric.getAscender(fontSize) / 1000;
}
/**
* Returns the font's CapHeight.
* @return the capital height
*/
public int getCapHeight() {
return metric.getCapHeight(fontSize) / 1000;
}
/**
* Returns the font's Descender.
* @return the descender
*/
public int getDescender() {
return metric.getDescender(fontSize) / 1000;
}
/**
* Returns the font's name.
* @return the font name
*/
public String getFontName() {
return fontName;
}
/**
* Returns the font size
* @return the font size
*/
public int getFontSize() {
return fontSize;
}
/**
* Returns the XHeight
* @return the XHeight
*/
public int getXHeight() {
return metric.getXHeight(fontSize) / 1000;
}
/**
* Returns the font's kerning table
* @return the kerning table
*/
public Map getKerning() {
Map ret = metric.getKerningInfo();
if (ret != null) {
return ret;
} else {
return java.util.Collections.EMPTY_MAP;
}
}
/**
* Returns the width of a character
* @param charnum character to look up
* @return width of the character
*/
public int getWidth(int charnum) {
// returns width of given character number in millipoints
return (metric.getWidth(charnum, fontSize) / 1000);
}
/**
* Map a java character (unicode) to a font character.
* Default uses CodePointMapping.
* @param c character to map
* @return the mapped character
*/
public char mapChar(char c) {
if (metric instanceof org.apache.fop.fonts.Typeface) {
return ((org.apache.fop.fonts.Typeface)metric).mapChar(c);
}
// Use default CodePointMapping
char d = CodePointMapping.getMapping("WinAnsiEncoding").mapChar(c);
if (d != 0) {
c = d;
} else {
c = '#';
}
return c;
}
/**
* Determines whether this font contains a particular character/glyph.
* @param c character to check
* @return True if the character is supported, Falso otherwise
*/
public boolean hasChar(char c) {
if (metric instanceof org.apache.fop.fonts.Typeface) {
return ((org.apache.fop.fonts.Typeface)metric).hasChar(c);
} else {
// Use default CodePointMapping
return (CodePointMapping.getMapping("WinAnsiEncoding").mapChar(c) > 0);
}
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append('(');
/*
sbuf.append(fontFamily);
sbuf.append(',');*/
sbuf.append(fontName);
sbuf.append(',');
sbuf.append(fontSize);
/*
sbuf.append(',');
sbuf.append(fontStyle);
sbuf.append(',');
sbuf.append(fontWeight);*/
sbuf.append(')');
return sbuf.toString();
}
/**
* Helper method for getting the width of a unicode char
* from the current fontstate.
* This also performs some guessing on widths on various
* versions of space that might not exists in the font.
* @param c character to inspect
* @return the width of the character
*/
public int getCharWidth(char c) {
int width;
if ((c == '\n') || (c == '\r') || (c == '\t') || (c == '\u00A0')) {
width = getCharWidth(' ');
} else {
width = getWidth(mapChar(c));
if (width <= 0) {
// Estimate the width of spaces not represented in
// the font
int em = getWidth(mapChar('m'));
int en = getWidth(mapChar('n'));
if (em <= 0) {
em = 500 * getFontSize();
}
if (en <= 0) {
en = em - 10;
}
if (c == ' ') {
width = em;
}
if (c == '\u2000') {
width = en;
}
if (c == '\u2001') {
width = em;
}
if (c == '\u2002') {
width = em / 2;
}
if (c == '\u2003') {
width = getFontSize();
}
if (c == '\u2004') {
width = em / 3;
}
if (c == '\u2005') {
width = em / 4;
}
if (c == '\u2006') {
width = em / 6;
}
if (c == '\u2007') {
width = getCharWidth(' ');
}
if (c == '\u2008') {
width = getCharWidth('.');
}
if (c == '\u2009') {
width = em / 5;
}
if (c == '\u200A') {
width = 5;
}
if (c == '\u200B') {
width = 100;
}
if (c == '\u202F') {
width = getCharWidth(' ') / 2;
}
if (c == '\u3000') {
width = getCharWidth(' ') * 2;
}
}
}
return width;
}
/**
* Calculates the word width.
* @param word text to get width for
* @return the width of the text
*/
public int getWordWidth(String word) {
if (word == null) {
return 0;
}
int wordLength = word.length();
int width = 0;
char[] characters = new char[wordLength];
word.getChars(0, wordLength, characters, 0);
for (int i = 0; i < wordLength; i++) {
width += getCharWidth(characters[i]);
}
return width;
}
}