WPF - сохранение шрифта на диск, а затем создание GlyphTypeface для исключения бросков шрифтов. Зачем? - PullRequest
5 голосов
/ 19 июня 2010

Я слоняюсь с глифами и документами WPF и натолкнулся на исключительную нулевую ссылку в среде .Net 4.

Я извлекаю и сохраняю шрифты true-type на диск как файлы .ttf, затем пытаюсьсоздавать глифы на основе шрифтов.В первый раз, когда я сохраняю шрифт на диск и создаю экземпляр GlyphTypeface на основе шрифта после , создавая GlyphTypeface из другого шрифта в той же папке, я получаю исключение нулевой ссылки.

Скажите, что у меня естьШрифты A и B. B не был сохранен на диск (A мог или не мог быть сохранен на диск; это не имеет значения):

1) сохранить B на диск в той же папке, что иA,
2) создайте GlyphTypeface, используя шрифт A,
3) создайте GlyphTypeface, используя шрифт B = исключение.

Null reference exception at:  
at MS.Internal.FontCache.FontFaceLayoutInfo.IntMap.TryGetValue(Int32 key, UInt16& value)  
at MS.Internal.FontCache.FontFaceLayoutInfo..ctor(Font font)  
at System.Windows.Media.GlyphTypeface.Initialize(Uri typefaceSource, StyleSimulations styleSimulations)  
at System.Windows.Media.GlyphTypeface..ctor(Uri typefaceSource)

Если я перезагружаю свое приложение и запускаю его снова (шрифт B уже на диске), шаг 3 не вызывает исключение.

Код для сохранения шрифта на дискепросто записывает раздел из двоичного потока и отпускает файл:

if (!File.Exists(filename))
{
    using (FileStream fs = File.Create(filename, length))
    {
        fs.Write(m_data, m_index, length);
        fs.Close();
    }
}

Есть идеи?Я не хочу помещать каждый шрифт в отдельную папку ...

Спасибо за ваше время.

Ответы [ 5 ]

2 голосов
/ 20 апреля 2012

Эта ошибка приводила меня в бешенство, но я думаю, что лучше понимаю, что происходит сейчас.

Для тестирования я использовал следующий XAML:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Glyphs
    FontUri="C:\Users\Public\Desktop\A.ttf"
    FontRenderingEmSize="100"
    Fill="Black"
    UnicodeString="Test"/>
</Page>

Используя приложение XamlPadX , которое работает в среде выполнения .NET 2, я мог надежно отобразить XAML независимо от того, где я разместил шрифт.

При использовании приложения Kaxaml , которое выполняется во время выполнения .NET 4, XAML часто не может отображаться в зависимости от того, где я разместил шрифт в файловой системе. Перемещая файл шрифта и переименовывая, я пытался найти образец в том, что было разрешено. Тем не менее, было очень трудно увидеть шаблон.

Например, хранение шрифта в указанном ниже пути приведет к отображению глифов:

C:\Users\Public\Desktop\A.ttf - OK

Переименование его с A.ttf на B.ttf приведет к исключению:

C:\Users\Public\Desktop\B.ttf - throws exception

Изменение расширения также вызовет исключение:

C:\Users\Public\Desktop\A.odttf - throws exception

Переименование частей пути иногда приводило к хаосу, но я не мог видеть никакой картины. Первоначально я использовал временный путь, и получение исключений привело меня к этому вопросу и ответу о том, что этот путь не используется. Однако позже я смог использовать этот путь, если имя файла A.ttf, а не B.ttf, поэтому избегание временного пути не является надежным решением.

В какой-то момент во время моих тестов с использованием моего собственного приложения WPF имя файла B.ttf неожиданно начало работать. Однако мне пришлось перезапустить приложение Kaxaml, чтобы оно приняло имя файла B.ttf. Кроме того, в этот момент имя файла A.odttf все еще вызывало исключения.

Я предлагаю использовать приложение, такое как Kaxaml, или создать небольшое приложение WPF, чтобы проверить, какие имена файлов шрифтов являются приемлемыми, а затем использовать их. Однако я боюсь, что природа этой ошибки такова, что «хорошее» имя файла шрифта может стать «плохим» в более поздний момент времени. Только время покажет.

2 голосов
/ 13 июля 2010

В итоге я использовал обходной путь сохранения каждого шрифта в своей папке (используя имя шрифта для имени папки).Исключение ушло, поэтому я думаю, мы можем объяснить это ошибкой в ​​.Net.

1 голос
/ 17 июля 2012

Согласно XamlToys не работает на framework 4.0 ??? , проблема в расширении файла для частичных шрифтов.

Когда я переименовал файлы .ofttf, которые я сохранил в .ttf, все снова работает. У меня нет ни малейшего представления о том, почему это так. Кажется, является новым в .NET 4.0.

1 голос
/ 18 апреля 2012

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

0 голосов
/ 04 февраля 2011

Мой обходной путь - просто заменить на эквивалентные . Разница в пару пикселей в макете не была проблемой в моем случае.

Как вы заметили, это был случай для вас, в моем случае это не было проблемой в .Net 3.5, но появилось в .Net 4.0.

...