public static TTFStringMeasurer Create(TrueTypeFile forfont, CMapEncoding encoding, TypeMeasureOptions options)
        {
            HorizontalMetrics table = forfont.Directories["hmtx"].Table as HorizontalMetrics;
            CMAPTable         cmap  = forfont.Directories["cmap"].Table as CMAPTable;
            OS2Table          os2   = forfont.Directories["OS/2"].Table as OS2Table;
            FontHeader        head  = forfont.Directories["head"].Table as FontHeader;
            HorizontalHeader  hhead = forfont.Directories["hhea"].Table as HorizontalHeader;

            CMAPSubTable map = cmap.GetOffsetTable(encoding);

            if (map == null)
            {
                encoding = CMapEncoding.Unicode_20;
                map      = cmap.GetOffsetTable(CMapEncoding.Unicode_20);
            }

            if (map == null)
            {
                encoding = CMapEncoding.MacRoman;
                map      = cmap.GetOffsetTable(CMapEncoding.MacRoman);
            }



            return(new TTFStringMeasurer(head.UnitsPerEm, map, os2, hhead, table.HMetrics, forfont, encoding, options));
        }
예제 #2
0
        private static FontStyle ConvertStyle(OS2Table os2, HeadTable head)
        {
            FontStyle style = FontStyle.Regular;

            if (os2 != null)
            {
                if (os2.FontStyle.HasFlag(OS2Table.FontStyleSelection.BOLD))
                {
                    style |= FontStyle.Bold;
                }

                if (os2.FontStyle.HasFlag(OS2Table.FontStyleSelection.ITALIC))
                {
                    style |= FontStyle.Italic;
                }
            }
            else if (head != null)
            {
                if (head.MacStyle.HasFlag(HeadTable.HeadMacStyle.Bold))
                {
                    style |= FontStyle.Bold;
                }

                if (head.MacStyle.HasFlag(HeadTable.HeadMacStyle.Italic))
                {
                    style |= FontStyle.Italic;
                }
            }

            return(style);
        }
 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)
 {
 }
예제 #4
0
        /// <summary>
        /// read only name entry
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public PreviewFontInfo ReadPreview(Stream stream)
        {
            var little = BitConverter.IsLittleEndian;

            using (var input = new ByteOrderSwappingBinaryReader(stream))
            {
                ushort majorVersion  = input.ReadUInt16();
                ushort minorVersion  = input.ReadUInt16();
                ushort tableCount    = input.ReadUInt16();
                ushort searchRange   = input.ReadUInt16();
                ushort entrySelector = input.ReadUInt16();
                ushort rangeShift    = input.ReadUInt16();
                var    tables        = new TableEntryCollection();
                for (int i = 0; i < tableCount; i++)
                {
                    tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input)));
                }


                NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry());
                OS2Table  os2Table  = ReadTableIfExists(tables, input, new OS2Table());

                return(new PreviewFontInfo(
                           nameEntry.FontName,
                           nameEntry.FontSubFamily,
                           Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table)
                           ));
            }
        }
예제 #5
0
        internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input)
        {
            var rd = new EntriesReaderHelper(tables, input);

            NameEntry nameEntry = rd.Read(new NameEntry());
            OS2Table  os2Table  = rd.Read(new OS2Table());
            //for preview, read ONLY  script list from gsub and gpos (set OnlyScriptList).
            Meta metaTable = rd.Read(new Meta());

            GSUB gsub = rd.Read(new GSUB()
            {
                OnlyScriptList = true
            });
            GPOS gpos = rd.Read(new GPOS()
            {
                OnlyScriptList = true
            });
            Cmap cmap = rd.Read(new Cmap());
            //gsub and gpos contains actual script_list that are in the typeface

            Languages langs = new Languages();

            langs.Update(os2Table, metaTable, cmap, gsub, gpos);

            return(new PreviewFontInfo(
                       nameEntry,
                       os2Table,
                       langs));
        }
예제 #6
0
 private void EnsureOS2Table()
 {
     if (os2 == null)
     {
         os2 = (OS2Table)GetTable(TableNames.Os2);
     }
 }
