コード例 #1
0
 internal FakeFontInstance(
     NameTable nameTable,
     MaximumProfileTable maxpTable,
     CMapTable cmap,
     GlyphTable glyphs,
     OS2Table os2,
     HorizontalHeadTable horizontalHeadTable,
     HorizontalMetricsTable horizontalMetrics,
     VerticalHeadTable verticalHeadTable,
     VerticalMetricsTable verticalMetrics,
     HeadTable head,
     KerningTable kern)
     : base(
         nameTable,
         maxpTable,
         cmap,
         glyphs,
         os2,
         horizontalHeadTable,
         horizontalMetrics,
         verticalHeadTable,
         verticalMetrics,
         head,
         kern,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null)
 {
 }
コード例 #2
0
        public static HorizontalMetricsTable Load(FontReader reader)
        {
            // you should load all dependent tables prior to manipulating the reader
            HorizontalHeadTable headTable    = reader.GetTable <HorizontalHeadTable>();
            MaximumProfileTable profileTable = reader.GetTable <MaximumProfileTable>();

            // Move to start of table
            using BigEndianBinaryReader binaryReader = reader.GetReaderAtTablePosition(TableName);
            return(Load(binaryReader, headTable.NumberOfHMetrics, profileTable.GlyphCount));
        }
コード例 #3
0
        public void ShouldReturnNullWhenTableCouldNotBeFound()
        {
            var writer = new BinaryWriter();

            writer.WriteTrueTypeFileHeader();

            using (var stream = writer.GetStream())
            {
                Assert.Null(HorizontalHeadTable.Load(new FontReader(stream)));
            }
        }
コード例 #4
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)
 {
 }
コード例 #5
0
ファイル: FontInstance.cs プロジェクト: KinsonDigital/Fonts
        internal static FontInstance LoadFont(FontReader reader)
        {
            // https://www.microsoft.com/typography/otspec/recom.htm#TableOrdering
            // recomended order
            HeadTable           head = reader.GetTable <HeadTable>();                              // head - not saving but loading in suggested order
            HorizontalHeadTable hhea = reader.GetTable <HorizontalHeadTable>();                    // hhea

            reader.GetTable <MaximumProfileTable>();                                               // maxp
            OS2Table os2 = reader.GetTable <OS2Table>();                                           // OS/2
            HorizontalMetricsTable horizontalMetrics = reader.GetTable <HorizontalMetricsTable>(); // hmtx

            // LTSH - Linear threshold data
            // VDMX - Vertical device metrics
            // hdmx - Horizontal device metrics
            CMapTable cmap = reader.GetTable <CMapTable>(); // cmap

            // fpgm - Font Program
            // prep - Control Value Program
            // cvt  - Control Value Table
            reader.GetTable <IndexLocationTable>();                    // loca
            GlyphTable   glyphs    = reader.GetTable <GlyphTable>();   // glyf
            KerningTable kern      = reader.GetTable <KerningTable>(); // kern - Kerning
            NameTable    nameTable = reader.GetTable <NameTable>();    // name

            ColrTable?colrTable = reader.TryGetTable <ColrTable>();    // colr
            CpalTable?cpalTable;

            if (colrTable != null)
            {
                cpalTable = reader.GetTable <CpalTable>(); // CPAL - required if COLR is provided
            }
            else
            {
                cpalTable = reader.TryGetTable <CpalTable>(); // colr
            }

            // post - PostScript information
            // gasp - Grid-fitting/Scan-conversion (optional table)
            // PCLT - PCL 5 data
            // DSIG - Digital signature
            return(new FontInstance(
                       nameTable,
                       cmap,
                       glyphs,
                       os2,
                       hhea,
                       horizontalMetrics,
                       head,
                       kern,
                       colrTable,
                       cpalTable));
        }
