internal static CMapTable GetCMAP(Reader reader) { reader.Position = 4; ushort numTables = (ushort)reader.ReadUint16(); ushort searchRange = (ushort)reader.ReadUint16(); ushort entrySelector = (ushort)reader.ReadUint16(); ushort rangeShift = (ushort)reader.ReadUint16(); int offset = -1; int length = -1; for (int i = 0; i < numTables; ++i) { OffsetTable table = new OffsetTable(); table.Read(reader); if (table.Tag == "cmap") { offset = (int)table.Offset; length = (int)table.Length; break; } } CMapTable cmap = new CMapTable(); cmap.Read(reader, offset, length); return(cmap); }
internal FakeFontInstance( NameTable nameTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalHeadTable horizontalHeadTable, HorizontalMetricsTable horizontalMetrics, HeadTable head, KerningTable kern) : base(nameTable, cmap, glyphs, os2, horizontalHeadTable, horizontalMetrics, head, kern, null, null) { }
public void ShouldThrowExceptionWhenTableCouldNotBeFound() { var writer = new BinaryWriter(); writer.WriteTrueTypeFileHeader(); using (var stream = writer.GetStream()) { var exception = Assert.Throws <InvalidFontTableException>(() => CMapTable.Load(new FontReader(stream))); Assert.Equal("cmap", exception.Table); } }
public void LoadFormat0() { var writer = new BinaryWriter(); writer.WriteCMapTable(new[] { new Format0SubTable(0, PlatformIDs.Windows, 9, new byte[] { 0, 1, 2 }) }); CMapTable table = CMapTable.Load(writer.GetReader()); Assert.Single(table.Tables.Where(x => x != null)); Format0SubTable[] format0Tables = table.Tables.OfType <Format0SubTable>().ToArray(); Assert.Single(format0Tables); }
public void LoadFormat0() { BinaryWriter writer = new BinaryWriter(); writer.WriteCMapTable(new [] { new SixLabors.Fonts.Tables.General.CMap.Format0SubTable(0, PlatformIDs.Windows, 9, new byte[] { 0, 1, 2 }) }); CMapTable table = CMapTable.Load(writer.GetReader()); Assert.Equal(1, table.Tables.Where(x => x != null).Count()); Format0SubTable[] format0Tables = table.Tables.OfType <Format0SubTable>().ToArray(); Assert.Equal(1, format0Tables.Length); }
private static CMapTable GetCMapTable(TrueTypeFont font, DirectoryEntry entry, OldToNewGlyphIndex[] encoding) { var data = new byte[256]; for (var i = 0; i < data.Length; i++) { if (i < encoding.Length) { data[i] = encoding[i].NewIndex; } else { break; } } var cmap = new CMapTable(font.TableRegister.CMapTable.Version, entry.DummyHeader, new[] { new ByteEncodingCMapTable(TrueTypeCMapPlatform.Macintosh, 0, 0, data) }); return(cmap); }
private bool TryGetGlyphIndex(int characterIdentifier, Func <int, int> characterIdentifierToGlyphIndex, out int glyphIndex) { glyphIndex = 0; if (characterIdentifierToGlyphIndex != null) { glyphIndex = characterIdentifierToGlyphIndex(characterIdentifier); return(true); } if (CMapTable == null) { return(false); } if (!CMapTable.TryGetGlyphIndex(characterIdentifier, out glyphIndex)) { return(false); } return(true); }
/// <summary> /// Initializes a new instance of the <see cref="FontInstance"/> class. /// </summary> /// <param name="nameTable">The name table.</param> /// <param name="cmap">The cmap.</param> /// <param name="glyphs">The glyphs.</param> /// <param name="os2">The os2.</param> /// <param name="horizontalHeadTable">The horizontal head table.</param> /// <param name="horizontalMetrics">The horizontal metrics.</param> /// <param name="head">The head.</param> /// <param name="kern">The kern.</param> /// <param name="colrTable">The COLR table</param> /// <param name="cpalTable">The CPAL table</param> internal FontInstance( NameTable nameTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalHeadTable horizontalHeadTable, HorizontalMetricsTable horizontalMetrics, HeadTable head, KerningTable kern, ColrTable?colrTable, CpalTable?cpalTable) { this.cmap = cmap; this.os2 = os2; this.glyphs = glyphs; this.horizontalMetrics = horizontalMetrics; this.head = head; this.glyphCache = new GlyphInstance[this.glyphs.GlyphCount]; if (!(colrTable is null)) { this.colorGlyphCache = new GlyphInstance[this.glyphs.GlyphCount][]; } bool useTypoMetrics = os2.FontStyle.HasFlag(OS2Table.FontStyleSelection.USE_TYPO_METRICS); // https://www.microsoft.com/typography/otspec/recom.htm#tad this.Ascender = useTypoMetrics ? os2.TypoAscender : horizontalHeadTable.Ascender; this.Descender = useTypoMetrics ? os2.TypoDescender : horizontalHeadTable.Descender; this.LineGap = useTypoMetrics ? os2.TypoLineGap : horizontalHeadTable.LineGap; this.LineHeight = this.Ascender - this.Descender + this.LineGap; this.EmSize = this.head.UnitsPerEm; this.kerning = kern; this.colrTable = colrTable; this.cpalTable = cpalTable; this.Description = new FontDescription(nameTable, os2, head); }
/// <summary> /// Initializes a new instance of the <see cref="StreamFontMetrics"/> class. /// </summary> /// <param name="nameTable">The name table.</param> /// <param name="maximumProfileTable">The maximum profile table.</param> /// <param name="cmap">The cmap table.</param> /// <param name="glyphs">The glyph table.</param> /// <param name="os2">The os2 table.</param> /// <param name="horizontalHeadTable">The horizontal head table.</param> /// <param name="horizontalMetrics">The horizontal metrics table.</param> /// <param name="verticalHeadTable">The vertical head table.</param> /// <param name="verticalMetrics">The vertical metrics table.</param> /// <param name="head">The head table.</param> /// <param name="kern">The kerning table.</param> /// <param name="gSubTable">The glyph substitution table.</param> /// <param name="gPosTable">The glyph positioning table.</param> /// <param name="colrTable">The COLR table</param> /// <param name="cpalTable">The CPAL table</param> /// <param name="fpgm">The font program table.</param> /// <param name="cvt">The control value table.</param> /// <param name="prep">The control value program table.</param> /// <param name="glyphDefinitionTable">The glyph definition table.</param> internal StreamFontMetrics( NameTable nameTable, MaximumProfileTable maximumProfileTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalHeadTable horizontalHeadTable, HorizontalMetricsTable horizontalMetrics, VerticalHeadTable?verticalHeadTable, VerticalMetricsTable?verticalMetrics, HeadTable head, KerningTable kern, GSubTable?gSubTable, GPosTable?gPosTable, ColrTable?colrTable, CpalTable?cpalTable, FpgmTable?fpgm, CvtTable?cvt, PrepTable?prep, GlyphDefinitionTable?glyphDefinitionTable) { this.maximumProfileTable = maximumProfileTable; this.cmap = cmap; this.os2 = os2; this.glyphs = glyphs; this.horizontalMetrics = horizontalMetrics; this.verticalMetricsTable = verticalMetrics; this.head = head; this.glyphCache = new GlyphMetrics[this.glyphs.GlyphCount][]; if (colrTable is not null) { this.colorGlyphCache = new GlyphMetrics[this.glyphs.GlyphCount][]; } // https://www.microsoft.com/typography/otspec/recom.htm#tad // We use the same approach as FreeType for calculating the the global ascender, descender, and // height of OpenType fonts for consistency. // // 1.If the OS/ 2 table exists and the fsSelection bit 7 is set (USE_TYPO_METRICS), trust the font // and use the Typo* metrics. // 2.Otherwise, use the HorizontalHeadTable "hhea" table's metrics. // 3.If they are zero and the OS/ 2 table exists, // - Use the OS/ 2 table's sTypo* metrics if they are non-zero. // - Otherwise, use the OS / 2 table's usWin* metrics. bool useTypoMetrics = os2.FontStyle.HasFlag(OS2Table.FontStyleSelection.USE_TYPO_METRICS); if (useTypoMetrics) { this.Ascender = os2.TypoAscender; this.Descender = os2.TypoDescender; this.LineGap = os2.TypoLineGap; this.LineHeight = (short)(this.Ascender - this.Descender + this.LineGap); } else { this.Ascender = horizontalHeadTable.Ascender; this.Descender = horizontalHeadTable.Descender; this.LineGap = horizontalHeadTable.LineGap; this.LineHeight = (short)(this.Ascender - this.Descender + this.LineGap); } if (this.Ascender == 0 || this.Descender == 0) { if (os2.TypoAscender != 0 || os2.TypoDescender != 0) { this.Ascender = os2.TypoAscender; this.Descender = os2.TypoDescender; this.LineGap = os2.TypoLineGap; this.LineHeight = (short)(this.Ascender - this.Descender + this.LineGap); } else { this.Ascender = (short)os2.WinAscent; this.Descender = (short)-os2.WinDescent; this.LineHeight = (short)(this.Ascender - this.Descender); } } this.UnitsPerEm = this.head.UnitsPerEm; // 72 * UnitsPerEm means 1pt = 1px this.ScaleFactor = this.UnitsPerEm * 72F; this.AdvanceWidthMax = (short)horizontalHeadTable.AdvanceWidthMax; this.AdvanceHeightMax = verticalHeadTable == null ? this.LineHeight : verticalHeadTable.AdvanceHeightMax; this.kerningTable = kern; this.gSubTable = gSubTable; this.gPosTable = gPosTable; this.colrTable = colrTable; this.cpalTable = cpalTable; this.fpgm = fpgm; this.cvt = cvt; this.prep = prep; this.glyphDefinitionTable = glyphDefinitionTable; this.Description = new FontDescription(nameTable, os2, head); }