예제 #7
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));
        }
        protected double GetLineHeight(FontUnitType units, OS2Table os2, HorizontalHeader hhead, FontHeader header, double emsize)
        {
            double h;
            bool   useTypo;

            if (units == FontUnitType.UseFontPreference)
            {
                useTypo = (os2.Version >= OS2TableVersion.OpenType15) && ((os2.Selection & FontSelection.UseTypographicSizes) > 0);
            }
            else if (units == FontUnitType.UseHeadMetrics)
            {
                useTypo = false;
            }
            else if (null == os2)
            {
                useTypo = false;
            }
            else
            {
                useTypo = true;
            }

            if (useTypo)
            {
                h = ((double)(os2.TypoAscender - os2.TypoDescender + os2.TypoLineGap) / ((double)header.UnitsPerEm) * emsize);
            }
            else
            {
                h = ((double)(hhead.Ascender - hhead.Descender + hhead.LineGap) / ((double)header.UnitsPerEm) * emsize);
            }

            return(h);
        }
예제 #9
0
        /// <summary>
        /// Reads a <see cref="FontDescription" /> from the specified stream.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>
        /// a <see cref="FontDescription" />.
        /// </returns>
        internal static FontDescription LoadDescription(FontReader reader)
        {
            HeadTable head      = reader.GetTable <HeadTable>();
            OS2Table  os2       = reader.GetTable <OS2Table>();
            NameTable nameTable = reader.GetTable <NameTable>();

            return(new FontDescription(nameTable, os2, head));
        }
예제 #10
0
        /// <summary>
        /// Reads a <see cref="FontDescription" /> from the specified stream.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>
        /// a <see cref="FontDescription" />.
        /// </returns>
        internal static FontDescription LoadDescription(FontReader reader)
        {
            // NOTE: These fields are read in their optimized order
            // https://docs.microsoft.com/en-gb/typography/opentype/spec/recom#optimized-table-ordering
            HeadTable head      = reader.GetTable <HeadTable>();
            OS2Table  os2       = reader.GetTable <OS2Table>();
            NameTable nameTable = reader.GetTable <NameTable>();

            return(new FontDescription(nameTable, os2, head));
        }
예제 #11
0
        private InstalledTypeface(NameEntry nameTable, OS2Table os2Table, Languages languages, string fontPath)
        {
            _nameEntry = nameTable;
            _os2Table  = os2Table;
            FontPath   = fontPath;
            Languages  = languages;

            var fsSelection = new OS2FsSelection(os2Table.fsSelection);

            TypefaceStyle = fsSelection.IsItalic ? TypefaceStyle.Italic : TypefaceStyle.Regular;
        }
예제 #12
0
        public void ShouldReturnNullWhenTableCouldNotBeFound()
        {
            var writer = new BigEndianBinaryWriter();

            writer.WriteTrueTypeFileHeader();

            using (System.IO.MemoryStream stream = writer.GetStream())
            {
                Assert.Null(OS2Table.Load(new FontReader(stream)));
            }
        }
        internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input)
        {
            NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry());
            OS2Table  os2Table  = ReadTableIfExists(tables, input, new OS2Table());

            return(new PreviewFontInfo(
                       nameEntry.TypographicFamilyName ?? nameEntry.FontName,
                       nameEntry.TypographyicSubfamilyName ?? nameEntry.FontSubFamily,
                       os2Table.usWeightClass,
                       Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table)));
        }
예제 #14
0
파일: Typeface.cs 프로젝트: zwcloud/ImGui
 internal void SetBasicTypefaceTables(OS2Table os2Table,
                                      NameEntry nameEntry,
                                      Head head,
                                      HorizontalMetrics horizontalMetrics)
 {
     OS2Table   = os2Table;
     _nameEntry = nameEntry;
     Head       = head;
     Bounds     = head.Bounds;
     UnitsPerEm = head.UnitsPerEm;
     _hMetrics  = horizontalMetrics;
 }
예제 #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
파일: OS2Table.cs 프로젝트: bixiu/BlueMine
 public OS2Table(OS2Table versionLessthan5Table, ushort lowerOpticalPointSize, ushort upperOpticalPointSize)
     : this(versionLessthan5Table,
            versionLessthan5Table.codePageRange1,
            versionLessthan5Table.codePageRange2,
            versionLessthan5Table.heightX,
            versionLessthan5Table.capHeight,
            versionLessthan5Table.defaultChar,
            versionLessthan5Table.breakChar,
            versionLessthan5Table.maxContext)
 {
     this.lowerOpticalPointSize = lowerOpticalPointSize;
     this.upperOpticalPointSize = upperOpticalPointSize;
 }
        private TTFStringMeasurer(int unitsPerEm, CMAPSubTable offsets, OS2Table oS2, HorizontalHeader hheader, List <HMetric> metrics, TrueTypeFile font, CMapEncoding encoding, TypeMeasureOptions options)
        {
            this._unitsPerEm  = unitsPerEm;
            this._offsets     = offsets;
            this._os2         = oS2;
            this._metrics     = metrics;
            this._lookup      = new Dictionary <char, HMetric>();
            this._options     = options;
            this._fontUseTypo = (oS2.Version >= OS2TableVersion.OpenType15) && ((oS2.Selection & FontSelection.UseTypographicSizes) > 0);

            this._hheader      = hheader;
            this._fontfile     = font;
            this._cMapEncoding = encoding;
        }
