返回首页

简介
每个人都可以得到一个安装的字体的字体名称。但是如果字体仍然没有安装在系统中,你想知道那是什么,编程?当然,你可以暂时把它添加到系统字体,并得到其属性,然后(hmm. ..但你怎么会找到现在是安装的字体)。好吧,也许你可以想想其他方法,但我决定去寻找规范的TrueType和OpenType字体文件。幸运的是,微软已经对这些文件的很好的文章。如果你想知道更多关于他们,看这篇文章的末尾的链接。编写代码
由于所有我感兴趣的(和你在大多数情况下)的只是字体名称和TTF文件没有其他属性,我们的代码是要去很简单(实际上只有一个函数)。从给定的文件检索功能将字体名称和返回到调用程序。数据类型的定义
由于是在Windows头文件(或者我没有找到)中定义的无结构,我们该怎么做我们自己。我们需要4结构和2的宏(我稍后会解释,他们)。
一个TTF文件的几个表组成,每个表代表的一些数据,关于它的类型。有些表是必需的,有些则不是。实际上,我们只需要其中之一,被称为"名",如名称表。这是其中的字体信息存储的地方,如字体名称,版权,商标和/ /这是TTF文件头typedef结构_tagTT_OFFSET_TABLE { USHORT uMajorVersion; USHORT uMinorVersion; USHORT uNumOfTables; USHORT uSearchRange; USHORT uEntrySelector; USHORT uRangeShift;} TT_OFFSET_TABLE;/ /表TTF文件的位置和名称(标签)typedef结构_tagTT_TABLE_DIRECTORY { 字符szTag [4]; /​​ /表的名称 ULONG uCheckSum; / /检查总和 ULONG uOffset; / /从文件开始偏移 ULONG uLength; / /表的长度,以字节为单位} TT_TABLE_DIRECTORY;/ /头名称表typedef结构_tagTT_NAME_TABLE_HEADER { USHORT uFSelector; / /格式选择。始终为0 USHORT uNRCount; / /名称记录计数 USHORT uStorageOffset; / /字符串存储偏移,   ; / /从表的开始} TT_NAME_TABLE_HEADER;/ /名称表中的记录typedef结构_tagTT_NAME_RECORD { USHORT uPlatformID; USHORT uEncodingID; USHORT uLanguageID; USHORT uNameID; USHORT uStringLength; USHORT uStringOffset; / /开始从存储区域} TT_NAME_RECORD;宏
现在唯一剩下的就是宏,我是说话之前。宏定义的样子:#定义SWAPWORD(X)MAKEWORD(HIBYTE(X),LOBYTE(X))#定义SWAPLONG(X)MAKELONG(SWAPWORD(HIWORD(X)),SWAPWORD(LOWORD(X)))
现在,那是什么?我们需要这些宏的原因是,不像在Windows系统中的所有文件的Little Endian,TTF文件存储在big - endian格式。是的,我知道这听起​​来与所有这些"endians"傻:)。大端Motorolla处理器,例如,高字节存储,而在小Endian(英特尔处理器)的高字节是最后一个。例如,你有一个整型变量1(这是4字节长)。尝试将它保存到文件,并在任何十六进制编辑器打开,你会看到:01 00 00 00 / /小Endian - 英特尔
这是Little Endian系统(英特尔)。但大端(Motorolla),这个数字将存储反之亦然:00 00 00 01 / /大端 - Motorolla
因此,这些格式是不兼容的。和TTF文件,正如我所说,存储在Motorolla风格(大端)。这就是为什么我们需要这些宏来重新排列从TrueType字体文件检索的变量字节。读文件
现在,我们准备读TTF文件。所以让我们开始。
首先我们需要阅读的文件头(TT_OFFSET_TABLE结构)的CFile f;CString的csRetVal;/ / lpszFilePath是我们的字体文件的路径(f.Open(lpszFilePath,CFile的:modeRead | CFile的::shareDenyWrite)){ / /定义和读取文件头 TT_OFFSET_TABLE ttOffsetTable; f.Read(安培; ttOffsetTable,SIZEOF(TT_OFFSET_TABLE)); / /记得你要去外地来重新排列字节 ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables); ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion); ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);& #160; / /检查,这是一个真正的字体和版本是1.0  0; (ttOffsetTable.uMajorVersion = 1 | |!ttOffsetTable.uMinorVersion = 0) 返回csRetVal;
右后的文件头偏移表。你可以在这里找到一个有趣的你表中,"名"在我们的例子偏移。 TT_TABLE_DIRECTORY tblDir; BOOL bFound = FALSE; CString的csTemp; (I = 0; ILT; ttOffsetTable.uNumOfTables;我){  0; f.Read(安培; tblDir,SIZEOF(TT_TABLE_DIRECTORY));  60; csTemp.Empty(); / /表的标签不能超过4个字符 strncpy(csTemp.GetBuffer(4),tblDir.szTag,4); csTemp.ReleaseBuffer(); (csTemp.CompareNoCase(_T("; namequot";))== 0){   ;/ /我们发现我们的餐桌。重新排列顺序,并退出循环  0; bFound = TRUE;  60; tblDir.uLength = SWAPLONG(tblDir.uLength);  0; tblDir.uOffset = SWAPLONG(tblDir.uOffset);  ; 打破; } 60; }
我们终于找到了名称表,让我们读它的头:(bFound) / /移动,以抵消我们从偏移表 f.Seek(tblDir.uOffset,CFile的::开始); TT_NAME_TABLE_HEADER ttNTHeader; &# 160; f.Read(安培; ttNTHeader,SIZEOF(TT_NAME_TABLE_HEADER)); / /再次,不要忘记交换字节! ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount); ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);  60; TT_NAME_RECORD ttRecord; bFound = FALSE;
名称表头后,在它的记录。因此,我们需要通过运行的所有记录,找到有趣的信息 - 字体名称。 (I = 0; ILT; ttNTHeader.uNRCount;我){ f.Read(安培; ttRecord,SIZEOF(TT_NAME_RECORD)); ttRecord.uNameID = SWAPWORD(ttRecord.uNameID); / / 1表示,这是字体的名称。例如0决定版权信息 (ttRecord.uNameID == 1){  60; ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength); ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset); / /保存文件的位置,这样我们就可以返回继续搜索 & #160; 非营利组织= f.GetPosition(); f.Seek(tblDir.uOffset ttRecord.uStringOffset   ; ttNTHeader.uStorageOffset的CFile::开始); / /错误修正:看到SimonSays后读更多 TCHAR lpszNameBuf = csTemp.GetBuffer(ttRecord.uStringLength 1); ZeroMemory(lpszNameBuf,ttRecord.uStringLength 1);  60; f.Read(lpszNameBuf,ttRecord.uStringLength); csTemp.ReleaseBuffer(); / /是的,仍然需要检查如果不是空的字体名称 / /如果是,继续搜索 如果csTemp.GetLength(GT; 0){ csRetVal = csTemp; 打破;   ; } f.Seek(非营利组织,的CFile::开始); 60; }}
这就是全部!现在我们可以返回csRetVal包含我们的字体名称。
您可以下载完整的工作功能,并在代码中使用。我还包括一个具有相同功能的演示项目,但定制位,所以它返回的版权和商标信息。
如果你想继续与TTF文件,你可以看看他们在微软的规范。但记得更深你要特遣队,TrueType和OpenType之间的差异,您可能会发现更多的。不管怎样,下面是关于TTF的文章的链接。参考文献  60;

