惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 聂微东
MyScale Blog
MyScale Blog
H
Help Net Security
Last Week in AI
Last Week in AI
T
The Blog of Author Tim Ferriss
M
MIT News - Artificial intelligence
大猫的无限游戏
大猫的无限游戏
酷 壳 – CoolShell
酷 壳 – CoolShell
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Proofpoint News Feed
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
Microsoft Security Blog
Microsoft Security Blog
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏

依云's Blog

Wayfire支持不缩放Xwayland啦 - 依云's Blog 使用wayvnc远程访问无头Wayfire会话 - 依云's Blog pacfiles: 高速的 pacman -F 替代品 用 Android 手机当电脑的话筒 - 依云's Blog 使用 ffmpeg 对音频文件进行响度归一化 - 依云's Blog 使用 nftables 屏蔽大量 IP - 依云's Blog YubiKey 初体验 - 依云's Blog fcitx5 码表同步方案 - 依云's Blog 我正在使用的火狐扩展(2024年版) - 依云's Blog 使用 PipeWire 实现自动应用均衡器 如果你发现你的 OOM Killer 在乱杀进程 使用 atuin 管理 shell 命令历史 btrfs 元数据满了怎么办 btrfs 翻车记 在 nspawn 里运行 docker Linux 上的字体配置与故障排除 新的 PaddleOCR 部署方案 使用 EasyEffects 调整 Bose 音箱的体验 让离线软件真正离线 我所讨厌的网页行为 tmux 状态栏优化 Google Chrome 中的字体设置 从 getmail6 到 offlineimap 微信消息通知的困扰 Qt 的字体渲染问题 Wayfire 迁移进展(四):不那么 high 的 DPI Wayfire 迁移进展(二):Xwayland HiDPI 以及 waybar Wayfire 迁移进展 不同情况下的图形效果 Wayland 初体验
使用 fontconfig 进行字体查询
依云 · 2011-10-23 · via 依云'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;
}
/* ===================================================================== */