news 2026/9/20 3:01:53

Inter 仓库 fontsample 工具实战指南:macOS 下用 CoreText 生成字体 PDF/PNG 文本样张

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Inter 仓库 fontsample 工具实战指南:macOS 下用 CoreText 生成字体 PDF/PNG 文本样张

Inter 仓库 fontsample 工具实战指南:macOS 下用 CoreText 生成字体 PDF/PNG 文本样张

【免费下载链接】interThe Inter font family项目地址: https://gitcode.com/gh_mirrors/in/inter

本文基于 Inter 开源字体仓库(gh_mirrors/in/inter)内的misc/tools/fontsample工具,完整讲解其构建方式、命令行用法与底层实现原理。fontsample是一个 macOS 专用的 Objective-C++ 命令行程序,用于将任意 macOS 可读取的字体文件渲染成居中的文本样张并输出为 PDF(或 PNG),是字体开发与质量检查流程中快速查验字形渲染效果的实用小工具。读完本文,你将掌握该工具的编译、参数配置、输出格式控制,以及其基于 CoreText / CoreGraphics / ImageIO 的完整渲染管线。

工具定位:为字体开发服务的 macOS 样张生成器

fontsample位于 misc/tools/fontsample/README.md,其定位非常明确:一个 macOS 专用程序,用于为某个具体字体文件生成带文本样式的 PDF。它面向的典型场景是字体开发者/设计师在构建出新的字形后,快速把字体文件丢给工具,得到一张可直接查看排版效果的样张,例如用于检查 Inter 各字重、斜体或可变字体的字形渲染是否正常。

工具本身只依赖 macOS 系统框架(Foundation、CoreText、CoreGraphics、CoreServices、ImageIO),不依赖任何第三方字体渲染库,因此构建极简:一条make即可完成编译。

构建与基本使用

编译

在 misc/tools/fontsample/ 目录下直接执行:

$ make

Makefile 中定义了完整的编译规则:使用clang作为编译器,源文件为 fontsample.mm(Objective-C++,故用clang的 C++ 模式编译,并开启-fobjc-arc自动引用计数),链接阶段引入-lobjc以及 Foundation、CoreText、CoreServices、CoreGraphics、ImageIO 五个系统框架。默认编译标志包含-Wall -g -fno-common,若需要调试构建可传DEBUG=1(此时关闭-O0优化),否则默认不额外优化。清理产物执行make clean

编译成功后,运行./fontsample -h查看完整用法:

$ ./fontsample -h usage: ./fontsample [options] <fontfile> options: -h, -help Show usage and exit. -z, -size <size> Font size to render. Defaults to 96. -t, -text <text> Text line to render. Defaults to "Rags78 **A**". -o <file> Write output to <file> instead of default filename. Defaults to <fontfile>.pdf. If the provided filename ends with ".png" a PNG is written instead of a PDF. <fontfile> Any font file that macOS can read.

注:-h输出中未列出-width-height,但源码 fontsample.mm 的usagetemplate及参数解析逻辑实际支持这两个选项(详见下文“参数说明”),这是源码与 README 的一个细微差异,使用时以实际行为为准。

最小示例

# 为 Inter-Regular.woff2 生成默认样张 PDF $ ./fontsample Inter-Regular.woff2 # 指定字号与文本,输出到自定义文件 $ ./fontsample -z 128 -t "The quick brown fox" -o sample.pdf Inter-Regular.woff2 # 输出 PNG 格式 $ ./fontsample -t "Hello Inter" -o sample.png Inter-Regular.woff2

输出文件名缺省时取输入字体文件去掉扩展名后加.pdf(例如Inter-Regular.woff2Inter-Regular.pdf);若-o指定的文件名以.png结尾(不区分大小写),则输出 PNG,否则一律输出 PDF。

命令行参数详解

fontsample支持的所有选项汇总如下:

参数别名取值默认值说明
-h-help打印用法并退出
-z-size数值96渲染字号(pt),必须>= 1且为合法数字
-t-text字符串"Rags78 **A**"渲染的单行文本
-o文件路径<fontfile>.pdf输出文件;以.png结尾则输出 PNG
-width像素整数自动PNG 输出时强制图像宽度(源码支持,README 未列出)
-height像素整数自动PNG 输出时强制图像高度(源码支持,README 未列出)

参数解析逻辑(源码级)

参数解析由 fontsample.mm 的parseargs完成,要点如下:

  • 所有选项必须以-开头且长度大于 1;-h/-help打印用法后以退出码 0 退出。
  • -z/-size通过atof解析为浮点数,若结果为 NaN 或小于 1,则通过badarg报错并退出;-width/-height使用strtoull解析为无符号整数。
  • getargval负责取选项的下一个参数值,若缺失、为空或以-开头,会报 “missing value for argument” 错误。
  • 未知标志一律报unknown flag;非选项参数被收集为位置参数,main中要求恰好一个<fontfile>——少于一个报missing <fontfile>,多于一个报extraneous argument after <fontfile>

渲染管线:从字体文件到 PDF/PNG

整个渲染流程可以从main → pdfmake这条调用链拆解,核心步骤依次为:加载字体、构建文本行、计算排版度量、绘制输出。

1. 加载字体:loadFont

loadFont 接收字体文件路径与字号,按以下顺序创建字体对象:

  1. CFURLCreateWithFileSystemPath将路径转为 POSIX 风格 URL;
  2. CGDataProviderCreateWithURL创建数据提供者(读取失败则报failed to read file退出);
  3. CGFontCreateWithDataProvider解析字体数据(解析失败报failed to parse font退出);
  4. CTFontCreateWithGraphicsFont以指定size创建 CoreText 字体对象(失败报CTFontCreateWithGraphicsFont failed退出),并在返回前释放cgfdataProviderurl

