【问题标题】:how does a font tell the OS that "I AM a MONSPACED / FIXED-WIDTH FONT"?字体如何告诉操作系统“我是 MONSPACED / FIXED-WIDTH FONT”?
【发布时间】:2017-04-03 06:54:55
【问题描述】:

起初,我只想知道,为什么在 Windows 10 上的 IDE PYCHARM 中,当“仅显示等宽字体”被选中时,许多字体不会在编辑器的字体选择对话框中列出[设置/编辑器/颜色和字体/字体],也是薄荷色的。

不知道pycharm是怎么做的,但是mintty使用的是win32 API“L​​OGFONT”。

那么,windows操作系统如何知道字体是否为等宽(固定宽度)?

即: “source code pro”列出来,“source code pro black/extralight/light...都没有;

“fira 代码”已列出,但 fira 代码 light/medium/retina 未列出;

并且,如果“仅显示等宽字体”,其他一些等宽字体不会在此处列出。

似乎pycharm在选中“仅显示单色字体”时只识别字体系列名称

在 OSX(Mavericks) 中有点复杂:如果选中了“仅显示等宽字体”,pycharm 仍然可以获得家族名称,但如果 rugular 加权字体版本是,它无法知道默认的字体粗细已安装。


然后,我尝试修改一些字体,顺便看看字体伪造中原始字体的“文件信息”,但我不知道哪个部分真正影响了 WINDOWS 或 PYCHARM(IDEA/INTELIJ /实际上是JDK?)知道哪种字体是等宽的。

在“OS/2”部分,所有提到的参数fixed-width/monospace/monospaced都被检查了,但没有任何帮助,并且在windows中pycharm仍然无法检测到它们。

所以,最后,我真的很想知道,TTF 文件或任何其他字体文件类型使用哪个参数来告诉 [windows/osx/mac os/linux] 操作系统“我是等宽字体”?

【问题讨论】:

    标签: winapi fonts pycharm fixed-width monospace


    【解决方案1】:

    PyCharm 和所有 JetBrains IDEA 套件都不使用字体标志来识别等宽字体。相反,他们使用以下算法确定字体是否为等宽字体:

    • 常规变体的'l''W'' ' 字符在大小为12 时是否具有相同的宽度?
    • 加粗变体的'l''W'' ' 字符宽度是否相同 作为 12 号的常规变体?
    • 斜体变体的'l''W'' '字符是否相同 宽度为 12 号的常规变体?
    • 粗斜体变体的'l''W'' ' 字符是 与 12 号的常规变体的宽度相同?

    如果上述任何宽度计算返回不一致的答案,该字体将被列为非等宽字体。

    要解决此问题,您应该安装您尝试使用的字体的粗体变体。如果字体的粗体版本不可用,IntelliJ 的字体渲染器将自动生成一个会影响字符宽度的字体,因此会导致等宽检查失败。


    来源The IntelliJ Community Edition Source Code(为简洁起见,摘录被缩短,并根据 Apache 2.0 许可而非 StackOverflow 的 CC-BY-SA 许可获得许可。)

    private static int getFontWidth(Font font, int mask) {
        int width = getCharWidth(font, ' ');
        return width == getCharWidth(font, 'l')
            && width == getCharWidth(font, 'W') ? width : 0;
    }
    

    FontInfo 构造函数中。

    int width = getFontWidth(font, Font.PLAIN);
    if (!plainOnly) {
        if (width != 0 && width != getFontWidth(font, Font.BOLD)) width = 0;
        if (width != 0 && width != getFontWidth(font, Font.ITALIC)) width = 0;
        if (width != 0 && width != getFontWidth(font, Font.BOLD | Font.ITALIC)) width = 0;
    }
    boolean isMonospaced = width > 0;
    

    【讨论】:

      【解决方案2】:

      TrueType 字体可以包含post 表格。 post 表包含一个名为 isFixedPitch 的 32 位字段。如果其中包含0,则表示比例字体。等宽字体应该将此设置为1(但通常建议字体引擎应接受任何非零值作为等宽字体,因为这是 TT 规范的早期版本所要求的)。

      等宽字体还应将hheahmtx 表中的numberOfHMetrics 设置为3

      panose 字体匹配数据(在 OS/2 表中)也有数据来指定字体是否为等宽字体。

      如果我不得不猜测,我会说 Apple 更有可能使用 post 表,而 Microsoft 更有可能使用 Panose 数据(但我很容易对其中一个或两个都搞错)。


      参考资料:

      1. Apple documentation of 'post' table
      2. Microsoft OpenType Recommendations
      3. Panose Classification Metrics Guide

      【讨论】:

      • 非常感谢,神奇的世界得到了有价值的答案。似乎我用 panose 位 '9' 为等宽修改的字体是成功的,它被 OSX 成功识别,根据你的 reflink#2,微软建议使用 panose 数据,但 pycharm 无法识别它,也许那是pycharm或jdk的问题。
      猜你喜欢
      • 2010-10-23
      • 1970-01-01
      • 2010-12-11
      • 2014-01-21
      • 1970-01-01
      • 2011-06-14
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多