Загрузка шрифта из ресурсов в PrivateFontCollection приводит к повреждению репоста

У меня возникли трудности при загрузке шрифта из ресурса в PrivateFontCollection.

Когда я начал это, я успешно загрузил шрифт из файла, однако я хотел встроить шрифт в свой проект (чтобы было меньше путаницы файлов на стороне пользователя и немного меньше операций ввода-вывода во время работы приложения).

Следующий код загружает шрифт, получает правильное имя и позволяет масштабировать, однако ни один из символов не отображается должным образом.

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 - Это не работает, так как строка доступа для шрифта возвращает ноль. В моем случае средство доступа MyProject.Properties.Resources.fontawesome_webfont

Решение № 2 - Это решение подошло ближе всего, но опять же метод, используемый для доступа к ресурсу, больше не работает. Мой код выше реализует собранную версию этого, исключая основную концепцию передачи массива byte[] в память и последующей загрузки из памяти. Поскольку свойство get{} ресурса в моем случае уже возвращает массив byte[], не было необходимости "преобразовывать" его в массив байтов, и, таким образом, я (казалось) смог безопасно удалить эту часть кода с помощью обновить его, чтобы использовать более новый метод доступа.

В любом случае я хотел бы получить решение для этой проблемы, которое позволит мне загрузить файл шрифта из встроенных ресурсов в PrivateFontCollection.

1 ответ

Решение

AddMemoryFont В разделе замечаний говорится:

Чтобы использовать шрифт памяти, текст в элементе управления должен отображаться с помощью GDI+. Использовать SetCompatibleTextRenderingDefault метод, прохождение true, чтобы установить рендеринг GDI + в приложении или на отдельных элементах управления, установив элементы управления UseCompatibleTextRendering собственность на true, Некоторые элементы управления не могут быть отображены с помощью GDI+.

Я воспроизвел вашу проблему локально и опробовал ее, изменив пример использования на:

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

Это включает рендеринг GDI + для этой метки, позволяя шрифт, добавленный с AddMemoryFont сделать правильно.

Другие вопросы по тегам