Функция MeasureString() дополняет текст слева и справа

StackOverflow https://stackoverflow.com/questions/118686

  •  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..

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top