I am having some difficulty in loading a font from a resource into PrivateFontCollection.
When I started this, I was successful in loading the font from a file, however I wish to embed the font into my project (so there is less file mess on the user side, and a bit less IO while the application is running).
The following code will load the font, gets the proper name, and allows for scaling however none of the characters are showing up properly.
static class Foo {
public static string FontAwesomeTTF { get; set; }
public static Font FontAwesome { get; set; }
public static float Size { get; set; }
public static FontStyle Style { get; set; }
private static PrivateFontCollection pfc { get; set; }
static Foo() {
// This was set when loading from a file.
// FontAwesomeTTF = "fontawesome-webfont.ttf";
Style = FontStyle.Regular;
Size = 20;
if ( pfc==null ) {
pfc=new PrivateFontCollection();
if ( FontAwesomeTTF==null ) {
var fontBytes=Properties.Resources.fontawesome_webfont;
var fontData=Marshal.AllocCoTaskMem( fontBytes.Length );
Marshal.Copy( fontBytes, 0, fontData, fontBytes.Length );
pfc.AddMemoryFont( fontData, fontBytes.Length );
Marshal.FreeCoTaskMem( fontData );
} else {
pfc.AddFontFile( FontAwesomeTTF );
}
}
FontAwesome = new Font(pfc.Families[0], Size, Style);
}
private static string UnicodeToChar( string hex ) {
int code=int.Parse( hex, System.Globalization.NumberStyles.HexNumber );
string unicodeString=char.ConvertFromUtf32( code );
return unicodeString;
}
public static string glass { get { return UnicodeToChar("f000"); } }
}
Example usage :
label1.Font = Foo.FontAwesome;
label1.Text = Foo.glass;
This is what it looks like loading from memory:
This is what it look like loading from file:
I am using the current FontAwesome TTF file in both the embedded resource and the file based tests. It seems that when embedded something is being lost or scrambled in the translation or when loading from embedded. I need help making this work so I can load the font from an embedded resource into PrivateFontCollection.
There are a few 'solutions' I looked at on SO however they are quite dated and some or all of the commands/accessors are no longer available in Visual Studio 2013 (article solution was from 4-5 years ago). Some example 'solutions' and why they don't work:
Solution #1 - This doesn't work as the accessor string for the font returns null. In my case, the accessor is MyProject.Properties.Resources.fontawesome_webfont
Solution #2 - This solution came the closest, but again the method used to access the resource no longer works. My code above implements a harvested version of this taking out the core concept of passing the byte[] array into memory and then loading from memory. Since the get{} property of the resource in my case returns a byte[] array already, there was no need to 'convert' it into a byte array and thus I was (seemingly) safely able to remove that portion of the code by updating it to use the newer accessor.
In either case, I would like a solution for this problem that allows me to load the font file from the embedded resources into PrivateFontCollection.
PrivateFontCollection
available? Bundling fonts as separate files is a fairly common practice (especially for DTP applications, because it means the fonts can be easily updated to newer versions by your users), and I am not sure there's an IO benefit, since fonts are dealt with by things like DirectWrite, which are specifically designed to perform as few accesses as is possible to shape text. – Jovanjove