Я использую DirectWrite для визуализации текста в окне. Кажется, все работает, кроме позиционирования при использовании шрифтов разных размеров: я ожидаю, что 2 текста с размером шрифта v1 и v2 и оба с (x, y) = (0, 0) будут в верхнем левом углу, но, как вы можете видеть:
ни «Test», ни «X» на самом деле не слева вверху.
Есть ли способ сделать эту работу?
Добро пожаловать в мир шрифтов. Шрифты, пожалуй, самая сложная вещь для использования, потому что сами шрифты неожиданны (существует так много новых стандартов, которые должны решить все и просто запутать больше, потому что почти 100% шрифтов не поддерживают его на 100%, даже некоторые «классические» шрифты имеют частичная / неверная информация в них) GDI, GDI +, DirectDraw не рисуют шрифт в одной и той же позиции в пикселях из-за математики, округления координат, сглаживания … (у вас может быть еще один бонус, если вы выполните математику с свободный тип).
При попытке напечатать шрифт есть другие pb. Так что единственный способ обойти это для меня. Даже не пытайтесь рисовать шрифт с определенными координатами пикселей. Делайте свою работу по рисованию шрифтов, рисунков, линий на экране, которые хорошо отрисовываются, старайтесь изо всех сил преобразовывать их в координаты печати для экспорта, но никогда не ожидайте управления пикселями в шрифтах, все округляется приблизительно.
PS: не доверяйте внутренним полям в шрифтах. В Arial они хороши для всех остальных шрифтов, некоторые из которых отсутствуют или инициализированы нулями, но «забавная» часть — это не всегда одно и то же поле, которого нет, это зависит от шрифтов. Вы можете использовать только поля, если вы попробуете их раньше шрифтом. Да, шрифты фантастические!
Термин @evilruff имеет в виду, называется «внутреннее лидерство». Ты можешь использовать IDWriteFontFace :: GetMetrics или возможно IDWriteFontFace :: GetDesignGlyphMetrics чтобы получить это значение (для GetMetrics, значение, которое вы ищете, скорее всего, metrics.ascent - metrics.capHeight
).
Здесь значения приведены в единицах дизайна шрифта, а не в пикселях (любого рода). Вы можете преобразовать эти значения в высоту, разделив на metrics.designUnitsPerEm
; как правило, размеры шрифта в DirectWrite определяются размером пикселя (в нижнем регистре) m; поэтому, если вы умножите значения в ems на размер шрифта, вы должны получить значения в пикселях.
Я предполагаю, что вы используете IDWriteTextLayout вместе с DrawTextLayout (а не создаете свой собственный DWRITE_GLYPH_RUN). IDWriteTextLayout выравнивает глифы по их ячейке макета (включая полное всплытие и разрыв строки), а не по чернилам глифа, и это справедливо практически для всех текстовых макетов, будь то веб-браузеры или текстовые процессоры или простые элементы управления редактированием. Если бы они этого не сделали (вместо выравнивания по верху буквы), то диакритические знаки в таких словах, как ishis, были бы вырезаны.
Если вы всегда хотите выровнять по чернилам, создайте IDWriteTextLayout, вызовите IDWriteTextLayout :: GetOverhangMetrics, а затем вызовите DrawTextLayout с источником, равным отрицательному DWRITE_OVERHANG_METRICS :: left&Топ. Если вы хотите выровнять по высоте колпачка всегда (таким образом, «привет» и «привет» будут рисовать с одинаковой вертикальной координатой), подход Эрика будет работать.