コード例 #1
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));
        }
コード例 #2
0
ファイル: OpenFontReader.cs プロジェクト: woodssh/Typography
        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);
        }
コード例 #3
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);
            }
        }
コード例 #4
0
        /// <summary>
        /// 显示各种Header信息,并返回字符Image的数据
        /// </summary>
        /// <param name="byteData"></param>
        private byte[] SetHeadersInfo(byte[] byData)
        {
            try
            {
                #region " 读取Rfnt Header "

                // 先读取Rfnt Header
                Array.Copy(byData, 0, byRfntHeader, 0, byRfntHeader.Length);
                this.rfntHeader.FileMagic           = Util.GetHeaderString(byData, 0, 3);
                this.rfntHeader.Endianess           = Util.GetBytesString(byData, 0x4, 0x5);
                this.rfntHeader.VersionMinor        = Util.GetBytesString(byData, 0x6, 0x7);
                this.rfntHeader.LengthOfFileInBytes = Util.GetOffset(byData, 0x8, 0xb);
                this.rfntHeader.OffsetToFinfHeader  = Util.GetOffset(byData, 0xc, 0xd);
                this.rfntHeader.NumberOfSections    = Util.GetOffset(byData, 0xe, 0xf);

                #endregion

                #region " 获取FINF Section信息 "

                // 获取FINF Section信息
                Array.Copy(byData, this.rfntHeader.OffsetToFinfHeader, byPinfHeader, 0, byPinfHeader.Length);

                // 获取FINF Section中相关信息
                this.finfHeader.Magic = Util.GetHeaderString(byPinfHeader, 0, 3);
                this.finfHeader.LengthOfSectionInBytes = Util.GetOffset(byPinfHeader, 0x4, 0x7);
                this.finfHeader.Fonttype    = Util.GetBytesString(byPinfHeader, 0x8, 0x8);
                this.finfHeader.Leading     = Util.GetBytesString(byPinfHeader, 0x9, 0x9);
                this.finfHeader.Leftmargin  = Util.GetOffset(byPinfHeader, 0xc, 0xc);
                this.finfHeader.CharWidth   = Util.GetOffset(byPinfHeader, 0xd, 0xd);
                this.finfHeader.FullWidth   = Util.GetOffset(byPinfHeader, 0xe, 0xe);
                this.finfHeader.Encoding    = Util.GetOffset(byPinfHeader, 0xf, 0xf);
                this.finfHeader.DefaultChar = Util.GetStrFromNumber(Util.GetOffset(byPinfHeader, 0xa, 0xb),
                                                                    this.finfHeader.Encoding, this.rfntHeader.Endianess);
                this.finfHeader.TglpDataOffset = Util.GetOffset(byPinfHeader, 0x10, 0x13);
                this.finfHeader.CwdhDataOffset = Util.GetOffset(byPinfHeader, 0x14, 0x17);
                this.finfHeader.CMapDataOffset = Util.GetOffset(byPinfHeader, 0x18, 0x1b);
                this.finfHeader.Height         = Util.GetOffset(byPinfHeader, 0x1c, 0x1c);
                this.finfHeader.Width          = Util.GetOffset(byPinfHeader, 0x1d, 0x1d);

                #endregion

                #region " 获取TGLP Header的字节信息 "

                // 获取TGLP Header的字节信息
                Array.Copy(byData, this.finfHeader.TglpDataOffset - 8, byTgplHeader, 0, byTgplHeader.Length);

                // 获取TGLP Header的具体信息
                this.tglpHeader.Magic               = Util.GetHeaderString(byTgplHeader, 0, 3);
                this.tglpHeader.LengthOfSection     = Util.GetOffset(byTgplHeader, 0x4, 0x7);
                this.tglpHeader.CellWidth           = Util.GetOffset(byTgplHeader, 0x8, 0x8);
                this.tglpHeader.CellHeight          = Util.GetOffset(byTgplHeader, 0x9, 0x9);
                this.tglpHeader.FontCharacterWidth  = Util.GetOffset(byTgplHeader, 0xa, 0xa);
                this.tglpHeader.FontCharacterHeight = Util.GetOffset(byTgplHeader, 0xb, 0xb);
                this.tglpHeader.TextureSize         = Util.GetOffset(byTgplHeader, 0xc, 0xf);
                this.tglpHeader.TextureNum          = Util.GetOffset(byTgplHeader, 0x10, 0x11);
                this.tglpHeader.ImageFormat         = Util.GetImageFormat(Util.GetOffset(byTgplHeader, 0x12, 0x13));
                this.tglpHeader.CharactersPerRow    = Util.GetOffset(byTgplHeader, 0x14, 0x15);
                this.tglpHeader.CharactersPerColumn = Util.GetOffset(byTgplHeader, 0x16, 0x17);
                this.tglpHeader.ImageWidth          = Util.GetOffset(byTgplHeader, 0x18, 0x19);
                this.tglpHeader.ImageHeight         = Util.GetOffset(byTgplHeader, 0x1a, 0x1b);
                this.tglpHeader.PositionOfData      = Util.GetOffset(byTgplHeader, 0x1c, 0x1f);

                #endregion

                #region " 取得TGLP Data信息 "

                // 取得TGLP Data信息
                byte[] byteTglpData = new byte[tglpHeader.LengthOfSection - 48];
                Array.Copy(byData, tglpHeader.PositionOfData, byteTglpData, 0, byteTglpData.Length);

                #endregion

                #region " 取得CWDH Section信息 "

                // 取得CWDH Section信息
                this.cwdhSection = new CwdhSection();
                Array.Copy(byData, this.finfHeader.CwdhDataOffset - 8, byteCwdhSection, 0, byteCwdhSection.Length);

                this.cwdhSection.Magic           = Util.GetHeaderString(byteCwdhSection, 0, 3);
                this.cwdhSection.LengthOfSection = Util.GetOffset(byteCwdhSection, 4, 7);
                this.cwdhSection.NumEntries      = Util.GetOffset(byteCwdhSection, 0x8, 0xb);
                this.cwdhSection.FirstCharacter  = Util.GetOffset(byteCwdhSection, 0xc, 0xf);
                if (!"CWDH".Equals(this.cwdhSection.Magic))
                {
                    MessageBox.Show("错误的CWDH!");
                    return(null);
                }

                #endregion

                #region " 获取CWDH entries信息 "

                this.cwdhEntriesList = new List <CwdhEntries>();
                int intCwdhEntriesPos = finfHeader.CwdhDataOffset + 8;
                for (int i = 0; i <= cwdhSection.NumEntries; i++)
                {
                    byte[] cwdhEntriesItem = new byte[3];
                    Array.Copy(byData, intCwdhEntriesPos, cwdhEntriesItem, 0, cwdhEntriesItem.Length);

                    CwdhEntries item = new CwdhEntries((sbyte)cwdhEntriesItem[0], cwdhEntriesItem[1], (sbyte)cwdhEntriesItem[2]);
                    this.cwdhEntriesList.Add(item);

                    intCwdhEntriesPos += 3;
                }
                this.cwdhEntriesList.Add(new CwdhEntries(0, 0, 0));

                #endregion

                #region " 取得CMap(字符映射表)信息 "

                this.cmapList = new List <KeyValuePair <int, int> >();
                //cmapDictionary = new SortedDictionary<int, int>();
                int cmapPos = finfHeader.CMapDataOffset - 8;
                while (cmapPos != -8)
                {
                    // 取得Cmap基本信息
                    byte[] cmapData = new byte[24];
                    Array.Copy(byData, cmapPos, cmapData, 0, cmapData.Length);

                    Cmap cmapItem = new Cmap();
                    cmapItem.Magic = Util.GetHeaderString(cmapData, 0, 3);
                    if (!"CMAP".Equals(cmapItem.Magic))
                    {
                        MessageBox.Show("错误的Cmap格式!");
                        return(null);
                    }
                    cmapItem.LengthOfSection      = Util.GetOffset(cmapData, 4, 7);
                    cmapItem.FirstChar            = Util.GetOffset(cmapData, 8, 9);
                    cmapItem.LastChar             = Util.GetOffset(cmapData, 10, 11);
                    cmapItem.CmapType             = Util.GetOffset(cmapData, 12, 13);
                    cmapItem.OffsetToNextCMAPdata = Util.GetOffset(cmapData, 16, 19);
                    cmapItem.TextureEntry         = Util.GetOffset(cmapData, 20, 21);
                    oldCmapList.Add(cmapData);

                    // 开始循环判断Cmap信息
                    int charIndex;
                    switch (cmapItem.CmapType)
                    {
                    case 0:
                        charIndex = cmapItem.TextureEntry;
                        for (int i = cmapItem.FirstChar; i <= cmapItem.LastChar; i++)
                        {
                            this.cmapList.Add(new KeyValuePair <int, int>(charIndex++, i));
                            //cmapDictionary.Add(charIndex++, i);
                            //cmapDictionary.Add(i, charIndex++);
                        }
                        break;

                    case 1:
                        byte[] indexByte = new byte[(cmapItem.LastChar - cmapItem.FirstChar + 1) * 2];
                        Array.Copy(byData, cmapPos + 20, indexByte, 0, indexByte.Length);
                        this.oldCmapEntriesList.Add(indexByte);

                        int[] indexEntries = new int[indexByte.Length / 2];
                        int   byteIndex    = 0;
                        for (int i = 0; i < indexEntries.Length; i++)
                        {
                            indexEntries[i] = Util.GetOffset(indexByte, byteIndex, byteIndex + 1);
                            byteIndex      += 2;
                        }

                        int entriesIndex = 0;
                        for (int i = cmapItem.FirstChar; i <= cmapItem.LastChar; i++)
                        {
                            charIndex = indexEntries[entriesIndex++];

                            if (charIndex == 0xFFFF)
                            {
                                this.cmapList.Add(new KeyValuePair <int, int>(charIndex, i));
                            }
                            else
                            {
                                this.cmapList.Add(new KeyValuePair <int, int>(charIndex, i));
                                //cmapDictionary.Add(charIndex, i);
                                //cmapDictionary.Add(i, charIndex);
                            }
                        }
                        break;

                    case 2:
                        byte[] entriesByte = new byte[cmapItem.TextureEntry * 2 * 2];
                        Array.Copy(byData, cmapPos + 0xE + 8, entriesByte, 0, entriesByte.Length);
                        this.oldCmapEntriesList.Add(entriesByte);
                        entriesIndex = 0;
                        for (int i = 0; i < cmapItem.TextureEntry; i++)
                        {
                            this.cmapList.Add(new KeyValuePair <int, int>(
                                                  Util.GetOffset(entriesByte, entriesIndex + 2, entriesIndex + 3),
                                                  Util.GetOffset(entriesByte, entriesIndex, entriesIndex + 1)));

                            //cmapDictionary.Add(
                            //    CommonUtil.GetOffset(entriesByte, entriesIndex + 2, entriesIndex + 3),
                            //    CommonUtil.GetOffset(entriesByte, entriesIndex, entriesIndex + 1));
                            //cmapDictionary.Add(
                            //    (int)CommonUtil.GetOffset(entriesByte, entriesIndex, entriesIndex + 1),
                            //    (int)CommonUtil.GetOffset(entriesByte, entriesIndex + 2, entriesIndex + 3)
                            //    );
                            entriesIndex += 4;
                        }
                        break;

                    default:
                        MessageBox.Show("错误的Cmap格式!");
                        return(null);
                    }

                    cmapPos = cmapItem.OffsetToNextCMAPdata - 8;
                }

                // CMap(字符映射表)信息排序
                this.cmapList.Sort(Util.Comparison);

                // 保存原来的Cmap信息
                foreach (KeyValuePair <int, int> item in this.cmapList)
                {
                    if (item.Key != 0xFFFF)
                    {
                        this.oldCharList.Add(Util.GetStrFromNumber(item.Value, this.finfHeader.Encoding, this.rfntHeader.Endianess));
                    }
                }

                #endregion

                #region " 显示信息 "

                // 显示RfntHeader信息
                this.lblEndianess.Text           = this.rfntHeader.Endianess;
                this.lblVersionMinor.Text        = this.rfntHeader.VersionMinor;
                this.lblLengthOfFileInBytes.Text = this.rfntHeader.LengthOfFileInBytes.ToString();
                this.lblOffsetToFinfHeader.Text  = this.rfntHeader.OffsetToFinfHeader.ToString();
                this.lblNumberOfSections.Text    = this.rfntHeader.NumberOfSections.ToString();

                // 显示FinfHeader信息
                this.lblEncoding.Text       = Util.GetFontEncodingStr(this.finfHeader.Encoding);
                this.lblFonttype.Text       = this.finfHeader.Fonttype;
                this.lblLeading.Text        = this.finfHeader.Leading;
                this.lblLeftmargin.Text     = this.finfHeader.Leftmargin.ToString();
                this.lblTglpDataOffset.Text = this.finfHeader.TglpDataOffset.ToString();
                this.lblCwdhDataOffset.Text = this.finfHeader.CwdhDataOffset.ToString();
                this.lblCMapDataOffset.Text = this.finfHeader.CMapDataOffset.ToString();

                // 显示TglpHeader信息
                this.lblLengthOfTglpSection.Text = this.tglpHeader.LengthOfSection.ToString();
                this.lblFontHeight.Text          = this.tglpHeader.CellHeight.ToString();
                this.lblFontWidth.Text           = this.tglpHeader.CellWidth.ToString();
                this.lblFontCharacterHeight.Text = this.tglpHeader.FontCharacterHeight.ToString();
                this.lblFontCharacterWidth.Text  = this.tglpHeader.FontCharacterWidth.ToString();
                this.lblLengthOfOneImage.Text    = this.tglpHeader.TextureSize.ToString();
                this.lblImageCount.Text          = this.tglpHeader.TextureNum.ToString();
                this.lblImageFormat.Text         = this.tglpHeader.ImageFormat;
                this.lblCharactersPerRow.Text    = this.tglpHeader.CharactersPerRow.ToString();
                this.lblCharactersPerColumn.Text = this.tglpHeader.CharactersPerColumn.ToString();
                this.lblImageHeight.Text         = this.tglpHeader.ImageHeight.ToString();
                this.lblImageWidth.Text          = this.tglpHeader.ImageWidth.ToString();
                this.lblPositionOfData.Text      = this.tglpHeader.PositionOfData.ToString();

                #endregion

                return(byteTglpData);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message + "\n" + e.StackTrace);
                return(null);
            }
        }
