📄 truetypefont.java
字号:
/*
* $Id: TrueTypeFont.java,v 1.10 2001/12/10 13:53:22 blowagie Exp $
* $Name: $
*
* Copyright 2001 by Paulo Soares
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or 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 Library general Public License for more
* details.
*
* You should have received a copy of the GNU Library General Public License along
* with this library; if not, write to the Free Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA.
*
* If you didn't download this code from the following link, you should check if
* you aren't using an obsolete version:
* http://www.lowagie.com/iText/
*
* ir-arch Bruno Lowagie,
* Adolf Baeyensstraat 121
* 9040 Sint-Amandsberg
* BELGIUM
* tel. +32 (0)9 228.10.97
* bruno@lowagie.com
*
*/
package com.lowagie.text.pdf;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import com.lowagie.text.DocumentException;
/** Reads a Truetype font
*
* @author Paulo Soares (psoares@consiste.pt)
*/
class TrueTypeFont extends BaseFont {
/** Contains the location of the several tables. The key is the name of
* the table and the value is an <CODE>int[2]</CODE> where position 0
* is the offset from the start of the file and position 1 is the length
* of the table.
*/
protected HashMap tables;
/** The file in use.
*/
protected RandomAccessFile rf;
/** The file name.
*/
protected String fileName;
/** The offset from the start of the file to the table directory.
* It is 0 for TTF and may vary for TTC depending on the chosen font.
*/
protected int directoryOffset;
/** The index for the TTC font. It is an empty <CODE>String</CODE> for a
* TTF file.
*/
protected String ttcIndex;
/** The style modifier */
protected String style = "";
/** The content of table 'head'.
*/
protected FontHeader head = new FontHeader();
/** The content of table 'hhea'.
*/
protected HorizontalHeader hhea = new HorizontalHeader();
/** The content of table 'OS/2'.
*/
protected WindowsMetrics os_2 = new WindowsMetrics();
/** The width of the glyphs. This is essentially the content of table
* 'hmtx' normalized to 1000 units.
*/
protected int GlyphWidths[];
/** The map containing the code information for the table 'cmap', encoding 1.0.
* The key is the code and the value is an <CODE>int[2]</CODE> where position 0
* is the glyph number and position 1 is the glyph width normalized to 1000
* units.
*/
protected HashMap cmap10;
/** The map containing the code information for the table 'cmap', encoding 3.1
* in Unicode.
* <P>
* The key is the code and the value is an <CODE>int</CODE>[2] where position 0
* is the glyph number and position 1 is the glyph width normalized to 1000
* units.
*/
protected HashMap cmap31;
/** The map containig the kerning information. It represents the content of
* table 'kern'. The key is an <CODE>Integer</CODE> where the top 16 bits
* are the Unicode for the first character and the lower 16 bits are the
* Unicode for the second character. The value is the amount of kerning in
* normalized 1000 units as an <CODE>Integer</CODE>. This value is usually negative.
*/
protected HashMap kerning;
/** The font name. this name is usually extracted from the table 'name' with
* the 'Name ID' 6.
*/
protected String fontName;
/** The italic angle. It is usually extracted from the 'post' table or in it's
* absence with the code:
* <P>
* <PRE>
* -Math.atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI
* </PRE>
*/
protected double italicAngle;
/** <CODE>true</CODE> if all the glyphs have the same width.
*/
protected boolean isFixedPitch = false;
/** The components of table 'head'.
*/
protected class FontHeader {
/** A variable. */
int flags;
/** A variable. */
int unitsPerEm;
/** A variable. */
short xMin;
/** A variable. */
short yMin;
/** A variable. */
short xMax;
/** A variable. */
short yMax;
/** A variable. */
int macStyle;
}
/** The components of table 'hhea'.
*/
protected class HorizontalHeader {
/** A variable. */
short Ascender;
/** A variable. */
short Descender;
/** A variable. */
short LineGap;
/** A variable. */
int advanceWidthMax;
/** A variable. */
short minLeftSideBearing;
/** A variable. */
short minRightSideBearing;
/** A variable. */
short xMaxExtent;
/** A variable. */
short caretSlopeRise;
/** A variable. */
short caretSlopeRun;
/** A variable. */
int numberOfHMetrics;
}
/** The components of table 'OS/2'.
*/
protected class WindowsMetrics {
/** A variable. */
short xAvgCharWidth;
/** A variable. */
int usWeightClass;
/** A variable. */
int usWidthClass;
/** A variable. */
short fsType;
/** A variable. */
short ySubscriptXSize;
/** A variable. */
short ySubscriptYSize;
/** A variable. */
short ySubscriptXOffset;
/** A variable. */
short ySubscriptYOffset;
/** A variable. */
short ySuperscriptXSize;
/** A variable. */
short ySuperscriptYSize;
/** A variable. */
short ySuperscriptXOffset;
/** A variable. */
short ySuperscriptYOffset;
/** A variable. */
short yStrikeoutSize;
/** A variable. */
short yStrikeoutPosition;
/** A variable. */
short sFamilyClass;
/** A variable. */
byte panose[] = new byte[10];
/** A variable. */
byte achVendID[] = new byte[4];
/** A variable. */
int fsSelection;
/** A variable. */
int usFirstCharIndex;
/** A variable. */
int usLastCharIndex;
/** A variable. */
short sTypoAscender;
/** A variable. */
short sTypoDescender;
/** A variable. */
short sTypoLineGap;
/** A variable. */
int usWinAscent;
/** A variable. */
int usWinDescent;
/** A variable. */
int sCapHeight;
}
/** This constructor is present to allow extending the class.
*/
protected TrueTypeFont() {
}
/** Creates a new TrueType font.
* @param ttFile the location of the font on file. The file must end in '.ttf' or
* '.ttc' but can have modifiers after the name
* @param enc the encoding to be applied to this font
* @param emb true if the font is to be embedded in the PDF
* @throws DocumentException the font is invalid
* @throws IOException the font file could not be read
*/
TrueTypeFont(String ttFile, String enc, boolean emb) throws DocumentException, IOException {
String nameBase = getBaseName(ttFile);
String ttcName = getTTCName(nameBase);
if (nameBase.length() < ttFile.length()) {
style = ttFile.substring(nameBase.length());
}
encoding = enc;
embedded = emb;
fileName = ttcName;
fontType = FONT_TYPE_TT;
ttcIndex = "";
if (ttcName.length() < nameBase.length())
ttcIndex = nameBase.substring(ttcName.length() + 1);
if (fileName.toLowerCase().endsWith(".ttf") || fileName.toLowerCase().endsWith(".ttc")) {
process();
}
else
throw new DocumentException(fileName + style + " is not a TTF or TTC font file.");
try {
" ".getBytes(enc); // check if the encoding exists
createEncoding();
}
catch (UnsupportedEncodingException e) {
throw new DocumentException(e.getMessage());
}
}
/** Gets the name from a composed TTC file name.
* If I have for input "myfont.ttc,2" the return will
* be "myfont.ttc".
* @param name the full name
* @return the simple file name
*/
protected static String getTTCName(String name) {
int idx = name.toLowerCase().indexOf(".ttc,");
if (idx < 0)
return name;
else
return name.substring(0, idx + 4);
}
/**
* Reads the tables 'head', 'hhea', 'OS/2' and 'post' filling several variables.
* @throws DocumentException the font is invalid
* @throws IOException the font file could not be read
*/
void fillTables() throws DocumentException, IOException {
int table_location[];
table_location = (int[])tables.get("head");
if (table_location == null)
throw new DocumentException("Table 'head' does not exist in " + fileName + style);
rf.seek(table_location[0] + 16);
head.flags = rf.readUnsignedShort();
head.unitsPerEm = rf.readUnsignedShort();
rf.skipBytes(16);
head.xMin = rf.readShort();
head.yMin = rf.readShort();
head.xMax = rf.readShort();
head.yMax = rf.readShort();
head.macStyle = rf.readUnsignedShort();
table_location = (int[])tables.get("hhea");
if (table_location == null)
throw new DocumentException("Table 'hhea' does not exist " + fileName + style);
rf.seek(table_location[0] + 4);
hhea.Ascender = rf.readShort();
hhea.Descender = rf.readShort();
hhea.LineGap = rf.readShort();
hhea.advanceWidthMax = rf.readUnsignedShort();
hhea.minLeftSideBearing = rf.readShort();
hhea.minRightSideBearing = rf.readShort();
hhea.xMaxExtent = rf.readShort();
hhea.caretSlopeRise = rf.readShort();
hhea.caretSlopeRun = rf.readShort();
rf.skipBytes(12);
hhea.numberOfHMetrics = rf.readUnsignedShort();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -