WPF-从流加载字体? [英] WPF - Load Font from Stream?
问题描述
我有一个带有字体文件(.ttf)内容的MemoryStream,并且我希望能够从该流中创建一个FontFamily WPF对象 WITHOUT ,将该流的内容写入磁盘.我知道这可以通过System.Drawing.FontFamily实现,但是我无法找到如何使用System.Windows.Media.FontFamily做到这一点.
I have a MemoryStream with the contents of a Font File (.ttf) and I would like to be able to create a FontFamily WPF object from that stream WITHOUT writing the contents of the stream to disk. I know this is possible with a System.Drawing.FontFamily but I cannot find out how to do it with System.Windows.Media.FontFamily.
注意:我将仅拥有流,因此我无法将其打包为应用程序中的资源,并且由于磁盘权限问题,将无法将字体文件作为内容"写入磁盘以供参考.
Note: I will only have the stream, so I can't pack it as a resource in the application and because of disk permissions issues, will not be able to write the font file to disk for reference as "content"
更新:
API文档如何描述如何使用应用程序资源,尽管我不清楚这是程序集中的嵌入式资源还是磁盘上的文件.
The API docs how describe how an application resource can be used, though it is not clear to me whether that is an Embedded resource in the assembly or a file on disk.
当您引用打包为应用程序一部分的字体时,可以使用基本URI值.例如,基本URI值可以是"pack://application".URI,使您可以引用打包为应用程序资源的字体.以下代码示例显示了由基本URI值和相对URI值组成的字体引用.
You can use a base URI value when you reference a font that is packaged as part of the application. For example, the base URI value can be a "pack://application" URI, which lets you reference fonts that are packaged as application resources. The following code example shows a font reference that is composed of a base URI value and a relative URI value.
推荐答案
There is a similar question here, which contains a supposed solution by converting a System.Drawing.FontFamily to a WPF font family, all in memory without any file IO:
public static void Load(MemoryStream stream)
{
byte[] streamData = new byte[stream.Length];
stream.Read(streamData, 0, streamData.Length);
IntPtr data = Marshal.AllocCoTaskMem(streamData.Length); // Very important.
Marshal.Copy(streamData, 0, data, streamData.Length);
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddMemoryFont(data, streamData.Length);
MemoryFonts.Add(pfc); // Your own collection of fonts here.
Marshal.FreeCoTaskMem(data); // Very important.
}
public static System.Windows.Media.FontFamily LoadFont(int fontId)
{
if (!Exists(fontId))
{
return null;
}
/*
NOTE:
This is basically how you convert a System.Drawing.FontFamily to System.Windows.Media.FontFamily, using PrivateFontCollection.
*/
return new System.Windows.Media.FontFamily(MemoryFonts[fontId].Families[0].Name);
}
这似乎使用了 System.Drawing.PrivateFontCollection
((
This seems to use the System.Drawing.PrivateFontCollection
(^) to add a System.Drawing.Font
created from a MemoryStream
and then use the Families[0].Name
of that font to pass into the System.Windows.Media.FontFamily
constructor. I assume the family name would then be a URI to the instance of that font in the PrivateFontCollection but you'd probably have to try it out.
这篇关于WPF-从流加载字体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!