internal static TrueTypeFont CreateFontProgram(PdfDictionary fontDictionary, FontEncoding fontEncoding) { iText.Kernel.Font.DocTrueTypeFont fontProgram = new iText.Kernel.Font.DocTrueTypeFont(fontDictionary); FillFontDescriptor(fontProgram, fontDictionary.GetAsDictionary(PdfName.FontDescriptor)); PdfNumber firstCharNumber = fontDictionary.GetAsNumber(PdfName.FirstChar); int firstChar = firstCharNumber != null?Math.Max(firstCharNumber.IntValue(), 0) : 0; int[] widths = FontUtil.ConvertSimpleWidthsArray(fontDictionary.GetAsArray(PdfName.Widths), firstChar, fontProgram .GetMissingWidth()); fontProgram.avgWidth = 0; int glyphsWithWidths = 0; for (int i = 0; i < 256; i++) { Glyph glyph = new Glyph(i, widths[i], fontEncoding.GetUnicode(i)); fontProgram.codeToGlyph[i] = glyph; //FontEncoding.codeToUnicode table has higher priority if (glyph.HasValidUnicode() && fontEncoding.ConvertToByte(glyph.GetUnicode()) == i) { fontProgram.unicodeToGlyph[glyph.GetUnicode()] = glyph; } if (widths[i] > 0) { glyphsWithWidths++; fontProgram.avgWidth += widths[i]; } } if (glyphsWithWidths != 0) { fontProgram.avgWidth /= glyphsWithWidths; } return(fontProgram); }
internal static TrueTypeFont CreateFontProgram(PdfDictionary fontDictionary, CMapToUnicode toUnicode) { iText.Kernel.Font.DocTrueTypeFont fontProgram = new iText.Kernel.Font.DocTrueTypeFont(fontDictionary); PdfDictionary fontDescriptor = fontDictionary.GetAsDictionary(PdfName.FontDescriptor); FillFontDescriptor(fontProgram, fontDescriptor); int dw = (fontDescriptor != null && fontDescriptor.ContainsKey(PdfName.DW)) ? (int)fontDescriptor.GetAsInt (PdfName.DW) : 1000; if (toUnicode != null) { IntHashtable widths = FontUtil.ConvertCompositeWidthsArray(fontDictionary.GetAsArray(PdfName.W)); fontProgram.avgWidth = 0; foreach (int cid in toUnicode.GetCodes()) { int width = widths.ContainsKey(cid) ? widths.Get(cid) : dw; Glyph glyph = new Glyph(cid, width, toUnicode.Lookup(cid)); if (glyph.HasValidUnicode()) { fontProgram.unicodeToGlyph[glyph.GetUnicode()] = glyph; } fontProgram.codeToGlyph[cid] = glyph; fontProgram.avgWidth += width; } if (fontProgram.codeToGlyph.Count != 0) { fontProgram.avgWidth /= fontProgram.codeToGlyph.Count; } } if (fontProgram.codeToGlyph.Get(0) == null) { fontProgram.codeToGlyph[0] = new Glyph(0, dw, -1); } return(fontProgram); }
internal static void FillFontDescriptor(iText.Kernel.Font.DocTrueTypeFont font, PdfDictionary fontDesc) { if (fontDesc == null) { ILog logger = LogManager.GetLogger(typeof(FontUtil)); logger.Warn(iText.IO.LogMessageConstant.FONT_DICTIONARY_WITH_NO_FONT_DESCRIPTOR); return; } PdfNumber v = fontDesc.GetAsNumber(PdfName.Ascent); if (v != null) { font.SetTypoAscender(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.Descent); if (v != null) { font.SetTypoDescender(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.CapHeight); if (v != null) { font.SetCapHeight(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.XHeight); if (v != null) { font.SetXHeight(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.ItalicAngle); if (v != null) { font.SetItalicAngle(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.StemV); if (v != null) { font.SetStemV(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.StemH); if (v != null) { font.SetStemH(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.FontWeight); if (v != null) { font.SetFontWeight(v.IntValue()); } v = fontDesc.GetAsNumber(PdfName.MissingWidth); if (v != null) { font.missingWidth = v.IntValue(); } PdfName fontStretch = fontDesc.GetAsName(PdfName.FontStretch); if (fontStretch != null) { font.SetFontStretch(fontStretch.GetValue()); } PdfArray bboxValue = fontDesc.GetAsArray(PdfName.FontBBox); if (bboxValue != null) { int[] bbox = new int[4]; bbox[0] = bboxValue.GetAsNumber(0).IntValue(); //llx bbox[1] = bboxValue.GetAsNumber(1).IntValue(); //lly bbox[2] = bboxValue.GetAsNumber(2).IntValue(); //urx bbox[3] = bboxValue.GetAsNumber(3).IntValue(); //ury if (bbox[0] > bbox[2]) { int t = bbox[0]; bbox[0] = bbox[2]; bbox[2] = t; } if (bbox[1] > bbox[3]) { int t = bbox[1]; bbox[1] = bbox[3]; bbox[3] = t; } font.SetBbox(bbox); // If ascender or descender in font descriptor are zero, we still want to get more or less correct valuee for // text extraction, stamping etc. Thus we rely on font bbox in this case if (font.GetFontMetrics().GetTypoAscender() == 0 && font.GetFontMetrics().GetTypoDescender() == 0) { float maxAscent = Math.Max(bbox[3], font.GetFontMetrics().GetTypoAscender()); float minDescent = Math.Min(bbox[1], font.GetFontMetrics().GetTypoDescender()); font.SetTypoAscender((int)(maxAscent * 1000 / (maxAscent - minDescent))); font.SetTypoDescender((int)(minDescent * 1000 / (maxAscent - minDescent))); } } PdfString fontFamily = fontDesc.GetAsString(PdfName.FontFamily); if (fontFamily != null) { font.SetFontFamily(fontFamily.GetValue()); } PdfNumber flagsValue = fontDesc.GetAsNumber(PdfName.Flags); if (flagsValue != null) { int flags = flagsValue.IntValue(); if ((flags & 1) != 0) { font.SetFixedPitch(true); } if ((flags & 262144) != 0) { font.SetBold(true); } } PdfName[] fontFileNames = new PdfName[] { PdfName.FontFile, PdfName.FontFile2, PdfName.FontFile3 }; foreach (PdfName fontFile in fontFileNames) { if (fontDesc.ContainsKey(fontFile)) { font.fontFileName = fontFile; font.fontFile = fontDesc.GetAsStream(fontFile); break; } } }