001: /*
002: * $Id: OutlineFont.java,v 1.2 2007/12/20 18:33:31 rbair Exp $
003: *
004: * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005: * Santa Clara, California 95054, U.S.A. All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020: */
021:
022: package com.sun.pdfview.font;
023:
024: import java.awt.geom.GeneralPath;
025: import java.awt.geom.Point2D;
026: import java.io.IOException;
027:
028: import com.sun.pdfview.PDFObject;
029:
030: /**
031: * Supports width operations for Type1, Type1C, TrueType and Type3 fonts
032: */
033: public abstract class OutlineFont extends PDFFont {
034:
035: /** the first character code */
036: private int firstChar = -1;
037:
038: /** the last character code */
039: private int lastChar = -1;
040:
041: /** the widths for each character code */
042: private float[] widths;
043:
044: /** Creates a new instance of OutlineFont */
045: public OutlineFont(String baseFont, PDFObject fontObj,
046: PDFFontDescriptor descriptor) throws IOException {
047: super (baseFont, descriptor);
048:
049: PDFObject firstCharObj = fontObj.getDictRef("FirstChar");
050: PDFObject lastCharObj = fontObj.getDictRef("LastChar");
051: PDFObject widthArrayObj = fontObj.getDictRef("Widths");
052:
053: if (firstCharObj != null) {
054: firstChar = firstCharObj.getIntValue();
055: }
056: if (lastCharObj != null) {
057: lastChar = lastCharObj.getIntValue();
058: }
059:
060: if (widthArrayObj != null) {
061: PDFObject[] widthArray = widthArrayObj.getArray();
062:
063: widths = new float[widthArray.length];
064:
065: for (int i = 0; i < widthArray.length; i++) {
066: widths[i] = widthArray[i].getFloatValue()
067: / getDefaultWidth();
068: }
069: }
070: }
071:
072: /** Get the first character code */
073: public int getFirstChar() {
074: return firstChar;
075: }
076:
077: /** Get the last character code */
078: public int getLastChar() {
079: return lastChar;
080: }
081:
082: /** Get the default width in text space */
083: public int getDefaultWidth() {
084: return 1000;
085: }
086:
087: /** Get the number of characters */
088: public int getCharCount() {
089: return (getLastChar() - getFirstChar()) + 1;
090: }
091:
092: /** Get the width of a given character */
093: public float getWidth(char code, String name) {
094: int idx = (code & 0xff) - getFirstChar();
095:
096: // make sure we're in range
097: if (idx < 0 || widths == null || idx >= widths.length) {
098: // try to get the missing width from the font descriptor
099: if (getDescriptor() != null) {
100: return getDescriptor().getMissingWidth();
101: } else {
102: return 0;
103: }
104: }
105:
106: return widths[idx];
107: }
108:
109: /**
110: * Get the glyph for a given character code and name
111: *
112: * The preferred method of getting the glyph should be by name. If the
113: * name is null or not valid, then the character code should be used.
114: * If the both the code and the name are invalid, the undefined glyph
115: * should be returned.
116: *
117: * Note this method must *always* return a glyph.
118: *
119: * @param src the character code of this glyph
120: * @param name the name of this glyph or null if unknown
121: * @return a glyph for this character
122: */
123: protected PDFGlyph getGlyph(char src, String name) {
124: GeneralPath outline = null;
125: float width = getWidth(src, name);
126:
127: // first try by name
128: if (name != null) {
129: outline = getOutline(name, width);
130: }
131:
132: // now try by character code (guaranteed to return)
133: if (outline == null) {
134: outline = getOutline(src, width);
135: }
136:
137: // calculate the advance
138: Point2D.Float advance = new Point2D.Float(width, 0);
139: return new PDFGlyph(src, name, outline, advance);
140: }
141:
142: /**
143: * Get a glyph outline by name
144: *
145: * @param name the name of the desired glyph
146: * @return the glyph outline, or null if unavailable
147: */
148: protected abstract GeneralPath getOutline(String name, float width);
149:
150: /**
151: * Get a glyph outline by character code
152: *
153: * Note this method must always return an outline
154: *
155: * @param src the character code of the desired glyph
156: * @return the glyph outline
157: */
158: protected abstract GeneralPath getOutline(char src, float width);
159: }
|