WPF - 将字体保存到磁盘,然后实例化字体的GlyphTypeface抛出异常。为什么?

时间:2010-06-19 12:04:28

标签: wpf fonts nullreferenceexception

我正在讨论WPF字形和文档,并且在.Net 4框架中遇到了一个空引用异常。

我将真实字体作为.ttf文件提取并保存到磁盘,然后尝试根据字体创建字形。我第一次将字体保存到磁盘并基于字体实例化GlyphTypeface 从同一文件夹中的另一种字体创建GlyphTypeface后,我得到一个空引用异常。

假设我有字体A和B. B尚未保存到磁盘(A可能已保存或未保存到磁盘;这似乎无关紧要):

1)将B保存到与A,
相同的文件夹中的磁盘 2)使用字体A,
创建GlyphTypeface 3)使用字体B =异常创建GlyphTypeface。

Null reference exception at:  
at MS.Internal.FontCache.FontFaceLayoutInfo.IntMap.TryGetValue(Int32 key, UInt16& value)  
at MS.Internal.FontCache.FontFaceLayoutInfo..ctor(Font font)  
at System.Windows.Media.GlyphTypeface.Initialize(Uri typefaceSource, StyleSimulations styleSimulations)  
at System.Windows.Media.GlyphTypeface..ctor(Uri typefaceSource)

如果我重新启动我的应用并再次运行(字体B已经在磁盘上),则步骤3不会抛出异常。

将字体保存到磁盘的代码只是从二进制流中编写一个部分并放开文件:

if (!File.Exists(filename))
{
    using (FileStream fs = File.Create(filename, length))
    {
        fs.Write(m_data, m_index, length);
        fs.Close();
    }
}

有什么想法吗?我不想把每个字体放在自己的文件夹中......

感谢您的时间。

5 个答案:

答案 0 :(得分:2)

我最终使用了将每种字体保存到自己的文件夹的解决方法(使用文件夹名称的字体名称)。例外情况消失了,所以我想我们可以将其归结为.Net中的一个错误。

答案 1 :(得分:2)

这个错误让我感到疯狂,但我想我对现在发生的事情有了更好的了解。

为了进行测试,我使用了以下XAML:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Glyphs
    FontUri="C:\Users\Public\Desktop\A.ttf"
    FontRenderingEmSize="100"
    Fill="Black"
    UnicodeString="Test"/>
</Page>

使用在.NET 2运行时运行的XamlPadX应用程序,无论我在哪里放置字体,都可以可靠地呈现XAML。

使用在.NET 4运行时运行的Kaxaml应用程序,XAML通常无法呈现,具体取决于我将字体放在文件系统中的位置。通过移动字体文件并重命名,我试图发现允许的模式。但是,很难看到一种模式。

例如,将字体存储在下面的路径中将呈现字形:

C:\Users\Public\Desktop\A.ttf - OK

将其从A.ttf重命名为B.ttf会抛出异常:

C:\Users\Public\Desktop\B.ttf - throws exception

更改扩展名也会引发异常:

C:\Users\Public\Desktop\A.odttf - throws exception

重命名部分路径有时会造成严重破坏,但我无法看到任何模式。最初我使用临时路径并获得异常引导我回答这个问题以及关于不使用该路径的答案。但是,后来我实际上只能使用该路径,只要文件名是A.ttf而不是B.ttf,所以避免临时路径不是一个可靠的修复。

在我使用自己的WPF应用程序测试期间的某个时刻,B.ttf文件名突然开始工作。但是,我必须重新启动Kaxaml应用程序才能接受B.ttf文件名。此外,此时A.odttf文件名仍然抛出异常。

我的建议是使用像Kaxaml这样的应用程序或创建一个小型WPF应用程序来测试哪些字体文件名是可接受的,然后使用它们。但是,我担心这个bug的性质使得“好”的字体文件名可能在以后变为“坏”。只有时间会显示出来。

答案 2 :(得分:1)

我(和同事)终于找到了我们的特定问题:不要将字体文件保存到%TEMP%。出于某种原因,将字体保存到其他文件夹使其工作(对我们而言),并将其保存到%TEMP%内的任何位置使其中断。

答案 3 :(得分:1)

根据XamlToys Doesn't work on framework 4.0???,问题在于扩展部分字体的文件。

当我将我保存的.ofttf文件重命名为.ttf时,它再次起作用。尽管如此,还没有最简单的想法。似乎是.NET 4.0中的新功能。

答案 4 :(得分:0)

我的解决方法是简单地替换&lt;字形&gt;等价&lt; TextBlock&gt; s。在我的情况下,布局中的几个像素差异不是问题。

就像你所说的那样,在我的情况下,它也不是.Net 3.5中的问题,而是出现在.Net 4.0中。