You have a really nice font (or several fonts) that you want to use with your application. However, you don't want to mess with the hassle of installing the font on every computer that uses your app.
So what can you do?
Embed the font as a resource.
.NET allows you to embed pretty much any file into the executable. It's just a matter of extracting the resource when you need it.
With fonts, there is a PrivateFontCollection object with an AddMemoryFont method. This method takes an IntPtr pointing to a location in memory and the length to read.
Step 1: The first thing you need to do is add the font to your solution. Go to the Project menu and select Add Existing Item (Ctrl-D shortcut). Navigate to the font you want to use and click Open. The font will be copied to your solution's folder, and you will see it in the Solution Explorer.
Step 2: Click on the font in Solution Explorer to highlight it. In Properties (under Solution Explorer) there is a line for Build Action. This defaults to Compile. You need to change it to Embedded Resource by selecting from the drop down list.
(Repeat steps 1 and 2 for any addtional fonts you want to embed.)
Step 3: Ok, now that the font is an embedded resource, you just have to write the code to extract it.
The following code assumes you have an Imports System statement at the top of your code file.
Private Declare Auto Function AddFontMemResourceEx Lib "Gdi32.dll" _ (ByVal pbFont As IntPtr, ByVal cbFont As Integer, _ ByVal pdv As Integer, ByRef pcFonts As Integer) As IntPtr
Public Function GetFont(ByVal FontResource() As String) As _ Drawing.Text.PrivateFontCollection 'Get the namespace of the application Dim NameSpc As String = _ Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString() Dim FntStrm As IO.Stream Dim FntFC As New Drawing.Text.PrivateFontCollection() Dim i As Integer For i = 0 To FontResource.GetUpperBound(0) 'Get the resource stream area where the font is located FntStrm = _ Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream( _ NameSpc + "." + FontResource(i)) 'Load the font off the stream into a byte array Dim ByteStrm(CType(FntStrm.Length, Integer)) As Byte FntStrm.Read(ByteStrm, 0, Int(CType(FntStrm.Length, Integer))) 'Allocate some memory on the global heap Dim FntPtr As IntPtr = _ Runtime.InteropServices.Marshal.AllocHGlobal( _ Runtime.InteropServices.Marshal.SizeOf(GetType(Byte)) * _ ByteStrm.Length) 'Copy the byte array holding the font into the allocated memory. Runtime.InteropServices.Marshal.Copy(ByteStrm, 0, _ FntPtr, ByteStrm.Length) 'Add the font to the PrivateFontCollection FntFC.AddMemoryFont(FntPtr, ByteStrm.Length) Dim pcFonts As Int32 pcFonts = 1 AddFontMemResourceEx(FntPtr, ByteStrm.Length, 0, pcFonts) 'Free the memory Runtime.InteropServices.Marshal.FreeHGlobal(FntPtr) Next Return FntFC End Function
So what does all this do?
Pass an array of the font names to the function.
The function gets NameSpc which is the name of your currently running applicaton.
A stream, a private font collection, and a loop counter are declared.
The stream is set to the font that's within the resource stream.
The font is read into a byte array from the stream.
Now a little unmanaged code has to be written...First an IntPtr variable is set to point to memory allocated on the global heap in the same size as the byte array holding the font.
The byte array is then copied to this allocated location on the global heap.
Now that you have a valid IntPtr pointing to the font, you can added it to the PrivateFontCollection using AddMemoryFont.
The memory on the global heap is then freed. You must do this or you'll have a memory leak.
Each font in the array you passed is repeated.
[li]After the loop is finished, the PrivateFontCollection is returned to the caller.
Now to use the fonts in the PrivateFontCollection you can use any of the many overloads of the Font constructor. Pass the index of the FontFamily you want to use.
Example: 'Use a 10 point font of the first font in your PrivateFontCollection Me.Font = New Font(FntFC.Families(0), 10)
The next time you want to use a nifty font, you'll be able to embed it right in your app.