回答

评论会员:chriha 时间:2011/11/29
如果你只在通用名称的字体(字体名称,字体),如"宋体",而不是"宋体加粗倾斜",您可以使用下面的代码:
进口System.Drawing.Text
进口Microsoft.VisualBasic

模块启动

的Sub Main(BYVAL参数)作为String()
MSGBOX(GetFontName("C:\ TEMP \ palabi.ttf"))
END SUB

公共功能GetFontName(作为字符串BYVAL aFileName)字符串
作为新PrivateFontCollection DIM myFC
尝试
& #160; myFC.AddFontFile(aFileName)
返回myFC.Families(0)名称
& #160; 最后
myFC.Dispose()
END TRY
结束函数

结束模块
但仍然存在的问题如何得到确切的名称,如。 "帕拉提诺行型活字粗体斜体"...{ BR}
关于
chha
评论会员:TP2000 时间:2011/11/29
喜感谢很多信息,它适用于大多数的文件,当我试图FREE3OF9.TTF它为"新"的名称,当我看到fontview.exe它显示"免费3 9"任何想法?

如果你可以发布更新的C#版本将是非常非常有帮助我。
也有API GetFontResourceInfoW在GDI32.DLL的,我不知道如何使用,所有参数是什么。预先感谢。
评论会员:菲利普帕特里克 时间:2011/11/29
您好,