예제 #18
0
        internal PreviewFontInfo(
            NameEntry nameEntry,
            OS2Table os2Table,
            Languages langs)
        {
            NameEntry = nameEntry;
            OS2Table  = os2Table;
            Languages = langs;

            Name               = nameEntry.FontName;
            SubFamilyName      = nameEntry.FontSubFamily;
            OS2TranslatedStyle = Extensions.TypefaceExtensions.TranslateOS2FontStyle(os2Table);
            OS2FsSelection     = Extensions.TypefaceExtensions.TranslateOS2FsSelection(os2Table);
        }
예제 #19
0
 internal Typeface(
     NameEntry nameEntry,
     Bounds bounds,
     ushort unitsPerEm,
     Glyph[] glyphs,
     HorizontalMetrics horizontalMetrics,
     OS2Table os2Table)
 {
     _nameEntry         = nameEntry;
     _bounds            = bounds;
     _unitsPerEm        = unitsPerEm;
     _glyphs            = glyphs;
     _horizontalMetrics = horizontalMetrics;
     OS2Table           = os2Table;
 }
예제 #20
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);
        }
예제 #21
0
        internal Typeface(
            NameEntry nameEntry,
            Bounds bounds,
            ushort unitsPerEm,
            CFFTable cffTable,
            HorizontalMetrics horizontalMetrics,
            OS2Table os2Table)
        {
            _nameEntry         = nameEntry;
            _bounds            = bounds;
            _unitsPerEm        = unitsPerEm;
            _cffTable          = cffTable;
            _horizontalMetrics = horizontalMetrics;
            OS2Table           = os2Table;


            //------
            _glyphs = _cffTable.Cff1FontSet._fonts[0]._glyphs;
        }
예제 #22
0
            internal static TranslatedOS2FontStyle TranslatedOS2FontStyle(OS2Table os2Table)
            {
                //@prepare's note, please note:=> this is not real value, this is 'translated' value from OS2.fsSelection


                //https://www.microsoft.com/typography/otspec/os2.htm
                //Bit #     macStyle bit    C definition    Description
                //0         bit 1           ITALIC          Font contains italic or oblique characters, otherwise they are upright.
                //1                         UNDERSCORE      Characters are underscored.
                //2                         NEGATIVE        Characters have their foreground and background reversed.
                //3                         OUTLINED        Outline(hollow) characters, otherwise they are solid.
                //4                         STRIKEOUT       Characters are overstruck.
                //5         bit 0           BOLD            Characters are emboldened.
                //6                         REGULAR Characters are in the standard weight / style for the font.
                //7                         USE_TYPO_METRICS    If set, it is strongly recommended to use OS / 2.sTypoAscender - OS / 2.sTypoDescender + OS / 2.sTypoLineGap as a value for default line spacing for this font.
                //8                         WWS     The font has ‘name’ table strings consistent with a weight / width / slope family without requiring use of ‘name’ IDs 21 and 22. (Please see more detailed description below.)
                //9                         OBLIQUE     Font contains oblique characters.
                //10–15 < reserved > Reserved; set to 0.
                ushort fsSelection            = os2Table.fsSelection;
                TranslatedOS2FontStyle result = Extensions.TranslatedOS2FontStyle.UNSET;

                if ((fsSelection & 0x1) != 0)
                {
                    result |= Extensions.TranslatedOS2FontStyle.ITALIC;
                }

                if (((fsSelection >> 5) & 0x1) != 0)
                {
                    result |= Extensions.TranslatedOS2FontStyle.BOLD;
                }

                if (((fsSelection >> 6) & 0x1) != 0)
                {
                    result |= Extensions.TranslatedOS2FontStyle.REGULAR;
                }
                if (((fsSelection >> 9) & 0x1) != 0)
                {
                    result |= Extensions.TranslatedOS2FontStyle.OBLIQUE;
                }

                return(result);
            }