注意:调用方必须对返回值执行CFRelease(函数注释已明确要求),pdfmake在渲染完成后确实释放了fonttextLine

2. 构建文本行:createTextLine

createTextLine 将文本与字体封装为带kCTFontAttributeName属性的NSAttributedString,再调用CTLineCreateWithAttributedString得到可绘制的排版行CTLineRef。若文本无效(例如无法排版),pdfmake会报invalid sample text并退出。

3. 计算度量:CTLineGetTypographicBounds

pdfmake中通过:

CGFloat width = CTLineGetTypographicBounds(textLine, &ascent, &descent, &leading); CGFloat height = ascent + descent + leading;

获得文本行的排版宽度与高度,作为后续页面/画布的自动尺寸。draw函数据此把文本在画布内水平、垂直居中:水平位置x = ceilf((width - textWidth) / 2),垂直位置y = descent + ceilf((height - textHeight) / 2)descent用于保证文本基线定位正确)。

4. 输出 PDF:makePDF

makePDF 使用CGPDFContextCreate创建 PDF 上下文,页尺寸mediaBox取文本行的排版宽高;流程为CGPDFContextBeginPage → draw → CGPDFContextEndPage → CGPDFContextClose,最终把生成的 PDF 数据写入输出文件。源码中draw的白色背景填充代码被注释掉(见 fontsample.mm),即默认输出透明背景、仅含居中文本的 PDF 页面。

5. 输出 PNG:makePNG

makePNG 走另一条路径:

  • 画布尺寸默认取width × height * 1.2(高度放大 120% 防止裁剪);若指定了-width/-height则覆盖对应维度。
  • 分配width * height * 4字节的位图缓冲区,用CGBitmapContextCreate创建 RGBA 位图上下文(kCGImageAlphaPremultipliedLast,8 位每通道)。
  • draw绘制文本后,CGBitmapContextCreateImage生成CGImageRef,再由writePNG借助 ImageIO 的CGImageDestinationCreateWithURLkUTTypePNG)写入 PNG 文件,失败时返回 NO 并在 stderr 记录日志。

应用场景与注意事项

  • 使用前提:本工具是 macOS 专用程序,依赖 Objective-C 运行时与系统框架,无法在 Linux/Windows 上直接编译运行;构建机器需具备 Xcode 命令行工具(提供clang与系统 SDK)。
  • 字体格式<fontfile>接受任何 macOS 能读取的字体文件,理论上涵盖 OTF、TTF、WOFF2、TTC/OTC 等;Inter 仓库构建产物(如 docs/font-files/Inter-Regular.woff2、docs/font-files/InterVariable.ttf)均可直接作为输入,用于快速查验样张。
  • 与仓库其他工具的配合fontsample是 Inter 工具链中偏“人工目检”的一环;自动化质量检查另有make test驱动的 fontbakery 报告(见仓库根 Makefile)。若需要批量生成字距(kerning)样张,可参考同为工具链的 misc/tools/kernsample.py。
  • 已知限制:源码中makePDF留有 “TODO: read and use options.width and options.height” 注释(fontsample.mm),即-width/-height目前仅对 PNG 输出生效,PDF 页面尺寸始终由文本度量自动决定。

小结

fontsample是一个小而完整的 macOS 字体渲染工具:约 300 行 Objective-C++ 源码,串联起 CoreText 文本排版、CoreGraphics 绘制、ImageIO 图片输出三大系统框架,提供了字号、文本、输出格式、画布尺寸等实用控制项。对于 Inter 这类需要高频验证字形渲染效果的字体项目,它是一条低成本、可复现的目检途径;其实现同时也是一个学习 macOS 系统级字体渲染 API 的简洁范本。相关文件可按以下路径深入阅读:README(misc/tools/fontsample/README.md)、构建配置(misc/tools/fontsample/Makefile)、完整实现(misc/tools/fontsample/fontsample.mm)。

【免费下载链接】interThe Inter font family项目地址: https://gitcode.com/gh_mirrors/in/inter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 2:59:40

IDEA插件W-Reader:在IDE内高效阅读小说的完整指南

我写代码的时候有个习惯&#xff0c;键盘敲到一半&#xff0c;脑子里突然冒出“这章剧情到底怎么发展”的念头。以前只能切到浏览器偷偷摸摸开个页面&#xff0c;老板一走过来就手忙脚乱切回IDE。后来发现IDEA插件市场里有个叫W-Reader的阅读插件&#xff0c;支持在线搜索小说&…

作者头像 李华
网站建设 2026/9/20 2:59:37

2026年桌面AI办公工具盘点:5款最值得装的效率神器

2026年了&#xff0c;桌面AI办公工具已经不是“要不要用”的问题&#xff0c;而是“怎么选才能不踩坑”的问题。我花了两周时间&#xff0c;把市面上主流的桌面端AI生产力工具挨个装了一遍&#xff0c;每天在真实工作流里高强度试用&#xff0c;最后筛出了5款对普通打工人最友好…

作者头像 李华
网站建设 2026/9/20 2:58:54

Nimmake:面向MCU的声明式固件构建元系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 2:58:11

Hermes Agent 跑 run_agent.py 报模型 401?TaoToken 的 Base URL 这样查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 2:55:51

Win10原版镜像安全下载指南:从官网获取纯净ISO并制作启动盘

自己动手重装 Windows 10 系统这件事&#xff0c;说难也难&#xff0c;说简单也简单。难的地方不在于安装过程&#xff0c;而在于第一步——怎么拿到一个干净、安全、不出幺蛾子的系统镜像。很多朋友在搜索引擎里输入“win10镜像下载”&#xff0c;点进排名靠前的某某装机站&am…

作者头像 李华