Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF - Load Font from Stream?

Tags:

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.

like image 797
viggity Avatar asked Sep 04 '08 18:09

viggity


1 Answers

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.

like image 59
Patrick Klug Avatar answered Sep 27 '22 17:09

Patrick Klug