public OpenTypeFontTable(OpenTypeFontface fontData, string tag) { _fontData = fontData; if (fontData != null && fontData.TableDictionary.ContainsKey(tag)) DirectoryEntry = fontData.TableDictionary[tag]; else DirectoryEntry = new TableDirectoryEntry(tag); DirectoryEntry.FontTable = this; }
/// <summary> /// Creates and reads a TableDirectoryEntry from the font image. /// </summary> public static TableDirectoryEntry ReadFrom(OpenTypeFontface fontData) { TableDirectoryEntry entry = new TableDirectoryEntry(); entry.Tag = fontData.ReadTag(); entry.CheckSum = fontData.ReadULong(); entry.Offset = fontData.ReadLong(); entry.Length = (int)fontData.ReadULong(); return(entry); }
/// <summary> /// Compiles the font to its binary representation. /// </summary> void Compile() { MemoryStream stream = new MemoryStream(); OpenTypeFontWriter writer = new OpenTypeFontWriter(stream); int tableCount = this.tableDictionary.Count; int selector = entrySelectors[tableCount]; this.offsetTable.Version = 0x00010000; this.offsetTable.TableCount = tableCount; this.offsetTable.SearchRange = (ushort)((1 << selector) * 16); this.offsetTable.EntrySelector = (ushort)selector; this.offsetTable.RangeShift = (ushort)((tableCount - (1 << selector)) * 16); this.offsetTable.Write(writer); // Sort tables by tag name string[] tags = new string[tableCount]; this.tableDictionary.Keys.CopyTo(tags, 0); Array.Sort(tags, StringComparer.Ordinal); #if VERBOSE Debug.WriteLine("Start Compile"); #endif // Write tables in alphabetical order int tablePosition = 12 + 16 * tableCount; for (int idx = 0; idx < tableCount; idx++) { TableDirectoryEntry entry = this.tableDictionary[tags[idx]]; #if DEBUG if (entry.Tag == "glyf" || entry.Tag == "loca") { GetType(); } #endif entry.FontTable.PrepareForCompilation(); entry.Offset = tablePosition; writer.Position = tablePosition; entry.FontTable.Write(writer); int endPosition = writer.Position; tablePosition = endPosition; writer.Position = 12 + 16 * idx; entry.Write(writer); #if VERBOSE Debug.WriteLine(String.Format(" Write Table '{0}', offset={1}, length={2}, checksum={3}, ", entry.Tag, entry.Offset, entry.Length, entry.CheckSum)); #endif } #if VERBOSE Debug.WriteLine("End Compile"); #endif writer.Stream.Flush(); int l = (int)writer.Stream.Length; l.GetType(); this.data = stream.ToArray(); }
public OpenTypeFontTable(FontData fontData, string tag) { this.fontData = fontData; if (fontData != null && fontData.tableDictionary.ContainsKey(tag)) { DirectoryEntry = fontData.tableDictionary[tag]; } else { DirectoryEntry = new TableDirectoryEntry(tag); } DirectoryEntry.FontTable = this; }
public OpenTypeFontTable(OpenTypeFontface?fontData, string tag) { _fontData = fontData; if (fontData != null && fontData.TableDictionary.ContainsKey(tag)) { DirectoryEntry = fontData.TableDictionary[tag] ?? throw new Exception("Invalid font table data"); } else { DirectoryEntry = new TableDirectoryEntry(tag); } DirectoryEntry !.FontTable = this; }
/// <summary> /// Reads all required tables from the font data. /// </summary> internal void Read() { // Determine font technology // ReSharper disable InconsistentNaming const uint OTTO = 0x4f54544f; // Adobe OpenType CFF data, tag: 'OTTO' const uint TTCF = 0x74746366; // TrueType Collection tag: 'ttcf' // ReSharper restore InconsistentNaming try { #if DEBUG_ if (Name == "Cambria") { Debug - Break.Break(); } #endif // Check if data is a TrueType collection font. uint startTag = ReadULong(); if (startTag == TTCF) { _fontTechnology = FontTechnology.TrueTypeCollection; throw new InvalidOperationException("TrueType collection fonts are not yet supported by PDFsharp."); } // Read offset table _offsetTable.Version = startTag; _offsetTable.TableCount = ReadUShort(); _offsetTable.SearchRange = ReadUShort(); _offsetTable.EntrySelector = ReadUShort(); _offsetTable.RangeShift = ReadUShort(); // Move to table dictionary at position 12 Debug.Assert(_pos == 12); //tableDictionary = (offsetTable.TableCount); if (_offsetTable.Version == OTTO) { _fontTechnology = FontTechnology.PostscriptOutlines; } else { _fontTechnology = FontTechnology.TrueTypeOutlines; } for (int idx = 0; idx < _offsetTable.TableCount; idx++) { TableDirectoryEntry entry = TableDirectoryEntry.ReadFrom(this); TableDictionary.Add(entry.Tag, entry); #if VERBOSE Debug.WriteLine(String.Format("Font table: {0}", entry.Tag)); #endif } // PDFlib checks this, but it is not part of the OpenType spec anymore if (TableDictionary.ContainsKey("bhed")) { throw new NotSupportedException("Bitmap fonts are not supported by PDFsharp."); } // Read required tables if (Seek(CMapTable.Tag) != -1) { cmap = new CMapTable(this); } if (Seek(ControlValueTable.Tag) != -1) { cvt = new ControlValueTable(this); } if (Seek(FontProgram.Tag) != -1) { fpgm = new FontProgram(this); } if (Seek(MaximumProfileTable.Tag) != -1) { maxp = new MaximumProfileTable(this); } if (Seek(NameTable.Tag) != -1) { name = new NameTable(this); } if (Seek(FontHeaderTable.Tag) != -1) { head = new FontHeaderTable(this); } if (Seek(HorizontalHeaderTable.Tag) != -1) { hhea = new HorizontalHeaderTable(this); } if (Seek(HorizontalMetricsTable.Tag) != -1) { hmtx = new HorizontalMetricsTable(this); } if (Seek(OS2Table.Tag) != -1) { os2 = new OS2Table(this); } if (Seek(PostScriptTable.Tag) != -1) { post = new PostScriptTable(this); } if (Seek(GlyphDataTable.Tag) != -1) { glyf = new GlyphDataTable(this); } if (Seek(IndexToLocationTable.Tag) != -1) { loca = new IndexToLocationTable(this); } if (Seek(GlyphSubstitutionTable.Tag) != -1) { gsub = new GlyphSubstitutionTable(this); } if (Seek(ControlValueProgram.Tag) != -1) { prep = new ControlValueProgram(this); } } catch (Exception) { GetType(); throw; } }
/// <summary> /// Creates and reads a TableDirectoryEntry from the font image. /// </summary> public static TableDirectoryEntry ReadFrom(FontData fontData) { TableDirectoryEntry entry = new TableDirectoryEntry(); entry.Tag = fontData.ReadTag(); entry.CheckSum = fontData.ReadULong(); entry.Offset = fontData.ReadLong(); entry.Length = (int)fontData.ReadULong(); return entry; }
/// <summary> /// Source: https://forum.pdfsharp.net/viewtopic.php?p=9039 /// </summary> internal void CorrectOffsetForTTC() { _pos = 0; string sTTCTag = this.ReadString(4); if (sTTCTag != "ttcf") { _pos = 0; // Reset offset return; } uint uiVersion = this.ReadULong(); uint uiFontCount = this.ReadULong(); bool bFoundFont = false; for (uint uiFontIndex = 0; uiFontIndex < uiFontCount; ++uiFontIndex) { _pos = (int)(12 + (uiFontIndex * 4)); _pos = (int)this.ReadULong(); // Read offset table uint nTempVersion = ReadULong(); uint nTempTableCount = ReadUShort(); uint nTempSearchRange = ReadUShort(); uint nTempEntrySelector = ReadUShort(); uint nTempRangeShift = ReadUShort(); TableDirectoryEntry nameTableEntry = null; for (int idx = 0; idx < nTempTableCount; idx++) { TableDirectoryEntry entry = TableDirectoryEntry.ReadFrom(this); if (entry.Tag == NameTable.Tag) { nameTableEntry = entry; break; } } if (nameTableEntry != null) { _pos = nameTableEntry.Offset; TableDictionary.Add(nameTableEntry.Tag, nameTableEntry); // Add for create NameTable NameTable nametbl = new NameTable(this); TableDictionary.Remove(nameTableEntry.Tag); // clear after used if (nametbl.Name == FontSource.FontName) { // Found font _pos = (int)(12 + (uiFontIndex * 4)); _pos = (int)this.ReadULong(); bFoundFont = true; break; } } } if (!bFoundFont) { _pos = 0; } }