3
votes

Well, I basically want to literally embed my collection of fonts that I will be using in my WPF app. They're stored in my own virtual file system (like WinRAR), and I just want to load them through a byte array or a memory stream. However, I haven't been able to find any working solutions. I've tried PrivateFontCollection, but at the end, I realized that the Families property is for WinForms (System.Drawing.FontFamily and NOT System.Windows.Media.FontFamily). I also classify extracting them to the OS level out of the question.

So the question still remains:

How to load a System.Windows.Media.FontFamily using a byte array or a memory stream?

EDIT:

This is a .ttf file (True Type Font)

1
Did you see the Packaging Fonts with Applications article?Clemens
Yes, but the problem is that I want to store my fonts in my own file system and not store them in an application level (or OS level).user4136548
I'm trying to implement this in my own application (a WebAPI hosted on Azure, so installing fonts on the system is not an option (that I could find)), but I'm stuck: what is MemoryFonts in this context, and how does FontFamily() in LoadFont know to look there instead of at the system fonts, since all you're passing it is the name?Dave the Sax
Actually, this is one of the things that are still strange to me... Although, for some reason, it works... I just don't know how. I passed the name of the font family into the font family constructor and it recognized the font without the font being installed on the OS level. For the "MemoryFonts" thing... It's a variable. Notice how I add fonts to it Dictionary<int, PrivateFontCollection>, the int being the key, which is the font's id on my resource system and the value is basically the "loader" of the ACTUAL font, of course loaded from the function "LoadFont".user4136548
Add your solution as an answer, so that this question isn't seen as unanswered.Peter O.

1 Answers

0
votes

You have posted this solution:

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