Подстановка и встраивание шрифтов

34

Подстановка шрифтов

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

Приведенный ниже пример пытается использовать шрифт Technical Italic, а в случае его отсутствия будут выбран запасной вариант — Comic Sans MS или Arial:

<Button FontFamily="Technical Italic, Comic Sans MS, Arial">A Button</Button>

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

Между прочим, имеется возможность получить список всех шрифтов, установленных на текущем компьютере — с помощью статической коллекции SystemFontFamilies из класса System.Windows.Media.Fonts. Ниже показан пример, в котором эта коллекция используется для добавления шрифтов в окно списка:

foreach (FontFamily fontFamily in Fonts.SystemFontFamilies)
{
   IstFonts.Items.Add(fontFamily.Source);
}

Объект FontFamily позволяет узнать и другие детали, такие как междустрочный интервал и родственные гарнитуры.

Одним из ингредиентов, отсутствующим в WPF, является диалоговое окно для выбора шрифта. Группа разработчиков WPF Text предложила два более привлекательных средства для выбора шрифта: версию без кода, использующую привязку данных и более сложную версию, которая поддерживает необязательные оформительские возможности, встречающиеся в некоторых шрифтах ОреnType.

Встраивание шрифтов

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

Процесс встраивания очень прост. Сначала нужно добавить в приложение файл шрифта (как правило, с расширением .ttf) и присвоить параметру Build Action значение Resource. (Это можно сделать в Visual Studio, выбрав файл шрифта в Solution Explorer и изменив значение Build Action в окне Properties (Свойства).)

Затем, при использовании шрифта, нужно добавить перед именем семейства символьную последовательность ./#:

<Grid>
    <Label FontFamily="./#VIVALDI" FontSize="48" VerticalAlignment="Center">Hello World!</Label>
</Grid>
Встроенный шрифт в WPF

WPF интерпретирует символы ./ как указание на текущую папку. Чтобы понять, что это означает, необходимо разобраться с системой упаковки XAML.

Можно запускать автономные (так называемые несвязанные) XAML-файлы прямо в браузере, не компилируя их. Единственное условие состоит в том, что XAML-файл не может использовать файл отделенного кода. Текущие папки допустимы, так что WPF ищет файлы шрифтов, которые находятся в одном каталоге с XAML-файлом, и делает их доступными для приложения.

Однако чаще WPF-приложение компилируется в сборку .NET, а уже затем выполняется. В этом случае текущая папка все так же является местом хранения XAML-документа, только теперь документ компилируется и встраивается в сборку. WPF ссылается на откомпилированные ресурсы с помощью специального синтаксиса URI. Все URI-адреса приложения начинаются с последовательности pack://application. Если создать проект под именем ClassicControls и добавить окно EmbeddedFont.xaml, то окно будет иметь следующий URI:

pack://application:,,,/ClassicControls/embeddedfont.xaml

Этот URI доступен в нескольких местах, в том числе и через свойство FontFamily.BaseUri. WPF использует этот URI как базовое местоположение при поиске шрифтов. Таким образом, при использовании синтаксиса ./ в скомпилированном WPF-приложении будет выполняться поиск шрифтов, которые встроены в виде ресурсов вместе с откомпилированным XAML.

После символов ./ можно просто указать имя файла, однако обычно добавляется знак номера (#) и имя семейства шрифтов. В приведенном выше примере встроенный шрифт называется Vivaldi.

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

О разрешениях на встраивание шрифтов можно узнать с помощью бесплатной утилиты просмотра свойств шрифтов Microsoft, которая доступна по адресу microsoft.com/typography/TrueTypeProperty21.mspx. После установки этой утилиты щелкните правой кнопкой мыши на любом файле шрифта и выберите в контекстном меню пункт Properties (Свойства), чтобы посмотреть более детальную информацию о нем.

В частности, посмотрите на вкладке Embedding (Встраивание), разрешено ли встраивание этого шрифта. Шрифты, помеченные как Installed Embedding Allowed (Разрешено инсталлированное встраивание), пригодны для использования в WPF-приложениях, а шрифты, помеченные как Editable Embedding Allowed (Разрешено редактируемое встраивание) могут оказаться не пригодными для этого. Информацию о лицензионном использовании какого-либо шрифта можно узнать у поставщика этого шрифта.

Режим форматирования текста

Прорисовка текста в WPF немного отличается от прорисовки в старых приложениях на основе GDI. В основном это отличие обусловлено применением в WPF независимой от устройства системы отображения, но появились также и значительные усовершенствования, которые позволяют тексту выглядеть яснее и четче, особенно на ЖК-мониторах.

Однако прорисовка текста в WPF имеет и один известный недостаток. При мелких размерах шрифтов текст становится размазанным и содержит нежелательные артефакты (вроде цветного ореола вокруг краев символов). Такие проблемы не возникают при выводе текста с помощью GDI, т.к. в этом интерфейсе используется несколько приемов, предназначенных для повышения четкости мелкого текста.

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

А как же решить задачу отображения мелкого текста в WPF? Лучше просто увеличить его размер (на мониторе с 96 dpi этот дефект пропадает при размере текста примерно в 15 независимых от устройства единиц) или использовать монитор с большим значением dpi, разрешения которого хватит на отображение четкого текста требуемого размера. Но поскольку эти варианты часто неприменимы на практике, в WPF 4 введена новая возможность: выборочное применение прорисовки текста в стиле GDI.

Для отображения текста в стиле GDI нужно добавить к элементу, отображающему этот текст (например, TextBlock или Label), прикрепленное свойство TextOptions.TextFormattingMode и изменить его значение на Display (со стандартного Ideal).

Учтите, что свойство TextFormattingMode годится в качестве решения только для небольшого шрифта. Если применять его для больших размеров (более 15 пунктов), то текст будет не таким четким, промежутки между символами — не такими ровными, а сами символы будут выглядеть не очень аккуратными.

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

Пройди тесты
Лучший чат для C# программистов