Пример #1
0
        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

            reader.GetTable <HoizontalHeadTable>();                                                // 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

            // post - PostScript information
            // gasp - Grid-fitting/Scan-conversion (optional table)
            // PCLT - PCL 5 data
            // DSIG - Digital signature
            return(new FontInstance(nameTable, cmap, glyphs, os2, horizontalMetrics, head, kern));
        }
Пример #2
0
        public void LoadSingleGlyphWithInt8Offset_signed_byte()
        {
            var writer = new BigEndianBinaryWriter();

            writer.WriteUInt16((ushort)CompositeFlags.ArgsAreXYValues); // signed byte
            writer.WriteUInt16(1);                                      // glyph id

            writer.WriteInt8(sbyte.MinValue + 1);                       // dx
            writer.WriteInt8(sbyte.MinValue + 2);                       // dy
            writer.GetReader();

            var bounds = new Bounds(0, 0, 100, 100);
            var glyph  = CompositeGlyphLoader.LoadCompositeGlyph(writer.GetReader(), in bounds);

            var tbl = new GlyphTable(new[]
            {
                new SimpleGlyphLoader(bounds), // padding
                new SimpleGlyphLoader(new short[] { 20 }, new short[] { 21 }, new[] { true }, new ushort[] { 1 }, bounds)
            });

            GlyphVector finalGlyph = glyph.CreateGlyph(tbl);

            Vector2 point = Assert.Single(finalGlyph.ControlPoints);

            Assert.Equal(new Vector2(sbyte.MinValue + 1 + 20, sbyte.MinValue + 2 + 21), point);
        }
Пример #3
0
        public override Glyphs.GlyphVector CreateGlyph(GlyphTable table)
        {
            List <Vector2>       controlPoints = new List <Vector2>();
            List <bool>          onCurves      = new List <bool>();
            List <ushort>        endPoints     = new List <ushort>();
            List <Vector2>       minBounds     = new List <Vector2>();
            List <Vector2>       maxBounds     = new List <Vector2>();
            List <GlyphInstance> parts         = new List <GlyphInstance>();

            foreach (Composite composite in this.result)
            {
                GlyphVector glyph          = table.GetGlyph(composite.GlyphIndex);
                int         pointcount     = glyph.PointCount;
                ushort      endPointOffset = (ushort)controlPoints.Count;
                for (int i = 0; i < pointcount; i++)
                {
                    controlPoints.Add(Vector2.Transform(glyph.ControlPoints[i], composite.Transformation));
                    onCurves.Add(glyph.OnCurves[i]);
                }

                foreach (ushort p in glyph.EndPoints)
                {
                    endPoints.Add((ushort)(p + endPointOffset));
                }
            }

            return(new Glyphs.GlyphVector(controlPoints.ToArray(), onCurves.ToArray(), endPoints.ToArray(), this.bounds));
        }
