📄 type1font.java
字号:
/*
* $Id: Type1Font.java,v 1.12 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 com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.afm.*;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.io.*;
/** Reads a Type1 font
*
* @author Paulo Soares (psoares@consiste.pt)
*/
class Type1Font extends BaseFont
{
/** The Postscript font name.
*/
private String FontName;
/** The full name of the font.
*/
private String FullName;
/** The family name of the font.
*/
private String FamilyName;
/** The weight of the font: normal, bold, etc.
*/
private String Weight = "";
/** The italic angle of the font, usually 0.0 or negative.
*/
private float ItalicAngle = 0.0f;
/** <CODE>true</CODE> if all the characters have the same
* width.
*/
private boolean IsFixedPitch = false;
/** The character set of the font.
*/
private String CharacterSet;
/** The llx of the FontBox.
*/
private int llx = -50;
/** The lly of the FontBox.
*/
private int lly = -200;
/** The lurx of the FontBox.
*/
private int urx = 1000;
/** The ury of the FontBox.
*/
private int ury = 900;
/** The underline position.
*/
private int UnderlinePosition = -100;
/** The underline thickness.
*/
private int UnderlineThickness = 50;
/** The font's encoding name. This encoding is 'StandardEncoding' or
* 'AdobeStandardEncoding' for a font that can be totally encoded
* according to the characters names. For all other names the
* font is treated as symbolic.
*/
private String EncodingScheme = "FontSpecific";
/** A variable.
*/
private int CapHeight = 700;
/** A variable.
*/
private int XHeight = 480;
/** A variable.
*/
private int Ascender = 800;
/** A variable.
*/
private int Descender = -200;
/** A variable.
*/
private int StdHW;
/** A variable.
*/
private int StdVW = 80;
/** Represents the section CharMetrics in the AFM file. Each
* element of this array contains a <CODE>Object[3]</CODE> with an
* Integer, Integer and String. This is the code, width and name.
*/
private ArrayList CharMetrics = new ArrayList();
/** Represents the section KernPairs in the AFM file. The key is
* the name of the first character and the value is a <CODE>Object[]</CODE>
* with 2 elements for each kern pair. Position 0 is the name of
* the second character and position 1 is the kerning distance. This is
* repeated for all the pairs.
*/
private HashMap KernPairs = new HashMap();
/** The file in use.
*/
private String fileName;
/** <CODE>true</CODE> if this font is one of the 14 built in fonts.
*/
private boolean builtinFont = false;
/** Types of records in a PFB file. 1 is ASCII and 2 is BINARY.
* They have to appear in the PFB file in this sequence.
*/
private final static int pfbTypes[] = {1, 2, 1};
/** Creates a new Type1 font.
* @param afmFile the name of one of the 14 built-in fonts or the location of an AFM file. The file must end in '.afm'
* @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 AFM file is invalid
* @throws IOException the AFM file could not be read
*/
Type1Font(String afmFile, String enc, boolean emb) throws DocumentException, IOException
{
encoding = enc;
embedded = emb;
fileName = afmFile;
fontType = FONT_TYPE_T1;
BufferedReader fin = null;
if (BuiltinFonts14.containsKey(afmFile)) {
embedded = false;
builtinFont = true;
try {
String afm = null;
if (afmFile.equals("Courier"))
afm = Courier.afm;
else if (afmFile.equals("Courier-Bold"))
afm = CourierBold.afm;
else if (afmFile.equals("Courier-BoldOblique"))
afm = CourierBoldOblique.afm;
else if (afmFile.equals("Courier-Oblique"))
afm = CourierOblique.afm;
else if (afmFile.equals("Helvetica-Bold")) {
afm = HelveticaBold1.afm;
afm += HelveticaBold2.afm;
}
else if (afmFile.equals("Helvetica-BoldOblique")) {
afm = HelveticaBoldOblique1.afm;
afm += HelveticaBoldOblique2.afm;
}
else if (afmFile.equals("Helvetica-Oblique")) {
afm = HelveticaOblique1.afm;
afm += HelveticaOblique2.afm;
}
else if (afmFile.equals("Symbol"))
afm = Symbol.afm;
else if (afmFile.equals("Times-Roman"))
afm = TimesRoman.afm;
else if (afmFile.equals("Times-Bold"))
afm = TimesBold.afm;
else if (afmFile.equals("Times-BoldItalic"))
afm = TimesBoldItalic.afm;
else if (afmFile.equals("Times-Italic")) {
afm = TimesItalic1.afm;
afm += TimesItalic2.afm;
}
else if (afmFile.equals("ZapfDingbats"))
afm = ZapfDingbats.afm;
else {
afm = Helvetica1.afm;
afm += Helvetica2.afm;
}
fin = new BufferedReader(new StringReader(afm));
process(fin);
}
finally {
if (fin != null) {
try {
fin.close();
}
catch (Exception e) {
}
}
}
}
else if (afmFile.toLowerCase().endsWith(".afm")) {
try {
fin = new BufferedReader(new InputStreamReader(new FileInputStream(afmFile), PdfObject.ENCODING));
if (fin == null)
throw new DocumentException(afmFile + " not found as file.");
process(fin);
}
finally {
if (fin != null) {
try {
fin.close();
}
catch (Exception e) {
}
}
}
}
else
throw new DocumentException(afmFile + " is not an AFM font file.");
try {
EncodingScheme = EncodingScheme.trim();
if (EncodingScheme.equals("AdobeStandardEncoding") || EncodingScheme.equals("StandardEncoding")) {
fontSpecific = false;
}
" ".getBytes(enc); // check if the encoding exists
createEncoding();
}
catch (Exception e) {
throw new DocumentException(e.getMessage());
}
}
/** Gets the width from the font according to the <CODE>name</CODE> or,
* if the <CODE>name</CODE> is null, meaning it is a symbolic font,
* the char <CODE>c</CODE>.
* @param c the char if the font is symbolic
* @param name the glyph name
* @return the width of the char
*/
protected int getRawWidth(int c, String name)
{
try {
if (name == null) { // font specific
for (int k = 0; k < CharMetrics.size(); ++k) {
Object metrics[] = (Object[])CharMetrics.get(k);
if (((Integer)(metrics[0])).intValue() == c)
return ((Integer)(metrics[1])).intValue();
}
}
else {
if (name.equals(".notdef"))
return 0;
for (int k = 0; k < CharMetrics.size(); ++k) {
Object metrics[] = (Object[])CharMetrics.get(k);
if (name.equals(metrics[2]))
return ((Integer)(metrics[1])).intValue();
}
}
}
catch (Exception e) {
}
return 0;
}
/** Gets the kerning between two Unicode characters. The characters
* are converted to names and this names are used to find the kerning
* pairs in the <CODE>HashMap</CODE> <CODE>KernPairs</CODE>.
* @param char1 the first char
* @param char2 the second char
* @return the kerning to be applied
*/
public int getKerning(char char1, char char2)
{
String first = GlyphList.unicodeToName((int)char1);
if (first == null)
return 0;
String second = GlyphList.unicodeToName((int)char2);
if (second == null)
return 0;
Object obj[] = (Object[])KernPairs.get(first);
if (obj == null)
return 0;
for (int k = 0; k < obj.length; k += 2) {
if (second.equals(obj[k]))
return ((Integer)obj[k + 1]).intValue();
}
return 0;
}
/** Reads the font metrics
* @param fin AFM file with the font metrics
* @throws DocumentException the AFM file is invalid
* @throws IOException the AFM file could not be read
*/
public void process(BufferedReader fin) throws DocumentException, IOException
{
String line;
boolean isMetrics = false;
while ((line = fin.readLine()) != null)
{
StringTokenizer tok = new StringTokenizer(line);
if (!tok.hasMoreTokens())
continue;
String ident = tok.nextToken();
if (ident.equals("FontName"))
FontName = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("FullName"))
FullName = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("FamilyName"))
FamilyName = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("Weight"))
Weight = tok.nextToken("\u00ff").substring(1);
else if (ident.equals("ItalicAngle"))
ItalicAngle = Float.valueOf(tok.nextToken()).floatValue();
else if (ident.equals("IsFixedPitch"))
IsFixedPitch = tok.nextToken().equals("true");
else if (ident.equals("CharacterSet"))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -