字体如何告诉 OS "I AM a MONSPACED / FIXED-WIDTH FONT"?
how does a font tell the OS that "I AM a MONSPACED / FIXED-WIDTH FONT"?
一开始我只想知道,为什么在IDE PYCHARM on Windows 10 的时候,勾选了"show only monospaced fonts",很多字体都不会列出来在编辑器的字体选择对话框中 [settings/editor/colors 和 fonts/font],也在 mintty 中。
我不知道 pycharm 是怎么做的,但是 mintty 使用的是 win32 API "LOGFONT".
那么,windows OS 是如何知道字体是否等宽(固定宽度)的?
即:
"source code pro" 列出,“源代码pro black / extralight / light ...都没有;
"fira code" 已列出,但 fira 代码 light/medium/retina 未列出;
并且,如果 "show only monospaced".
,其他一些等宽字体未在此处列出
似乎pycharm勾选后只能识别字体家族名称"show only monospced fonts"
in OSX(Mavericks) 有点复杂:如果选中 'show only monospaced fonts',pycharm 仍然可以获得姓氏,但无法知道是哪种字体-如果安装了 rugular weighted 字体版本,weight 是默认值。
然后,我试着修改了一些字体,顺便在font forge里看了一眼原来的字体'file-info',但我不知道哪个部分真正影响了WINDOWS或 PYCHARM(IDEA/INTELIJ/by JDK 事实上?)知道哪种字体是等宽的。
在"OS/2"部分,检查了fixed-width/monospace/monospaced提到的任何参数,但没有任何帮助,在windows pycharm仍然无法检测到它们。
所以,最后,我真的很想知道,TTF 文件或任何其他字体文件类型使用哪个参数来告诉 [windows/osx/mac os/linux] OS 'i am monospaced'?
TrueType 字体可以包含 post
table。 post
table 包含一个名为 isFixedPitch
的 32 位字段。如果它包含 0
,则表示比例字体。等宽字体 应该 将此设置为 1
(但通常建议字体引擎应接受任何非零值作为等宽字体,因为这是早期版本需要 TT 规范)。
等宽字体还应将 hhea
和 hmtx
table 中的 numberOfHMetrics
设置为 3
。
panose字体匹配数据中也有数据(在OS/2table中)指定字体是否等宽
如果非要我猜的话,我会说 Apple 更有可能使用 post
table,而 Microsoft 更有可能使用 Panose 数据(但我很容易错关于其中一个或两个)。
参考文献:
PyCharm 就此而言,所有 JetBrains IDEA 套件都不使用字体标志来识别等宽字体。相反,他们使用以下算法确定字体是否为等宽字体:
- 常规变体的
'l'
、'W'
和 ' '
字符在 12 号时宽度相同吗?
- 粗体的
'l'
、'W'
和' '
字符是否宽度相同
作为 12 码的常规变体?
- 斜体变体的
'l'
、'W'
和' '
字符是否相同
宽度为 12 码的常规变体?
- bold-italics 变体的
'l'
、'W'
和 ' '
字符是
与 12 码的常规款式宽度相同?
如果上面的任何宽度计算 return 答案不一致,字体将被列为 non-monospace。
要解决此问题,您应该安装您尝试使用的字体的粗体变体。如果粗体版本的字体不可用,IntelliJ 的字体渲染器将 auto-generate 影响字符宽度的字体,因此导致等宽检查失败。
来源:The IntelliJ Community Edition Source Code(为简洁起见缩短了摘录,并根据 Apache 2.0 许可而不是 Whosebug 的 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;
一开始我只想知道,为什么在IDE PYCHARM on Windows 10 的时候,勾选了"show only monospaced fonts",很多字体都不会列出来在编辑器的字体选择对话框中 [settings/editor/colors 和 fonts/font],也在 mintty 中。
我不知道 pycharm 是怎么做的,但是 mintty 使用的是 win32 API "LOGFONT".
那么,windows OS 是如何知道字体是否等宽(固定宽度)的?
即: "source code pro" 列出,“源代码pro black / extralight / light ...都没有;
"fira code" 已列出,但 fira 代码 light/medium/retina 未列出;
并且,如果 "show only monospaced".
,其他一些等宽字体未在此处列出似乎pycharm勾选后只能识别字体家族名称"show only monospced fonts"
in OSX(Mavericks) 有点复杂:如果选中 'show only monospaced fonts',pycharm 仍然可以获得姓氏,但无法知道是哪种字体-如果安装了 rugular weighted 字体版本,weight 是默认值。
然后,我试着修改了一些字体,顺便在font forge里看了一眼原来的字体'file-info',但我不知道哪个部分真正影响了WINDOWS或 PYCHARM(IDEA/INTELIJ/by JDK 事实上?)知道哪种字体是等宽的。
在"OS/2"部分,检查了fixed-width/monospace/monospaced提到的任何参数,但没有任何帮助,在windows pycharm仍然无法检测到它们。
所以,最后,我真的很想知道,TTF 文件或任何其他字体文件类型使用哪个参数来告诉 [windows/osx/mac os/linux] OS 'i am monospaced'?
TrueType 字体可以包含 post
table。 post
table 包含一个名为 isFixedPitch
的 32 位字段。如果它包含 0
,则表示比例字体。等宽字体 应该 将此设置为 1
(但通常建议字体引擎应接受任何非零值作为等宽字体,因为这是早期版本需要 TT 规范)。
等宽字体还应将 hhea
和 hmtx
table 中的 numberOfHMetrics
设置为 3
。
panose字体匹配数据中也有数据(在OS/2table中)指定字体是否等宽
如果非要我猜的话,我会说 Apple 更有可能使用 post
table,而 Microsoft 更有可能使用 Panose 数据(但我很容易错关于其中一个或两个)。
参考文献:
PyCharm 就此而言,所有 JetBrains IDEA 套件都不使用字体标志来识别等宽字体。相反,他们使用以下算法确定字体是否为等宽字体:
- 常规变体的
'l'
、'W'
和' '
字符在 12 号时宽度相同吗? - 粗体的
'l'
、'W'
和' '
字符是否宽度相同 作为 12 码的常规变体? - 斜体变体的
'l'
、'W'
和' '
字符是否相同 宽度为 12 码的常规变体? - bold-italics 变体的
'l'
、'W'
和' '
字符是 与 12 码的常规款式宽度相同?
如果上面的任何宽度计算 return 答案不一致,字体将被列为 non-monospace。
要解决此问题,您应该安装您尝试使用的字体的粗体变体。如果粗体版本的字体不可用,IntelliJ 的字体渲染器将 auto-generate 影响字符宽度的字体,因此导致等宽检查失败。
来源:The IntelliJ Community Edition Source Code(为简洁起见缩短了摘录,并根据 Apache 2.0 许可而不是 Whosebug 的 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;