Шрифт WPF: почему отсутствуют некоторые символы?

Я пишу приложение WPF, и шрифт, который я использую только, имеет проблемы с запуском в WPF — он отлично работает, используя его во всем остальном (блокнот, текстовый блокнот и т. д.). Проблема с WPF заключается в том, что он иногда использует другой шрифт. Под «иногда» я подразумеваю, что только символы [a-zA-Z] отображаются правильно, а все остальное отображается как шрифт TextBox по умолчанию.

Кто-нибудь знает, есть ли у WPF какие-то ограничения для поддерживаемых шрифтов? Это почти похоже на ошибку в WPF - везде шрифт работает нормально.

Я пытаюсь использовать шрифт TTF "Scramble" (http://famousfonts.smackbomb.com/fonts/scrabble.php).

Числа и пробелы должны отображаться как пустая плитка Scrabble/Scramble, но вместо этого само число появляется в текстовом поле, которое я использую.

Код, который я использую:

<TextBox Text="Testing testing testing" FontFamily="Fonts/#Scramble" />

Кто-нибудь еще испытал что-то подобное?

Любые предложения будут рок!

Спасибо!


person Charles    schedule 07.05.2009    source источник


Ответы (5)


Из MSDN:

Резервный шрифт

Резервный шрифт относится к автоматической замене шрифта, отличного от шрифта, выбранного клиентским приложением. Есть две основные причины, по которым вызывается откат шрифта:

  • Шрифт, указанный клиентским приложением, не существует в системе.
  • Шрифт, указанный клиентским приложением, не содержит глифов, необходимых для отображения текста.

В WPF резервный механизм шрифта использует семейство резервных шрифтов по умолчанию, «Глобальный пользовательский интерфейс», в качестве замещающего шрифта. Этот шрифт определяется как составной шрифт с именем файла «GlobalUserInterface.CompositeFont». Дополнительные сведения о составных шрифтах см. в разделе «Композитные шрифты» в этом разделе.

Резервный механизм шрифтов WPF заменяет предыдущие технологии замены шрифтов Win32.

Я предполагаю, что шрифт не поддерживает Unicode — сам шрифт был создан в 1996 году, и, поскольку он предназначен для имитации фрагментов Scrabble, я не уверен, что автор шрифта даже думал о локализации.

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

person GalacticCowboy    schedule 06.07.2009
comment
О, да ладно. У кого-то должен быть лучший ответ, чем этот... Мне было бы неловко получить награду за копирование/вставку из MSDN, которая даже не полностью отвечает на вопрос... :\ - person GalacticCowboy; 07.07.2009

Короткий ответ заключается в том, что Scramble не использует пустую часть перетаскивания для пробела em в WPF или где-либо еще. Вам понадобится другой шрифт или что-то подобное для редактирования глифов пробелов em/en (что-то вроде Font Creator).

У меня есть другой шрифт (x-grid), который, как я ЗНАЮ, имеет специальный глиф для пробелов и использовал их, как в приведенном ниже коде.

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="500">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" FontFamily="Scramble" TextAlignment="Center" HorizontalAlignment="Center" FontSize="24" Text="Example Text M M M"/>
    <TextBlock Grid.Row="1" FontFamily="x-grid"  TextAlignment="Center" HorizontalAlignment="Center" FontSize="24" Text="Example Text M M M"/>
</Grid>

The resulting window looked like this.

альтернативный текст

Боюсь, ничего общего с font-fallback. Извините, но я надеюсь, что это поможет.

**ОБНОВЛЕНИЕ:**Извините, я только что заметил, что вы тоже упомянули цифры. Быстрый тест в Paint.Net показывает, что числа также не отображаются на плитках.

person EightyOne Unite    schedule 10.07.2009
comment
Я попробовал это в Word, и сначала числа не отображались, но если я вернулся и специально установил форматирование шрифта, они появились. Но да, цифры какие-то нелепые. Они также не отображаются в предварительном просмотре шрифта. - person GalacticCowboy; 13.07.2009
comment
Хм, а какое форматирование ты поставил? В любом случае я бы попытался получить лучший шрифт, если он ведет себя так странно. - person EightyOne Unite; 13.07.2009
comment
После того, как я ввел числа, я выбрал их, а затем переключил шрифт на другое начертание, а затем снова на Scramble, и они появились. - person GalacticCowboy; 13.07.2009
comment
Как действительно странно. Я только что сделал то же самое, и он снова переключается на Arial, как только вы набираете номер. Это предполагает, что в шрифте на самом деле отсутствуют эти глифы и что вместо них используется шрифт по умолчанию. Возможно, MS Word заменяет эти глифы символом типа по умолчанию, когда вы явно устанавливаете его форматирование обратно на выбранный вами тип. WPF, конечно, не будет этого делать. ЕСТЬ обходные пути, но, честно говоря, я бы просто изменил шрифт, если вы можете, или нашел бы альтернативу, вместо того, чтобы решать проблему. - person EightyOne Unite; 13.07.2009

Вместо установки FontFaily="Fonts/#Scrambe" просто используйте имя шрифта без "Fonts/#":

<TextBox Text="Testing testing testing" FontFamily="Scramble" />

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

person awe    schedule 10.07.2009

Типографика в целом и шрифты в частности — довольно сложная тема, которой я не особо увлекаюсь. Тем не менее, вот что я понял из Типографика в Windows Presentation Foundation и соответствующая документация MSDN:

  • Текст рендерится с помощью конвейера рендеринга текста (схему см. по ссылке выше).
  • WPF facilitates OpenType as an extension of the TrueType font format.
    • The Typography object exposes many of the advanced features of OpenType fonts.
  • Важной концепцией рендеринга текста низкого уровня является элемент Glyphs, см. введение.

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

Теперь, в зависимости от требований вашего приложения, это уже может дать решение. Если вам действительно не нужен TextBox, вы можете просто использовать Glyphs сами по себе, например:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:sys="clr-namespace:System;assembly=mscorlib" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
  <Grid>
    <TextBox Text="TextBox: 1234567890" FontFamily="Scramble" FontSize="12" />
    <Glyphs UnicodeString="Glyphs: 1234567890" FontUri="C:\WINDOWS\Fonts\Scramble.TTF" 
            FontRenderingEmSize="12" Fill="Black" OriginX="5" OriginY="32"/>
  </Grid>
</Page>

Элемент Glyphs отображает пустые плитки для чисел по желанию, а элемент TextBox — нет. Обратите внимание, что из-за того, что глифы являются низкоуровневым элементом, применяются некоторые ограничения, в частности, требуются все параметры FontUri/Fill/FontRenderingEmSize, т. е. нет значений по умолчанию, как для связанных свойств TextBox.

Имея все это в виду, вернемся к вашему первоначальному вопросу: я бы не стал думать о проблеме как об ограничении WPF (или даже об ошибке), а скорее о влиянии требований к рендерингу текста и значений по умолчанию, применяемых в контексте пользовательского интерфейса WPF. макет. Например. составной (т. е. не низкоуровневый) элемент управления TextBox применяет параметры форматирования текста и типографики к его содержимому (глифам), упрощая работу с различными таблицами сопоставления символов, встроенными в шрифты (потенциально существуют множество из них...); специальные/упрощенные шрифты, такие как Scramble, могут просто не предоставить здесь достаточной или правильной информации, следовательно, механизм рендеринга WPF может быть вынужден применить откат шрифта как уже описаны GalacticCowboy.

Если это действительно так, возможно, можно каким-то образом переопределить алгоритм рендеринга WPF по умолчанию (см. class TextFormatter, текстовый движок WPF), но, вероятно, потребуется довольно глубоко изучить структуру, чтобы понять, что происходит внутри TextBox. Вероятно, гораздо проще «отладить» отсутствующие или неправильные сопоставления символов в шрифте Scramble. Хотя это было бы совсем другое дело...

person Steffen Opel    schedule 13.07.2009

Я не в WPF, но я знаю, что Microsoft в целом обрабатывает латинские и нелатинские символы по-разному. Я видел, что вы можете определить составной шрифт и сопоставить определенный диапазон юникода со шрифтом. Вы можете попробовать использовать свой шрифт для всего диапазона юникода. текст ссылки

person Luzifer42    schedule 09.07.2009