WPF - 从流加载字体?

发布于 2024-07-04 23:11:07 字数 655 浏览 6 评论 0原文

我有一个包含字体文件 (.ttf) 内容的 MemoryStream,并且我希望能够从该流创建一个 FontFamily WPF 对象,将该流的内容写入磁盘。 我知道这对于 System.Drawing.FontFamily 是可能的,但我不知道如何使用 System.Windows.Media.FontFamily 做到这一点。

注意:我只有流,因此无法将其打包为应用程序中的资源,并且由于磁盘权限问题,将无法将字体文件写入磁盘以作为“内容”参考

更新:

API 文档如何描述如何使用应用程序资源,尽管我不清楚它是程序集中的嵌入式资源还是磁盘上的文件。

当您引用打包为应用程序一部分的字体时,可以使用基本 URI 值。 例如,基本 URI 值可以是“pack://application”URI,它允许您引用打包为应用程序资源的字体。 以下代码示例显示由基本 URI 值和相对 URI 值组成的字体引用。

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"

UPDATE:

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如果没结果 2024-07-11 23:11:08

我能想到的最好方法是将 oldFont 保存到临时目录,并立即使用接受 uri 的 newFont 构造函数加载它。

The best approach I could think of, was to save the oldFont to a temp directory, and immediately load it using the newFont constructor that accepts a uri.

差↓一点笑了 2024-07-11 23:11:07

这里有一个类似的问题,其中包含一个假定的解决方案,通过将 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(^) 添加从 MemoryStream 创建的 System.Drawing.Font,然后使用该字体的 Families[0].Name 传递进入 System.Windows.Media.FontFamily 构造函数。 我假设家族名称将是 PrivateFontCollection 中该字体实例的 URI,但您可能必须尝试一下。

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);
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文