コード例 #6
0
        public static void WriteHorizontalHeadTable(this BinaryWriter writer, HorizontalHeadTable table)
        {
            // Type      | Name                 | Description
            // ----------|----------------------|----------------------------------------------------------------------------------------------------
            // uint16    | majorVersion         | Major version number of the horizontal header table — set to 1.
            // uint16    | minorVersion         | Minor version number of the horizontal header table — set to 0.
            // FWORD     | Ascender             | Typographic ascent (Distance from baseline of highest ascender).
            // FWORD     | Descender            | Typographic descent (Distance from baseline of lowest descender).
            // FWORD     | LineGap              | Typographic line gap. - Negative  LineGap values are treated as zero in Windows 3.1, and in Mac OS System 6 and System 7.
            // UFWORD    | advanceWidthMax      | Maximum advance width value in 'hmtx' table.
            // FWORD     | minLeftSideBearing   | Minimum left sidebearing value in 'hmtx' table.
            // FWORD     | minRightSideBearing  | Minimum right sidebearing value; calculated as Min(aw - lsb - (xMax - xMin)).
            // FWORD     | xMaxExtent           | Max(lsb + (xMax - xMin)).
            // int16     | caretSlopeRise       | Used to calculate the slope of the cursor (rise/run); 1 for vertical.
            // int16     | caretSlopeRun        | 0 for vertical.
            // int16     | caretOffset          | The amount by which a slanted highlight on a glyph needs to be shifted to produce the best appearance. Set to 0 for non-slanted fonts
            // int16     | (reserved)           | set to 0
            // int16     | (reserved)           | set to 0
            // int16     | (reserved)           | set to 0
            // int16     | (reserved)           | set to 0
            // int16     | metricDataFormat     | 0 for current format.
            // uint16    | numberOfHMetrics     | Number of hMetric entries in 'hmtx' table

            writer.WriteUInt16(1);
            writer.WriteUInt16(1);
            writer.WriteFWORD(table.Ascender);
            writer.WriteFWORD(table.Descender);
            writer.WriteFWORD(table.LineGap);
            writer.WriteUFWORD(table.AdvanceWidthMax);
            writer.WriteFWORD(table.MinLeftSideBearing);
            writer.WriteFWORD(table.MinRightSideBearing);
            writer.WriteFWORD(table.XMaxExtent);
            writer.WriteInt16(table.CaretSlopeRise);
            writer.WriteInt16(table.CaretSlopeRun);
            writer.WriteInt16(table.CaretOffset);
            writer.WriteInt16(0); // reserved
            writer.WriteInt16(0); // reserved
            writer.WriteInt16(0); // reserved
            writer.WriteInt16(0); // reserved
            writer.WriteInt16(0); // metricDataFormat should be 0
            writer.WriteUInt16(table.NumberOfHMetrics);
        }
コード例 #7
0
        public void LoadHorizontalHeadTable()
        {
            var writer = new BinaryWriter();

            writer.WriteHorizontalHeadTable(new HorizontalHeadTable(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));

            HorizontalHeadTable tbl = HorizontalHeadTable.Load(writer.GetReader());

            Assert.Equal(1, tbl.Ascender);
            Assert.Equal(2, tbl.Descender);
            Assert.Equal(3, tbl.LineGap);
            Assert.Equal(4, tbl.AdvanceWidthMax);
            Assert.Equal(5, tbl.MinLeftSideBearing);
            Assert.Equal(6, tbl.MinRightSideBearing);
            Assert.Equal(7, tbl.XMaxExtent);
            Assert.Equal(8, tbl.CaretSlopeRise);
            Assert.Equal(9, tbl.CaretSlopeRun);
            Assert.Equal(10, tbl.CaretOffset);
            Assert.Equal(11, tbl.NumberOfHMetrics);
        }
コード例 #8
0
ファイル: FontInstance.cs プロジェクト: KinsonDigital/Fonts
        /// <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);
        }
コード例 #9
0
        /// <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);
        }