예제 #23
0
 public OS2Table(OS2Table version0Table, ushort codePageRange1, ushort codePageRange2, short heightX, short capHeight, ushort defaultChar, ushort breakChar, ushort maxContext)
     : this(
         version0Table.averageCharWidth,
         version0Table.weightClass,
         version0Table.widthClass,
         version0Table.styleType,
         version0Table.subscriptXSize,
         version0Table.subscriptYSize,
         version0Table.subscriptXOffset,
         version0Table.subscriptYOffset,
         version0Table.superscriptXSize,
         version0Table.superscriptYSize,
         version0Table.superscriptXOffset,
         version0Table.superscriptYOffset,
         version0Table.strikeoutSize,
         version0Table.strikeoutPosition,
         version0Table.familyClass,
         version0Table.panose,
         version0Table.unicodeRange1,
         version0Table.unicodeRange2,
         version0Table.unicodeRange3,
         version0Table.unicodeRange4,
         version0Table.tag,
         version0Table.FontStyle,
         version0Table.firstCharIndex,
         version0Table.lastCharIndex,
         version0Table.TypoAscender,
         version0Table.TypoDescender,
         version0Table.TypoLineGap,
         version0Table.winAscent,
         version0Table.winDescent)
 {
     this.codePageRange1 = codePageRange1;
     this.codePageRange2 = codePageRange2;
     this.heightX        = heightX;
     this.capHeight      = capHeight;
     this.defaultChar    = defaultChar;
     this.breakChar      = breakChar;
     this.maxContext     = maxContext;
 }
예제 #24
0
        internal Typeface(
            NameEntry nameEntry,
            Bounds bounds,
            ushort unitsPerEm,
            Glyph[] glyphs,
            CharacterMap[] cmaps,
            HorizontalMetrics horizontalMetrics,
            OS2Table os2Table)
        {
            _nameEntry         = nameEntry;
            _bounds            = bounds;
            _unitsPerEm        = unitsPerEm;
            _glyphs            = glyphs;
            _cmaps             = cmaps;
            _horizontalMetrics = horizontalMetrics;
            OS2Table           = os2Table;

            //---------------------------------------------------
            //cmap - Character To Glyph Index Mapping Table
            //---------------------------------------------------
            //This table defines the mapping of character codes to the glyph index values used in the font. It may contain more than one subtable, in order to support more than one character encoding scheme.Character codes that do not correspond to any glyph in the font should be mapped to glyph index 0.The glyph at this location must be a special glyph representing a missing character, commonly known as .notdef.
            //The table header indicates the character encodings for which subtables are present.Each subtable is in one of seven possible formats and begins with a format code indicating the format used.
            //The platform ID and platform - specific encoding ID in the header entry(and, in the case of the Macintosh platform, the language field in the subtable itself) are used to specify a particular 'cmap' encoding.The header entries must be sorted first by platform ID, then by platform - specific encoding ID, and then by the language field in the corresponding subtable.Each platform ID, platform - specific encoding ID, and subtable language combination may appear only once in the 'cmap' table.
            //When building a Unicode font for Windows, the platform ID should be 3 and the encoding ID should be 1.When building a symbol font for Windows, the platform ID should be 3 and the encoding ID should be 0.When building a font that will be used on the Macintosh, the platform ID should be 1 and the encoding ID should be 0.
            //All Microsoft Unicode BMP encodings(Platform ID = 3, Encoding ID = 1) must provide at least a Format 4 'cmap' subtable.If the font is meant to support supplementary(non - BMP) Unicode characters, it will additionally need a Format 12 subtable with a platform encoding ID 10.The contents of the Format 12 subtable need to be a superset of the contents of the Format 4 subtable.Microsoft strongly recommends using a BMP Unicode 'cmap' for all fonts. However, some other encodings that appear in current fonts follow:
            //Windows Encodings
            //Platform ID Encoding ID Description
            //3   0   Symbol
            //3   1   Unicode BMP(UCS - 2)
            //3   2   ShiftJIS
            //3   3   PRC
            //3   4   Big5
            //3   5   Wansung
            //3   6   Johab
            //3   7   Reserved
            //3   8   Reserved
            //3   9   Reserved
            //3   10  Unicode UCS - 4
            //---------------------------------------------------
        }
