Пример #1
0
        public static FsType GetFsType(string fontFullName)
        {
            if (!File.Exists(fontFullName))
            {
                throw new FileNotFoundException(fontFullName);
            }

            FileStream      fs       = new FileStream(fontFullName, FileMode.Open, FileAccess.Read);
            BinaryReader    r        = new BinaryReader(fs);
            TT_OFFSET_TABLE ttResult = GetOffsetTable(r);

            //ttf Must be maj =1 minor = 0
            int numTables = 0;

            if (ttResult.uMajorVersion == 1 && ttResult.uMinorVersion == 0)
            {
                numTables = ttResult.uNumOfTables;
            }
            else
            {
                fs.Position = 0L;
                SFNT   sFnt   = GetSfnt(r);
                string szSfnt = string.Format("{0}{1}{2}{3}", (char)sFnt.szSfnt1, (char)sFnt.szSfnt2, (char)sFnt.szSfnt3, (char)sFnt.szSfnt4);
                switch (szSfnt)
                {
                case "OTTO":
                    OT_OFFSET_TABLE otResult = GetOpenTypeOffsetTable(r);
                    numTables = otResult.uNumOfTables;
                    break;

                case "ttcf":
                    TTC_HEADER_1 ttcHeader = GetTtcHeader(r);
                    if ((ttcHeader.uMajorVersion != 1 && ttcHeader.uMajorVersion != 2) || ttcHeader.uMinorVersion != 0)
                    {
                        throw new VersionNotFoundException(fontFullName + " Expected header version 1.0 or 2.0");
                    }
                    GetTtcOffsets(r, ttcHeader.uNumFonts);
                    fs.Position = long.Parse(ttcOffsets[0].ToString());
                    ttResult    = GetOffsetTable(r);
                    if (ttResult.uMajorVersion == 1 && ttResult.uMinorVersion == 0)
                    {
                        numTables = ttResult.uNumOfTables;
                    }
                    else
                    {
                        throw new VersionNotFoundException(fontFullName + " expected TrueType version 1.0");
                    }
                    break;

                default:
                    throw new MissingFieldException(fontFullName + " Font type should be ttcf or OTTO");
                }
            }

            bool bFound = false;
            TT_TABLE_DIRECTORY tbName = new TT_TABLE_DIRECTORY();

            for (int i = 0; i < numTables; i++)
            {
                tbName = GetNameTable(r);
                string szName = tbName.szTag1.ToString() + tbName.szTag2.ToString() + tbName.szTag3.ToString() + tbName.szTag4.ToString();
                if (szName != null)
                {
                    if (szName == "OS/2") // http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=IWS-AppendixC
                    {
                        bFound         = true;
                        tbName.uLength = BigEndianValue(tbName.uLength);
                        tbName.uOffset = BigEndianValue(tbName.uOffset);
                        break;
                    }
                }
            }
            if (bFound)
            {
                fs.Position = tbName.uOffset;
                TT_OS2_RECORD ttOs2Result = GetOs2Record(r);
                return(ttOs2Result.fsType);
            }
            throw new MissingFieldException(fontFullName + " should contain OS/2 table");
        }
Пример #2
0
        public static string GetPostscriptName(string fontFullName)
        {
            if (!File.Exists(fontFullName))
            {
                return(string.Empty);
            }

            FileStream      fs       = new FileStream(fontFullName, FileMode.Open, FileAccess.Read);
            BinaryReader    r        = new BinaryReader(fs);
            TT_OFFSET_TABLE ttResult = GetOffsetTable(r);

            //ttf Must be maj =1 minor = 0
            int numTables = 0;

            if (ttResult.uMajorVersion == 1 && ttResult.uMinorVersion == 0)
            {
                numTables = ttResult.uNumOfTables;
            }
            else
            {
                fs.Position = 0L;
                SFNT   sFnt   = GetSfnt(r);
                string szSfnt = string.Format("{0}{1}{2}{3}", (char)sFnt.szSfnt1, (char)sFnt.szSfnt2, (char)sFnt.szSfnt3, (char)sFnt.szSfnt4);
                switch (szSfnt)
                {
                case "OTTO":
                    OT_OFFSET_TABLE otResult = GetOpenTypeOffsetTable(r);
                    numTables = otResult.uNumOfTables;
                    break;

                case "ttcf":
                    TTC_HEADER_1 ttcHeader = GetTtcHeader(r);
                    if ((ttcHeader.uMajorVersion != 1 && ttcHeader.uMajorVersion != 2) || ttcHeader.uMinorVersion != 0)
                    {
                        return(string.Empty);
                    }
                    GetTtcOffsets(r, ttcHeader.uNumFonts);
                    fs.Position = long.Parse(ttcOffsets[0].ToString());
                    ttResult    = GetOffsetTable(r);
                    if (ttResult.uMajorVersion == 1 && ttResult.uMinorVersion == 0)
                    {
                        numTables = ttResult.uNumOfTables;
                    }
                    else
                    {
                        return(string.Empty);
                    }
                    break;

                default:
                    return(string.Empty);
                }
            }

            bool bFound = false;
            TT_TABLE_DIRECTORY tbName = new TT_TABLE_DIRECTORY();

            for (int i = 0; i < numTables; i++)
            {
                tbName = GetNameTable(r);
                string szName = tbName.szTag1.ToString() + tbName.szTag2.ToString() + tbName.szTag3.ToString() + tbName.szTag4.ToString();
                if (szName != null)
                {
                    if (szName == "name")
                    {
                        bFound         = true;
                        tbName.uLength = BigEndianValue(tbName.uLength);
                        tbName.uOffset = BigEndianValue(tbName.uOffset);
                        break;
                    }
                }
            }
            if (bFound)
            {
                fs.Position = tbName.uOffset;
                TT_NAME_TABLE_HEADER ttNTResult = GetNameTableHeader(r);
                for (int i = 0; i < ttNTResult.uNRCount; i++)
                {
                    TT_NAME_RECORD ttNMResult       = GetNameRecord(r);
                    const int      PostscriptNameId = 6;
                    if (ttNMResult.uNameID == PostscriptNameId)
                    {
                        fs.Position = tbName.uOffset + ttNMResult.uStringOffset + ttNTResult.uStorageOffset;
                        char[] szResult = r.ReadChars(ttNMResult.uStringLength);
                        string result   = "";
                        // Usually the uEncodingID will tell us whether we're using single or double-byte encoding,
                        // but sometimes it lies. Verify by testing the first character in the array for '\0'
                        int uId = ttNMResult.uEncodingID;
                        if (szResult[0] == '\0')
                        {
                            uId = 3;
                        }
                        for (int j = 0; j < ttNMResult.uStringLength; j++)
                        {
                            switch (uId)
                            {
                            case 0:     // SIL Fonts use this encoding
                                result += szResult[j];
                                break;

                            case 3:     // Windows Fonts use this encoding (first byte is NUL)
                                j++;
                                if (j < ttNMResult.uStringLength)
                                {
                                    result += szResult[j];
                                }
                                break;
                            }
                        }
                        return(result);
                    }
                }
            }
            return(string.Empty);
        }
Пример #3
0
 private static SFNT GetSfnt(BinaryReader r)
 {
     byte[] buff = r.ReadBytes(Marshal.SizeOf(sFnt));
     IntPtr ptr = Marshal.AllocHGlobal(buff.Length);
     Marshal.Copy(buff, 0x0, ptr, buff.Length);
     sFnt = (SFNT)Marshal.PtrToStructure(ptr, typeof(SFNT));
     Marshal.FreeHGlobal(ptr);
     return sFnt;
 }