private byte[] BuildPostTable() { PostScriptTable post = ttf.PostScript; if (post == null || keepTables != null && !keepTables.Contains("post", StringComparer.Ordinal)) { return(null); } using (var bos = new MemoryStream()) using (var output = new BinaryWriter(bos)) { WriteFixed(output, 2.0); // version WriteFixed(output, post.ItalicAngle); WriteSInt16(output, post.UnderlinePosition); WriteSInt16(output, post.UnderlineThickness); WriteUint32(output, post.IsFixedPitch); WriteUint32(output, post.MinMemType42); WriteUint32(output, post.MaxMemType42); WriteUint32(output, post.MinMemType1); WriteUint32(output, post.MaxMemType1); // version 2.0 // numberOfGlyphs WriteUint16(output, glyphIds.Count); // glyphNameIndex[numGlyphs] ConcurrentDictionary <string, int> names = new ConcurrentDictionary <string, int>(StringComparer.Ordinal); foreach (int gid in glyphIds) { string name = post.GetName(gid); if (WGL4Names.MAC_GLYPH_NAMES_INDICES.TryGetValue(name, out int macId)) { // the name input implicit, as it's from MacRoman WriteUint16(output, macId); } else { // the name will be written explicitly int ordinal = names.GetOrAdd(name, (p) => names.Count); WriteUint16(output, 258 + ordinal); } } // names[numberNewGlyphs] foreach (string name in names.Keys) { byte[] buf = Charset.ASCII.GetBytes(name); WriteUint8(output, buf.Length); output.Write(buf); } output.Flush(); return(bos.ToArray()); } }
private TTFTable ReadTableDirectory(TrueTypeFont font, TTFDataStream raf) { TTFTable table; string tag = raf.ReadString(4); switch (tag) { case CmapTable.TAG: table = new CmapTable(font); break; case GlyphTable.TAG: table = new GlyphTable(font); break; case HeaderTable.TAG: table = new HeaderTable(font); break; case HorizontalHeaderTable.TAG: table = new HorizontalHeaderTable(font); break; case HorizontalMetricsTable.TAG: table = new HorizontalMetricsTable(font); break; case IndexToLocationTable.TAG: table = new IndexToLocationTable(font); break; case MaximumProfileTable.TAG: table = new MaximumProfileTable(font); break; case NamingTable.TAG: table = new NamingTable(font); break; case OS2WindowsMetricsTable.TAG: table = new OS2WindowsMetricsTable(font); break; case PostScriptTable.TAG: table = new PostScriptTable(font); break; case DigitalSignatureTable.TAG: table = new DigitalSignatureTable(font); break; case KerningTable.TAG: table = new KerningTable(font); break; case VerticalHeaderTable.TAG: table = new VerticalHeaderTable(font); break; case VerticalMetricsTable.TAG: table = new VerticalMetricsTable(font); break; case VerticalOriginTable.TAG: table = new VerticalOriginTable(font); break; case GlyphSubstitutionTable.TAG: table = new GlyphSubstitutionTable(font); break; default: table = ReadTable(font, tag); break; } table.Tag = tag; table.CheckSum = raf.ReadUnsignedInt(); table.Offset = raf.ReadUnsignedInt(); table.Length = raf.ReadUnsignedInt(); // skip tables with zero length (except glyf) if (table.Length == 0 && !tag.Equals(GlyphTable.TAG, StringComparison.Ordinal)) { return(null); } return(table); }
/** * Parse all tables and check if all needed tables are present. * * @param font the TrueTypeFont instance holding the parsed data. * @ If there is an error parsing the TrueType font. */ private void ParseTables(TrueTypeFont font) { foreach (TTFTable table in font.Tables) { if (!table.Initialized) { font.ReadTable(table); } } bool isPostScript = AllowCFF && font.TableMap.ContainsKey(CFFTable.TAG); HeaderTable head = font.Header; if (head == null) { throw new IOException("head is mandatory"); } HorizontalHeaderTable hh = font.HorizontalHeader; if (hh == null) { throw new IOException("hhead is mandatory"); } MaximumProfileTable maxp = font.MaximumProfile; if (maxp == null) { throw new IOException("maxp is mandatory"); } PostScriptTable post = font.PostScript; if (post == null && !isEmbedded) { // in an embedded font this table is optional throw new IOException("post is mandatory"); } if (!isPostScript) { IndexToLocationTable loc = font.IndexToLocation; if (loc == null) { throw new IOException("loca is mandatory"); } if (font.Glyph == null) { throw new IOException("glyf is mandatory"); } } if (font.Naming == null && !isEmbedded) { throw new IOException("name is mandatory"); } if (font.HorizontalMetrics == null) { throw new IOException("hmtx is mandatory"); } if (!isEmbedded && font.Cmap == null) { throw new IOException("cmap is mandatory"); } }