MeasureString () накладывает текст слева и справа

Я использую 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;

5 ответов


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

MSDN предлагает использовать другой метод, если вам нужно больше точности:

чтобы получить метрики, подходящие для соседних строк в макете (например, при реализации форматированного текста), используйте MeasureCharacterRanges метод или один из MeasureString методы, которые принимает StringFormat и передать GenericTypographic. Кроме того, убедитесь, что TextRenderingHint на графика is сглаживания.


Это правда, что по дизайну, однако ссылка на принятый ответ на самом деле не идеальна. Проблема заключается в использовании поплавков во всех этих методах, когда вы действительно хотите использовать пиксели (ints).

на класс TextRenderer предназначен для этой цели и работает с истинными размерами. Смотрите это ссылка из msdn для пошагового руководства по использованию этого.


добавить StringFormat.GenericTypographic исправит вашу проблему:

graphics->MeasureString(L"PP", 1, font, width, StringFormat.GenericTypographic);

применить тот же атрибут к DrawString.


похоже, что он также может подключаться к намеку, основанному на этой статье kb,почему текст выглядит по-разному при рисовании с GDIPlus против GDI


TextRenderer отлично подходит для получения размера шрифта. Но в цикле рисования, используя TextRenderer.DrawText был мучительно медленным по сравнению с графикой.шнурок.)(

поскольку ширина строки является проблемой, вам намного лучше использовать комбинацию TextRenderer.MeasureText и графики.шнурок..