Хотя Джефим правильно ответил на свой вопрос, я хотел объяснить, почему вы получаете это поведение при использовании этого конкретного набора функций. Джефим предполагает, что это ошибка в WPF, но это не так. Проблема возникает в результате запроса WPF сделать что-то невозможное. Он должен выбрать компромисс, когда вы просили эту невозможную вещь, и результат - то, что вы видите выше.
Объяснение немного длинное для комментария, поэтому я помещаю его в отдельный ответ.
В этом примере используются две взаимоисключающие функции WPF. Эти особенности:
- Способность оказывать визуальными последовательно в любом масштабе
- Способность визуализации текста таким же образом gdi32 делает текст
Вы не можете использовать обе функции одновременно. GDI32 отображает текст таким образом, который нельзя масштабировать последовательно: если конкретный фрагмент текста с определенным размером шрифта имеет ширину 200 пикселей, если вы умножаете размер шрифта на 3 и отображаете один и тот же текст в том же семействе шрифтов в что новый размер шрифта, в GDI32 он, вероятно, не будет 600 пикселей - он будет близок, но, как правило, это будет не совсем правильно.
GDI32 смешивает фигуры и ширину символов, чтобы повысить четкость и четкость текста. В частности, он изгибает буквы не по форме, чтобы их функции лучше соответствовали пикселям на экране. И там, где это необходимо, он будет регулировать ширину отдельных символов как точное количество пикселей в ширину. Поскольку этот изгиб письма основан на фактических пикселях, он изгибает текст по-разному при разных размерах шрифта.
Хотя это дает вам красивый текст, выглядящий ужасно, это выглядит абсолютно ужасно, если вы пытаетесь постепенно менять масштаб. Если вы попытаетесь оживить размер шрифта какого-либо текста, представленного таким образом, вещь будет казаться мерцающей и дрожащей, потому что корректировки, сделанные во имя ясности, в результате немного отличаются при каждом размере шрифта.Даже если вы не анимируете, он все равно может дать плохие результаты - если у вас есть один шрифт, показанный на разных размерах, он может выглядеть совсем по-разному при каждом размере; если ваше приложение имеет функцию масштабирования, характер текста может заметно измениться по мере увеличения и уменьшения масштаба. (И так может быть и макет. Если вы используете Microsoft Word, возможно, вы заметили, что иногда вы получаете необычные пространственные пробелы между определенными словами. Это результат взаимодействия Word с GDI32 - Word пытается сохранить экранную компоновку как можно ближе к тому, как будут выглядеть вещи при печати, а это значит, что иногда он сталкивается с сеткой GDI32.)
Таким образом, WPF предлагает другой подход к текстовому рендерингу: он может визуализировать текст так, насколько это возможно к оригинальному дизайну шрифта. Это искажает текст меньше, а это означает, что вы не получаете разрывов по мере масштабирования.
Недостатком является то, что текст выглядит размытым по сравнению с тем, как выглядит текст, визуализируемый GDI32. (Искажения, сделанные GDI32, направлены на улучшение ясности.)
Итак, в WPF 4.0 Microsoft добавила возможность визуализации текста способом GDI32. Вот что делает TextOptions.TextFormattingMode="Display"
.
Включив эту опцию, вы говорите: «Я не нуждаюсь в последовательном масштабировании, и я бы предпочел ясность, поэтому создайте те же пиксели, которые вы сделали бы в GDI32». Если вы затем примените масштабирование, сообщив WPF, что вам не нужна масштабируемость, вы получите дрянные результаты. WPF тщательно сгенерировал растровое представление текста точно в соответствии с вашими спецификациями, и затем вы сказали, чтобы он отображал этот текст в другом масштабе. И так оно выглядит так: масштабированное растровое изображение некоторого текста, который был сгенерирован для другого разрешения.
Вы можете утверждать, что WPF мог бы сделать что-то другое: если вы примените масштабное преобразование в GDI32, вы увидите другое поведение - вы увидите несогласованность в разных масштабах, описанных ранее. Если вы действительно хотите получить этот эффект в WPF, вы можете получить его, изменив размер шрифта напрямую. Но WPF не ставит перед собой приоритет в получении такого же эффекта - его целью является получение текста с четким текстом в формате GDI32, когда он вам действительно нужен, и обеспечить постоянное масштабирование по умолчанию.
И что вы здесь используете, это «согласованное масштабирование». Включение текстового рендеринга в стиле GDI32 не нарушает согласованного масштабирования: применение масштабного коэффициента (либо напрямую, через ScaleTransform
, либо косвенно через Viewbox
) изменит размеры визуального изображения точно заданным коэффициентом масштабирования. Если бы было регенерация текстовых изображений с помощью привязки сетки к вновь масштабированному размеру, текст выходил бы на другой ширине. Это фактически вызовет проблемы Viewbox
: он применяет масштабный коэффициент, основанный на натуральном размере контента, предназначенном для того, чтобы он соответствовал доступному пространству. Но если он изменил сетку после масштабирования, это фактически изменило бы ширину. Из-за несоответствий, присущих тому, как работает текстовый рендеринг GDI32, для может оказаться невозможным найти подходящий масштаб - можно придумать фрагмент текста, который при визуализации в определенном шрифте никогда не появится шириной 200 пикселей. Для некоторых размеров шрифта округление, связанное с подгонкой сетки, может привести к уменьшению размера до, скажем, 198, и это может повлиять на это, поскольку вы делаете крошечные приращения размера шрифта, пока не пройдете какой-то порог, после чего он может прыгать до 202 пикселей.
Для получения Viewbox
попыток заставить текст вписаться в ровно 200 пикселей, это будет проблемой. Но Viewbox
не работает таким образом - он использует согласованное масштабирование WPF, расположенное ниже точки, в которой вы выбрали размер шрифта, с которым работает текстовый рендеринг в стиле GDI32. Таким образом, Viewbox
всегда сможет делать то, что он предназначен, но это задача, которая принципиально несовместима с визуализацией текста в стиле GDI32.
Итак, WPF отображает текст для требуемого размера шрифта, а затем масштабирует результат.
Итак, вам нужно выбрать только одну функцию - вы не можете иметь обоих, потому что это просто невозможно. Либо не пытайтесь отображать текст в контексте, в котором может применяться произвольный масштабный коэффициент (например, Viewbox
), либо не включать текстовый рендеринг в стиле GDI32. В противном случае вы получите тот странный пиксельный текст, с которым вы столкнулись.
отлично смотрится на моей машине – 2010-12-10 12:20:16
Выглядит неплохо на моей машине! Какую версию WPF вы используете? Можете ли вы протестировать его в новом окне, поскольку это только контент? – decyclone 2010-12-10 12:25:35