예제 #25
0
        internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input)
        {
            NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry());
            OS2Table  os2Table  = ReadTableIfExists(tables, input, new OS2Table());

            return(new PreviewFontInfo(
                       nameEntry.FontName,
                       nameEntry.FontSubFamily,
                       nameEntry.TypographicFamilyName,
                       nameEntry.TypographyicSubfamilyName,
                       os2Table.usWeightClass,
                       Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table))
            {
                PostScriptName = nameEntry.PostScriptName,
                UniqueFontIden = nameEntry.UniqueFontIden,
                VersionString = nameEntry.VersionString,
                UnicodeRange1 = os2Table.ulUnicodeRange1,
                UnicodeRange2 = os2Table.ulUnicodeRange2,
                UnicodeRange3 = os2Table.ulUnicodeRange3,
                UnicodeRange4 = os2Table.ulUnicodeRange4,
            });
        }
예제 #26
0
        internal PreviewFontInfo ReadPreviewFontInfo(TableEntryCollection tables, BinaryReader input)
        {
            var rd = new EntriesReaderHelper(tables, input);

            NameEntry nameEntry = rd.Read(new NameEntry());
            OS2Table  os2Table  = rd.Read(new OS2Table());
            //for preview, read ONLY  script list from gsub and gpos (set OnlyScriptList).
            Meta metaTable = rd.Read(new Meta());

            GSUB gsub = rd.Read(new GSUB()
            {
                OnlyScriptList = true
            });
            GPOS gpos = rd.Read(new GPOS()
            {
                OnlyScriptList = true
            });
            //gsub and gpos contains actual script_list that are in the typeface

            Languages langs = new Languages();

            langs.Update(os2Table, metaTable, gsub, gpos);

            return(new PreviewFontInfo(
                       nameEntry.FontName,
                       nameEntry.FontSubFamily,
                       nameEntry.TypographicFamilyName,
                       nameEntry.TypographyicSubfamilyName,
                       os2Table.usWeightClass,
                       langs,
                       Extensions.TypefaceExtensions.TranslatedOS2FontStyle(os2Table))
            {
                PostScriptName = nameEntry.PostScriptName,
                UniqueFontIden = nameEntry.UniqueFontIden,
                VersionString = nameEntry.VersionString
            });
        }
예제 #27
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);
        }
