MSDN上2007年已经有人问过这个问题,如果你的英文还可以的话,可以看下地址: http://social.msdn.microsoft.com/Forums/en-US/windowsxps/thread/843d0e98-ac8e-4021-94f9-5e3130d058b9解决方案在:http://www.codeproject.com/Articles/4190/XFont-Get-font-name-and-file-information就是第一篇帖子最后一个人所说:It's not perfect, but it works.Good Luck!
刚好我也需要这个功能,就一次回复到位吧。 以下C#代码可读取指定.ttf文件里的字体名,思路反过来:遍历<windir\>Fonts目录下的所有文件,即可找到通过“字体选择器”返回的字体名的字体文件。 虽然办法笨了点,但确实也没啥好办法,凑合着能用。 It's not perfect, but it works. ---------------------------------------------- using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO;namespace FontNameGetter { [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_OFFSET_TABLE { public ushort uMajorVersion; public ushort uMinorVersion; public ushort uNumOfTables; public ushort uSearchRange; public ushort uEntrySelector; public ushort uRangeShift; } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_TABLE_DIRECTORY { public char szTag1; public char szTag2; public char szTag3; public char szTag4; public uint uCheckSum; //Check sum public uint uOffset; //Offset from beginning of file public uint uLength; //length of the table in bytes } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_NAME_TABLE_HEADER { public ushort uFSelector; public ushort uNRCount; public ushort uStorageOffset; } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_NAME_RECORD { public ushort uPlatformID; public ushort uEncodingID; public ushort uLanguageID; public ushort uNameID; public ushort uStringLength; public ushort uStringOffset; } partial class Form1 : Form { public Form1() { InitializeComponent(); } private TT_OFFSET_TABLE ttOffsetTable; private TT_TABLE_DIRECTORY tblDir; private TT_NAME_TABLE_HEADER ttNTHeader; private TT_NAME_RECORD ttNMRecord; private void button1_Click(object sender, EventArgs e) { FileStream fs = new FileStream("f:\\simsun.ttc", FileMode.Open, FileAccess.Read); BinaryReader r = new BinaryReader(fs); byte[] buff = r.ReadBytes(Marshal.SizeOf(ttOffsetTable)); buff = BigEndian(buff); IntPtr ptr = Marshal.AllocHGlobal(buff.Length); Marshal.Copy(buff, 0x0, ptr, buff.Length); TT_OFFSET_TABLE ttResult = (TT_OFFSET_TABLE)Marshal.PtrToStructure(ptr, typeof(TT_OFFSET_TABLE)); Marshal.FreeHGlobal(ptr); //Must be maj =1 minor = 0 if (ttResult.uMajorVersion != 1 || ttResult.uMinorVersion != 0) return; bool bFound = false; TT_TABLE_DIRECTORY tbName = new TT_TABLE_DIRECTORY(); for (int i = 0; i < ttResult.uNumOfTables; i++) { byte[] bNameTable = r.ReadBytes(Marshal.SizeOf(tblDir)); IntPtr ptrName = Marshal.AllocHGlobal(bNameTable.Length); Marshal.Copy(bNameTable, 0x0, ptrName, bNameTable.Length); tbName = (TT_TABLE_DIRECTORY)Marshal.PtrToStructure(ptrName, typeof(TT_TABLE_DIRECTORY)); Marshal.FreeHGlobal(ptrName); string szName = tbName.szTag1.ToString() + tbName.szTag2.ToString() + tbName.szTag3.ToString() + tbName.szTag4.ToString(); if (szName != null) { if (szName.ToString() == "name") { bFound = true; byte[] btLength = BitConverter.GetBytes(tbName.uLength); byte[] btOffset = BitConverter.GetBytes(tbName.uOffset); Array.Reverse(btLength); Array.Reverse(btOffset); tbName.uLength = BitConverter.ToUInt32(btLength, 0); tbName.uOffset = BitConverter.ToUInt32(btOffset, 0); break; } } } if (bFound) { fs.Position = tbName.uOffset; byte[] btNTHeader = r.ReadBytes(Marshal.SizeOf(ttNTHeader)); btNTHeader = BigEndian(btNTHeader); IntPtr ptrNTHeader = Marshal.AllocHGlobal(btNTHeader.Length); Marshal.Copy(btNTHeader, 0x0, ptrNTHeader, btNTHeader.Length); TT_NAME_TABLE_HEADER ttNTResult = (TT_NAME_TABLE_HEADER)Marshal.PtrToStructure(ptrNTHeader, typeof(TT_NAME_TABLE_HEADER)); Marshal.FreeHGlobal(ptrNTHeader); bFound = false; for (int i = 0; i < ttNTResult.uNRCount; i++) { 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); if (ttNMResult.uNameID == 1) { long fPos = fs.Position; fs.Position = tbName.uOffset + ttNMResult.uStringOffset + ttNTResult.uStorageOffset; char[] szResult = r.ReadChars(ttNMResult.uStringLength); if (szResult.Length != 0) { int y = 0;//szResult now contains the font name. //szResult即是文件中的字体名,遍历Fonts目录下的所有文件,目标就实现了 } } } } } private byte[] BigEndian(byte[] bLittle) { byte[] bBig = new byte[bLittle.Length]; for (int y = 0; y < (bLittle.Length - 1); y += 2) { byte b1, b2; b1 = bLittle[y]; b2 = bLittle[y + 1]; bBig[y] = b2; bBig[y + 1] = b1; } return bBig; } } } ----------------------------------------------- 别说不会用这个例子啊,仔细看下代码就知道啦。
经测试,上面老外的方法不好用,不好意思。 自己写了个简单的,经测可用: class FontNameFile { public static string getFontFileName(string fontname) { string folderFullName = System.Environment.GetEnvironmentVariable("windir") + "\\fonts"; DirectoryInfo TheFolder = new DirectoryInfo(folderFullName); foreach (FileInfo NextFile in TheFolder.GetFiles()) { if (NextFile.Exists) { if (fontname == getFontName(NextFile.FullName)) return NextFile.FullName; } } return (""); } private static string getFontName(string fontfilename) { PrivateFontCollection pfc = new PrivateFontCollection(); try { pfc.AddFontFile(fontfilename); } catch (Exception ex) { return ""; } return(pfc.Families[0].Name); } }
查过了,没有找到 宋体名和simsun.ttc文件名的对应
http://social.msdn.microsoft.com/Forums/en-US/windowsxps/thread/843d0e98-ac8e-4021-94f9-5e3130d058b9解决方案在:http://www.codeproject.com/Articles/4190/XFont-Get-font-name-and-file-information就是第一篇帖子最后一个人所说:It's not perfect, but it works.Good Luck!
以下C#代码可读取指定.ttf文件里的字体名,思路反过来:遍历<windir\>Fonts目录下的所有文件,即可找到通过“字体选择器”返回的字体名的字体文件。
虽然办法笨了点,但确实也没啥好办法,凑合着能用。
It's not perfect, but it works.
----------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;namespace FontNameGetter
{ [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_OFFSET_TABLE
{ public ushort uMajorVersion;
public ushort uMinorVersion;
public ushort uNumOfTables;
public ushort uSearchRange;
public ushort uEntrySelector;
public ushort uRangeShift;
}
[StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_TABLE_DIRECTORY
{ public char szTag1; public char szTag2;
public char szTag3;
public char szTag4;
public uint uCheckSum; //Check sum public uint uOffset; //Offset from beginning of file public uint uLength; //length of the table in bytes } [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_NAME_TABLE_HEADER
{ public ushort uFSelector;
public ushort uNRCount;
public ushort uStorageOffset;
} [StructLayout(LayoutKind.Sequential, Pack = 0x1)] struct TT_NAME_RECORD
{ public ushort uPlatformID;
public ushort uEncodingID;
public ushort uLanguageID;
public ushort uNameID;
public ushort uStringLength;
public ushort uStringOffset;
} partial class Form1 : Form
{ public Form1()
{ InitializeComponent();
} private TT_OFFSET_TABLE ttOffsetTable;
private TT_TABLE_DIRECTORY tblDir;
private TT_NAME_TABLE_HEADER ttNTHeader;
private TT_NAME_RECORD ttNMRecord;
private void button1_Click(object sender, EventArgs e)
{ FileStream fs = new FileStream("f:\\simsun.ttc", FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
byte[] buff = r.ReadBytes(Marshal.SizeOf(ttOffsetTable));
buff = BigEndian(buff);
IntPtr ptr = Marshal.AllocHGlobal(buff.Length);
Marshal.Copy(buff, 0x0, ptr, buff.Length);
TT_OFFSET_TABLE ttResult = (TT_OFFSET_TABLE)Marshal.PtrToStructure(ptr, typeof(TT_OFFSET_TABLE));
Marshal.FreeHGlobal(ptr);
//Must be maj =1 minor = 0 if (ttResult.uMajorVersion != 1 || ttResult.uMinorVersion != 0) return;
bool bFound = false;
TT_TABLE_DIRECTORY tbName = new TT_TABLE_DIRECTORY();
for (int i = 0; i < ttResult.uNumOfTables; i++)
{ byte[] bNameTable = r.ReadBytes(Marshal.SizeOf(tblDir));
IntPtr ptrName = Marshal.AllocHGlobal(bNameTable.Length);
Marshal.Copy(bNameTable, 0x0, ptrName, bNameTable.Length);
tbName = (TT_TABLE_DIRECTORY)Marshal.PtrToStructure(ptrName, typeof(TT_TABLE_DIRECTORY));
Marshal.FreeHGlobal(ptrName);
string szName = tbName.szTag1.ToString() + tbName.szTag2.ToString() + tbName.szTag3.ToString() + tbName.szTag4.ToString();
if (szName != null)
{ if (szName.ToString() == "name")
{ bFound = true;
byte[] btLength = BitConverter.GetBytes(tbName.uLength);
byte[] btOffset = BitConverter.GetBytes(tbName.uOffset);
Array.Reverse(btLength);
Array.Reverse(btOffset);
tbName.uLength = BitConverter.ToUInt32(btLength, 0);
tbName.uOffset = BitConverter.ToUInt32(btOffset, 0);
break;
} } } if (bFound)
{ fs.Position = tbName.uOffset;
byte[] btNTHeader = r.ReadBytes(Marshal.SizeOf(ttNTHeader));
btNTHeader = BigEndian(btNTHeader);
IntPtr ptrNTHeader = Marshal.AllocHGlobal(btNTHeader.Length);
Marshal.Copy(btNTHeader, 0x0, ptrNTHeader, btNTHeader.Length);
TT_NAME_TABLE_HEADER ttNTResult = (TT_NAME_TABLE_HEADER)Marshal.PtrToStructure(ptrNTHeader, typeof(TT_NAME_TABLE_HEADER));
Marshal.FreeHGlobal(ptrNTHeader);
bFound = false;
for (int i = 0; i < ttNTResult.uNRCount; i++)
{ 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);
if (ttNMResult.uNameID == 1)
{ long fPos = fs.Position;
fs.Position = tbName.uOffset + ttNMResult.uStringOffset + ttNTResult.uStorageOffset;
char[] szResult = r.ReadChars(ttNMResult.uStringLength);
if (szResult.Length != 0)
{ int y = 0;//szResult now contains the font name.
//szResult即是文件中的字体名,遍历Fonts目录下的所有文件,目标就实现了 } } } } } private byte[] BigEndian(byte[] bLittle)
{ byte[] bBig = new byte[bLittle.Length];
for (int y = 0; y < (bLittle.Length - 1); y += 2)
{ byte b1, b2;
b1 = bLittle[y];
b2 = bLittle[y + 1];
bBig[y] = b2;
bBig[y + 1] = b1;
} return bBig;
}
}
}
-----------------------------------------------
别说不会用这个例子啊,仔细看下代码就知道啦。
自己写了个简单的,经测可用: class FontNameFile
{
public static string getFontFileName(string fontname)
{
string folderFullName = System.Environment.GetEnvironmentVariable("windir") + "\\fonts";
DirectoryInfo TheFolder = new DirectoryInfo(folderFullName);
foreach (FileInfo NextFile in TheFolder.GetFiles())
{
if (NextFile.Exists)
{
if (fontname == getFontName(NextFile.FullName)) return NextFile.FullName;
}
}
return ("");
} private static string getFontName(string fontfilename)
{
PrivateFontCollection pfc = new PrivateFontCollection();
try
{
pfc.AddFontFile(fontfilename);
}
catch (Exception ex)
{
return "";
}
return(pfc.Families[0].Name);
}
}