📄 basefont.java
字号:
bytes = contents; put(PdfName.LENGTH, new PdfNumber(bytes.length)); if (subType != null) put(PdfName.SUBTYPE, new PdfName(subType)); flateCompress(); } catch (Exception e) { throw new DocumentException(e.getMessage()); } } } /** *Creates new BaseFont */ protected BaseFont() { } /** Creates a new font. This font can be one of the 14 built in types, * a Type1 font referred by an AFM 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> * 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 by an AFM 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. The name is still required to identify * the font type. * @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 { 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")) { fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb); fontBuilt.fastWinansi = encoding.equals(CP1252); } else if (nameBase.toLowerCase().endsWith(".ttf") || 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 (nameBase.toLowerCase().endsWith(".otf")) { fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm); fontBuilt.fastWinansi = encoding.equals(CP1252); } else if (isCJKFont) fontBuilt = new CJKFont(name, encoding, embedded); 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; } /** * 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 * @throws UnsupportedEncodingException the encoding is not supported */ protected void createEncoding() throws UnsupportedEncodingException { if (fontSpecific) { for (int k = 0; k < 256; ++k) widths[k] = getRawWidth(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 = new String(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); } } } /** * Gets the width from the font according to the Unicode char <CODE>c</CODE> * or the <CODE>name</CODE>. If the <CODE>name</CODE> is null it's a symbolic font. * @param c the unicode char * @param name the glyph name * @return the width of the char */ protected abstract int getRawWidth(int c, String name); /** * Gets the kerning between two Unicode chars. * @param char1 the first char * @param char2 the second char * @return the kerning to be applied */ public abstract int getKerning(char char1, char char2); /** * Gets the width of a <CODE>char</CODE> in normalized 1000 units. * @param char1 the unicode <CODE>char</CODE> to get the width of * @return the width in normalized 1000 units */ public int getWidth(char char1) { if (fastWinansi) { if (char1 < 128 || (char1 >= 160 && char1 <= 255)) return widths[char1]; return widths[PdfEncodings.winansi.get(char1)]; } return getWidth(new String(new char[]{char1})); } /** * Gets the width of a <CODE>String</CODE> in normalized 1000 units. * @param text the <CODE>String</CODE> to get the witdth of * @return the width in normalized 1000 units */ public int getWidth(String text) { int total = 0; if (fastWinansi) { int len = text.length(); for (int k = 0; k < len; ++k) { char char1 = text.charAt(k); if (char1 < 128 || (char1 >= 160 && char1 <= 255)) total += widths[char1]; else total += widths[PdfEncodings.winansi.get(char1)]; } return total; } else { byte mbytes[] = convertToBytes(text); for (int k = 0; k < mbytes.length; ++k) total += widths[0xff & mbytes[k]]; } return total; } /** * Gets the width of a <CODE>String</CODE> in points taking kerning * into account. * @param text the <CODE>String</CODE> to get the witdth of * @param fontSize the font size * @return the width in points */ public float getWidthPointKerned(String text, float fontSize) { float size = (float)getWidth(text) * 0.001f * fontSize; if (!hasKernPairs()) return size; int len = text.length() - 1; int kern = 0; char c[] = text.toCharArray(); for (int k = 0; k < len; ++k) { kern += getKerning(c[k], c[k + 1]); } return size + kern * 0.001f * fontSize; } /** * Gets the width of a <CODE>String</CODE> in points. * @param text the <CODE>String</CODE> to get the witdth of * @param fontSize the font size * @return the width in points */ public float getWidthPoint(String text, float fontSize) { return (float)getWidth(text) * 0.001f * fontSize; } /** * Gets the width of a <CODE>char</CODE> in points. * @param char1 the <CODE>char</CODE> to get the witdth of * @param fontSize the font size * @return the width in points */ public float getWidthPoint(char char1, float fontSize) { return getWidth(char1) * 0.001f * fontSize; } /** * Converts a <CODE>String</CODE> to a </CODE>byte</CODE> array according * to the font's encoding. * @param text the <CODE>String</CODE> to be converted
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -