1

リソースから PrivateFontCollection にフォントをロードする際に問題があります。

これを開始したとき、ファイルからフォントを読み込むことに成功しましたが、プロジェクトにフォントを埋め込みたいと思います (そのため、ユーザー側のファイルの混乱が少なくなり、アプリケーションの実行中の IO が少し少なくなります)。

次のコードは、フォントをロードし、適切な名前を取得し、スケーリングを可能にしますが、どの文字も適切に表示されません。

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"); } }

}

使用例:

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

これは、メモリからのロードのように見えます: メモリからの読み込み

これは、ファイルからのロードのように見えます: ファイルからの読み込み

埋め込みリソースとファイル ベースのテストの両方で、現在の FontAwesome TTF ファイルを使用しています。埋め込み時、または埋め込みからの読み込み時に、翻訳で何かが失われたり、スクランブルされたりしているようです。フォントを埋め込みリソースから PrivateFontCollection にロードできるように、これを機能させるには助けが必要です。

SO で調べた「解決策」がいくつかありますが、それらはかなり古く、一部またはすべてのコマンド/アクセサーは Visual Studio 2013 では使用できなくなりました (記事の解決策は 4 ~ 5 年前のものです)。「解決策」の例と、それらが機能しない理由:

解決策 #1 - フォントのアクセサー文字列が null を返すため、これは機能しません。私の場合、アクセサはMyProject.Properties.Resources.fontawesome_webfont

解決策 2 - この解決策が最も近かったのですが、リソースへのアクセスに使用されていた方法が機能しなくなりました。上記のコードは、byte[] 配列をメモリに渡し、メモリからロードするというコア コンセプトを取り除いた、このハーベスト バージョンを実装しています。私の場合、リソースの get{} プロパティはすでに byte[] 配列を返しているため、それをバイト配列に「変換」する必要はなく、コードのその部分を (一見) 安全に削除することができました。新しいアクセサーを使用するように更新します。

どちらの場合も、フォント ファイルを埋め込みリソースから PrivateFontCollection にロードできるようにする、この問題の解決策が必要です。

4

1 に答える 1

3

AddMemoryFontの備考欄には次のように書かれています。

メモリ フォントを使用するには、コントロールのテキストを GDI+ でレンダリングする必要があります。SetCompatibleTextRenderingDefaultを渡すメソッドを使用しtrueて、アプリケーションで GDI+ レンダリングを設定するか、コントロールのUseCompatibleTextRenderingプロパティを に設定して個々のコントロールで GDI+ レンダリングを設定しtrueます。一部のコントロールは GDI+ でレンダリングできません。

問題をローカルで再現し、使用例を次のように変更して試しました。

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

これにより、そのラベルの GDI+ レンダリングが有効になり、 で追加されたフォントがAddMemoryFont正しくレンダリングされます。

于 2015-10-13T00:17:32.177 に答える