/*
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.sun.pdfview.font;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.io.IOException;
import com.sun.pdfview.PDFObject;
/**
* Supports width operations for Type1, Type1C, TrueType and Type3 fonts
*/
public abstract class OutlineFont extends PDFFont {
/** the first character code */
private int firstChar = -1;
/** the last character code */
private int lastChar = -1;
/** the widths for each character code */
private float[] widths;
/** Creates a new instance of OutlineFont */
public OutlineFont(String baseFont, PDFObject fontObj,
PDFFontDescriptor descriptor) throws IOException {
super(baseFont, descriptor);
PDFObject firstCharObj = fontObj.getDictRef("FirstChar");
PDFObject lastCharObj = fontObj.getDictRef("LastChar");
PDFObject widthArrayObj = fontObj.getDictRef("Widths");
if (firstCharObj != null) {
this.firstChar = firstCharObj.getIntValue();
}
if (lastCharObj != null) {
this.lastChar = lastCharObj.getIntValue();
}
if (widthArrayObj != null) {
PDFObject[] widthArray = widthArrayObj.getArray();
this.widths = new float[widthArray.length];
for (int i = 0; i < widthArray.length; i++) {
this.widths[i] = widthArray[i].getFloatValue() / getDefaultWidth();
}
}
}
/** Get the first character code */
public int getFirstChar() {
return this.firstChar;
}
/** Get the last character code */
public int getLastChar() {
return this.lastChar;
}
/** Get the default width in text space */
public int getDefaultWidth() {
return 1000;
}
/** Get the number of characters */
public int getCharCount() {
return (getLastChar() - getFirstChar()) + 1;
}
/** Get the width of a given character */
public float getWidth(char code, String name) {
int idx = (code & 0xff) - getFirstChar();
// make sure we're in range
if (idx < 0 || this.widths == null || idx >= this.widths.length) {
// try to get the missing width from the font descriptor
if (getDescriptor() != null) {
return getDescriptor().getMissingWidth() / (float)getDefaultWidth();
} else {
return 0;
}
}
return this.widths[idx];
}
/**
* Get the glyph for a given character code and name
*
* The preferred method of getting the glyph should be by name. If the
* name is null or not valid, then the character code should be used.
* If the both the code and the name are invalid, the undefined glyph
* should be returned.
*
* Note this method must *always* return a glyph.
*
* @param src the character code of this glyph
* @param name the name of this glyph or null if unknown
* @return a glyph for this character
*/
@Override
protected PDFGlyph getGlyph(char src, String name) {
GeneralPath outline = null;
float width = getWidth(src, name);
// first try by name
if (name != null) {
outline = getOutline(name, width);
}
// now try by character code (guaranteed to return)
if (outline == null) {
outline = getOutline(src, width);
}
// calculate the advance
Point2D.Float advance = new Point2D.Float(width, 0);
return new PDFGlyph(src, name, outline, advance);
}
/**
* Get a glyph outline by name
*
* @param name the name of the desired glyph
* @return the glyph outline, or null if unavailable
*/
protected abstract GeneralPath getOutline(String name, float width);
/**
* Get a glyph outline by character code
*
* Note this method must always return an outline
*
* @param src the character code of the desired glyph
* @return the glyph outline
*/
protected abstract GeneralPath getOutline(char src, float width);
}