Loading a font from resources into PrivateFontCollection results in corruption
Asked Answered
P

0

0

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: Loading from memory

This is what it look like loading from file: 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.

Pawl answered 12/10, 2015 at 11:33 Comment(2)
@HansPassant - did you even read the question? My application is not crashing. I am also not having any problems 'freeing' the memory.Pawl
No, I'm a moron that's incapable of reading. Happens a lot around here, questioners alike, so it isn't that obvious. That you call Marshal.FreeCoTaskMem() right after adding the font and have obvious memory corruption issues is of course a complete coincidence that you should never suspect as the source of the problem.Noncompliance

© 2022 - 2024 — McMap. All rights reserved.