我有一个包含字体文件 (.ttf) 内容的 MemoryStream,我希望能够从该流创建 FontFamily WPF 对象WITHOUT将流的内容写入磁盘。我知道这对于 System.Drawing.FontFamily 是可能的,但我不知道如何使用 System.Windows.Media.FontFamily 做到这一点。
注意:我只有流,因此无法将其打包为应用程序中的资源,并且由于磁盘权限问题,将无法将字体文件写入磁盘以作为“内容”引用
UPDATE:
The API docs https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.fontfamily?view=netframework-4.6.1how 描述如何使用应用程序资源,尽管我不清楚它是程序集中的嵌入式资源还是磁盘上的文件。
当您引用打包为应用程序一部分的字体时,可以使用基本 URI 值。例如,基本 URI 值可以是“pack://application”URI,它允许您引用打包为应用程序资源的字体。以下代码示例显示由基本 URI 值和相对 URI 值组成的字体引用。
有一个类似的问题here https://stackoverflow.com/questions/44912480/c-sharp-wpf-how-to-load-a-fontfamily-from-a-byte-array,其中包含一个假定的解决方案,通过将 System.Drawing.FontFamily 转换为 WPF 字体系列,所有内容都在内存中,没有任何文件 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
(^ https://learn.microsoft.com/en-us/dotnet/api/system.drawing.text.privatefontcollection?view=dotnet-plat-ext-5.0)添加一个System.Drawing.Font
创建自MemoryStream
然后使用Families[0].Name
该字体的传递到System.Windows.Media.FontFamily
构造函数。我假设家族名称将是 PrivateFontCollection 中该字体实例的 URI,但您可能必须尝试一下。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)