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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With