2008-10-15 4 views
3

Я пытался найти метод на C# для измерения размера строки. standard method для измерения строки в Win32 - это использование GetTextExtent. Реальная цель - найти средний ширину и высоту шрифта. Стандартный метод, чтобы найти среднюю ширину символа начинается с получения ширины всех алфавитных символов и разделить на 52:Graphics.MeasureString возвращает разные значения, чем Win32 GetTextExtent

size = dc.GetTextExtent(
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52); 
averageWidth = size/52; 

Microsoft имеет страницу, которая перечисляет average character widths для некоторых размеров шрифта при определенных настройках DPI, и Я подтвердил их своими вызовами GetTextExtent.

  • Tahoma 8pt, 96dpi: 13x6 точек
  • Tahoma 9пт, 96dpi: 14x7 точек
  • Segoe UI 9пт, 96dpi: 15x7 точек

Теперь я хочу выполните те же вычисления в .NET WinForms. Использование Graphics.MeasureString() я пришел с кодом:

public static SizeF GetAvgCharSizeF(Graphics g, Font font) 
{ 
    String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 

    SizeF textSize = g.MeasureString(s, font); 

    float baseUnitX = (textSize.Width/s.Length); 
    float baseUnitY = textSize.Height; 

    return new SizeF(baseUnitX, baseUnitY); 
} 

Unfortunatly значения не совпадают с известными, принятые, истинные ценности:

  • Tahoma 8pt, 96dpi: 14x6 точек (14.21x6.09 точек)
  • Tahoma 9пт, 96dpi: 16x7 точек (15.98x6.85 точек)
  • Segoe UI 9пт, 96dpi: 17x7 точек (17.46x6.91 ПВ)

Средние значения ширины символов оказываются в порядке, но высота символов слишком велики, примерно на 13%. Я предполагаю, что дополнительная высота обусловлена ​​различием в классификации высоты, которая была изменена, чтобы включать восходящие и спусковые устройства. Если измерительная строка мерил слишком высокая, я попытался изменить его от:

String s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 

в

String s = "acemnorsuvwxyz"; 

, думая, что теперь строка не так высока, и поэтому измеренная высота должна быть короче. Нет, он возвращает точные такие же высоты, как версия строки, которая включает в себя восходящие и десендерные (хотя средняя ширина немного больше).

Что может быть причиной этого и может получить среднюю высоту символа, что можно сделать для средней высоты текста, чтобы она соответствовала принятым значениям, возвращаемым GetTextExtent?

Примечание. Хотя стандартная практика получения средней высоты символа заключается в использовании GetTextMetrics, высота, возвращаемая GetTextExtents, возвращает то же значение.

+4

Вы попробовали TextRenderer.MeasureText? – 2008-12-24 03:40:29

ответ

3

Я подозреваю, что это связано с тем, что механизм отображения текста отличается в .NET. Вы можете найти различия между GDI и GDI +. Вещи также могут измениться снова для вас, если вы вызовете метод Application.SetCompatibleTextRenderingDefault(<bool>), с истинным или ложным в качестве параметра (я считаю, что значение по умолчанию истинно).

В общем, если вы рисуете с помощью API Windows, то измерьте с помощью API Windows, а если вы рисуете с .NET, измерьте с помощью .NET.

+0

Стандартные позиции и размеры управления выражаются в терминах «средний символ с и высота». Если средняя ширина и высота изменяются в зависимости от того, кто измеряет, вы теряете стандарт. – 2008-10-15 14:19:37