Как измерить пиксельную ширину цифры в данном шрифте / размер (C#)

Подсказка (использующий axfr) только работает, если NS, который Вы запрашиваете (ns1.foo.bar в Вашем примере) настроен для разрешения запросов AXFR от IP, Вы используете; это маловероятно, если Ваш IP не настроен как вторичное устройство для рассматриваемого домена.

В основном, нет никакого простого способа сделать это, если Нельзя использовать axfr. Это является намеренным, таким образом, единственный путь вокруг этого был бы через грубую силу (т.е. dig a.some_domain.com, dig b.some_domain.com...), который я не могу рекомендовать, поскольку это могло быть просмотрено как атака "отказ в обслуживании".

9
задан Community 23 May 2017 в 12:10
поделиться

5 ответов

Сначала позвольте мне сказать, что код, о котором я говорю to show выглядит как ужасный взлом, и я не представляю его как решение. Скорее, я надеюсь, что он откроет немного больше о поведении MeasureText, что может привести вас к окончательному решению.

Я внес небольшие изменения в ваш код. Я измеряю длину двух символов подчеркивания. Затем в теле цикла for я измеряю желаемый символ с помощью подчеркиваний с обеих сторон и вычитаю длину только двух символов подчеркивания. Для тестового сценария я получаю результат 7. Основная цель этого заключалась в том, чтобы определить, учитывает ли MeasureText заполнение посимвольно или заполнение в начале / конце строки. Похоже, что это последнее. Возможно, это в сочетании с некоторыми другими полученными вами данными приведет вас к более элегантному решению.

var font = new Font("Calibri", 11.0f, FontStyle.Regular);
int underscoreWidth = TextRenderer.MeasureText("__", font).Width; 
for (var i = 0; i < 10; i++)
   {
      int charWidth = TextRenderer.MeasureText(String.Concat("_", i.ToString(), "_"), font).Width - underscoreWidth;
      Debug.WriteLine(charWidth);
   }
5
ответ дан 4 December 2019 в 11:05
поделиться

TextRenderer не всегда работает так, как вы ожидали:

Из MSDN: http://msdn.microsoft.com/en-us/library/8wafk2kt.aspx

Например, поведение TextRenderer по умолчанию заключается в добавлении отступов к ограничивающему прямоугольнику нарисованного текста для размещения выступающих глифов

У вас есть объект Graphics или объект Control? Если вы используете их, вы можете получить точные результаты, как и ожидали.

Взгляните на http://msdn.microsoft.com/en-us/library/6xe5hazb (VS.80) .aspx

5
ответ дан 4 December 2019 в 11:05
поделиться

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

        float size = 5;
        for (int ix = 0; ix < 10; ++ix) {
            var font = new Font("Calibri", size, FontStyle.Regular);
            string txt = new string('0', 100);
            SizeF sz1 = TextRenderer.MeasureText("00", font) - TextRenderer.MeasureText("0", font);
            Console.WriteLine("{0} {1:N3}", size, sz1.Width);
            size += 2;
        }

Вывод:

5 4.000
7 5.000
9 6.000
11 7.000
13 9.000
15 10.000
17 12.000
19 13.000
21 14.000
23 16.000

Это дает вам 7 пикселей, которые вы ищете. Помните, что вам придется использовать хинтинг TrueType, он может настроить форму цифры так, чтобы ее основные основы приходились на границы пикселей. Добавьте хотя бы один пиксель.

5
ответ дан 4 December 2019 в 11:05
поделиться

Измерение ширины текста может быть проблемой .. Я не знаю, почему они сделали это так запутанным ..

Вот самый точный способ, которым я смог измерить длину текста:

    protected int _MeasureDisplayStringWidth ( Graphics graphics, string text, Font font )
    {
        if ( text == "" )
            return 0;

        StringFormat format = new StringFormat ( StringFormat.GenericDefault );
        RectangleF rect = new RectangleF ( 0, 0, 1000, 1000 );
        CharacterRange[] ranges = { new CharacterRange ( 0, text.Length ) };
        Region[] regions = new Region[1];

        format.SetMeasurableCharacterRanges ( ranges );
        format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

        regions = graphics.MeasureCharacterRanges ( text, font, rect, format );
        rect = regions[0].GetBounds ( graphics );

        return (int)( rect.Right );
    }
3
ответ дан 4 December 2019 в 11:05
поделиться

Я не уверен на 100% это именно то, что вам нужно.

Но вы можете взглянуть на эту страницу Microsoft:

1
ответ дан 4 December 2019 в 11:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: