我一直在打击从嵌入式文件加载字体以与DirectWrite一起使用的失败之战。我正在编写一个简单的益智游戏,它有一个C#/ XAML接口,但也使用SurfaceImageSource来添加一些DirectX内容。
我编写了一个处理所有DirectX代码的WinRT组件,它运行得非常好。我的一些DirectX内容是使用DirectWrite API绘制的文本。只要我使用 IDWriteFactory :: GetSystemFontCollection()等从系统加载已安装的字体,我就可以绘制我喜欢的所有文本。但是,我似乎找不到加载方法的方法嵌入式文件中的自定义字体。
据我所知,Metro应用程序不允许以与传统应用程序相同的方式从文件系统加载文件。因此,采用普通文件路径的 IDWriteFactory :: CreateFontFileReference()方法对我来说毫无价值,对吧?我需要从ms-appx URL加载我的文件。
所以,我在我的WinRT组件中编写了一个自定义字体加载器,它实现了 IDWriteFontCollectionLoader 接口(如果你以前从未在btw之前完成它,这是很多工作)加载来自的字体使用新的 StorageFile API的ms-appx网址。现在,我可以加载 IDWriteFontFile ,我可以获得 IDWriteFontFace ,但是如果我尝试在字体上调用任何真正有用的方法,则返回 E_UNEXPECTED 即可。我可以获得字形和字形索引的数量,但是如果我尝试调用类似 GetGlyphRunOutline()或 GetDesignGlyphMetrics()的内容,则会失败并显示 E_UNEXPECTED < / strong>即可。使用 GetGlyphRunOutline()生成 ID2D1PathGeometry 的相同绘图代码,只要我安装字体文件并获取 IDWriteFontFace ,就可以正常工作以 IDWriteFactory :: GetSystemFontCollection()开头的一系列调用。我正在使用普通的真实字体。
那么,如何在Metro应用程序中将嵌入文件中的自定义字体加载到DirectWrite中?我可能只是错过了一些简单的东西,因为我确信其他人会希望能够以这种方式加载自定义字体。
我有一个示例项目(或者可以轻松准备一个项目)给任何可以帮我识别问题的人。
我已经并排加载了两个 IDWriteFontFace 对象,我试图找出有效的对象和破坏的对象之间的区别。我需要看到的是为了找出它失败的原因,我隐藏在 IDWriteFontFace 界面后面是不透明的。请帮忙!
答案 0 :(得分:3)
嗯,答案是......不要写一个 IDWriteFontCollectionLoader !您可以将 IDWriteFactory :: CreateFontFileReference()与 StorageFile API一起使用。我在Metro上参加过的所有微软会议会议的印象都是在Metro中,你将无法直接访问本机文件系统;前进的方法是使用 StorageFile API,它使用ms-appx URL引用资源等。我知道这是为了并发性,并允许操作系统将自己与将通过创建文件系统沙箱从商店下载的Metro应用程序隔离开来。我认为这是准确的。但是,我觉得我被引导相信我们永远无法获得原生文件系统路径。那不是真的。 IStorageFile 提供了一种方法。只需使用 IStorageFile.Path 即可。我从来没有看过它,因为我只是假设 Path 属性将保存我用来创建对象的ms-appx URL。 Microsoft可能在上面的问题中提供了这个目的:调用需要本机路径的传统COM接口。
如果您尝试访问自己的应用包之外的本机文件系统路径,我还没有进行任何测试来确定WinRT框架是否实际上是沙箱。我打赌它确实......