コード例 #5
0
ファイル: Languages.cs プロジェクト: ywscr/Typography
        internal void Update(OS2Table os2Tabble, Meta meta, Cmap cmap, GSUB gsub, GPOS gpos)
        {
            //https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur


            //This field is used to specify the Unicode blocks or ranges encompassed by the font file in 'cmap' subtables for platform 3,
            //encoding ID 1 (Microsoft platform, Unicode BMP) and platform 3,
            //encoding ID 10 (Microsoft platform, Unicode full repertoire).
            //If a bit is set (1), then the Unicode ranges assigned to that bit are considered functional.
            //If the bit is clear (0), then the range is not considered functional.

            //unicode BMP (Basic Multilingual Plane),OR plane0 (see https://unicode.org/roadmaps/bmp/)

            //Each of the bits is treated as an independent flag and the bits can be set in any combination.
            //The determination of “functional” is left up to the font designer,
            //although character set selection should attempt to be functional by ranges if at all possible.

            //--------------
            //Different versions of the OS/2 table were created when different Unicode versions were current,
            //and the initial specification for a given version defined fewer bit assignments than for later versions.
            //Some applications may not support all assignments for fonts that have earlier OS/2 versions.

            //All of the bit assignments listed above are valid for any version of the OS/2 table,
            //though OS/2 versions 1 and 2 were specified with some assignments that did not correspond to well-defined Unicode ranges and
            //that conflict with later assignments — see the details below.
            //If a font has a version 1 or version 2 OS/2 table with one of these bits set,
            //the obsolete assignment may be the intended interpretation.
            //Because these assignments do not correspond to well-defined ranges,
            //however, the implied character coverage is unclear.

            //Version 0: When version 0 was first specified, no bit assignments were defined.
            //Some applications may ignore these fields in a version 0 OS/2 table.

            //Version 1:
            //Version 1 was first specified concurrent with Unicode 1.1,
            //and bit assigments were defined for bits 0 to 69 only. With fonts that have a version 1 table,
            //some applications might recognize only bits 0 to 69.

            //Also, version 1 was specified with some bit assignments that did not correspond to a well-defined Unicode range:

            //    Bit 8: “Greek Symbols and Coptic” (bit 7 was specified as “Basic Greek”)
            //    Bit 12: “Hebrew Extended” (bit 11 was specified as “Basic Hebrew”)
            //    Bit 14: “Arabic Extended” (bit 13 was specified as “Basic Arabic”)
            //    Bit 27: “Georgian Extended” (bit 26 was specified as “Basic Georgian”)

            //These assignments were discontinued as of version 2.

            //In addition, versions 1 and 2 were defined with bit 53 specified as “CJK Miscellaneous”,
            //which also does not correspond to any well-defined Unicode range.
            //This assignment was discontinued as of version 3.

            //Version 2:
            //Version 2 was defined in OpenType 1.1, which was concurrent with Unicode 2.1.
            //At that time, bit assignments were defined for bits 0 to 69 only.
            //Bit assignments for version 2 were updated in OpenType 1.3,
            //adding assignments for bits 70 to 83 corresponding to new blocks assigned in Unicode 2.0 and Unicode 3.0.
            //With fonts that have a version 2 table,
            //some applications might recognize only those bits assigned in OpenType 1.2 or OpenType 1.3.

            //Also, the specification for version 2 continued to use a problematic assignment for bit 53 —
            //see details for version 1. This assignment was discontinued as of version 3.

            //Version 3: Version 3 was defined in OpenType 1.4 with assignments for bits 84 to 91 corresponding to additional
            //ranges in Unicode 3.2.
            //In addition, some already-assigned bits were extended to cover additional Unicode ranges for related characters; s
            //ee details in the table above.

            //Version 4: Version 4 was defined in OpenType 1.5 with assignments for bit 58 and bits 92 to 122 corresponding to additional ranges in Unicode 5.1.
            //Also, bits 8, 12, 14, 27 and 53 were re-assigned (see version 1 for previous assignments).
            //In addition, some already-assigned bits were extended to cover additional Unicode ranges for related characters;
            //see details in the table above.

            OS2Version    = os2Tabble.version;
            UnicodeRange1 = os2Tabble.ulUnicodeRange1;
            UnicodeRange2 = os2Tabble.ulUnicodeRange2;
            UnicodeRange3 = os2Tabble.ulUnicodeRange3;
            UnicodeRange4 = os2Tabble.ulUnicodeRange4;
            //ULONG     ulUnicodeRange1     Bits 0-31
            //ULONG     ulUnicodeRange2     Bits 32-63
            //ULONG     ulUnicodeRange3     Bits 64-95
            //ULONG     ulUnicodeRange4     Bits 96-127



            //-------
            //IMPORTANT:***
            //All available bits were exhausted as of Unicode 5.1.  ***
            //The bit assignments were last updated for OS/2 version 4 in OpenType 1.5.
            //There are many additional ranges supported in the current version of Unicode that are not supported by these fields in the OS/2 table.
            //
            //See the 'dlng' and 'slng' tags in the 'meta' table for an alternate mechanism to declare
            //what scripts or languages that a font can support or is designed for.
            //-------


            if (meta != null)
            {
                SupportedLangs = meta.SupportedLanguageTags;
                DesignLangs    = meta.DesignLanguageTags;
            }

            //----
            //gsub and gpos contains actual script_list that are in the typeface
            GSUBScriptList = gsub?.ScriptList;
            GPOSScriptList = gpos?.ScriptList;

            _cmap = cmap;
        }
