Почему TextRenderer.MeasureText неправильно измеряет текст, используя большие шрифты в C #? - PullRequest
5 голосов
/ 29 декабря 2010

Что я делаю, так это получаю размер строки в пикселях и преобразую ее в сотые доли дюйма (т.е. пиксели / DPI = дюймы, дюймы * 100 = сотые доли дюйма). Вот мой код:

private static SizeF TextSize(string text, Font txtFnt)
{
    SizeF txtSize = new SizeF();

    // The size returned is 'Size(int width, int height)' where width and height
    // are the dimensions of the string in pixels
    Size s = System.Windows.Forms.TextRenderer.MeasureText(text, txtFnt);

    // Value based on normal DPI settings of 96
    txtSize.Width = (float)Math.Ceiling((float)s.Width / 96f * 100f); 
    txtSize.Height = (float)Math.Ceiling((float)s.Height / 96f * 100f);

    return txtSize;
}

Теперь, используя шрифт Arial, все это прекрасно работает для шрифтов меньше 12, но после этого символы начинают обрезаться, потому что вычисленный размер меньше фактического размера. Я знаю, что мои настройки DPI установлены на 96. Все мои шрифты определены одинаково с изменением размера шрифта:

Font myFont = new Font("Arial", <font size>, FontStyle.Regular, GraphicsUnit.Point);

Я считаю, что мне нужно использовать GraphicsUnit.Point из-за пользовательского элемента управления, к которому я рисую строки, но имеет ли значение GraphicsUnit?

Функция MeasureText даже работает правильно или происходит что-то еще?

EDIT

Я рисую для пользовательского элемента управления предварительным просмотром печати. Единицами управления предварительным просмотром являются «Дюймы / 100» (отсюда и конверсия). Я считаю, что текст, изображения и т. Д. Нарисованы с помощью графического объекта «Принтер», но я не совсем уверен.

Ответы [ 3 ]

3 голосов
/ 29 декабря 2010

Давным-давно я столкнулся с подобной проблемой, особенно измеряя текст INSIDE текстовое поле.Суть дела такова: есть два основных способа рисования текста.Win32 API и System.Drawing.Если вы попытаетесь измерить текст внутри текстового поля, он будет нарисован с использованием Win32 API, и вам также потребуется измерить его с помощью Win32 API.Если вы измеряете текст, нарисованный с помощью System.Drawing, то ваши измерения с использованием .net будут совпадать.

По сути, текстовое поле Forms использует Win32 API для компоновки и рисования, а измерения также должны исходить из Win32.

Вы не сказали, что конкретно вы измеряли и где, так что этот ответ может даже не относиться.

0 голосов
/ 10 июня 2011

Подсказка шрифта.

Подсказки шрифтов, которые использует Windows, означают, что они могут не соответствовать размеру, указанному шрифтом.

0 голосов
/ 10 июня 2011

Параметры имеют значение, и чем больше шрифт, тем больше влияние.Вот настройки, которые лучше всего сработали для нас - ваш пробег может отличаться.(Код странный, потому что мы используем это в J #):

private static System.Drawing.StringFormat createStringFormat()
{

    System.Drawing.StringFormat fmt = new System.Drawing.StringFormat (System.Drawing.StringFormat.get_GenericTypographic());
    fmt.set_Trimming(System.Drawing.StringTrimming.None);
    fmt.set_FormatFlags(System.Drawing.StringFormatFlags.MeasureTrailingSpaces | System.Drawing.StringFormatFlags.NoWrap);
    return fmt;
}
...