Пример #4
0
        public override GlyphVector CreateGlyph(GlyphTable table)
        {
            var controlPoints = new List <Vector2>();
            var onCurves      = new List <bool>();
            var endPoints     = new List <ushort>();
            var minBounds     = new List <Vector2>();
            var maxBounds     = new List <Vector2>();
            var parts         = new List <GlyphInstance>();

            for (int resultIndex = 0; resultIndex < this.result.Length; resultIndex++)
            {
                ref Composite composite = ref this.result[resultIndex];

                GlyphVector glyph          = table.GetGlyph(composite.GlyphIndex);
                int         pointcount     = glyph.PointCount;
                ushort      endPointOffset = (ushort)controlPoints.Count;
                for (int i = 0; i < pointcount; i++)
                {
                    controlPoints.Add(Vector2.Transform(glyph.ControlPoints[i], composite.Transformation));
                    onCurves.Add(glyph.OnCurves[i]);
                }

                foreach (ushort p in glyph.EndPoints)
                {
                    endPoints.Add((ushort)(p + endPointOffset));
                }
            }
Пример #5
0
        /// <summary>
        ///     Fixes the shape of letters based on their position.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="output"></param>
        /// <param name="preserveNumbers"></param>
        /// <param name="farsi"></param>
        /// <returns></returns>
        public static void Fix(FastStringBuilder input, FastStringBuilder output, bool preserveNumbers, bool farsi)
        {
            FixYah(input, farsi);

            output.SetValue(input);

            for (int i = 0; i < input.Length; i++)
            {
                bool skipNext = false;
                char iChar = input.Get(i);

                // For special Lam Letter connections.
                if (iChar == (char)GeneralLetters.Lam)
                {
                    if (i < input.Length - 1)
                    {
                        skipNext = HandleSpecialLam(input, output, i);
                        if (skipNext)
                            iChar = output.Get(i);
                    }
                }

                // We don't want to fix tatweel or zwnj character
                if (iChar == (int)GeneralLetters.ArabicTatweel ||
                    iChar == (int)GeneralLetters.ZeroWidthNoJoiner)
                {
                    continue;
                }

                if (TextUtils.IsRTLCharacter(iChar))
                {
                    char converted = GlyphTable.Convert(iChar);

                    if (IsMiddleLetter(input, i))
                    {
                        output.Set(i, (char)(converted + 3));
                    }
                    else if (IsFinishingLetter(input, i))
                    {
                        output.Set(i, (char)(converted + 1));
                    }
                    else if (IsLeadingLetter(input, i))
                    {
                        output.Set(i, (char)(converted + 2));
                    }
                }

                // If this letter as Lam and special Lam-Alef connection was made, We want to skip the Alef
                // (Lam-Alef occupies 1 space)
                if (skipNext)
                {
                    i++;
                }
            }

            if (!preserveNumbers)
            {
                FixNumbers(output, farsi);
            }
        }
 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)
 {
 }
Пример #7
0
 public void GetGlyphTable()
 {
     if (glyphTable == null)
     {
         glyphTable = FindObjectOfType <GlyphTable>();
     }
 }
        public void LoadSingleGlyphWithUInt8Offset_unsigned_byte()
        {
            var writer = new BigEndianBinaryWriter();

            writer.WriteUInt16(0);                 // 8bit unsigned
            writer.WriteUInt16(1);                 // glyph id

            writer.WriteUInt8(sbyte.MaxValue + 1); // dx
            writer.WriteUInt8(sbyte.MaxValue + 2); // dy
            writer.GetReader();

            var bounds = new Bounds(0, 0, 100, 100);
            var glyph  = CompositeGlyphLoader.LoadCompositeGlyph(writer.GetReader(), in bounds);

            var tbl = new GlyphTable(new[]
            {
                new SimpleGlyphLoader(bounds), // padding
                new SimpleGlyphLoader(new short[] { 20 }, new short[] { 21 }, new[] { true }, new ushort[] { 1 }, bounds, Array.Empty <byte>())
            });

            GlyphVector finalGlyph = glyph.CreateGlyph(tbl);

            Vector2 point = Assert.Single(finalGlyph.GetOutline().ControlPoints.ToArray());

            Assert.Equal(new Vector2(sbyte.MaxValue + 1 + 20, sbyte.MaxValue + 2 + 21), point);
        }
        public void LoadSingleGlyphWithInt16Offset_signed_short()
        {
            var writer = new BigEndianBinaryWriter();

            writer.WriteUInt16((ushort)(CompositeGlyphFlags.Args1And2AreWords /* 16bit */ | CompositeGlyphFlags.ArgsAreXYValues /* signed */)); // flags
            writer.WriteUInt16(1);                                                                                                              // glyph id

            writer.WriteInt16(short.MinValue + 1);                                                                                              // dx
            writer.WriteInt16(short.MinValue + 2);                                                                                              // dy
            writer.GetReader();

            var bounds = new Bounds(0, 0, 100, 100);
            var glyph  = CompositeGlyphLoader.LoadCompositeGlyph(writer.GetReader(), in bounds);

            var tbl = new GlyphTable(new[]
            {
                new SimpleGlyphLoader(bounds), // padding
                new SimpleGlyphLoader(new short[] { 20 }, new short[] { 21 }, new[] { true }, new ushort[] { 1 }, bounds, Array.Empty <byte>())
            });

            GlyphVector finalGlyph = glyph.CreateGlyph(tbl);

            Vector2 point = Assert.Single(finalGlyph.GetOutline().ControlPoints.ToArray());

            Assert.Equal(new Vector2(short.MinValue + 1 + 20, short.MinValue + 2 + 21), point);
        }