예제 #28
0
        public TtfTypeface Read(Stream stream, ReadFlags readFlags = ReadFlags.Full)
        {
            var little = BitConverter.IsLittleEndian;

            using (var input = new ByteOrderSwappingBinaryReader(stream))
            {
                ushort majorVersion  = input.ReadUInt16();
                ushort minorVersion  = input.ReadUInt16();
                ushort tableCount    = input.ReadUInt16();
                ushort searchRange   = input.ReadUInt16();
                ushort entrySelector = input.ReadUInt16();
                ushort rangeShift    = input.ReadUInt16();
                var    tables        = new TableEntryCollection();
                for (int i = 0; i < tableCount; i++)
                {
                    tables.AddEntry(new UnreadTableEntry(ReadTableHeader(input)));
                }
                //------------------------------------------------------------------
                OS2Table  os2Table  = ReadTableIfExists(tables, input, new OS2Table());
                NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry());


                Head              header            = ReadTableIfExists(tables, input, new Head());
                MaxProfile        maximumProfile    = ReadTableIfExists(tables, input, new MaxProfile());
                HorizontalHeader  horizontalHeader  = ReadTableIfExists(tables, input, new HorizontalHeader());
                HorizontalMetrics horizontalMetrics = ReadTableIfExists(tables, input, new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount));

                //--------------
                Cmap           cmaps          = ReadTableIfExists(tables, input, new Cmap());
                GlyphLocations glyphLocations = ReadTableIfExists(tables, input, new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations));
                Glyf           glyf           = ReadTableIfExists(tables, input, new Glyf(glyphLocations));
                //--------------
                Gasp gaspTable             = ReadTableIfExists(tables, input, new Gasp());
                VerticalDeviceMetrics vdmx = ReadTableIfExists(tables, input, new VerticalDeviceMetrics());
                //--------------
                PostTable postTable = ReadTableIfExists(tables, input, new PostTable());
                Kern      kern      = ReadTableIfExists(tables, input, new Kern());
                //--------------
                //advanced typography
                GDEF           gdef      = ReadTableIfExists(tables, input, new GDEF());
                GSUB           gsub      = ReadTableIfExists(tables, input, new GSUB());
                GPOS           gpos      = ReadTableIfExists(tables, input, new GPOS());
                BASE           baseTable = ReadTableIfExists(tables, input, new BASE());
                COLR           colr      = ReadTableIfExists(tables, input, new COLR());
                CPAL           cpal      = ReadTableIfExists(tables, input, new CPAL());
                VerticalHeader vhea      = ReadTableIfExists(tables, input, new VerticalHeader());
                if (vhea != null)
                {
                    VerticalMatric vmtx = ReadTableIfExists(tables, input, new VerticalMatric(vhea.NumOfLongVerMetrics));
                }

                EBLCTable fontBmpTable = ReadTableIfExists(tables, input, new EBLCTable());
                //---------------------------------------------
                //about truetype instruction init

                //---------------------------------------------
                var typeface = new TtfTypeface(
                    nameEntry,
                    header.Bounds,
                    header.UnitsPerEm,
                    glyf.Glyphs,
                    horizontalMetrics,
                    os2Table);
                //----------------------------
                typeface.CmapTable  = cmaps;
                typeface.KernTable  = kern;
                typeface.GaspTable  = gaspTable;
                typeface.MaxProfile = maximumProfile;
                typeface.HheaTable  = horizontalHeader;
                //----------------------------
                FpgmTable fpgmTable = ReadTableIfExists(tables, input, new FpgmTable());
                //control values table
                CvtTable cvtTable = ReadTableIfExists(tables, input, new CvtTable());
                if (cvtTable != null)
                {
                    typeface.ControlValues = cvtTable.controlValues;
                }
                if (fpgmTable != null)
                {
                    typeface.FpgmProgramBuffer = fpgmTable.programBuffer;
                }
                PrepTable propProgramTable = ReadTableIfExists(tables, input, new PrepTable());
                if (propProgramTable != null)
                {
                    typeface.PrepProgramBuffer = propProgramTable.programBuffer;
                }
                //-------------------------
                typeface.LoadOpenFontLayoutInfo(
                    gdef,
                    gsub,
                    gpos,
                    baseTable,
                    colr,
                    cpal);
                return(typeface);
            }
        }
