Правильное измерение символов в пикселях - PullRequest
1 голос
/ 21 февраля 2012

Я пишу текстовое поле с нуля, чтобы оптимизировать его для подсветки синтаксиса. Тем не менее, мне нужно получить ширину символов в пикселях, а не мусор Graphics :: MeasureString дает мне. Я нашел много вещей в сети, в частности this , однако, похоже, что ничего из этого не работает или не учитывает вкладки. Мне нужен самый быстрый способ измерить точные размеры символа в пикселях и пространства табуляции. Я не могу понять это ...

Следует отметить, что я использую C ++, CLR / CLI и GDI +


Вот моя измерительная функция. В другой функции RectangleF, которую он возвращает, выводится на экран:

RectangleF TextEditor::MeasureStringWidth(String^ ch, Graphics^ g, int xDistance, int lineYval)
{
    RectangleF measured;
    Font^ currentFont = gcnew Font(m_font, (float)m_fontSize);
    StringFormat^ stringFormat = gcnew StringFormat;
    RectangleF layout = RectangleF(xDistance,lineYval,35,m_fontHeightPix);
    array<CharacterRange>^ charRanges = {CharacterRange(0,1)};
    array<Region^>^ strRegions;

    stringFormat->FormatFlags = StringFormatFlags::DirectionVertical;
    stringFormat->SetMeasurableCharacterRanges(charRanges);

    strRegions = g->MeasureCharacterRanges(ch, currentFont, layout, stringFormat);

    if(strRegions->Length >= 1)
        measured = strRegions[0]->GetBounds(g);
    else
        measured = RectangleF(0,0,0,0);

    return measured;
}

Я не совсем понимаю, что делает параметр MeasureCharacterRanges layoutRect. Я изменил код из примера Microsoft, чтобы работать только с одним символом или измерять его только.

Ответы [ 2 ]

5 голосов
/ 21 февраля 2012

Не следует использовать Graphics для визуализации текста.

Начиная с .NET Framework 2.0 использование Graphics.MeasureString и Graphics.DrawString устарело в пользу недавно добавленного вспомогательного класса TextRenderer:

  • TextRenderer.MeasureText
  • TextRenderer.DrawText

Средство визуализации текста GDI + было прекращено и не получало каких-либо улучшений или исправлений более10 лет;Кроме того, выполняется рендеринг программного обеспечения.

Рендеринг GDI (для которого TextRenderer - простая оболочка) ускоряется аппаратно и продолжает улучшать рендеринг (лигатуры, Uniscribe и т. д.). Примечание: Рендеринг текста GDI + заключен в Graphics.DrawString и MeasureString

Вот сравнение результатов измерений Graphics и TextRenderer:

enter image description here

Измерения GDI + не являются «неправильными» , они делают именно то, что они намеревались - возвращают размер, который будет иметь текст , если он был представленкак и предполагал автор оригинального шрифта (чего можно добиться с помощью рендеринга сглаживания ):

enter image description here

Но никто на самом деле не хочет Посмотрите на текст так, как задумал дизайнер шрифтов, потому что это приводит к тому, что материал не выстраивается в линию на границах пикселей, что делает текст слишком размытым (то есть, как вы видите на Mac).В идеале текст должен быть привязан к фактическим границам пикселей (т. Е. Windows ' Grid Fitting )

Bonus Reading

2 голосов
/ 21 февраля 2012

Есть MeasureCharacterRanges, что похоже на MeasureString, но более мощное и более точное (а также более медленное).

...