private static TT_NAME_RECORD GetNameRecord(BinaryReader r) { byte[] btNMRecord = r.ReadBytes(Marshal.SizeOf(ttNMRecord)); btNMRecord = BigEndian(btNMRecord); IntPtr ptrNMRecord = Marshal.AllocHGlobal(btNMRecord.Length); Marshal.Copy(btNMRecord, 0x0, ptrNMRecord, btNMRecord.Length); TT_NAME_RECORD ttNMResult = (TT_NAME_RECORD)Marshal.PtrToStructure(ptrNMRecord, typeof(TT_NAME_RECORD)); Marshal.FreeHGlobal(ptrNMRecord); return(ttNMResult); }
public static string GetFontCopyright(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); //Must be maj =1 minor = 0 if (ttResult.uMajorVersion != 1 || ttResult.uMinorVersion != 0) { return(string.Empty); } TT_TABLE_DIRECTORY tbName = new TT_TABLE_DIRECTORY(); bool bFound = false; for (int i = 0; i < ttResult.uNumOfTables; 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) { try { fs.Position = tbName.uOffset; TT_NAME_TABLE_HEADER ttNTResult = GetNameTableHeader(r); string result = ""; for (int i = 0; i < ttNTResult.uNRCount; i++) { TT_NAME_RECORD ttNMResult = GetNameRecord(r); const int CopyrightId = 0; if (ttNMResult.uNameID == CopyrightId) { fs.Position = tbName.uOffset + ttNMResult.uStringOffset + ttNTResult.uStorageOffset; char[] szResult = r.ReadChars(ttNMResult.uStringLength); // 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 (but sometimes lie) result += szResult[j]; break; case 3: // Windows Fonts use this encoding (first byte is NUL) j++; if (j < ttNMResult.uStringLength) { result += szResult[j]; } break; } } break; } } return(result); } catch (Exception e) { Debug.WriteLine(e.ToString()); return(string.Empty); } } return(string.Empty); }
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); }