예제 #29
0
        public static OS2Table Load(BinaryReader reader)
        {
            // Version 1.0
            // Type   | Name                   | Comments
            // -------|------------------------|-----------------------
            // uint16 |version                 | 0x0005
            // int16  |xAvgCharWidth           |
            // uint16 |usWeightClass           |
            // uint16 |usWidthClass            |
            // uint16 |fsType                  |
            // int16  |ySubscriptXSize         |
            // int16  |ySubscriptYSize         |
            // int16  |ySubscriptXOffset       |
            // int16  |ySubscriptYOffset       |
            // int16  |ySuperscriptXSize       |
            // int16  |ySuperscriptYSize       |
            // int16  |ySuperscriptXOffset     |
            // int16  |ySuperscriptYOffset     |
            // int16  |yStrikeoutSize          |
            // int16  |yStrikeoutPosition      |
            // int16  |sFamilyClass            |
            // uint8  |panose[10]              |
            // uint32 |ulUnicodeRange1         | Bits 0–31
            // uint32 |ulUnicodeRange2         | Bits 32–63
            // uint32 |ulUnicodeRange3         | Bits 64–95
            // uint32 |ulUnicodeRange4         | Bits 96–127
            // Tag    |achVendID               |
            // uint16 |fsSelection             |
            // uint16 |usFirstCharIndex        |
            // uint16 |usLastCharIndex         |
            // int16  |sTypoAscender           |
            // int16  |sTypoDescender          |
            // int16  |sTypoLineGap            |
            // uint16 |usWinAscent             |
            // uint16 |usWinDescent            |
            // uint32 |ulCodePageRange1        | Bits 0–31
            // uint32 |ulCodePageRange2        | Bits 32–63
            // int16  |sxHeight                |
            // int16  |sCapHeight              |
            // uint16 |usDefaultChar           |
            // uint16 |usBreakChar             |
            // uint16 |usMaxContext            |
            // uint16 |usLowerOpticalPointSize |
            // uint16 |usUpperOpticalPointSize |
            ushort version          = reader.ReadUInt16(); // assert 0x0005
            short  averageCharWidth = reader.ReadInt16();
            ushort weightClass      = reader.ReadUInt16();
            ushort widthClass       = reader.ReadUInt16();
            ushort styleType        = reader.ReadUInt16();
            short  subscriptXSize   = reader.ReadInt16();
            short  subscriptYSize   = reader.ReadInt16();
            short  subscriptXOffset = reader.ReadInt16();
            short  subscriptYOffset = reader.ReadInt16();

            short superscriptXSize   = reader.ReadInt16();
            short superscriptYSize   = reader.ReadInt16();
            short superscriptXOffset = reader.ReadInt16();
            short superscriptYOffset = reader.ReadInt16();

            short strikeoutSize     = reader.ReadInt16();
            short strikeoutPosition = reader.ReadInt16();
            short familyClass       = reader.ReadInt16();

            byte[]             panose         = reader.ReadUInt8Array(10);
            uint               unicodeRange1  = reader.ReadUInt32(); // Bits 0–31
            uint               unicodeRange2  = reader.ReadUInt32(); // Bits 32–63
            uint               unicodeRange3  = reader.ReadUInt32(); // Bits 64–95
            uint               unicodeRange4  = reader.ReadUInt32(); // Bits 96–127
            string             tag            = reader.ReadTag();
            FontStyleSelection fontStyle      = reader.ReadUInt16 <FontStyleSelection>();
            ushort             firstCharIndex = reader.ReadUInt16();
            ushort             lastCharIndex  = reader.ReadUInt16();
            short              typoAscender   = reader.ReadInt16();
            short              typoDescender  = reader.ReadInt16();
            short              typoLineGap    = reader.ReadInt16();
            ushort             winAscent      = reader.ReadUInt16();
            ushort             winDescent     = reader.ReadUInt16();

            var version0Table = new OS2Table(
                averageCharWidth,
                weightClass,
                widthClass,
                styleType,
                subscriptXSize,
                subscriptYSize,
                subscriptXOffset,
                subscriptYOffset,
                superscriptXSize,
                superscriptYSize,
                superscriptXOffset,
                superscriptYOffset,
                strikeoutSize,
                strikeoutPosition,
                familyClass,
                panose,
                unicodeRange1,
                unicodeRange2,
                unicodeRange3,
                unicodeRange4,
                tag,
                fontStyle,
                firstCharIndex,
                lastCharIndex,
                typoAscender,
                typoDescender,
                typoLineGap,
                winAscent,
                winDescent);

            if (version == 0)
            {
                return(version0Table);
            }

            ushort codePageRange1 = 0;
            ushort codePageRange2 = 0;
            short  heightX        = 0;
            short  capHeight      = 0;

            ushort defaultChar = 0;
            ushort breakChar   = 0;
            ushort maxContext  = 0;

            codePageRange1 = reader.ReadUInt16(); // Bits 0–31
            codePageRange2 = reader.ReadUInt16(); // Bits 32–63
            heightX        = reader.ReadInt16();
            capHeight      = reader.ReadInt16();

            defaultChar = reader.ReadUInt16();
            breakChar   = reader.ReadUInt16();
            maxContext  = reader.ReadUInt16();

            var versionLessthan5Table = new OS2Table(
                version0Table,
                codePageRange1,
                codePageRange2,
                heightX,
                capHeight,
                defaultChar,
                breakChar,
                maxContext);

            if (version < 5)
            {
                return(versionLessthan5Table);
            }

            ushort lowerOpticalPointSize = reader.ReadUInt16();
            ushort upperOpticalPointSize = reader.ReadUInt16();

            return(new OS2Table(
                       versionLessthan5Table,
                       lowerOpticalPointSize,
                       upperOpticalPointSize));
        }
