Заполнить текст внутри прямоугольника - PullRequest
12 голосов
/ 11 ноября 2010

Я использую GDI + для рисования строки на графическом объекте.

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

Есть ли способ сделать это, кроме использования TextRenderer.MeasureString () в цикле, пока не будет возвращен желаемый размер?

что-то вроде:

DrawScaledString(Graphics g, string myString, Rectangle rect)

Ответы [ 2 ]

8 голосов
/ 11 ноября 2010

Вы можете использовать ScaleTransform

string testString = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse et nisl adipiscing nisl adipiscing ultricies in ac lacus.
Vivamus malesuada eros at est egestas varius tincidunt libero porttitor.
Pellentesque sollicitudin egestas augue, ac commodo felis ultricies sit amet.";

Bitmap bmp = new Bitmap(300, 300);
using (var graphics = Graphics.FromImage(bmp))
{
    graphics.FillRectangle(Brushes.White, graphics.ClipBounds);
    var stringSize = graphics.MeasureString(testString, this.Font);
    var scale = bmp.Width / stringSize.Width;
    if (scale < 1)
    {
        graphics.ScaleTransform(scale, scale);
    }
    graphics.DrawString(testString, this.Font, Brushes.Black, new PointF());
}
bmp.Save("lorem.png", System.Drawing.Imaging.ImageFormat.Png);

Но вы можете получить некоторые эффекты псевдонима.

alt text

Редактировать:

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

5 голосов
/ 23 февраля 2012

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

public class RenderInBox
{
    Rectangle box; 
    Form root;
    Font font;
    string text;

    StringFormat format;

    public RenderInBox(Rectangle box, Form root, string text, string fontFamily, int startFontSize = 150)
    {
        this.root = root;
        this.box = box;
        this.text = text;

        Graphics graphics = root.CreateGraphics();

        bool fits = false;
        int size = startFontSize;
        do
        {
            if (font != null)
                font.Dispose();

            font = new Font(fontFamily, size, FontStyle.Regular, GraphicsUnit.Pixel);

            SizeF stringSize = graphics.MeasureString(text, font, box.Width, format);

            fits = (stringSize.Height < box.Height);
            size -= 2;
        } while (!fits);

        graphics.Dispose();

        format = new StringFormat()
        {
            Alignment = StringAlignment.Center,
            LineAlignment = StringAlignment.Center
        };

    }

    public void Render(Graphics graphics, Brush brush)
    {
        graphics.DrawString(text, font, brush, box, format);
    }
}

Чтобы использовать его, просто создайте новый класс и вызовите Render (). Обратите внимание, что это специально написано для рендеринга в форму.

var titleBox = new RenderInBox(new Rectangle(10, 10, 400, 100), thisForm, "This is my text it may be quite long", "Tahoma", 200);
titleBox.Render(myGraphics, Brushes.White);

Вы должны создать объект RenderInBox заранее из-за его интенсивного характера создания. Поэтому он не подходит для любых нужд.

...