WPF模糊字体问题 - 解决方案

时间:2008-10-10 06:50:27

标签: wpf fonts

问题在以下链接中描述和演示:

说明:Text Clarity in WPF。此链接具有字体比较。

我想为这个问题收集所有可能的解决方案。 Microsoft Expression Blend使用WPF但字体看起来可读。

  • Microsoft Expression Blend中的深色背景
  • 增加字体大小并更改字体(Calibri ...)[link]
  • 嵌入窗体[link]
  • 使用GDI +和/或Windows窗体TextRenderer类将文本呈现到位图,然后将该位图呈现为WPF控件。 [link]

还有其他解决方案吗?

This is going to be fixed in VS2010 (and WPF4) beta 2

看起来它已经被最终解决了!

Scott Hanselman's ComputerZen.com: WPF and Text Blurriness, now with complete Clarity

11 个答案:

答案 0 :(得分:122)

.NET 4最终解决了WPF文本呈现质量差的问题,但它隐藏得很好。为每个窗口设置以下内容:

TextOptions.TextFormattingMode="Display"

默认值为“理想”,完全不是名称所暗示的。

TextOptions中还有另外两个选项,即TextHintingMode和TextRenderingMode,但它们都有合理的默认值。

答案 1 :(得分:103)

技术背景

有一篇关于WPF文本呈现的深入文章来自windowsclient.net上的一个WPF文本程序管理器:Text Clarity in WPF

问题归结为WPF需要线性缩放字体渲染器以获得流畅的动画效果。另一方面,Pure ClearType使用字体将相当大的自由度推入下一个像素。

如果比较经典的“级联”模式,差异是显而易见的。左下角的WinForms,右上角的WPF:

虽然我不喜欢WPF的字体渲染特性,但我可以想象,如果动画会像Winforms级联中那样跳跃,那就是吵闹。

使用注册表

我特别感兴趣的是MSDN文章“ClearType Registry Settings”的链接,该文章解释了注册表中可能的用户端调整:

  • ClearType级别:子像素提示量
  • Gamma等级
  • 像素结构:如何排列显示像素中的彩色条纹
  • 文本对比度级别:调整字形词干的宽度以使字体更重

使用这些设置并没有真正改善潜在的问题,但可以通过减少敏感用户的色彩渗透效果来提供帮助。

另一种方法

Text Clarity文章给出的最佳建议是增加字体大小和更改字体。 Calibri比标准的Segoe UI更适合我。由于它作为网络字体的流行,我也尝试了Verdana,但它在14pt和15pt之间有一个令人讨厌的重量跳跃,这在动画字体大小时非常明显。

WPF 4.0

WPF 4将改进对影响字体呈现的支持。 an article on the WPF Text Blog解释了这些变化。最突出的是,现在(至少)有三种不同的文本呈现方式:

text rendering comparison

< grumble>对于每个设计师来说,这应该足够了。< / grumble>

答案 2 :(得分:35)

有一天,当我使用了应用了DropShadowEffect的边框时,我遇到了一个问题。结果是该边界内的所有文本都非常模糊。如果文本位于其他面板内或直接位于边框下方并不重要 - 任何应用了Effect的父级子级的文本块似乎都会受到影响。

这个特殊情况的解决方案是不要将东西放在有效果的边框内,而是使用网格(或任何其他支持将内容放在彼此之上的东西)并在同一个单元格中放置一个矩形。文本(即作为视觉树中的兄弟姐妹)并将效果放在那里。

像这样:

<!-- don't do this --->
<Border>
     <Border.Effect>
          <DropShadowEffect BlurRadius="25" ShadowDepth="0" Opacity="1"/>
     </Border.Effect>
     <TextBlock Text="This Text Will Be Blurry" />
</Border>

<!-- Do this instead -->
<Grid>
  <Rectangle>
     <Rectangle.Effect>
          <DropShadowEffect BlurRadius="25" ShadowDepth="0" Opacity="1"/>
     </Rectangle.Effect>
  </Rectangle>
  <TextBlock Text="This Text Will Be Crisp and Clear" />
</Grid>

答案 3 :(得分:10)

这将在VS2010(和WPF4)beta 2中修复:

答案 4 :(得分:6)

SnapToDevicePixels仅适用于WPF形状(行等),而不适用于文本渲染器。

此问题没有已知的解决方法。根据微软的说法,这种行为是“按设计”。

另请参阅微软论坛上的this帖子讨论问题 - 它已经得到了MS人员的一些回复,澄清了他们在这个问题上的立场。

答案 5 :(得分:6)

从开发人员的角度来看,迄今为止唯一已知的“解决方法”是使用GDI +和/或Windows Forms TextRenderer类将文本呈现到位图,然后将该位图呈现为WPF控件。除了明显的性能影响之外,这并没有缓解现有应用程序的问题。

我现在已经创建了一个Microsoft Connect ticket for this issue(令我惊讶的是,尽管存在所有的否定性,但指定的跟踪器中没有实际的错误报告)。

由于这是向微软传达请求和问题的官方渠道之一,我建议也要通过它来更快地回答。至少,如果您希望以某种方式解决问题,在那里投票和/或验证问题将有助于引起Microsoft PM和工程师对此问题的关注,并可能提高其感知优先级。

答案 6 :(得分:4)

刚刚试用了VS2010测试版,这一切都是在WPF中完成的,并且它因模糊字体问题而受到严重影响。特别是在工具提示上。

这似乎提供了一些证据表明WPF4实际上无法解决问题(如果看起来更糟糕的话)

答案 7 :(得分:4)

哇,我简直不敢相信我终于让我的WPF字体可读了。而且我也无法相信没有选项对话框可以轻松实现这些更改,而我的显示屏上的默认值非常糟糕。

这些registry settings(十进制)对我有用,并且最接近我的常规cleartype字体:

  • ClearTypeLevel:10(主要是灰度别名)
  • GammaLevel:1300(更高的伽玛使字体太薄,我看到了别名中的颜色)

答案 8 :(得分:4)

我不认为这是一个错误,但默认配置确实非常烦人。这是

所有组合的比较
TextOptions.TextRenderingMode
TextOptions.TextFormattingMode
RenderOptions.ClearTypeHint

SnapToDevicePixels在文字渲染方面没有任何差异。

http://i.stack.imgur.com/cS3S2.png

我更喜欢:

TextOptions.TextRenderingMode="Auto"
TextOptions.TextFormattingMode="Ideal"
RenderOptions.ClearTypeHint="Auto"

垂直线永远不会模糊。

使用的字体是Open Sans Light,如果使用得很好,可以非常漂亮,就像最新的TeamViewer一样。

对于那些使用Mahapps.Metro的人来说,问题是TransitioningContentControl https://github.com/MahApps/MahApps.Metro/issues/889

答案 9 :(得分:3)

他们说“SnapToDevicePixels = true”有效,但我从未见过任何好结果。

我通过切换到不同的字体来对抗模糊文本。

显然这不是问题的解决方案,但这就是我解决这个问题的方法。

答案 10 :(得分:0)

如果您希望使用C#基类为应用程序自定义窗口(或现在有理由),可以通过以下方法设置文本格式以使用吸引人的显示模式:

public class SnappyWindow : Window
{
    public SnappyWindow()
    {
        SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
    }
}