C#求教如何获取字体的文件名
如题如宋体对应的是simsun.ttc
用C#如何获取 --------------------编程问答-------------------- 用IO查找Fonts文件夹 --------------------编程问答-------------------- 除 --------------------编程问答--------------------
我想知道的是"宋体"是如何关联上simsun.ttc
就是说我用FontDialog得到"宋体"这个名称后,然后我该如何去获得simsun.ttc这个系统文件名
有现成的函数或者方法吗?
--------------------编程问答-------------------- 注册表
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts --------------------编程问答--------------------
查过了,没有找到 宋体名和simsun.ttc文件名的对应 --------------------编程问答-------------------- 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);
}
}
补充:.NET技术 , C#