正如我在 cmets 中提到的,一种选择是不断尝试越来越小的字体,直到找到合适的字体。这不是超级有效,但如果不经常这样做,它会起作用。
// 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);
}
}
示例代码的输出: