为什么等宽字体中的某些字符不是真正等宽的?

jsv*_*jsv 48 windows fonts

原始问题中此代码部分中的行长度不相等。请参阅下面的更正版本。我不确定这可能如何影响相关图像

| entity    | characters    |
| ---       | ---           |
| tab       | <see extends> |
| space     | • ? · ? .     |
| nbsp      | ? _ ~ +       |
| precedes  | … ? ? « ‹ ? ? < |
| extends   | … ? ? » › ? ? > |
| eol       | ? ¶ $ ? ?     |
| showbreak | ? ? ^         |
Run Code Online (Sandbox Code Playgroud)

Vim(唯一正确显示它的编辑器,没有错位!):

在此处输入图片说明

埃马克:

在此处输入图片说明

崇高的文字

在此处输入图片说明

视觉工作室代码

在此处输入图片说明

记事本

在此处输入图片说明

字体是一样的:Consolas。

为什么它会发生在我的 Windows 7 上?你在 Windows 10 上有同样的问题吗?我怎样才能阻止它?

[更新,请参阅 Tetsujin 回答下的评论]以下是我从问题顶部看到的代码示例:

在此处输入图片说明

(浏览器是基于 Chromium 的 Edge。字体是 Consolas。)

编辑
代码部分的行长修正版本...

| entity    | characters      |
| ---       | ---             |
| tab       | <see extends>   |
| space     | • ? · ? .       |
| nbsp      | ? _ ~ +         |
| precedes  | … ? ? « ‹ ? ? < |
| extends   | … ? ? » › ? ? > |
| eol       | ? ¶ $ ? ?       |
| showbreak | ? ? ^           |
Run Code Online (Sandbox Code Playgroud)

Tet*_*jin 64

他们都对 Consolas 本身中不包含的字形使用不同的字体替换 [或在某些情况下无法找到替换*] 并且 subs 不是等宽 [或不完全相同大小的等宽]。

一种测试方法是在编辑器中打开字体并查看它缺少哪些字形。

在此处输入图片说明

不幸的是,很难说出被替换的内容。

完全“治愈”是使用已经包含所有所需字形的字体,因此不需要 subs。

Deja Vu Sans Mono 总是比其他人更全面的好(并且很好的跨平台)候选人

在此处输入图片说明

& 维基百科在https://en.wikipedia.org/wiki/List_of_monospaced_typefaces 上有一个等宽字体列表

*Vim、emacs、Sublime 和 Notepad 都未能替换所有字符,因此具有讽刺意味的是,Vim“运行得最好”,因为它实际上“失败了最好”。

顺便说一句,我在 Mac 上看这个,它“应该擅长这种事情”......证明没有系统是完美的 - 它使用 Stack Exchange 的标准字体拧两行......

在此处输入图片说明

编辑
我刚刚注意到问题顶部的代码部分中的行长度并不完全相等,主要是管道之间的 15 个字符,但 17 个字符的 2 行......这会抛出所有内容。

使用 SE 的默认值修改了 Mac 字体替换的行长校正图片……

在此处输入图片说明

现在可以正确呈现(我有没有提到 Mac 应该擅长这些东西?;)

Deja Vu Sans、Menlo [似乎是 SE Mac 默认] 和 Consolas [在这个比较中表现不佳] 的行长校正图像。

在此处输入图片说明

  • 啊哈……无济于事的是,您的代码部分中的行长度实际上并不完全相同!它们主要是管道之间的 15 个字符,但两条悬垂线 [显示在我的 Mac 图片上] 是 17。我已经编辑了问答以进行更正。我将它复制粘贴到 Mac 原生应用程序中进行测试,但不知道为什么它 ** 仍然** 不起作用。 (6认同)
  • 它不应该需要“牺牲”任何东西,它应该能够找到等价的 subs,它们都应该是 - 事情是......一旦你远远超出标准 ASCII,它很少会这样,因为很少有字体包含甚至一个好的所有可能性的子集。在某些情况下替换将由操作系统完成,其他时间由应用程序设置。没有一种方法是完美的。看看您的操作系统如何处理顶部的“代码文本”示例或您的问题会很有趣。我的使用 SE 的标准字体 [在我的情况下为 Mac] 拧紧前面和扩展行。 (3认同)
  • @jsv 是的,U+FFFD(Unicode 中的官方替换字符)也有同样的问题。Vim 实际上有一个选项来控制该行为(`ambiwidth`),它允许您为具有不明确宽度的字符强制使用单宽或双宽。 (2认同)
  • 某些 [Nerd Fonts](https://www.nerdfonts.com/) 修补可能更可取,尤其是如果要使用 powerline 等扩展程序。 (2认同)

小智 8

每当我处理对齐至关重要的 ASCII 艺术流程图等内容时,我喜欢将内容粘贴到 Word 之类的内容中作为完整性检查。粘贴问题中的内容,按 Ctrl+A,然后将字体更改为 Consolas,结果:

在此处输入图片说明

现在,将光标放在一个字符之后,屏幕顶部的字体选择器将指示该字符正在使用哪种字体。我现在可以看到“空格”行上倒数第二个点使用的是 Cambria Math,“nbsp”中的第一个条目使用的是 MS Gothic,呈现为蓝色框的字形是 Segoe UI Emoji 等等。这些都是表示在 Consolas 中不可用的字符。这使得测试各种字体选择并找到一种具有您需要的所有字形的字体变得相当容易。

在上面的屏幕截图中,我还告诉 Word 显示空白字符的格式标记(文件 > 选项 > 显示)。这通常会使哪些字符与其他字符的宽度不同,这一点非常明显。在这个特定的例子中,标记与“空格”线上的点融合在一起,但仍然足以看到“延伸”中“x”大致下方的点比其他点窄。