本文章主要解决的问题是:
如何获知TTF文件包含哪些字符,进而判断给定字符是否在此TTF字库中。
使用的API 函数为 : GetGlyphIndices
The GetFontUnicodeRanges function returns information about which Unicode characters are supported by a font. The information is returned as a GLYPHSET structure.
DWORD GetFontUnicodeRanges( HDC hdc, // handle to DC LPGLYPHSET lpgs // glyph set );
GetFontUnicodeRanges的作用就是得到指定场景使用的字体包含的所有字符。
使用方法:
1 头文件 及 依赖库 与预编译选项
头文件
#include "windows.h"
#include "Wingdi.h "
依赖库
#pragma comment(lib,"gdi32.lib")
预编译选项
vs2005 项目属性中 配置属性--》C/C++--》预处理器 在右边的预处理定义中添加 _WIN32_WINNT=0x0500
这三个步骤都完成后,才可使用该API函数。
2 使用方法
该函数GetFontUnicodeRanges 需要调用2次, 第一次使其第二个参数为NULL,目的是获得GLYPHSET 对象所需空间
然后分配空间
最后,再次调用GetFontUnicodeRanges函数,此时第二个参数为刚分配好空间的GLYPHSET对象指针,目的是将字库中的字符信息保存在此对象中,以便进一步处理。
示例1:
HDC hdc=dc.GetSafeHdc();
DWORD size=0;
//第一次调用,获得所需空间大小
size=GetFontUnicodeRanges(hdc,NULL);
// 分配空间
GLYPHSET *pGlyphSet=(GLYPHSET*) new BYTE[size];
pGlyphSet->cbThis=size;
//第二次调用,获得字库相关信息
size=GetFontUnicodeRanges(hdc,pGlyphSet);
//将字库中的字 保存在数组中
WCHAR myChar[30000]={0};
int q=0;
WCHAR tempFont=L'的';
for (int i=0;icRanges;i++)
{
for (int j=0;jranges[i].cGlyphs;j++)
{
myChar[q]=j+pGlyphSet->ranges[i].wcLow; // 字库中的字
//判断字库中是否包含 tempFont L‘的’ 这个字
if (myChar[q]==tempFont)
{
//......
}
q++;
}
}
// 释放分配的空间
delete [] pGlyphSet;
示例2: 获取已知的场景中使用的字体包含的所有字符
DWORD fsize;
LPGLYPHSET lgp;
HDC DC:int q;
int i;int j;wchar_t myChar[20000];
q=0;
DC=GetDC(GetForegroundWindow());//通过窗口句柄得到场景
fsize=GetFontUnicodeRanges(DC,NULL);
lgp=(LPGLYPHSET) malloc(fsize);
GetFontUnicodeRanges(DC,lgp);
for(i=0;icRanges;i++){
for(j=0;jranges[i].cGlyphs;j++){
myChar[q]=j+lgp->ranges[i].wcLow;//这就是包含的字符
q++;
}
}
示例3: 获得字符对应的字形索引
GetGlyphIndices-------该函数将一个字符串转为字形下标的数组。此函数可用来确定一种字体里是否存在某个字形。
函数原型:WINGDIAPI DWORD WINAPI GetGlyphIndices(HDC hdc, LPCTSTR lpstr, int c, LPWORD pgi, DWORD fl);
参数:
hdc:设备环境句柄。
lpstr:指向将被转换的字符串的指针。
c:在参数中的字符数。
pgi:与字符串的字符对应的字形下标数组。
fl:用来表示当一个字形不被支持时如何处理,此参数可取下列值:
GGI_MARK_NONEXISTING_GLYPHS:将不被支持的字形与十六进制的0XFFFF进行掩码操作。
返回值:如果函数调用成功,返回转换的字符数;如果函数调用失败,返回值是GDI_ERROR。
DWORD fsize;
LPGLYPHSET lgp;
HDC DC:int q;
int i;int j;wchar_t myChar[20000];
q=0;
DC=GetDC(GetForegroundWindow());//通过窗口句柄得到场景
fsize=GetFontUnicodeRanges(DC,NULL);
lgp=(LPGLYPHSET) malloc(fsize);
GetFontUnicodeRanges(DC,lgp);
for(i=0;icRanges;i++){
for(j=0;jranges[i].cGlyphs;j++){
myChar[q]=j+lgp->ranges[i].wcLow;//这就是包含的字符
GetGlyphIndices(DC,myChar[q],1,&gp,1);
if(gp==114) MessageBoxW(NULL,L"成功获取了字符,这个字符就是myChar",L"哈哈",MB_OK);
q++;
}
}
参考资料: http://mayorvb.blogbus.com/logs/25342866.html