C#解决方案,请参阅以下的职位之一,有人已经移植到C#

不知道是什么,TTF文件的问题,因为我没有 - 你将不得不自己调试{S0}

最后GetFontResourceInfo功能 - 这是无证的方法。所以,真的取决于你在哪里尝试使用它,因为要记住,任何无证功能,可能会发生变化在任何给定的的时间,没有向后兼容性,。当然,这不会发生一个虽然​​很多{S0}例如,相同的FontView使用此功能。如果你想使用它,下面是其声明。但要记住,这几年老的宣言 - 当我感兴趣。我不知道如果它已被更改或不DWORD GetFontResourceInfoW(
LPCWCHAR wzFontName,
& #160; DWORD dwBufSize,
 0; LPWCHAR wzBuffer,
  ; DWORD dwInfo); 无论是我做不记得如何使用它 - 你会找到自己,对不起{S0}

菲利普帕特里克
网址:
"两家啤酒或两个啤酒?" Shakesbeer
评论会员:TP2000 时间:2011/11/29
您好,

很多快速回复表示感谢,我曾试图调试的代码,但不能找出没有得到正确的名称
原因
我很欣赏,如果你可以从下列网站下载字体文件
http://www.barcodesinc.com/free-barcode-font

一些我是如何得到的TT_NAME_RECORD.uStringLength 3只