Пример #10
0
 public void Get(BinaryWriter writer)
 {
     Header.Get(writer);
     Dictionary.Get(writer);
     GlyphTable.Get(writer);
     writer.Write(CompressedData);
 }
        /**
         * Builds vertical metrics with a custom CIDToGIDMap (for embedding font subset).
         */
        private void BuildVerticalMetrics(Dictionary <int, int> cidToGid)
        {
            // The "vhea" and "vmtx" tables that specify vertical metrics shall never be used by a conforming
            // reader. The only way to specify vertical metrics in PDF shall be by means of the DW2 and W2
            // entries in a CIDFont dictionary.

            if (!BuildVerticalHeader(cidFont))
            {
                return;
            }

            float scaling = 1000f / ttf.Header.UnitsPerEm;

            VerticalHeaderTable    vhea = ttf.VerticalHeader;
            VerticalMetricsTable   vmtx = ttf.VerticalMetrics;
            GlyphTable             glyf = ttf.Glyph;
            HorizontalMetricsTable hmtx = ttf.HorizontalMetrics;

            long v_y = (long)Math.Round(vhea.Ascender * scaling);
            long w1  = (long)Math.Round(-vhea.AdvanceHeightMax * scaling);

            PdfArray heights = new PdfArray();
            PdfArray w2      = new PdfArray();
            int      prev    = int.MinValue;
            // Use a sorted list to get an optimal width array
            ISet <int> keys = new HashSet <int>(cidToGid.Keys);

            foreach (int cid in keys)
            {
                // Unlike buildWidths, we look up with cid (not gid) here because this is
                // the original TTF, not the rebuilt one.
                GlyphData glyph = glyf.GetGlyph(cid);
                if (glyph == null)
                {
                    continue;
                }
                long height  = (long)Math.Round((glyph.YMaximum + vmtx.GetTopSideBearing(cid)) * scaling);
                long advance = (long)Math.Round(-vmtx.GetAdvanceHeight(cid) * scaling);
                if (height == v_y && advance == w1)
                {
                    // skip default metrics
                    continue;
                }
                // c [w1_1y v_1x v_1y w1_2y v_2x v_2y ... w1_ny v_nx v_ny]
                if (prev != cid - 1)
                {
                    w2 = new PdfArray();
                    heights.Add(PdfInteger.Get(cid)); // c
                    heights.Add(w2);
                }
                w2.Add(PdfInteger.Get(advance));   // w1_iy
                long width = (long)Math.Round(hmtx.GetAdvanceWidth(cid) * scaling);
                w2.Add(PdfInteger.Get(width / 2)); // v_ix
                w2.Add(PdfInteger.Get(height));    // v_iy
                prev = cid;
            }
            cidFont[PdfName.W2] = heights;
        }
        public void GlyphsCount_WithWoffFormat_EqualsTtf()
        {
            var        fontReaderWoff = new FontReader(TestFonts.OpensSansWoff1Data());
            GlyphTable glyphsWoff     = fontReaderWoff.GetTable <GlyphTable>();
            var        fontReaderTtf  = new FontReader(TestFonts.OpenSansTtfData());
            GlyphTable glyphsTtf      = fontReaderTtf.GetTable <GlyphTable>();

            Assert.Equal(glyphsTtf.GlyphCount, glyphsWoff.GlyphCount);
        }
        public override GlyphVector CreateGlyph(GlyphTable table)
        {
            GlyphVector glyph = default;

            for (int resultIndex = 0; resultIndex < this.result.Length; resultIndex++)
            {
                ref Composite composite = ref this.result[resultIndex];
                glyph = GlyphVector.Append(glyph, GlyphVector.Transform(GlyphVector.DeepClone(table.GetGlyph(composite.GlyphIndex)), composite.Transformation), this.bounds);
            }
Пример #14
0
        public override Glyphs.GlyphVector CreateGlyph(GlyphTable table)
        {
            this.counter++;
            if (this.counter > 100)
            {
                throw new Fonts.Exceptions.FontException("loop detected loading glyphs");
            }

            return(table.GetGlyph(0));
        }
Пример #15
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)
 {
 }
