Как динамически изменить размер шрифта, чтобы объем текста соответствовал размеру прямоугольника?

avatar
Cavarne
1 июля 2021 в 19:20
119
1
1

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

enter image description here

Вопрос в том, как динамически уменьшать шрифт, когда объем текста превышает размер прямоугольника?
Код:

private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
    using (Font font1 = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Point))
    {
        RectangleF rectF1 = new RectangleF(30, 30, 780, 200);
        e.Graphics.DrawString(richTextBox2.Text, font1, Brushes.Black, rectF1);
        e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(rectF1));
    }
}
Источник
Xerillio
1 июля 2021 в 19:23
0

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

GSerg
1 июля 2021 в 19:25
1

Отвечает ли это на ваш вопрос? Автоматическое изменение размера шрифта по размеру прямоугольника

Cavarne
1 июля 2021 в 19:25
0

Потому что я хочу сделать так, чтобы шрифт стал меньше. И я хочу распечатать документ после того, как я записал данные в RichTextBox, и с полосами прокрутки это не сработает.

Cavarne
1 июля 2021 в 19:26
0

Это не тот ответ, который я пробовал, но код делает прямоугольник подходящим для строки, и я хочу, чтобы все было наоборот.

GSerg
1 июля 2021 в 19:29
0

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

Johnny Mopp
1 июля 2021 в 19:30
0

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

Jimi
1 июля 2021 в 19:33
0

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

GSerg
1 июля 2021 в 19:38
0

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

Jimi
1 июля 2021 в 19:59
0

@GSerg Это зависит от того, как это применяется. Например, это вычисляет масштаб текста на основе размера текста Control: Scale Label в соответствии с размером Label. -- Я предполагаю, что в OP есть небольшое количество текста, чтобы поместиться в границы этого прямоугольника, это точно не может быть неопределенное количество текста, поскольку размер шрифта может стать настолько маленьким, что текст будет полностью нечитаемым. Так что, если применить простую шкалу к тексту, который едва помещается, вы не заметите этого, даже если расчет будет очень простым. В противном случае расчет несколько усложняется.

Cavarne
1 июля 2021 в 21:26
0

Но как переписать этот код, чтобы размер прямоугольника не менялся?

Ответы (1)

avatar
Johnny Mopp
2 июля 2021 в 12:27
0

Как я упоминал в комментариях, один из вариантов — просто продолжать пробовать все меньшие и меньшие шрифты, пока не найдете подходящий. Это не очень эффективно, но если делать это не часто, то работает.

// Try to find a font size that fits
int GetFontSize(string text, Graphics graphics, RectangleF rect, string fontName, int maxFontSize=32)
{
    while (maxFontSize > 6)
    {
        using (var font = new Font(fontName, maxFontSize))
        {
            var calc = graphics.MeasureString(text, font, (int)rect.Width, StringFormat.GenericTypographic);
            if (calc.Height <= rect.Height)
            {
                break;
            }
        }
        maxFontSize -= 1;
    }
    return maxFontSize;
}

Пример использования:

// Helper function to draw a string and rectangle
void DrawText(Graphics graphics, string text, RectangleF rect, string fontName="Arial")
{
    int fontSize = GetFontSize(text, graphics, rect, fontName);
    using(var brush = new SolidBrush(Color.Black))
    using(var pen = new Pen(brush))
    using (var font = new Font(fontName, fontSize))
    {
        graphics.DrawString(text, font, brush, rect, StringFormat.GenericTypographic);
        graphics.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
    }
}

// Test cases
private void Form1_Paint(object sender, PaintEventArgs e)
{
    string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
    RectangleF[] testCases = {
        new RectangleF(10, 10, 300, 100),
        new RectangleF(10, 120, 600, 200),
        new RectangleF(10, 330, 60, 400),
        new RectangleF(10, 330, 60, 400),
        new RectangleF(80, 330, 400, 60)
    };
    foreach (var r in testCases) {
        DrawText(e.Graphics, text, r);
    }
}

Вывод примера кода: enter image description here

Cavarne
22 июля 2021 в 18:46
0

Это то, что я искал большое спасибо вам!!!!