//TODO: merge this to Typography //from http://stackoverflow.com/questions/3633000/net-enumerate-winforms-font-styles // https://www.microsoft.com/Typography/OTSpec/name.htm public static InstalledFont GetFontDetails(string fontFilePath) { //TODO: review here //merge to the Typography? string fontName = string.Empty; string fontSubFamily = string.Empty; string strRet = string.Empty; using (FileStream fs = new FileStream(fontFilePath, FileMode.Open, FileAccess.Read)) { TT_OFFSET_TABLE ttOffsetTable = new TT_OFFSET_TABLE() { uMajorVersion = ReadUShort(fs), uMinorVersion = ReadUShort(fs), uNumOfTables = ReadUShort(fs), uSearchRange = ReadUShort(fs), uEntrySelector = ReadUShort(fs), uRangeShift = ReadUShort(fs), }; if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0) { return(null); } TT_TABLE_DIRECTORY tblDir = new TT_TABLE_DIRECTORY(); bool found = false; Encoding enc = Encoding.UTF8; for (int i = 0; i <= ttOffsetTable.uNumOfTables; i++) { tblDir = new TT_TABLE_DIRECTORY(); tblDir.Initialize(); fs.Read(tblDir.szTag, 0, tblDir.szTag.Length); tblDir.uCheckSum = ReadULong(fs); tblDir.uOffset = ReadULong(fs); tblDir.uLength = ReadULong(fs); string s = enc.GetString(tblDir.szTag); if (s.CompareTo("name") == 0) { found = true; break; } } if (!found) { return(null); } fs.Seek(tblDir.uOffset, SeekOrigin.Begin); TT_NAME_TABLE_HEADER ttNTHeader = new TT_NAME_TABLE_HEADER { uFSelector = ReadUShort(fs), uNRCount = ReadUShort(fs), uStorageOffset = ReadUShort(fs) }; TT_NAME_RECORD ttRecord = new TT_NAME_RECORD(); for (int j = 0; j <= ttNTHeader.uNRCount; j++) { ttRecord = new TT_NAME_RECORD() { uPlatformID = ReadUShort(fs), uEncodingID = ReadUShort(fs), uLanguageID = ReadUShort(fs), uNameID = ReadUShort(fs), uStringLength = ReadUShort(fs), uStringOffset = ReadUShort(fs) }; //if (ttRecord.uNameID > 2) //{ //} long nPos = fs.Position; fs.Seek(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, SeekOrigin.Begin); byte[] buf = new byte[ttRecord.uStringLength]; fs.Read(buf, 0, ttRecord.uStringLength); Encoding enc2; if (ttRecord.uEncodingID == 3 || ttRecord.uEncodingID == 1) { enc2 = Encoding.BigEndianUnicode; } else { enc2 = Encoding.UTF8; } strRet = enc2.GetString(buf); switch (ttRecord.uNameID) { case 1: fontName = strRet; break; case 2: fontSubFamily = strRet; break; default: break; } fs.Seek(nPos, SeekOrigin.Begin); } return(new InstalledFont(fontName, fontSubFamily, fontFilePath)); } }
static public FontFamily FromPath(string fontFilePath) { string FontName = string.Empty; string FontSubFamily = string.Empty; string encStr = "UTF-8"; string strRet = string.Empty; using (FileStream fs = new FileStream(fontFilePath, FileMode.Open, FileAccess.Read)) { TT_OFFSET_TABLE ttOffsetTable = new TT_OFFSET_TABLE() { uMajorVersion = ReadUShort(fs), uMinorVersion = ReadUShort(fs), uNumOfTables = ReadUShort(fs), uSearchRange = ReadUShort(fs), uEntrySelector = ReadUShort(fs), uRangeShift = ReadUShort(fs), }; TT_TABLE_DIRECTORY tblDir = new TT_TABLE_DIRECTORY(); bool found = false; for (int i = 0; i <= ttOffsetTable.uNumOfTables; i++) { tblDir = new TT_TABLE_DIRECTORY(); tblDir.Initialize(); fs.Read(tblDir.szTag, 0, tblDir.szTag.Length); tblDir.uCheckSum = ReadULong(fs); tblDir.uOffset = ReadULong(fs); tblDir.uLength = ReadULong(fs); Encoding enc = Encoding.GetEncoding(encStr); string s = enc.GetString(tblDir.szTag); if (s.CompareTo("name") == 0) { found = true; break; } } if (!found) { return(null); } fs.Seek(tblDir.uOffset, SeekOrigin.Begin); TT_NAME_TABLE_HEADER ttNTHeader = new TT_NAME_TABLE_HEADER { uFSelector = ReadUShort(fs), uNRCount = ReadUShort(fs), uStorageOffset = ReadUShort(fs) }; TT_NAME_RECORD ttRecord = new TT_NAME_RECORD(); for (int j = 0; j <= ttNTHeader.uNRCount; j++) { ttRecord = new TT_NAME_RECORD() { uPlatformID = ReadUShort(fs), uEncodingID = ReadUShort(fs), uLanguageID = ReadUShort(fs), uNameID = ReadUShort(fs), uStringLength = ReadUShort(fs), uStringOffset = ReadUShort(fs) }; if (ttRecord.uNameID > 2) { break; } long nPos = fs.Position; fs.Seek(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, SeekOrigin.Begin); byte[] buf = new byte[ttRecord.uStringLength]; fs.Read(buf, 0, ttRecord.uStringLength); Encoding enc; if (ttRecord.uEncodingID == 3 || ttRecord.uEncodingID == 1) { enc = Encoding.BigEndianUnicode; } else { enc = Encoding.UTF8; } strRet = enc.GetString(buf); if (ttRecord.uNameID == 1) { FontName = strRet; } if (ttRecord.uNameID == 2) { FontSubFamily = strRet; } fs.Seek(nPos, SeekOrigin.Begin); } return(new FontFamily(FontName, FontSubFamily, fontFilePath)); } }
static public FontFamily FromPath(string fontFilePath) { string FontName = string.Empty; string FontSubFamily = string.Empty; string encStr = "UTF-8"; string strRet = string.Empty; using (FileStream fs = new FileStream(fontFilePath, FileMode.Open, FileAccess.Read)) { TT_OFFSET_TABLE ttOffsetTable = new TT_OFFSET_TABLE() { uMajorVersion = ReadUShort(fs), uMinorVersion = ReadUShort(fs), uNumOfTables = ReadUShort(fs), uSearchRange = ReadUShort(fs), uEntrySelector = ReadUShort(fs), uRangeShift = ReadUShort(fs), }; TT_TABLE_DIRECTORY tblDir = new TT_TABLE_DIRECTORY(); bool found = false; for (int i = 0; i <= ttOffsetTable.uNumOfTables; i++) { tblDir = new TT_TABLE_DIRECTORY(); tblDir.Initialize(); fs.Read(tblDir.szTag, 0, tblDir.szTag.Length); tblDir.uCheckSum = ReadULong(fs); tblDir.uOffset = ReadULong(fs); tblDir.uLength = ReadULong(fs); Encoding enc = Encoding.GetEncoding(encStr); string s = enc.GetString(tblDir.szTag); if (s.CompareTo("name") == 0) { found = true; break; } } if (!found) return null; fs.Seek(tblDir.uOffset, SeekOrigin.Begin); TT_NAME_TABLE_HEADER ttNTHeader = new TT_NAME_TABLE_HEADER { uFSelector = ReadUShort(fs), uNRCount = ReadUShort(fs), uStorageOffset = ReadUShort(fs) }; TT_NAME_RECORD ttRecord = new TT_NAME_RECORD(); for (int j = 0; j <= ttNTHeader.uNRCount; j++) { ttRecord = new TT_NAME_RECORD() { uPlatformID = ReadUShort(fs), uEncodingID = ReadUShort(fs), uLanguageID = ReadUShort(fs), uNameID = ReadUShort(fs), uStringLength = ReadUShort(fs), uStringOffset = ReadUShort(fs) }; if (ttRecord.uNameID > 2) { break; } long nPos = fs.Position; fs.Seek(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, SeekOrigin.Begin); byte[] buf = new byte[ttRecord.uStringLength]; fs.Read(buf, 0, ttRecord.uStringLength); Encoding enc; if (ttRecord.uEncodingID == 3 || ttRecord.uEncodingID == 1) { enc = Encoding.BigEndianUnicode; } else { enc = Encoding.UTF8; } strRet = enc.GetString(buf); if (ttRecord.uNameID == 1) { FontName = strRet; } if (ttRecord.uNameID == 2) { FontSubFamily = strRet; } fs.Seek(nPos, SeekOrigin.Begin); } return new FontFamily(FontName, FontSubFamily, fontFilePath); } }