C# WPF如何从字节数组加载FontFamily?

3

我想在我的WPF应用程序中嵌入我的字体集合,它们存储在我自己的虚拟文件系统中(类似于WinRAR),我只想通过字节数组或内存流加载它们。然而,我还没有找到任何可行的解决方案。我尝试了PrivateFontCollection,但最终我意识到Families属性是针对WinForms(System.Drawing.FontFamily和不是System.Windows.Media.FontFamily)。我也不考虑将它们提取到操作系统级别。

所以问题仍然存在:

如何使用字节数组或内存流加载System.Windows.Media.FontFamily?

编辑:

这是一个.ttf文件(True Type Font)


你看过使用应用程序打包字体这篇文章了吗? - Clemens
1
是的,但问题在于我想将字体存储在自己的文件系统中,而不是存储在应用程序级别(或操作系统级别)。 - user4136548
我正在尝试在我的应用程序中实现这个功能(一个托管在Azure上的WebAPI,因此在系统上安装字体不是一个选项(至少我没有找到)),但我卡住了:在这种情况下,MemoryFonts是什么?LoadFont中的FontFamily()如何知道要在那里查找而不是在系统字体中查找,因为你只传递了名称? - Dave the Sax
1
实际上,这是我仍然感到陌生的事情之一...尽管出于某种原因,它可以正常工作...我只是不知道为什么。我将字体系列的名称传递到字体系列构造函数中,它识别了字体,而无需在操作系统级别安装字体。对于“MemoryFonts”这个东西...它是一个变量。请注意如何将字体添加到它的Dictionary<int,PrivateFontCollection>中,int是键,即字体在我的资源系统中的id,值基本上是实际字体的“加载器”,当然从“LoadFont”函数加载。 - user4136548
请将您的解决方案添加为答案,以便此问题不被视为未回答。 - Peter O.
1个回答

1

您已发布了此解决方案:

If someone is searching for this kind of solution, it's right here:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接