I response to our article Using custom fonts in C# application from March 2016 we had question about loading multiple fonts. After looking the the previous code I made few changes what makes it simpler and also allows to load more than one font.
To see details about embedding actual font files please see previous article.
Used fonts are just two first one appeared on http://www.1001fonts.com/ page. Great thanks to site and fonts authors.
Registered users can download full solution EmbeddedFontsExaple.zip (12 downloads) (Visual Studio 2015)
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Text; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; /* http://www.1001fonts.com/ Bully Regular by Bully http://www.1001fonts.com/bully-font.html Romochka Regular by Jovanny Lemonad http://www.1001fonts.com/romochka-font.html */ namespace EmbeddedFontsExaple { public partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("gdi32.dll")] private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts); public static PrivateFontCollection private_fonts = new PrivateFontCollection(); public static void LoadFont(string FontResourceName) { // receive resource stream Stream fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(FontResourceName); //create an unsafe memory block for the data System.IntPtr data = Marshal.AllocCoTaskMem((int)fontStream.Length); //create a buffer to read in to Byte[] fontData = new Byte[fontStream.Length]; //fetch the font program from the resource fontStream.Read(fontData, 0, (int)fontStream.Length); //copy the bytes to the unsafe memory block Marshal.Copy(fontData, 0, data, (int)fontStream.Length); // We HAVE to do this to register the font to the system (Weird .NET bug !) uint cFonts = 0; AddFontMemResourceEx(data, (uint)fontData.Length, IntPtr.Zero, ref cFonts); //pass the font to the font collection private_fonts.AddMemoryFont(data, (int)fontStream.Length); //close the resource stream fontStream.Close(); //free the unsafe memory Marshal.FreeCoTaskMem(data); } public static void LoadFont(Byte[] fontData) { //create an unsafe memory block for the data System.IntPtr data = Marshal.AllocCoTaskMem(fontData.Length); //copy the bytes to the unsafe memory block Marshal.Copy(fontData, 0, data, fontData.Length); // We HAVE to do this to register the font to the system (Weird .NET bug !) uint cFonts = 0; AddFontMemResourceEx(data, (uint)fontData.Length, IntPtr.Zero, ref cFonts); //pass the font to the font collection private_fonts.AddMemoryFont(data, fontData.Length); //free the unsafe memory Marshal.FreeCoTaskMem(data); } private void Form1_Load(object sender, EventArgs e) { LoadFont(EmbeddedFontsExaple.Properties.Resources.Bully); Font bullyFont = new Font(private_fonts.Families[0], 20); LoadFont(EmbeddedFontsExaple.Properties.Resources.Romochka); Font romochkaFont = new Font(private_fonts.Families[1], 20); label1.Font = bullyFont; label2.Font = romochkaFont; label1.Text += " " + bullyFont.Name; label2.Text += " " + romochkaFont.Name; } } }
And the final result: