/// <summary> /// Each font used in a document has an instance of this class. /// This class stores the characters used in the document and other /// specifics unique to the current working document. /// </summary> /// <param name="fontName">the font name</param> /// <param name="indirectReference">the indirect reference to the font</param> /// <param name="baseFont">the BaseFont </param> internal FontDetails(PdfName fontName, PdfIndirectReference indirectReference, BaseFont baseFont) { _fontName = fontName; _indirectReference = indirectReference; _baseFont = baseFont; _fontType = baseFont.FontType; switch (_fontType) { case BaseFont.FONT_TYPE_T1: case BaseFont.FONT_TYPE_TT: _shortTag = new byte[256]; break; case BaseFont.FONT_TYPE_CJK: _cjkTag = new IntHashtable(); _cjkFont = (CjkFont)baseFont; break; case BaseFont.FONT_TYPE_TTUNI: _longTag = new Hashtable(); _ttu = (TrueTypeFontUnicode)baseFont; _symbolic = baseFont.IsFontSpecific(); break; } }
/** Each font used in a document has an instance of this class. * This class stores the characters used in the document and other * specifics unique to the current working document. * @param fontName the font name * @param indirectReference the indirect reference to the font * @param baseFont the <CODE>BaseFont</CODE> */ internal FontDetails(PdfName fontName, PdfIndirectReference indirectReference, BaseFont baseFont) { this.fontName = fontName; this.indirectReference = indirectReference; this.baseFont = baseFont; fontType = baseFont.FontType; switch (fontType) { case BaseFont.FONT_TYPE_T1: case BaseFont.FONT_TYPE_TT: shortTag = new byte[256]; break; case BaseFont.FONT_TYPE_CJK: cjkTag = new IntHashtable(); cjkFont = (CJKFont)baseFont; break; case BaseFont.FONT_TYPE_TTUNI: longTag = new Dictionary <int, int[]>(); ttu = (TrueTypeFontUnicode)baseFont; symbolic = baseFont.IsFontSpecific(); break; } }
/** Each font used in a document has an instance of this class. * This class stores the characters used in the document and other * specifics unique to the current working document. * @param fontName the font name * @param indirectReference the indirect reference to the font * @param baseFont the <CODE>BaseFont</CODE> */ internal FontDetails(PdfName fontName, PdfIndirectReference indirectReference, BaseFont baseFont) { this.fontName = fontName; this.indirectReference = indirectReference; this.baseFont = baseFont; fontType = baseFont.FontType; switch (fontType) { case BaseFont.FONT_TYPE_T1: case BaseFont.FONT_TYPE_TT: shortTag = new byte[256]; break; case BaseFont.FONT_TYPE_CJK: cjkTag = new IntHashtable(); cjkFont = (CJKFont)baseFont; break; case BaseFont.FONT_TYPE_TTUNI: longTag = new Dictionary<int,int[]>(); ttu = (TrueTypeFontUnicode)baseFont; symbolic = baseFont.IsFontSpecific(); break; } }
/** 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 its 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 * @param forceRead in some cases (TrueTypeFont, Type1Font), the full font file will be read and kept in memory if forceRead is true * @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 * @since 2.1.5 */ public static BaseFont CreateFont(String name, String encoding, bool embedded, bool cached, byte[] ttfAfm, byte[] pfb, bool noThrow, bool forceRead) { string nameBase = GetBaseName(name); encoding = NormalizeEncoding(encoding); bool isBuiltinFonts14 = BuiltinFonts14.ContainsKey(name); bool 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) { lock (fontCache) { fontCache.TryGetValue(key, out fontFound); } if (fontFound != null) return fontFound; } if (isBuiltinFonts14 || name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".afm") || name.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".pfm")) { fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb, forceRead); fontBuilt.fastWinansi = encoding.Equals(CP1252); } else if (nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".ttf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).EndsWith(".otf") || nameBase.ToLower(System.Globalization.CultureInfo.InvariantCulture).IndexOf(".ttc,") > 0) { if (encoding.Equals(IDENTITY_H) || encoding.Equals(IDENTITY_V)) fontBuilt = new TrueTypeFontUnicode(name, encoding, embedded, ttfAfm, forceRead); else { fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm, false, forceRead); fontBuilt.fastWinansi = encoding.Equals(CP1252); } } else if (isCJKFont) fontBuilt = new CJKFont(name, encoding, embedded); else if (noThrow) return null; else throw new DocumentException(MessageLocalization.GetComposedMessage("font.1.with.2.is.not.recognized", name, encoding)); if (cached) { lock (fontCache) { fontCache.TryGetValue(key, out fontFound); if (fontFound != null) return fontFound; fontCache[key] = fontBuilt; } } return fontBuilt; }
protected internal virtual void WriteFont(TrueTypeFontUnicode font, PdfIndirectReference refer, Object[] parms, byte[] rotbits) { Dictionary<int, int[]> longTag = (Dictionary<int, int[]>)parms[0]; font.AddRangeUni(longTag, true, font.Subset); int[][] metrics = new int[longTag.Count][]; longTag.Values.CopyTo(metrics, 0); Array.Sort(metrics, font); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; PdfIndirectReference cidset = null; // sivan: cff if (font.Cff) { byte[] b = font.ReadCffFont(); if (font.Subset || font.SubsetRanges != null) { CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b), longTag); b = cff.Process(cff.GetNames()[0]); } pobj = new BaseFont.StreamFont(b, "CIDFontType0C", font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } else { byte[] b; if (font.Subset || font.DirectoryOffset != 0) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(font.FileName, new RandomAccessFileOrArray(font.Rf), longTag, font.DirectoryOffset, false, false); b = sb.Process(); } else { b = font.GetFullFont(); } int[] lengths = new int[] { b.Length }; pobj = new BaseFont.StreamFont(b, lengths, font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } String subsetPrefix = ""; if (font.Subset) subsetPrefix = TrueTypeFontUnicode.CreateSubsetPrefix(); PdfDictionary dic = font.GetFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.AddToBody(dic); ind_font = obj.IndirectReference; pobj = font.GetCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; pobj = font.GetToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.AddToBody(pobj); toUnicodeRef = obj.IndirectReference; } pobj = font.GetFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.AddToBody(pobj, refer); }
/** * @see TtfUnicodeWriter#writeFont(TrueTypeFontUnicode, PdfIndirectReference, Object[], byte[]) */ override protected void WriteFont(TrueTypeFontUnicode font, PdfIndirectReference refer, Object[] parameters, byte[] rotbits) { Dictionary<int, int[]> longTag = (Dictionary<int, int[]>)parameters[0]; font.AddRangeUni(longTag, true, font.Subset); int [][] metrics = new int[longTag.Count][]; longTag.Values.CopyTo(metrics, 0); Array.Sort(metrics, font); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; PdfIndirectReference cidset = null; PdfStream stream; if (metrics.Length == 0) { stream = new PdfStream(new byte[]{(byte)0x80}); } else { int top = metrics[metrics.Length - 1][0]; byte[] bt = new byte[top / 8 + 1]; for (int k = 0; k < metrics.Length; ++k) { int v = metrics[k][0]; bt[v / 8] |= rotbits[v % 8]; } stream = new PdfStream(bt); stream.FlateCompress(font.CompressionLevel); } cidset = writer.AddToBody(stream).IndirectReference; if (font.Cff) { byte[] b = font.ReadCffFont(); if (font.Subset || font.SubsetRanges != null) { CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b),longTag); b = cff.Process(cff.GetNames()[0]); } pobj = new BaseFont.StreamFont(b, "CIDFontType0C", font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } else { byte[] b; if (font.Subset || font.DirectoryOffset != 0) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(font.FileName, new RandomAccessFileOrArray(font.Rf), longTag, font.DirectoryOffset, false, false); b = sb.Process(); } else { b = font.GetFullFont(); } int[] lengths = new int[] { b.Length }; pobj = new BaseFont.StreamFont(b,lengths, font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } String subsetPrefix = ""; if (font.Subset) subsetPrefix = BaseFont.CreateSubsetPrefix(); PdfDictionary dic = font.GetFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.AddToBody(dic); ind_font = obj.IndirectReference; pobj = font.GetCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; pobj = font.GetToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.AddToBody(pobj); toUnicodeRef = obj.IndirectReference; } pobj = font.GetFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.AddToBody(pobj, refer); }
internal protected virtual void WriteFont(TrueTypeFontUnicode font, PdfIndirectReference refer, Object[] parms, byte[] rotbits) { Dictionary <int, int[]> longTag = (Dictionary <int, int[]>)parms[0]; font.AddRangeUni(longTag, true, font.Subset); int[][] metrics = new int[longTag.Count][]; longTag.Values.CopyTo(metrics, 0); Array.Sort(metrics, font); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; // sivan: cff if (font.Cff) { byte[] b = font.ReadCffFont(); if (font.Subset || font.SubsetRanges != null) { CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b), longTag); try { b = cff.Process(cff.GetNames()[0]); } catch (Exception e) { // temporary fix for cff subset failure font.Subset = false; font.AddRangeUni(longTag, true, font.Subset); metrics = new int[longTag.Count][]; longTag.Values.CopyTo(metrics, 0); Array.Sort(metrics, font); } } pobj = new BaseFont.StreamFont(b, "CIDFontType0C", font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } else { byte[] b; if (font.Subset || font.DirectoryOffset != 0) { lock (font.Rf) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(font.FileName, new RandomAccessFileOrArray(font.Rf), new HashSet2 <int>(longTag.Keys), font.DirectoryOffset, true, false); b = sb.Process(); } } else { b = font.GetFullFont(); } int[] lengths = new int[] { b.Length }; pobj = new BaseFont.StreamFont(b, lengths, font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } String subsetPrefix = ""; if (font.Subset) { subsetPrefix = TrueTypeFontUnicode.CreateSubsetPrefix(); } PdfDictionary dic = font.GetFontDescriptor(ind_font, subsetPrefix, null); obj = writer.AddToBody(dic); ind_font = obj.IndirectReference; pobj = font.GetCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; pobj = font.GetToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.AddToBody(pobj); toUnicodeRef = obj.IndirectReference; } pobj = font.GetFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.AddToBody(pobj, refer); }
/** * @see TtfUnicodeWriter#writeFont(TrueTypeFontUnicode, PdfIndirectReference, Object[], byte[]) */ internal protected override void WriteFont(TrueTypeFontUnicode font, PdfIndirectReference refer, Object[] parameters, byte[] rotbits) { Dictionary <int, int[]> longTag = (Dictionary <int, int[]>)parameters[0]; font.AddRangeUni(longTag, true, font.Subset); int [][] metrics = new int[longTag.Count][]; longTag.Values.CopyTo(metrics, 0); Array.Sort(metrics, font); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; if (font.Cff) { byte[] b = font.ReadCffFont(); if (font.Subset || font.SubsetRanges != null) { CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b), longTag); try { b = cff.Process(cff.GetNames()[0]); } catch (Exception e) { //temporary fix for cff subset failure font.Subset = false; font.AddRangeUni(longTag, true, font.Subset); metrics = new int[longTag.Count][]; longTag.Values.CopyTo(metrics, 0); Array.Sort(metrics, font); } } pobj = new BaseFont.StreamFont(b, "CIDFontType0C", font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } else { byte[] b; if (font.Subset || font.DirectoryOffset != 0) { lock (font.Rf) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(font.FileName, new RandomAccessFileOrArray(font.Rf), new HashSet2 <int>(longTag.Keys), font.DirectoryOffset, false, false); b = sb.Process(); } } else { b = font.GetFullFont(); } int[] lengths = new int[] { b.Length }; pobj = new BaseFont.StreamFont(b, lengths, font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } // CIDSet shall be based on font.maxGlyphId property of the font, it is maxp.numGlyphs for ttf, // because technically we convert all unused glyphs to space, e.g. just remove outlines. byte[] cidSetBytes = new byte[font.MaxGlyphId / 8 + 1]; for (int i = 0; i < font.MaxGlyphId / 8; i++) { cidSetBytes[i] |= 0xff; } for (int i = 0; i < font.MaxGlyphId % 8; i++) { cidSetBytes[cidSetBytes.Length - 1] |= rotbits[i]; } PdfStream stream = new PdfStream(cidSetBytes); stream.FlateCompress(font.CompressionLevel); PdfIndirectReference cidset = writer.AddToBody(stream).IndirectReference; String subsetPrefix = ""; if (font.Subset) { subsetPrefix = BaseFont.CreateSubsetPrefix(); } PdfDictionary dic = font.GetFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.AddToBody(dic); ind_font = obj.IndirectReference; pobj = font.GetCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; pobj = font.GetToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.AddToBody(pobj); toUnicodeRef = obj.IndirectReference; } pobj = font.GetFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.AddToBody(pobj, refer); }
/** * @see TtfUnicodeWriter#writeFont(TrueTypeFontUnicode, PdfIndirectReference, Object[], byte[]) */ internal protected override void WriteFont(TrueTypeFontUnicode font, PdfIndirectReference refer, Object[] parameters, byte[] rotbits) { Dictionary <int, int[]> longTag = (Dictionary <int, int[]>)parameters[0]; font.AddRangeUni(longTag, true, font.Subset); int [][] metrics = new int[longTag.Count][]; longTag.Values.CopyTo(metrics, 0); Array.Sort(metrics, font); PdfIndirectReference ind_font = null; PdfObject pobj = null; PdfIndirectObject obj = null; PdfIndirectReference cidset = null; if (pdfAConformanceLevel == PdfAConformanceLevel.PDF_A_1A || pdfAConformanceLevel == PdfAConformanceLevel.PDF_A_1B) { PdfStream stream; if (metrics.Length == 0) { stream = new PdfStream(new byte[] { (byte)0x80 }); } else { int top = metrics[metrics.Length - 1][0]; byte[] bt = new byte[top / 8 + 1]; for (int k = 0; k < metrics.Length; ++k) { int v = metrics[k][0]; bt[v / 8] |= rotbits[v % 8]; } stream = new PdfStream(bt); stream.FlateCompress(font.CompressionLevel); } cidset = writer.AddToBody(stream).IndirectReference; } if (font.Cff) { byte[] b = font.ReadCffFont(); if (font.Subset || font.SubsetRanges != null) { CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b), longTag); b = cff.Process(cff.GetNames()[0]); } pobj = new BaseFont.StreamFont(b, "CIDFontType0C", font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } else { byte[] b; if (font.Subset || font.DirectoryOffset != 0) { lock (font.Rf) { TrueTypeFontSubSet sb = new TrueTypeFontSubSet(font.FileName, new RandomAccessFileOrArray(font.Rf), new HashSet2 <int>(longTag.Keys), font.DirectoryOffset, false, false); b = sb.Process(); } } else { b = font.GetFullFont(); } int[] lengths = new int[] { b.Length }; pobj = new BaseFont.StreamFont(b, lengths, font.CompressionLevel); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; } String subsetPrefix = ""; if (font.Subset) { subsetPrefix = BaseFont.CreateSubsetPrefix(); } PdfDictionary dic = font.GetFontDescriptor(ind_font, subsetPrefix, cidset); obj = writer.AddToBody(dic); ind_font = obj.IndirectReference; pobj = font.GetCIDFontType2(ind_font, subsetPrefix, metrics); obj = writer.AddToBody(pobj); ind_font = obj.IndirectReference; pobj = font.GetToUnicode(metrics); PdfIndirectReference toUnicodeRef = null; if (pobj != null) { obj = writer.AddToBody(pobj); toUnicodeRef = obj.IndirectReference; } pobj = font.GetFontBaseType(ind_font, subsetPrefix, toUnicodeRef); writer.AddToBody(pobj, refer); }
/** 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, bool embedded, bool cached, byte[] ttfAfm, byte[] pfb) { string nameBase = getBaseName(name); encoding = normalizeEncoding(encoding); bool isBuiltinFonts14 = BuiltinFonts14.ContainsKey(name); bool 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) { lock (fontCache) { fontFound = (BaseFont)fontCache[key]; } if (fontFound != null) { return(fontFound); } } if (isBuiltinFonts14 || name.ToLower().EndsWith(".afm")) { fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb); fontBuilt.fastWinansi = encoding.Equals(CP1252); } else if (nameBase.ToLower().EndsWith(".ttf") || nameBase.ToLower().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.ToLower().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) { lock (fontCache) { fontFound = (BaseFont)fontCache[key]; if (fontFound != null) { return(fontFound); } fontCache.Add(key, fontBuilt); } } return(fontBuilt); }
/** 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, bool embedded, bool cached, byte[] ttfAfm, byte[] pfb) { string nameBase = GetBaseName(name); encoding = NormalizeEncoding(encoding); bool isBuiltinFonts14 = BuiltinFonts14.ContainsKey(name); bool 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) { lock (fontCache) { fontFound = (BaseFont)fontCache[key]; } if (fontFound != null) return fontFound; } if (isBuiltinFonts14 || name.ToLower().EndsWith(".afm") || name.ToLower().EndsWith(".pfm")) { fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb); fontBuilt.fastWinansi = encoding.Equals(CP1252); } else if (nameBase.ToLower().EndsWith(".ttf") || nameBase.ToLower().EndsWith(".otf") || nameBase.ToLower().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 throw new DocumentException("Font '" + name + "' with '" + encoding + "' is not recognized."); if (cached) { lock (fontCache) { fontFound = (BaseFont)fontCache[key]; if (fontFound != null) return fontFound; fontCache.Add(key, fontBuilt); } } return fontBuilt; }