本文来自依云's Blog,转载请注明。
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; } /* ===================================================================== */
Apr 18, 2012 03:35:48 AM
为何没有 FcInit()、FcInitLoadConfig() 那些呢?
Apr 18, 2012 05:19:07 PM
因为还是不太懂。
Apr 19, 2012 06:57:06 PM
我也没搞懂,那手册太蛋疼了。我打算读它的源码了!