Пример #16
0
 public override Glyphs.GlyphVector CreateGlyph(GlyphTable table)
 {
     if (this.loop)
     {
         if (this.glyph == null)
         {
             this.glyph = new GlyphVector(new Vector2[0], new bool[0], new ushort[0], this.fallbackEmptyBounds);
         }
         return(this.glyph.Value);
     }
     this.loop = true;
     return(table.GetGlyph(0));
 }
Пример #17
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FontDescription" /> 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="horizontalMetrics">The horizontal metrics.</param>
        /// <param name="head">The head.</param>
        /// <param name="kern">The kern.</param>
        internal FontInstance(NameTable nameTable, CMapTable cmap, GlyphTable glyphs, OS2Table os2, HorizontalMetricsTable horizontalMetrics, HeadTable head, KerningTable kern)
        {
            this.cmap              = cmap;
            this.os2               = os2;
            this.glyphs            = glyphs;
            this.horizontalMetrics = horizontalMetrics;
            this.head              = head;
            this.glyphCache        = new GlyphInstance[this.glyphs.GlyphCount];

            // https://www.microsoft.com/typography/otspec/recom.htm#tad
            this.LineHeight  = os2.TypoAscender - os2.TypoDescender + os2.TypoLineGap;
            this.EmSize      = this.head.UnitsPerEm;
            this.kerning     = kern;
            this.Description = new FontDescription(nameTable, os2, head);
        }
Пример #18
0
        private void ProcessTables()
        {
            // TODO: These may need to be Processed() in a certain order, for example the horizontal metrics table
            // 'needs' to know the number of metrics from the horizontal header table.
            // However, it looks like the tables are listed in the proper order, so we get that for free. But that seems awfully fragile....
            foreach (var table in Tables)
            {
                // Call each table's process method to parse data
                table.Process(this);

                switch (table.Type)
                {
                case FontTableType.CharacterToGlyphMap:
                    cmap = (CharacterToGlyphTable)table;
                    break;

                case FontTableType.FontHeader:
                    head = (HeaderTable)table;
                    break;

                case FontTableType.HorizontalHeader:
                    hhea = (HorizontalHeaderTable)table;
                    break;

                case FontTableType.HorizontalMetrics:
                    hmtx = (HorizontalMetricsTable)table;
                    break;

                case FontTableType.Kerning:
                    kern = (KerningTable)table;
                    break;

                case FontTableType.MaximumProfile:
                    maxp = (MaximumProfileTable)table;
                    break;

                case FontTableType.IndexToLocation:
                    loca = (IndexToLocationTable)table;
                    break;

                case FontTableType.GlyphData:
                    glyf = (GlyphTable)table;
                    break;
                }
            }
        }
Пример #19
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);
        }
Пример #20
0
 public override GlyphVector CreateGlyph(GlyphTable table)
 {
     // lets build some shapes ??? here from
     return(new GlyphVector(Convert(this.xs, this.ys), this.onCurves, this.endPoints, this.bounds));
 }
        /// <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);
        }
Пример #22
0
 public abstract GlyphVector CreateGlyph(GlyphTable table);
Пример #23
0
 public override GlyphVector CreateGlyph(GlyphTable table)
 => new(Convert(this.xs, this.ys), this.onCurves, this.endPoints, this.bounds, this.instructions);