📄 basefont.java
字号:
*Creates new BaseFont
*/
protected BaseFont() {
}
/**
* Creates a new font. This font can be one of the 14 built in types,
* a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the
* Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier
* appended to the name. These modifiers are: Bold, Italic and BoldItalic. An
* example would be "STSong-Light,Bold". Note that this modifiers do not work if
* the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1".
* This would get the second font (indexes start at 0), in this case "MS PGothic".
* <P>
* The fonts are cached and if they already exist they are extracted from the cache,
* not parsed again.
* <P>
* Besides the common encodings described by name, custom encodings
* can also be made. These encodings will only work for the single byte fonts
* Type1 and TrueType. The encoding string starts with a '#'
* followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list
* of hex values representing the Unicode codes that compose that encoding.<br>
* The "simple" encoding is recommended for TrueType fonts
* as the "full" encoding risks not matching the character with the right glyph
* if not done with care.<br>
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be
* described by non standard names like the Tex math fonts. Each group of three elements
* compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character
* used to access the glyph. The space must be assigned to character position 32 otherwise
* text justification will not work.
* <P>
* Example for a "simple" encoding that includes the Unicode
* character space, A, B and ecyrillic:
* <PRE>
* "# simple 32 0020 0041 0042 0454"
* </PRE>
* <P>
* Example for a "full" encoding for a Type1 Tex font:
* <PRE>
* "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
* </PRE>
* <P>
* This method calls:<br>
* <PRE>
* createFont(name, encoding, embedded, true, null, null);
* </PRE>
* @param name the name of the font or it's location on file
* @param encoding the encoding to be applied to this font
* @param embedded true if the font is to be embedded in the PDF
* @return returns a new font. This font may come from the cache
* @throws DocumentException the font is invalid
* @throws IOException the font file could not be read
*/
public static BaseFont createFont(String name, String encoding, boolean embedded) throws DocumentException, IOException {
return createFont(name, encoding, embedded, true, null, null);
}
/** Creates a new font. This font can be one of the 14 built in types,
* a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the
* Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier
* appended to the name. These modifiers are: Bold, Italic and BoldItalic. An
* example would be "STSong-Light,Bold". Note that this modifiers do not work if
* the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1".
* This would get the second font (indexes start at 0), in this case "MS PGothic".
* <P>
* The fonts may or may not be cached depending on the flag <CODE>cached</CODE>.
* If the <CODE>byte</CODE> arrays are present the font will be
* read from them instead of the name. A name is still required to identify
* the font type.
* <P>
* Besides the common encodings described by name, custom encodings
* can also be made. These encodings will only work for the single byte fonts
* Type1 and TrueType. The encoding string starts with a '#'
* followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list
* of hex values representing the Unicode codes that compose that encoding.<br>
* The "simple" encoding is recommended for TrueType fonts
* as the "full" encoding risks not matching the character with the right glyph
* if not done with care.<br>
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be
* described by non standard names like the Tex math fonts. Each group of three elements
* compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character
* used to access the glyph. The space must be assigned to character position 32 otherwise
* text justification will not work.
* <P>
* Example for a "simple" encoding that includes the Unicode
* character space, A, B and ecyrillic:
* <PRE>
* "# simple 32 0020 0041 0042 0454"
* </PRE>
* <P>
* Example for a "full" encoding for a Type1 Tex font:
* <PRE>
* "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
* </PRE>
* @param name the name of the font or it's location on file
* @param encoding the encoding to be applied to this font
* @param embedded true if the font is to be embedded in the PDF
* @param cached true if the font comes from the cache or is added to
* the cache if new, false if the font is always created new
* @param ttfAfm the true type font or the afm in a byte array
* @param pfb the pfb in a byte array
* @return returns a new font. This font may come from the cache but only if cached
* is true, otherwise it will always be created new
* @throws DocumentException the font is invalid
* @throws IOException the font file could not be read
*/
public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[]) throws DocumentException, IOException {
return createFont(name, encoding, embedded, cached, ttfAfm, pfb, false);
}
/** Creates a new font. This font can be one of the 14 built in types,
* a Type1 font referred to by an AFM or PFM file, a TrueType font (simple or collection) or a CJK font from the
* Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier
* appended to the name. These modifiers are: Bold, Italic and BoldItalic. An
* example would be "STSong-Light,Bold". Note that this modifiers do not work if
* the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1".
* This would get the second font (indexes start at 0), in this case "MS PGothic".
* <P>
* The fonts may or may not be cached depending on the flag <CODE>cached</CODE>.
* If the <CODE>byte</CODE> arrays are present the font will be
* read from them instead of the name. A name is still required to identify
* the font type.
* <P>
* Besides the common encodings described by name, custom encodings
* can also be made. These encodings will only work for the single byte fonts
* Type1 and TrueType. The encoding string starts with a '#'
* followed by "simple" or "full". If "simple" there is a decimal for the first character position and then a list
* of hex values representing the Unicode codes that compose that encoding.<br>
* The "simple" encoding is recommended for TrueType fonts
* as the "full" encoding risks not matching the character with the right glyph
* if not done with care.<br>
* The "full" encoding is specially aimed at Type1 fonts where the glyphs have to be
* described by non standard names like the Tex math fonts. Each group of three elements
* compose a code position: the one byte code order in decimal or as 'x' (x cannot be the space), the name and the Unicode character
* used to access the glyph. The space must be assigned to character position 32 otherwise
* text justification will not work.
* <P>
* Example for a "simple" encoding that includes the Unicode
* character space, A, B and ecyrillic:
* <PRE>
* "# simple 32 0020 0041 0042 0454"
* </PRE>
* <P>
* Example for a "full" encoding for a Type1 Tex font:
* <PRE>
* "# full 'A' nottriangeqlleft 0041 'B' dividemultiply 0042 32 space 0020"
* </PRE>
* @param name the name of the font or it's location on file
* @param encoding the encoding to be applied to this font
* @param embedded true if the font is to be embedded in the PDF
* @param cached true if the font comes from the cache or is added to
* the cache if new, false if the font is always created new
* @param ttfAfm the true type font or the afm in a byte array
* @param pfb the pfb in a byte array
* @param noThrow if true will not throw an exception if the font is not recognized and will return null, if false will throw
* an exception if the font is not recognized. Note that even if true an exception may be thrown in some circumstances.
* This parameter is useful for FontFactory that may have to check many invalid font names before finding the right one
* @return returns a new font. This font may come from the cache but only if cached
* is true, otherwise it will always be created new
* @throws DocumentException the font is invalid
* @throws IOException the font file could not be read
*/
public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[], boolean noThrow) throws DocumentException, IOException {
String nameBase = getBaseName(name);
encoding = normalizeEncoding(encoding);
boolean isBuiltinFonts14 = BuiltinFonts14.containsKey(name);
boolean isCJKFont = isBuiltinFonts14 ? false : CJKFont.isCJKFont(nameBase, encoding);
if (isBuiltinFonts14 || isCJKFont)
embedded = false;
else if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V))
embedded = true;
BaseFont fontFound = null;
BaseFont fontBuilt = null;
String key = name + "\n" + encoding + "\n" + embedded;
if (cached) {
synchronized (fontCache) {
fontFound = (BaseFont)fontCache.get(key);
}
if (fontFound != null)
return fontFound;
}
if (isBuiltinFonts14 || name.toLowerCase().endsWith(".afm") || name.toLowerCase().endsWith(".pfm")) {
fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb);
fontBuilt.fastWinansi = encoding.equals(CP1252);
}
else if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) {
if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V))
fontBuilt = new TrueTypeFontUnicode(name, encoding, embedded, ttfAfm);
else {
fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm);
fontBuilt.fastWinansi = encoding.equals(CP1252);
}
}
else if (isCJKFont)
fontBuilt = new CJKFont(name, encoding, embedded);
else if (noThrow)
return null;
else
throw new DocumentException("Font '" + name + "' with '" + encoding + "' is not recognized.");
if (cached) {
synchronized (fontCache) {
fontFound = (BaseFont)fontCache.get(key);
if (fontFound != null)
return fontFound;
fontCache.put(key, fontBuilt);
}
}
return fontBuilt;
}
/**
* Creates a font based on an existing document font. The created font font may not
* behave as expected, depending on the encoding or subset.
* @param fontRef the reference to the document font
* @return the font
*/
public static BaseFont createFont(PRIndirectReference fontRef) {
return new DocumentFont(fontRef);
}
/**
* Gets the name without the modifiers Bold, Italic or BoldItalic.
* @param name the full name of the font
* @return the name without the modifiers Bold, Italic or BoldItalic
*/
protected static String getBaseName(String name) {
if (name.endsWith(",Bold"))
return name.substring(0, name.length() - 5);
else if (name.endsWith(",Italic"))
return name.substring(0, name.length() - 7);
else if (name.endsWith(",BoldItalic"))
return name.substring(0, name.length() - 11);
else
return name;
}
/**
* Normalize the encoding names. "winansi" is changed to "Cp1252" and
* "macroman" is changed to "MacRoman".
* @param enc the encoding to be normalized
* @return the normalized encoding
*/
protected static String normalizeEncoding(String enc) {
if (enc.equals("winansi") || enc.equals(""))
return CP1252;
else if (enc.equals("macroman"))
return MACROMAN;
else
return enc;
}
/**
* Creates the <CODE>widths</CODE> and the <CODE>differences</CODE> arrays
*/
protected void createEncoding() {
if (encoding.startsWith("#")) {
specialMap = new IntHashtable();
StringTokenizer tok = new StringTokenizer(encoding.substring(1), " ,\t\n\r\f");
if (tok.nextToken().equals("full")) {
while (tok.hasMoreTokens()) {
String order = tok.nextToken();
String name = tok.nextToken();
char uni = (char)Integer.parseInt(tok.nextToken(), 16);
int orderK;
if (order.startsWith("'"))
orderK = (int)order.charAt(1);
else
orderK = Integer.parseInt(order);
orderK %= 256;
specialMap.put((int)uni, orderK);
differences[orderK] = name;
unicodeDifferences[orderK] = uni;
widths[orderK] = getRawWidth((int)uni, name);
charBBoxes[orderK] = getRawCharBBox((int)uni, name);
}
}
else {
int k = 0;
if (tok.hasMoreTokens())
k = Integer.parseInt(tok.nextToken());
while (tok.hasMoreTokens() && k < 256) {
String hex = tok.nextToken();
int uni = Integer.parseInt(hex, 16) % 0x10000;
String name = GlyphList.unicodeToName(uni);
if (name != null) {
specialMap.put(uni, k);
differences[k] = name;
unicodeDifferences[k] = (char)uni;
widths[k] = getRawWidth(uni, name);
charBBoxes[k] = getRawCharBBox(uni, name);
++k;
}
}
}
for (int k = 0; k < 256; ++k) {
if (differences[k] == null) {
differences[k] = notdef;
}
}
}
else if (fontSpecific) {
for (int k = 0; k < 256; ++k) {
widths[k] = getRawWidth(k, null);
charBBoxes[k] = getRawCharBBox(k, null);
}
}
else {
String s;
String name;
char c;
byte b[] = new byte[1];
for (int k = 0; k < 256; ++k) {
b[0] = (byte)k;
s = PdfEncodings.convertToString(b, encoding);
if (s.length() > 0) {
c = s.charAt(0);
}
else {
c = '?';
}
name = GlyphList.unicodeToName((int)c);
if (name == null)
name = notdef;
differences[k] = name;
unicodeDifferences[k] = c;
widths[k] = getRawWidth((int)c, name);
charBBoxes[k] = getRawCharBBox((int)c, name);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -