Функция MeasureString() дополняет текст слева и справа
-
02-07-2019 - |
Вопрос
Я использую GDI + в C ++.(Эта проблема может существовать и в C #).
Я заметил, что всякий раз, когда я вызываю Graphics::MeasureString() или Graphics:: DrawString(), строка дополняется пробелами слева и справа.
Например, если я использую шрифт Courier (не курсив!) и измеряю "P", я получаю 90, но "PP" дает мне 150.Я бы ожидал, что моноширинный шрифт даст ровно двойную ширину для "PP".
Мой вопрос заключается в следующем:является ли это намеренным или документированным поведением, и как мне отключить это?
RectF Rect(0,0,32767,32767);
RectF Bounds1, Bounds2;
graphics->MeasureString(L"PP", 1, font, Rect, &Bounds1);
graphics->MeasureString(L"PP", 2, font, Rect, &Bounds2);
margin = Bounds1.Width * 2 - Bounds2.Width;
Решение
По замыслу, этот метод не использует фактические глифы для измерения ширины и поэтому добавляет небольшое отступление в случае выступов.
MSDN предлагает использовать другой метод, если вам нужна большая точность:
Чтобы получить показатели, подходящие для смежных строк в макете (например, при реализации форматированного текста), используйте Диапазоны измеряемых символов способ или один из Измеряемая строка методы, которые требуют Строковый формат, и передать Обобщенно - типографский.Кроме того, убедитесь, что TextRenderingHint текстовый переход для Графика является Антиалии.
Другие советы
Это правда, что так задумано, однако ссылка на принятый ответ на самом деле не идеальна.Проблема заключается в использовании значений с плавающей точкой во всех этих методах, когда то, что вы действительно хотите использовать, - это пиксели (целые числа).
Тот Самый Класс TextRenderer предназначен для этой цели и работает с истинными размерами.Видишь это ссылка из msdn для пошагового руководства по использованию этого.
Добавить StringFormat.GenericTypographic
исправит вашу проблему:
graphics->MeasureString(L"PP", 1, font, width, StringFormat.GenericTypographic);
Примените тот же атрибут к DrawString
.
Похоже, это также может быть связано с хинтингом, основываясь на этой статье kb, Почему текст выглядит по-разному при рисовании с помощью GDIPlus по сравнению с GDI
TextRenderer отлично подходил для получения размера шрифта.Но в цикле рисования использование TextRenderer.DrawText было мучительно медленным по сравнению с графикой.DrawString().
Поскольку проблема заключается в ширине строки, вам гораздо лучше использовать комбинацию TextRenderer.measureText и graphics.DrawString..