如何用 GDI 正确渲染部分 Opentype 字体

2021-03-05 17:05:31 +08:00
 darer

我最近在尝试修复 VSFilter 系字幕滤镜中部分 Opentype 字体横排竖排相同字号大小不同的问题,下面是问题的示意图
横排的正常情况 竖排的情况 同样的问题在思源黑体,思源宋体等 Opentype 字体上也可以复现
之前群友聊过,推测是一些语言的连字导致了字高和字宽比例出现了问题
在 VSFilter 系滤镜中,字体是通过如下方式渲染的

  1. 创建 LOGFONT 结构
  2. CreateFontIndirect 创建逻辑字体
  3. SelectFont 选择字体
  4. TextOutW 渲染字体

考虑到群友的推论,我将创建 LOGFONT 结构中

lf.lfHeight = (LONG)(style.fontSize + 0.5);

改为了

lf.lfHeight = -MulDiv((int)(style.fontSize + 0.5), GetDeviceCaps(hDC, LOGPIXELSY), 72);

横排竖排的大小一致了,但大小是原来的 1.93~1.94 倍
我之前也尝试过用设置 LOGFONT 的 lfOrientation 字段来强行旋转每一个字符,但最后效果和竖排字体还是有一定的不一致
想问下各位有什么修复这个问题的思路吗
探索这个问题的时候我主要查阅了GDI 的文档,项目仓库的地址是:VSFilterMod

1273 次点击
所在节点    问与答
4 条回复
ysc3839
2021-03-05 17:19:45 +08:00
建议改用其他字体系统,比如 DirectWrite 。
darer
2021-03-05 17:24:37 +08:00
@ysc3839 之前也考虑过像 libass 那样改用 freetype,但迁移的成本还是有点高
laincat
2021-03-05 17:31:26 +08:00
先 Star 了。
darer
2021-03-09 13:16:13 +08:00
如果想迁移到 DirectWrite 有什么最简的迁移方式吗
看了下 MSDN 有点没看懂

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/758870

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX