/// <exception cref="System.IO.IOException"/> private void InitializeFontProperties() { // initialize sfnt tables OpenTypeParser.HeaderTable head = fontParser.GetHeadTable(); OpenTypeParser.HorizontalHeader hhea = fontParser.GetHheaTable(); OpenTypeParser.WindowsMetrics os_2 = fontParser.GetOs_2Table(); OpenTypeParser.PostTable post = fontParser.GetPostTable(); isFontSpecific = fontParser.GetCmapTable().fontSpecific; kerning = fontParser.ReadKerning(head.unitsPerEm); bBoxes = fontParser.ReadBbox(head.unitsPerEm); // font names group fontNames = fontParser.GetFontNames(); // font metrics group fontMetrics.SetUnitsPerEm(head.unitsPerEm); fontMetrics.UpdateBbox(head.xMin, head.yMin, head.xMax, head.yMax); fontMetrics.SetNumberOfGlyphs(fontParser.ReadNumGlyphs()); fontMetrics.SetGlyphWidths(fontParser.GetGlyphWidthsByIndex()); fontMetrics.SetTypoAscender(os_2.sTypoAscender); fontMetrics.SetTypoDescender(os_2.sTypoDescender); fontMetrics.SetCapHeight(os_2.sCapHeight); fontMetrics.SetXHeight(os_2.sxHeight); fontMetrics.SetItalicAngle(post.italicAngle); fontMetrics.SetAscender(hhea.Ascender); fontMetrics.SetDescender(hhea.Descender); fontMetrics.SetLineGap(hhea.LineGap); fontMetrics.SetWinAscender(os_2.usWinAscent); fontMetrics.SetWinDescender(os_2.usWinDescent); fontMetrics.SetAdvanceWidthMax(hhea.advanceWidthMax); fontMetrics.SetUnderlinePosition((post.underlinePosition - post.underlineThickness) / 2); fontMetrics.SetUnderlineThickness(post.underlineThickness); fontMetrics.SetStrikeoutPosition(os_2.yStrikeoutPosition); fontMetrics.SetStrikeoutSize(os_2.yStrikeoutSize); fontMetrics.SetSubscriptOffset(-os_2.ySubscriptYOffset); fontMetrics.SetSubscriptSize(os_2.ySubscriptYSize); fontMetrics.SetSuperscriptOffset(os_2.ySuperscriptYOffset); fontMetrics.SetSuperscriptSize(os_2.ySuperscriptYSize); fontMetrics.SetIsFixedPitch(post.isFixedPitch); // font identification group String[][] ttfVersion = fontNames.GetNames(5); if (ttfVersion != null) { fontIdentification.SetTtfVersion(ttfVersion[0][3]); } String[][] ttfUniqueId = fontNames.GetNames(3); if (ttfUniqueId != null) { fontIdentification.SetTtfVersion(ttfUniqueId[0][3]); } byte[] pdfPanose = new byte[12]; pdfPanose[1] = (byte)(os_2.sFamilyClass); pdfPanose[0] = (byte)(os_2.sFamilyClass >> 8); Array.Copy(os_2.panose, 0, pdfPanose, 2, 10); fontIdentification.SetPanose(pdfPanose); IDictionary <int, int[]> cmap = GetActiveCmap(); int[] glyphWidths = fontParser.GetGlyphWidthsByIndex(); int numOfGlyphs = fontMetrics.GetNumberOfGlyphs(); unicodeToGlyph = new LinkedDictionary <int, Glyph>(cmap.Count); codeToGlyph = new LinkedDictionary <int, Glyph>(numOfGlyphs); avgWidth = 0; foreach (int charCode in cmap.Keys) { int index = cmap.Get(charCode)[0]; if (index >= numOfGlyphs) { ILog LOGGER = LogManager.GetLogger(typeof(iText.IO.Font.TrueTypeFont)); LOGGER.Warn(MessageFormatUtil.Format(iText.IO.LogMessageConstant.FONT_HAS_INVALID_GLYPH, GetFontNames().GetFontName (), index)); continue; } Glyph glyph = new Glyph(index, glyphWidths[index], charCode, bBoxes != null ? bBoxes[index] : null); unicodeToGlyph.Put(charCode, glyph); // This is done on purpose to keep the mapping to glyphs with smaller unicode values, in contrast with // larger values which often represent different forms of other characters. if (!codeToGlyph.ContainsKey(index)) { codeToGlyph.Put(index, glyph); } avgWidth += glyph.GetWidth(); } FixSpaceIssue(); for (int index = 0; index < glyphWidths.Length; index++) { if (codeToGlyph.ContainsKey(index)) { continue; } Glyph glyph = new Glyph(index, glyphWidths[index], -1); codeToGlyph.Put(index, glyph); avgWidth += glyph.GetWidth(); } if (codeToGlyph.Count != 0) { avgWidth /= codeToGlyph.Count; } ReadGdefTable(); ReadGsubTable(); ReadGposTable(); isVertical = false; }
/// <exception cref="System.IO.IOException"/> private static FontProgramDescriptor FetchOpenTypeFontDescriptor(OpenTypeParser fontParser) { fontParser.LoadTables(false); return(new FontProgramDescriptor(fontParser.GetFontNames(), fontParser.GetPostTable().italicAngle, fontParser .GetPostTable().isFixedPitch)); }