当前位置:编程学习 > C#/ASP.NET >>

C#求教如何获取字体的文件名

如题
如宋体对应的是simsun.ttc
用C#如何获取 --------------------编程问答-------------------- 用IO查找Fonts文件夹 --------------------编程问答-------------------- 除 --------------------编程问答--------------------
引用 1 楼 DENQH 的回复:
用IO查找Fonts文件夹

我想知道的是"宋体"是如何关联上simsun.ttc
就是说我用FontDialog得到"宋体"这个名称后,然后我该如何去获得simsun.ttc这个系统文件名
有现成的函数或者方法吗?
--------------------编程问答-------------------- 注册表 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts --------------------编程问答--------------------
引用 4 楼 hjywyj 的回复:
注册表 

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#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,