WPF字体:为什么有些字符缺失?

时间:2009-05-07 01:01:39

标签: wpf fonts textbox

我正在编写一个WPF应用程序,我正在使用 的字体在WPF中运行时出现问题 - 它可以在其他任何地方使用它(记事本,wordpad等)。 WPF的问题在于它会回退到另一种字体有时候。 “有时”是指只有字符[a-zA-Z]才能正确呈现 - 其他所有内容都会呈现为默认的TextBox字体。

有没有人知道WPF是否对它支持的字体有某种限制?它几乎似乎是WPF中的错误 - 字体在其他任何地方都能正常工作。

我尝试使用的字体是“Scramble”TTF字体(http://famousfonts.smackbomb.com/fonts/scrabble.php)。

数字和空格应该被视为空白的Scrabble / Scramble拼贴,但数字本身会出现在我正在使用的文本框中。

我正在使用的代码:

<TextBox Text="Testing testing testing" FontFamily="Fonts/#Scramble" />

还有其他人经历过类似的事吗?

任何建议都会摇滚!

谢谢!

5 个答案:

答案 0 :(得分:8)

来自MSDN

  

字体回退

     

字体后备是指自动   替换除以外的字体   客户端选择的字体   应用。主要有两个   调用字体回退的原因:

     
      
  • 客户端应用程序指定的字体不存在   在系统上。
  •   
  • 客户端应用程序指定的字体不是   包含所需的字形   渲染文字。
  •   
     

在WPF中,字体回退机制   使用默认的回退字体系列,   “全球用户界面”,作为   替代字体。此字体已定义   作为复合字体,其文件名   是   “GlobalUserInterface.CompositeFont”。   有关复合的更多信息   字体,请参阅“复合字体”部分   在这个主题中。

     

WPF字体回退机制   替换以前的Win32字体   替代技术。

我的猜测是字体不支持Unicode - 字体本身是在1996年创建的,因为它打算模仿Scrabble片段,我不确定字体作者是否考虑过本地化。

<强> 修改 根据字体文档,字体支持字母,任何数字都应该呈现空白图块。空格不会渲染图块。

答案 1 :(得分:3)

简短的回答是,Scramble不会在WPF或其他任何内容中使用空白的拼字游戏作为em空间。你需要另一种字体来编辑em / en空格字形(类似Font Creator)。

我得到了another font(x-grid),我知道它有一个特殊的空格符号,并在下面的代码中使用它们。

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="500">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" FontFamily="Scramble" TextAlignment="Center" HorizontalAlignment="Center" FontSize="24" Text="Example Text M M M"/>
    <TextBlock Grid.Row="1" FontFamily="x-grid"  TextAlignment="Center" HorizontalAlignment="Center" FontSize="24" Text="Example Text M M M"/>
</Grid>

生成的窗口看起来像这样。

alt text

我担心与字体后备没什么关系。对不起,我希望有所帮助。

**更新:**对不起,刚注意到你也提到了数字。 Paint.Net中的快速测试表明,数字也不会显示在图块中。

答案 2 :(得分:2)

不使用FontFaily =“Fonts /#Scrambe”,只需使用不带“字体/#”的字体名称:

<TextBox Text="Testing testing testing" FontFamily="Scramble" />

这对我有用。我下载并安装了您引用的字体,它在VS2008的设计视图和运行应用程序的运行时都完美地显示了字体。

答案 3 :(得分:2)

一般的排版和特别是字体是一个相当复杂的话题,我并不是真的。这就是我从Typography in Windows Presentation Foundation和相关的MSDN文档中得到的结果:

  • 文本通过文本渲染管道呈现(参见上面的链接图)。
  • WPF使OpenType成为TrueType字体格式的扩展。
    • Typography对象公开了OpenType字体的许多高级功能。
  • 一个重要的低级文本呈现概念是Glyphs元素,请参阅MSDN introduction

如果你看一下上面提到的文本渲染管道图,你会发现虽然字形是构建块,但它们可以在最终显示在特定介质上之前以各种方式(过滤/转换/ ...)进行操作,例如屏幕或打印机;一个例子是将ClearType应用于LCD屏幕。然而,正如通常使用流水线概念一样,这些变换通常更不可选。

现在,根据您的应用程序要求,这可能已经产生了解决方案。如果你真的不需要TextBox,你也可以像这样使用Glyph:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:sys="clr-namespace:System;assembly=mscorlib" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
  <Grid>
    <TextBox Text="TextBox: 1234567890" FontFamily="Scramble" FontSize="12" />
    <Glyphs UnicodeString="Glyphs: 1234567890" FontUri="C:\WINDOWS\Fonts\Scramble.TTF" 
            FontRenderingEmSize="12" Fill="Black" OriginX="5" OriginY="32"/>
  </Grid>
</Page>

Glyphs元素根据需要渲染数字的空图块,而TextBox元素则不会。请注意,由于Glyphs是一个低级元素,因此有几个限制,特别是FontUri / Fill / FontRenderingEmSize都是必需的,即没有像相关TextBox属性那样的默认值。

记住这一切回到原来的问题: 我不认为手头的问题是WPF限制(或甚至是bug),而是关于文本呈现要求和WPF UI布局上下文中应用的默认值的影响。例如。复合(即非低级别)TextBox控件将文本格式和排版设置应用于其内容(字形),便于嵌入字体中的各种字符映射表(可能有lots个字符映射表。 );像Scramble这样的特殊/简单字体可能在这里没有提供足够或正确的信息,因此WPF渲染引擎可能被迫将字体回退应用为outlined by GalacticCowboy

如果情况确实如此,那么有可能以某种方式覆盖WPF默认渲染算法(参见类TextFormatter,WPF文本引擎),但很可能需要深入挖掘框架来构建在TextBox内发生了什么。在Scramble字体中“调试”最终丢失或不正确的字符映射可能要容易得多。尽管......这将是一次完全不同的努力。

答案 4 :(得分:0)

我不是WPF,但我知道微软总的来说拉丁语的非拉丁字符不同。我已经看到您可以定义复合字体,并将特定的unicode范围映射到字体。您可以尝试强制使用整个unicode范围的字体。 link text