简介
每个人都可以得到一个安装的字体的字体名称。但是如果字体仍然没有安装在系统中,你想知道那是什么,编程?当然,你可以暂时把它添加到系统字体,并得到其属性,然后(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;