Графика. MeasureCharacterRanges, дающий неправильные вычисления размера

Я пытаюсь представить некоторый текст в определенной части изображения в приложении Веб-форм. Текст будет вводимым пользователем, таким образом, я захочу варьироваться размер шрифта, чтобы удостовериться, что он соответствует в ограничительной рамке.

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

Я выполняю вычисление размера следующим образом:

StringFormat fmt = new StringFormat();
fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Near;
fmt.FormatFlags = StringFormatFlags.NoClip;
fmt.Trimming = StringTrimming.None;

int size = __startingSize;
Font font = __fonts.GetFontBySize(size);

while (GetStringBounds(text, font, fmt).IsLargerThan(__textBoundingBox))
{
    context.Trace.Write("MyHandler.ProcessRequest",
        "Decrementing font size to " + size + ", as size is "
        + GetStringBounds(text, font, fmt).Size()
        + " and limit is " + __textBoundingBox.Size());

    size--;

    if (size < __minimumSize)
    {
        break;
    }

    font = __fonts.GetFontBySize(size);
}

context.Trace.Write("MyHandler.ProcessRequest", "Writing " + text + " in "
    + font.FontFamily.Name + " at " + font.SizeInPoints + "pt, size is "
    + GetStringBounds(text, font, fmt).Size()
    + " and limit is " + __textBoundingBox.Size());

Я затем использую следующую строку для рендеринга текста на изображение, которое я вытягиваю от файловой системы:

g.DrawString(text, font, __brush, __textBoundingBox, fmt);

где:

  • __fonts a PrivateFontCollection,
  • PrivateFontCollection.GetFontBySize дополнительный метод, который возвращает a FontFamily
  • RectangleF __textBoundingBox = new RectangleF(150, 110, 212, 64);
  • int __minimumSize = 8;
  • int __startingSize = 48;
  • Brush __brush = Brushes.White;
  • int size начинается в 48 и постепенно уменьшается в том цикле
  • Graphics g имеет SmoothingMode.AntiAlias и TextRenderingHint.AntiAlias набор
  • context a System.Web.HttpContext (это - выборка от ProcessRequest метод IHttpHandler)

Другие методы:

private static RectangleF GetStringBounds(string text, Font font,
    StringFormat fmt)  
{  
    CharacterRange[] range = { new CharacterRange(0, text.Length) };  
    StringFormat myFormat = fmt.Clone() as StringFormat;  
    myFormat.SetMeasurableCharacterRanges(range);  

    using (Graphics g = Graphics.FromImage(new Bitmap(
       (int) __textBoundingBox.Width - 1,
       (int) __textBoundingBox.Height - 1)))
    {
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

        Region[] regions = g.MeasureCharacterRanges(text, font,
            __textBoundingBox, myFormat);
        return regions[0].GetBounds(g);
    }  
}

public static string Size(this RectangleF rect)
{
    return rect.Width + "×" + rect.Height;
}

public static bool IsLargerThan(this RectangleF a, RectangleF b)
{
    return (a.Width > b.Width) || (a.Height > b.Height);
}

Теперь у меня есть две проблемы.

Во-первых, текст иногда настаивает на том, чтобы переноситься путем вставки разрыва строки в слове, когда он просто не должен соответствовать и заставляет цикл с условием продолжения постепенно уменьшаться снова. Я не вижу отчего получается, что Graphics.MeasureCharacterRanges думает, что это соответствует в поле, когда это не должен быть переход на новую строку в слове. Это поведение показано независимо от используемого набора символов (я получаю его в словах Латинского алфавита, а также других частях Диапазона Unicode, как кириллица, греческий язык, грузинский язык и армянский язык). Есть ли некоторая установка, которую я должен использовать для силы Graphics.MeasureCharacterRanges только быть переходом на новую строку в пробельных символах (или дефисы)? Эта первая проблема совпадает с сообщением 2499067.

Во-вторых, в увеличении масштаба до нового размера изображения и размера шрифта, Graphics.MeasureCharacterRanges дает мне высоты, которые дико выключены. RectangleF Я тяну в, соответствует визуально очевидной области изображения, таким образом, я могу легко видеть, когда текст постепенно уменьшается больше, чем необходимо. Все же, когда я передаю его некоторый текст, GetBounds вызов дает мне высоту, которая является почти двойной, что он на самом деле берет.

Используя метод проб и ошибок для установки __minimumSize для принуждения выхода цикл с условием продолжения я вижу, что текст на 24 ПБ соответствует в ограничительной рамке, все же Graphics.MeasureCharacterRanges сообщает, что высота того текста, когда-то представленного к изображению, составляет 122 пкс (когда ограничительная рамка 64 пкс высотой, и это соответствует в том поле). Действительно, не вызывая вопрос, цикл с условием продолжения выполняет итерации к 18 ПБ, в который точка Graphics.MeasureCharacterRanges возвращает значение, которое соответствует.

Выборка журнала трассировки следующие:

Постепенное уменьшение размера шрифта к 24, как размер 193×122 и предел, 212×64
Постепенное уменьшение размера шрифта к 23, как размер 191×117 и предел, 212×64
Постепенное уменьшение размера шрифта к 22, как размер 200×75 и предел, 212×64
Постепенное уменьшение размера шрифта к 21, как размер 192×71 и предел, 212×64
Постепенное уменьшение размера шрифта к 20, как размер 198×68 и предел, 212×64
Постепенное уменьшение размера шрифта к 19, как размер 185×65 и предел, 212×64
Пишущий VENNEGOOR HESSELINK Черного как DIN цвета на уровне 18 ПБ, размер 178×61, и предел 212×64

Итак, почему Graphics.MeasureCharacterRanges предоставление мне неправильный результат? Я мог понять это являющийся, скажем, высотой строки шрифта, если бы цикл остановил приблизительно 21 ПБ (который визуально соответствовал бы, если я снимок экрана результаты и измеряю его в Краске. Сеть), но это идет намного далее, чем это должно делать, потому что, откровенно говоря, это возвращает неправильные проклятые результаты.

6
задан Drew Noakes 12 July 2018 в 22:10
поделиться

1 ответ

Не могли бы вы удалить следующую строку?

fmt.FormatFlags = StringFormatFlags.NoClip;

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

Это лучшее, что я могу придумать для этого: (

0
ответ дан 17 December 2019 в 20:30
поделиться
Другие вопросы по тегам:

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