评论会员:阿伦拉詹 时间:2011/11/29
您可以在下面的链接
CSHARP实施
昆达普尔
评论会员:游客 时间:2011/11/29
嗨,我有一些查询相关字体。这将是非常有益的,如果你给我一些指针下面querries。1.Is有什么办法检查字体的符号字体/衬线/无衬线等,如如何计算基线/baselineoffset,charwidth/MaxCharWidth?BR}如何获得字体的属性,如字体样式,登顶,血统等我试图通过使用Win32GDIAPI的,但无法得到的信息。-Ganesh神
softcode
评论会员:游客 时间:2011/11/29
!我希望看到老的意见感谢。
西蒙Kittle
评论会员:游客 时间:2011/11/29
您提供的源代码,这是一个MFC代码?或ATL代码我一直在试图得到它的工作作为一项基本的命令行应用程序,但不能得到它来编译不管包括我的头。任何提示将是巨大的的。
菲利普帕特里克
评论会员:游客 时间:2011/11/29
该应用程序是基于MFC。您应该取代所有的CFile和CString等,使用替代品或包括MFC的头文件和库在您的命令行应用程序菲利普帕特里克网址:"两家啤酒或两个啤酒?"Shakesbeer
Jihodg
评论会员:游客 时间:2011/11/29
非常,非常,非常谢谢!!这只是我需要的东西。只是一个小问题......似乎一些TrueType字体存储在Unicode或一些其他2个字节的字符编码​​的名称,但我觉得我读某处在规范的名称应该是完全Unicode和ANSI相同,所以这是一个问题的检查和消除交错(零)字节ANSI兼容的字符串。有可能是一些文件,它规定的字符编码​​convension的地方,但我是懒得去检查,因为这种小伎俩我每一个字体文件的工作。Jihodg
Rangashan
评论会员:游客 时间:2011/11/29
我试图保存整数1到UTF16LE文件和UTF16文件UTF16LE文件显示"FFFE00010000"正如你所说的上层......它的还好。但UTF16文件显示象下面这样。"FEFF00010000"是什么问题?
菲利普帕特里克
评论会员:游客 时间:2011/11/29
我们可以使用这个任务GetFontData。如果是的话,请帮助我。请您检查下面的链接http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_8d7l.asp预先感谢Rangashan
阿里夫Saiyed
评论会员:游客 时间:2011/11/29
GetFontData工程直流,这意味着字体已到是已经在系统安装和应用目标直流,其中,在转弯,意味着你可以不使用它得到的字体尚未信息尚未安装菲利普帕特里克网址:"两家啤酒或两个啤酒?"Shakesbeer
Ganesh神昆达普尔
评论会员:游客 时间:2011/11/29
嗨,哪里可以找到GetfontData示例代码?我看到在MSDNhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_8d7l.asp原型但我不不知道任何其他那么第一个参数,我以为如何提取字体,字体样式,字体大小,字体颜色,字体BCK颜色从"lpvBuffer"当我不知道"lpvBuffer"格式/结构。有这方面的帮助将不胜感激。阿里夫  从MSDN GetFontDataGetFontData函数检索TrueType字体的字体度量数据。DWORDGetFontData(HDC的HDC,//处理直流DWORDdwTable,//公制表名称DWORDdwOffset,//表偏移LPVOIDlpvBuffer,//返回的数据缓冲区的DWORD的cbData//数据长度)参数HDC[在]的设备上下文句柄。dwTable []指定字体的度量要检索表,从字体数据的名称。此参数可确定由微软公司公布的TrueType字体文件规范记录的度量表之一。如果这个参数是零,信息检索TrueType字体文件的文件的开头或从目前选定的字体TrueType集合文件中的数据开始开始。TrueType字体集文件指定"ttcf"(0x66637474)检索数据从文件的开头。dwOffset[]指定的偏移,从字体的度量表开始功能应开始检索信息的位置。如果这个参数是零,检索的信息是由dwTable参数指定的表开始。如果这个值大于或等于表的大小,就会发生错误。lpvBuffer[out]指向一个缓冲区,接收的字体信息。如果这个参数是NULL,则函数返回字体数据所需的缓冲区的大小。将cbData[]指定的字节长度,要检索的信息。如果这个参数是零,GetFontData返回在dwTable参数中指定的数据的大小。返回值如果函数成功,返回值是返回的字节数。如果函数失败,返回值是GDI_ERROR。 http://groups.yahoo.com/group/programmers-town/
Rangashan
评论会员:游客 时间:2011/11/29
请给我一些使用GetFontDataAPI的例子。
菲利普帕特里克
评论会员:游客 时间:2011/11/29
{五}不读的ttf文件有任何WindowsAPI,得到一个TTF文件字体名称。Rangashan
留尼汪
评论会员:游客 时间:2011/11/29
不,我知道,否则我不会发表文章S6}菲利普帕特里克网址:"两家啤酒或两个啤酒?"Shakesbeer
beaverdown
评论会员:游客 时间:2011/11/29
使用无证字体资源的API,它是在GDI32.DLLGetFontResourceInfoW
阿萨德Palekar
评论会员:游客 时间:2011/11/29
!您好这篇文章是非常有用的!谢谢。我有一个问题的OpenType(*.TTF)。他们在ttRecord.uNameID信息0和=20(前7或8类似的TrueType,他们可以easyly读)。但我需要阅读的信息,当ttRecord.uNameID超过7。我怎样才能做到这一点。预先感谢您。
tommywang
评论会员:游客 时间:2011/11/29
{S0}我真的需要帮助,在这...有谁知道如何,我可以从C#内部使用。OTF文件,以查看在应用程序内的字体。我知道,GDI不支持OTF文件,但如果有人知道要调用的方法或什么,那将是巨大的。提前感谢了很多阿德尔H
rimuk
评论会员:游客 时间:2011/11/29
!伟大的工作我知道看的字体,但我有一个项目,要求我找出如何可能里面的TTF字体。该应用程序是像characted映射,但只显示可用的字体。imgsrc=http://www.orcode.com/upimg/2011_11_29_00_29_28_8.gif任何帮助将是巨大的的。感谢imgsrc=http://www.orcode.com/upimg/2011_11_29_00_29_28_9.gif