Vayn想知道如何判断一个字体是否支持中文,我也对字体的种种特性好奇,于是我再一次淹没在文档之中。先是翻了半天Pango的文档,各种字体相关的函数,还找到个pango_has_char
函数。不过我没能弄明白怎么它需要的参数类型PangoFcFont
怎么弄。后来查到这个函数需要底层支持,于是我直接找到 fontconfig 去了。
fontconfig 的文档不怎么样,虽然后来发现它提供了manpages、PDF、HTML、TXT等格式,但我依旧没能从文档中弄明白如何得到一个字体的信息。看了 fc-query 的源代码才知道,原来FcPattern
既用来作输入,也用来作输出。查询字体时它是查询条件,而返回时它就是字体信息。
/* ===================================================================== *
* 判断某个字符是否存在于指定的字体(文件)中
* ===================================================================== */
#include<stdio.h>
#include<string.h>
#include<fontconfig/fontconfig.h>
/* --------------------------------------------------------------------- */
int main(int argc, char **argv){
int ret = 0;
FcChar8* file = (FcChar8*)"/home/lilydjwg/.fonts/迷你简启体.ttf";
FcPattern* pat;
FcCharSet* cs;
FcChar32 ch;
int count;
FcBlanks* blanks = FcConfigGetBlanks(NULL);
pat = FcFreeTypeQuery((FcChar8 *)file, 0, blanks, &count);
if(FcPatternGetCharSet(pat, FC_CHARSET, 0, &cs) != FcResultMatch){
fprintf(stderr, "no match\n");
ret = -1;
goto cleanup;
}
FcUtf8ToUcs4((FcChar8*)"简", &ch, 3);
if(FcCharSetHasChar(cs, ch)){
puts("Yes");
}else{
puts("No");
}
cleanup:
FcPatternDestroy(pat);
return ret;
}
/* ===================================================================== *
* vim modeline *
* vim:se fdm=expr foldexpr=getline(v\:lnum)=~'^\\S.*{'?'>1'\:1: *
* ===================================================================== */
/* ===================================================================== *
* 判断某个字符是否存在于指定的字体(条件匹配)中
* ===================================================================== */
#include<stdio.h>
#include<fontconfig/fontconfig.h>
/* --------------------------------------------------------------------- */
int main(int argc, char **argv){
FcFontSet* fs = NULL;
FcPattern* pat = NULL;
FcObjectSet* os = NULL;
FcChar8* strpat = (FcChar8*)":lang=zh";
pat = FcNameParse(strpat);
os = FcObjectSetBuild(FC_FAMILY, FC_CHARSET, FC_FILE, (char *)0);
fs = FcFontList(0, pat, os);
if(os)
FcObjectSetDestroy(os);
os = NULL;
FcPatternDestroy(pat);
pat = NULL;
if(!fs || fs->nfont <= 0)
goto nofont;
FcChar8 *family;
FcChar8 *file;
FcCharSet* cs;
FcChar32 ch;
FcUtf8ToUcs4((FcChar8*)"这", &ch, 3);
int i;
for(i=0; i<fs->nfont; i++){
if(FcPatternGetCharSet(fs->fonts[i], FC_CHARSET, 0, &cs) != FcResultMatch){
fprintf(stderr, "no match\n");
FcPatternPrint(fs->fonts[i]);
goto nofont;
}
if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 1, &family) != FcResultMatch)
if(FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) != FcResultMatch)
goto nofont;
printf("[%d] %s ", i, (char *)family);
if(FcPatternGetString(fs->fonts[i], FC_FILE, 0, &file) != FcResultMatch)
goto nofont;
printf("(%s): ", (char *)file);
if(FcCharSetHasChar(cs, ch)){
puts("Yes");
}else{
puts("No");
}
}
FcFontSetDestroy(fs);
return 0;
nofont:
return 1;
}
/* ===================================================================== */