jnm*_*nm2 15 c# fonts gdi+ cleartype opentype
当使用默认的Microsoft Office字体Calibri在9pt和14pt之间指定ClearTypeGridFit时,究竟是什么让GDI +切换到二进制混叠?
这有点令人不安.还有多少其他字体也受到此背后的任何影响以及尺寸的影响?有解决方法吗?(不包括GDI,它没有相同的文本布局功能?)

这是我用来生成图像的代码:
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
var height = 0;
for (var i = 1; i <= 17; i++)
{
using (var font = new Font("Calibri", i))
{
var text = "ClearTypeGridFit " + i + "pt";
e.Graphics.DrawString(text, font, SystemBrushes.ControlText, 0, height);
height += (int)e.Graphics.MeasureString(text, font).Height;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mik*_*ans 14
Calibri附带一个EBLC表和EBDT表,它告诉文本引擎,对于某些点大小,他们不应该尝试"他们自己的缩放算法",而只是使用直接存储在字体中的位图.
每个字体大小都可以带有自己的列表"以下字形必须以此大小进行位图",称为"打击",因此一个字形可以有多个大小的多个位图(但可能存在间隙,当发生这种情况时,位图需要缩放,事情可能会发生灾难性的错误).
例如,Calibri对点大小为12,13,15,16,17和19进行了攻击,A的示例位图为:
<ebdt_bitmap_format_1 name="A">
<SmallGlyphMetrics>
<height value="8"/>
<width value="7"/>
<BearingX value="0"/>
<BearingY value="8"/>
<Advance value="7"/>
</SmallGlyphMetrics>
<rawimagedata>
10102828 447c8282
</rawimagedata>
</ebdt_bitmap_format_1>
Run Code Online (Sandbox Code Playgroud)
该位图由字体大小12 strike引用,并编码为7x8像素位图.由于12是最低值,当我们使用低于12的字体大小时,我们会遇到问题:突然我们必须缩放位图.这只会出现可怕的错误.
如果你看一下像写字板这样的东西,你可以看到微软的Uniscribe引擎(与GDI +一起使用;现代的等价物是Direct2D ,而DirectWrite作为文本引擎)可以很好地缩放这些位图(显示的是5到20的大小),但是即便是微软自己的技术也有明显的局限性.我们看到在字体大小为5,6和7px时,位图非常糟糕,甚至8,10和11看起来有些不稳定:

放大:

事情变得更有趣,因为不是每个字形都在每次打击中表示,所以虽然"A"在点大小为12时有位图,但是有一些字形,其中具有显式位图的最低点大小可以是13,或15或16,或者17岁,甚至19岁.
这意味着您有三个问题:
找出哪些字体可以做到这一点的最简单方法是简单地检查EBDT表的字体 - 如果有的话,这种字体会强制引擎使用位图来表示非常小(有时非常大)的字体.如果你想要这些细节,你可以通过TTX运行字体,然后找到<EBDT>表格开始,看看究竟发生了什么.
不过准备不堪重负.例如,仅Calibri就有超过一千个字形指定的位图.