1

我一直在与从嵌入式文件加载字体以用于 DirectWrite 进行一场失败的战斗。我正在编写一个简单的益智游戏,它具有 C#/XAML 接口,但也使用 SurfaceImageSource 添加一些 DirectX 内容。

我编写了一个处理所有 DirectX 代码的 WinRT 组件,它工作得非常好。我的一些 DirectX 内容是使用 DirectWrite API 绘制的文本。只要我使用IDWriteFactory::GetSystemFontCollection()等从系统加载安装的字体,我就可以绘制我喜欢的所有文本。但是,我似乎找不到从嵌入文件加载自定义字体的方法。

据我所知,不允许 Metro 应用程序以与传统应用程序相同的方式从文件系统加载文件。所以,采用普通文件路径的IDWriteFactory::CreateFontFileReference()方法对我来说毫无价值,对吧?我需要从 ms-appx URL 加载我的文件。

因此,我在我的 WinRT 组件中编写了一个自定义字体加载器,它实现了IDWriteFontCollectionLoader接口(如果您之前从未做过,这将是一项繁重的工作),它使用新的StorageFile API从 ms-appx URL 加载字体。现在,我可以加载我的IDWriteFontFile并获得一个IDWriteFontFace,但是如果我尝试在字体上调用任何真正有用的方法,它会返回E_UNEXPECTED。我可以获得字形的数量和字形索引,但是如果我尝试调用GetGlyphRunOutline()GetDesignGlyphMetrics()之类的东西,它会因E_UNEXPECTED而失败。使用相同的绘图代码生成只要我安装字体文件并通过以IDWriteFactory::GetSystemFontCollection()开头的一系列调用来获取IDWriteFontFace ,使用GetGlyphRunOutline()的ID2D1PathGeometry 就可以很好地工作。我正在使用普通的 true type 字体。

那么,如何将嵌入文件中的自定义字体加载到 Metro 应用程序的 DirectWrite 中?我可能只是遗漏了一些简单的东西,因为我确信其他人会希望能够以这种方式加载自定义字体。

我有一个示例项目(或者可以很容易地准备一个)给任何可以帮助我识别我的问题的人。

我已经并排加载了两个IDWriteFontFace对象,并试图找出有效的对象和损坏的对象之间的不同之处。为了找出它失败的原因,我需要看到的是隐藏在IDWriteFontFace界面中的不透明内容。请帮忙!

此处还发布了问题:使用 DirectX 论坛构建 Metro 风格游戏

4

1 回答 1

3

好吧,答案是……不要写IDWriteFontCollectionLoader!您可以将IDWriteFactory::CreateFontFileReference()StorageFile API 一起使用。我参加的所有 Microsoft 会议演讲都给我的印象是,在 Metro 中您将无法直接访问本机文件系统。前进的方法是使用使用 ms-appx URL 引用资源等的StorageFile API。我知道这样做是为了并发,并允许操作系统通过创建文件系统沙箱将自己与将从商店下载的 Metro 应用程序隔离开来。我认为这是准确的。但是,我觉得我被引导相信我们永远无法获得本机文件系统路径。那不是真的。 IStorageFile提供了一种方法。只需使用IStorageFile.Path。我从来没有看过它,因为我只是假设Path属性将保存我用来创建对象的 ms-appx URL。Microsoft 可能完全出于上述问题的目的提供了此功能:调用需要本机路径的旧 COM 接口。

如果您尝试访问您自己的应用程序包之外的本机文件系统路径,我还没有进行任何测试来确定 WinRT 框架是否真的对您进行沙箱处理。我打赌它确实...

于 2012-08-18T16:22:45.087 回答