예제 #30
0
        internal Typeface ReadTableEntryCollection(TableEntryCollection tables, BinaryReader input)
        {
            OS2Table  os2Table  = ReadTableIfExists(tables, input, new OS2Table());
            NameEntry nameEntry = ReadTableIfExists(tables, input, new NameEntry());

            Head              header            = ReadTableIfExists(tables, input, new Head());
            MaxProfile        maximumProfile    = ReadTableIfExists(tables, input, new MaxProfile());
            HorizontalHeader  horizontalHeader  = ReadTableIfExists(tables, input, new HorizontalHeader());
            HorizontalMetrics horizontalMetrics = ReadTableIfExists(tables, input, new HorizontalMetrics(horizontalHeader.HorizontalMetricsCount, maximumProfile.GlyphCount));

            //---
            PostTable postTable = ReadTableIfExists(tables, input, new PostTable());
            CFFTable  ccf       = ReadTableIfExists(tables, input, new CFFTable());

            //--------------
            Cmap           cmaps          = ReadTableIfExists(tables, input, new Cmap());
            GlyphLocations glyphLocations = ReadTableIfExists(tables, input, new GlyphLocations(maximumProfile.GlyphCount, header.WideGlyphLocations));

            Glyf glyf = ReadTableIfExists(tables, input, new Glyf(glyphLocations));
            //--------------
            Gasp gaspTable             = ReadTableIfExists(tables, input, new Gasp());
            VerticalDeviceMetrics vdmx = ReadTableIfExists(tables, input, new VerticalDeviceMetrics());
            //--------------


            Kern kern = ReadTableIfExists(tables, input, new Kern());
            //--------------
            //advanced typography
            GDEF           gdef      = ReadTableIfExists(tables, input, new GDEF());
            GSUB           gsub      = ReadTableIfExists(tables, input, new GSUB());
            GPOS           gpos      = ReadTableIfExists(tables, input, new GPOS());
            BASE           baseTable = ReadTableIfExists(tables, input, new BASE());
            COLR           colr      = ReadTableIfExists(tables, input, new COLR());
            CPAL           cpal      = ReadTableIfExists(tables, input, new CPAL());
            VerticalHeader vhea      = ReadTableIfExists(tables, input, new VerticalHeader());

            if (vhea != null)
            {
                VerticalMetrics vmtx = ReadTableIfExists(tables, input, new VerticalMetrics(vhea.NumOfLongVerMetrics));
            }



            //test math table
            MathTable mathtable    = ReadTableIfExists(tables, input, new MathTable());
            EBLCTable fontBmpTable = ReadTableIfExists(tables, input, new EBLCTable());
            //---------------------------------------------
            //about truetype instruction init

            //---------------------------------------------
            Typeface typeface            = null;
            bool     isPostScriptOutline = false;

            if (glyf == null)
            {
                //check if this is cff table ?
                if (ccf == null)
                {
                    //TODO: review here
                    throw new NotSupportedException();
                }
                //...
                //PostScript outline font
                isPostScriptOutline = true;
                typeface            = new Typeface(
                    nameEntry,
                    header.Bounds,
                    header.UnitsPerEm,
                    ccf,
                    horizontalMetrics,
                    os2Table);
            }
            else
            {
                typeface = new Typeface(
                    nameEntry,
                    header.Bounds,
                    header.UnitsPerEm,
                    glyf.Glyphs,
                    horizontalMetrics,
                    os2Table);
            }

            //----------------------------
            typeface.CmapTable  = cmaps;
            typeface.KernTable  = kern;
            typeface.GaspTable  = gaspTable;
            typeface.MaxProfile = maximumProfile;
            typeface.HheaTable  = horizontalHeader;
            //----------------------------

            if (!isPostScriptOutline)
            {
                FpgmTable fpgmTable = ReadTableIfExists(tables, input, new FpgmTable());
                //control values table
                CvtTable cvtTable = ReadTableIfExists(tables, input, new CvtTable());
                if (cvtTable != null)
                {
                    typeface.ControlValues = cvtTable._controlValues;
                }
                if (fpgmTable != null)
                {
                    typeface.FpgmProgramBuffer = fpgmTable._programBuffer;
                }
                PrepTable propProgramTable = ReadTableIfExists(tables, input, new PrepTable());
                if (propProgramTable != null)
                {
                    typeface.PrepProgramBuffer = propProgramTable._programBuffer;
                }
            }
            //-------------------------
            typeface.LoadOpenFontLayoutInfo(
                gdef,
                gsub,
                gpos,
                baseTable,
                colr,
                cpal);

            //------------


            //test
            {
                SvgTable svgTable = ReadTableIfExists(tables, input, new SvgTable());
                if (svgTable != null)
                {
                    typeface._svgTable = svgTable;
                }
            }

            typeface.PostTable = postTable;
            if (mathtable != null)
            {
                var mathGlyphLoader = new MathGlyphLoader();
                mathGlyphLoader.LoadMathGlyph(typeface, mathtable);
            }
#if DEBUG
            //test
            //int found = typeface.GetGlyphIndexByName("Uacute");
            if (typeface.IsCffFont)
            {
                //optional
                typeface.UpdateAllCffGlyphBounds();
            }
#endif
            return(typeface);
        }