Loading a font from resources into PrivateFontCollection results in corruption repost

筅森魡賤 提交于 2020-01-05 10:12:10

问题


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.


回答1:


AddMemoryFont's remarks section says:

To use the memory font, text on a control must be rendered with GDI+. Use the SetCompatibleTextRenderingDefault method, passing true, to set GDI+ rendering on the application, or on individual controls by setting the control's UseCompatibleTextRendering property to true. Some controls cannot be rendered with GDI+.

I reproduced your issue locally and tried it out by changing your usage sample to:

label1.Font = Foo.FontAwesome;
label1.Text = Foo.glass;
label1.UseCompatibleTextRendering = true;

This turns on GDI+ rendering for that label, allowing the font added with AddMemoryFont to render correctly.



来源:https://stackoverflow.com/questions/33087848/loading-a-font-from-resources-into-privatefontcollection-results-in-corruption-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!