/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.awt.font.truetype;
import java.awt.Font;
import java.awt.FontMetrics;
import java.io.IOException;
import org.jnode.awt.font.truetype.tables.CMapTable;
import org.jnode.awt.font.truetype.tables.HorizontalMetricsTable;
/**
* @author epr
*/
public class TTFFontMetrics extends FontMetrics {
private static final long serialVersionUID = 1L;
private final TTFFontData fontData;
private final double scale;
private final int fontSize;
/**
* @param font
* @param fontData
* @throws IOException
*/
public TTFFontMetrics(Font font, TTFFontData fontData)
throws IOException {
super(font);
if (font == null) {
throw new IllegalArgumentException("font cannot be null");
}
if (fontData == null) {
throw new IllegalArgumentException("fontData cannot be null");
}
this.fontData = fontData;
this.fontSize = font.getSize();
final double ascent = fontData.getHorizontalHeaderTable().getAscent();
this.scale = fontSize / ascent;
//System.out.println("Font=" + font.getName() + ", size=" + fontSize + ",
// scale=" + scale + ", ascent=" + ascent);
}
/**
* @param ch
* @return The width
* @see java.awt.FontMetrics#charWidth(char)
*/
public int charWidth(char ch) {
try {
final CMapTable cmapTable = fontData.getCMapTable();
final CMapTable.EncodingTable encTable = cmapTable.getEncodingTable(0);
final HorizontalMetricsTable hmTable = fontData.getHorizontalMetricsTable();
final int index = encTable.getTableFormat().getGlyphIndex(ch);
return (int) (hmTable.getAdvanceWidth(index) * scale);
} catch (IOException ex) {
return 0;
}
}
/**
* Note : We must override that method from {@link FontMetrics}.
* If we don't override {@link FontMetrics#charsWidth(char[], int, int)}
* or {@link FontMetrics#stringWidth(String)} then a stack overflow will
* happen since they are calling each other without any exit way !!!
*
*/
@Override
public int charsWidth(char[] data, int off, int len) {
int total = 0;
for (int i = off; i < (off + len); i++) {
total += charWidth(data[i]);
}
return total;
}
/**
* @return The ascent
* @see java.awt.FontMetrics#getAscent()
*/
public int getAscent() {
try {
final int ascent = (int) (fontData.getHorizontalHeaderTable().getAscent() * scale);
return ascent;
} catch (IOException ex) {
return 0;
}
}
/**
* @return The descent
* @see java.awt.FontMetrics#getDescent()
*/
public int getDescent() {
try {
final int descent = Math.abs((int) (fontData.getHorizontalHeaderTable().getDescent() * scale));
return descent;
} catch (IOException ex) {
return 0;
}
}
/**
* @return The maximum advance
* @see java.awt.FontMetrics#getMaxAdvance()
*/
public int getMaxAdvance() {
try {
return (int) (fontData.getHorizontalHeaderTable().getMaxAdvance() * scale);
} catch (IOException ex) {
return 0;
}
}
/**
* @return The maximum ascent
* @see java.awt.FontMetrics#getMaxAscent()
*/
public int getMaxAscent() {
return getAscent();
}
/**
* @return The maximum descent
* @see java.awt.FontMetrics#getMaxDescent()
*/
public int getMaxDescent() {
return getDescent();
}
}