コード例 #6
0
        internal bool ReadTableEntryCollection(Typeface typeface, RestoreTicket ticket, TableEntryCollection tables, BinaryReader input)
        {
            if (ticket != null)
            {
                return(ReadTableEntryCollectionOnRestoreMode(typeface, ticket, tables, input));
            }

            typeface.SetTableEntryCollection(tables.CloneTableHeaders());

            var rd = new EntriesReaderHelper(tables, input);
            //PART 1: basic information
            OS2Table          os2Table          = rd.Read(new OS2Table());
            Meta              meta              = rd.Read(new Meta());
            NameEntry         nameEntry         = rd.Read(new NameEntry());
            Head              head              = rd.Read(new Head());
            MaxProfile        maxProfile        = rd.Read(new MaxProfile());
            HorizontalHeader  horizontalHeader  = rd.Read(new HorizontalHeader());
            HorizontalMetrics horizontalMetrics = rd.Read(new HorizontalMetrics(horizontalHeader.NumberOfHMetrics, maxProfile.GlyphCount));
            VerticalHeader    vhea              = rd.Read(new VerticalHeader());

            if (vhea != null)
            {
                VerticalMetrics vmtx = rd.Read(new VerticalMetrics(vhea.NumOfLongVerMetrics));
            }

            Cmap cmaps = rd.Read(new Cmap());
            VerticalDeviceMetrics vdmx = rd.Read(new VerticalDeviceMetrics());
            Kern kern = rd.Read(new Kern());
            //------------------------------------
            //PART 2: glyphs detail
            //2.1 True type font

            GlyphLocations glyphLocations = rd.Read(new GlyphLocations(maxProfile.GlyphCount, head.WideGlyphLocations));
            Glyf           glyf           = rd.Read(new Glyf(glyphLocations));
            Gasp           gaspTable      = rd.Read(new Gasp());
            COLR           colr           = rd.Read(new COLR());
            CPAL           cpal           = rd.Read(new CPAL());

            //2.2 Cff font
            PostTable postTable = rd.Read(new PostTable());
            CFFTable  cff       = rd.Read(new CFFTable());

            //additional math table (if available)
            MathTable mathtable = rd.Read(new MathTable());
            //------------------------------------

            //PART 3: advanced typography
            GDEF gdef      = rd.Read(new GDEF());
            GSUB gsub      = rd.Read(new GSUB());
            GPOS gpos      = rd.Read(new GPOS());
            BASE baseTable = rd.Read(new BASE());
            JSTF jstf      = rd.Read(new JSTF());

            STAT stat = rd.Read(new STAT());

            if (stat != null)
            {
                //variable font
                FVar fvar = rd.Read(new FVar());
                if (fvar != null)
                {
                    GVar gvar = rd.Read(new GVar());
                    CVar cvar = rd.Read(new CVar());
                    HVar hvar = rd.Read(new HVar());
                    MVar mvar = rd.Read(new MVar());
                    AVar avar = rd.Read(new AVar());
                }
            }

            bool isPostScriptOutline = false;
            bool isBitmapFont        = false;

            typeface.SetBasicTypefaceTables(os2Table, nameEntry, head, horizontalMetrics);
            if (glyf == null)
            {
                //check if this is cff table ?
                if (cff == null)
                {
                    //check  cbdt/cblc ?
                    CBLC cblcTable = rd.Read(new CBLC());
                    if (cblcTable != null)
                    {
                        CBDT cbdtTable = rd.Read(new CBDT());
                        //read cbdt
                        //bitmap font

                        BitmapFontGlyphSource bmpFontGlyphSrc = new BitmapFontGlyphSource(cblcTable);
                        bmpFontGlyphSrc.LoadCBDT(cbdtTable);
                        Glyph[] glyphs = bmpFontGlyphSrc.BuildGlyphList();
                        typeface.SetBitmapGlyphs(glyphs, bmpFontGlyphSrc);
                        isBitmapFont = true;
                    }
                    else
                    {
                        //TODO:
                        EBLC fontBmpTable = rd.Read(new EBLC());
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    isPostScriptOutline = true;
                    typeface.SetCffFontSet(cff.Cff1FontSet);
                }
            }
            else
            {
                typeface.SetTtfGlyphs(glyf.Glyphs);
            }

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

            if (!isPostScriptOutline && !isBitmapFont)
            {
                //for true-type font outline
                FpgmTable fpgmTable = rd.Read(new FpgmTable());
                //control values table
                CvtTable  cvtTable         = rd.Read(new CvtTable());
                PrepTable propProgramTable = rd.Read(new PrepTable());

                typeface.ControlValues     = cvtTable?._controlValues;
                typeface.FpgmProgramBuffer = fpgmTable?._programBuffer;
                typeface.PrepProgramBuffer = propProgramTable?._programBuffer;
            }

            //-------------------------
            typeface.LoadOpenFontLayoutInfo(
                gdef,
                gsub,
                gpos,
                baseTable,
                colr,
                cpal);
            //------------

            typeface.SetSvgTable(rd.Read(new SvgTable()));
            typeface.PostTable = postTable;

            if (mathtable != null)
            {
                MathGlyphLoader.LoadMathGlyph(typeface, mathtable);
            }
#if DEBUG
            //test
            //int found = typeface.GetGlyphIndexByName("Uacute");
            if (typeface.IsCffFont)
            {
                //optional
                typeface.UpdateAllCffGlyphBounds();
            }
#endif
            typeface.UpdateLangs(meta);
            typeface.UpdateFrequentlyUsedValues();
            return(true);
        }
コード例 #7
0
ファイル: Top.FromFile.cs プロジェクト: htna/explsolv
            public static Top FromFile(string path, List <string> defines)
            {
                List <string> lines = new List <string>(HFile.ReadAllLines(path));

                List <LineElement> elements = new List <LineElement>();
                //List<Tuple<string,List<LineElement>>> elementgroup = new List<Tuple<string, List<LineElement>>>();
                //Dictionary<int,Atom> atoms = new Dictionary<int, Atom>();
                //List<Bond> bonds = new List<Bond>();
                //List<Pair> pairs = new List<Pair>();
                //List<Angle> angles = new List<Angle>();
                string type = null;

                while (lines.Count > 0)
                //for(int i=0; i<lines.Length; i++)
                {
                    string line = lines[0];
                    lines.RemoveAt(0);
                    //LineElement element = new LineElement(lines[i]);
                    string typei = LineElement.GetType(line);
                    if (typei != null)
                    {
                        type = typei;
                        //elementgroup.Add(new Tuple<string, List<LineElement>>(type, new List<LineElement>()));
                        continue;
                    }

                    {
                        line = line.Trim();
                        if (line.EndsWith("\\"))
                        {
                            while (lines.Count > 0)
                            {
                                line = line + "\n" + lines[0].Trim();
                                lines.RemoveAt(0);
                                if (line.EndsWith("\\") == false)
                                {
                                    break;
                                }
                            }
                            //line = "";
                            //for(; i<lines.Length; i++)
                            //{
                            //    string lline = lines[i].Trim();
                            //    line = line + lline + "\n";
                            //    if(lline.EndsWith("\\") == false)
                            //        break;
                            //}
                        }
                        line = (line.IndexOf(';') == -1) ? line.Trim() : line.Substring(0, line.IndexOf(';')).Trim();
                        if (line.Length == 0)
                        {
                            continue;
                        }
                        if (line[0] == '*')
                        {
                            continue;
                        }
                        if (line.StartsWith("#define"))
                        {
                            string define = line.Replace("#define", "").Trim();
                            defines.Add(define);
                            continue;
                        }
                        if (line.StartsWith("#include"))
                        {
                            string includepath;
                            {
                                includepath = line.Replace("#include", "").Trim().Replace("\"", "").Trim();
                                if (HFile.Exists(includepath) == false)
                                {
                                    includepath = @"C:\Program Files (x86)\Gromacs\share\gromacs\top\"
                                                  + line.Replace("#include", "").Trim().Replace("\"", "").Trim();
                                }
                                if (HFile.Exists(includepath) == false)
                                {
                                    includepath = HDirectory.GetParent(path).FullName + "\\" //path.Substring(0, path.LastIndexOf('/')+1)
                                                  + line.Replace("#include", "").Trim().Replace("\"", "").Trim();
                                }
                                HDebug.Assert(HFile.Exists(includepath));
                            }
                            Top includetop = FromFile(includepath, defines);
                            elements.AddRange(includetop.elements);
                            type = null;
                            continue;
                        }
                        if (line.StartsWith("#ifdef"))
                        {
                            FromFile_ifdef(defines, lines, line);
                            continue;
                        }
                        if (line.StartsWith("#"))
                        {
                            HDebug.Assert(false);
                        }
                        if (type == "moleculetype")
                        {
                            LineElement element = new Moleculetype(line, path); elements.Add(element); continue;
                        }
                        if (type == "atoms")
                        {
                            LineElement element = new Atom(line, path); elements.Add(element); continue;
                        }
                        if (type == "bonds")
                        {
                            LineElement element = new Bond(line, path); elements.Add(element); continue;
                        }
                        if (type == "pairs")
                        {
                            LineElement element = new Pair(line, path); elements.Add(element); continue;
                        }
                        if (type == "angles")
                        {
                            LineElement element = new Angle(line, path); elements.Add(element); continue;
                        }
                        if (type == "dihedrals")
                        {
                            LineElement element = new Dihedral(line, path); elements.Add(element); continue;
                        }
                        if (type == "cmap")
                        {
                            LineElement element = new Cmap(line, path); elements.Add(element); continue;
                        }
                        if (type == "position_restraints")
                        {
                            LineElement element = new Position_restraints(line, path); elements.Add(element); continue;
                        }
                        if (type == "system")
                        {
                            LineElement element = new System(line, path); elements.Add(element); continue;
                        }
                        if (type == "molecules")
                        {
                            LineElement element = new Molecules(line, path); elements.Add(element); continue;
                        }

                        if (type == "defaults")
                        {
                            LineElement element = new Defaults(line, path); elements.Add(element); continue;
                        }
                        if (type == "atomtypes")
                        {
                            LineElement element = new Atomtypes(line, path); elements.Add(element); continue;
                        }
                        if (type == "pairtypes")
                        {
                            LineElement element = new Pairtypes(line, path); elements.Add(element); continue;
                        }
                        if (type == "bondtypes")
                        {
                            LineElement element = new Bondtypes(line, path); elements.Add(element); continue;
                        }
                        if (type == "constrainttypes")
                        {
                            LineElement element = new Constrainttypes(line, path); elements.Add(element); continue;
                        }
                        if (type == "angletypes")
                        {
                            LineElement element = new Angletypes(line, path); elements.Add(element); continue;
                        }
                        if (type == "dihedraltypes")
                        {
                            LineElement element = new Dihedraltypes(line, path); elements.Add(element); continue;
                        }
                        if (type == "implicit_genborn_params")
                        {
                            LineElement element = new Implicit_genborn_params(line, path); elements.Add(element); continue;
                        }
                        if (type == "cmaptypes")
                        {
                            LineElement element = new Cmaptypes(line, path); elements.Add(element); continue;
                        }
                        if (type == "settles")
                        {
                            LineElement element = new Settles(line, path); elements.Add(element); continue;
                        }
                        if (type == "exclusions")
                        {
                            LineElement element = new Exclusions(line, path); elements.Add(element); continue;
                        }

                        HDebug.Assert(false);
                    }
                }

                Top top = new Top();

                top.elements = elements.ToArray();

                return(top);
            }