V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
darer
V2EX  ›  问与答

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

  •  
  •   darer · 326 天前 · 494 次点击
    这是一个创建于 326 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我最近在尝试修复 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

    4 条回复    2021-03-09 13:16:13 +08:00
    ysc3839
        1
    ysc3839  
       326 天前
    建议改用其他字体系统,比如 DirectWrite 。
    darer
        2
    darer  
    OP
       326 天前
    @ysc3839 之前也考虑过像 libass 那样改用 freetype,但迁移的成本还是有点高
    laincat
        3
    laincat  
       326 天前
    先 Star 了。
    darer
        4
    darer  
    OP
       322 天前
    如果想迁移到 DirectWrite 有什么最简的迁移方式吗
    看了下 MSDN 有点没看懂
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3048 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:59 · PVG 12:59 · LAX 20:59 · JFK 23:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.