Esempio n. 1
0
        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);
        }
Esempio n. 2
0
 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)
 {
 }
Esempio n. 3
0
        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);
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        /// <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);
        }