2010-11-11 41 views
12

Tôi đang sử dụng GDI + để vẽ một chuỗi trên đối tượng Đồ họa.Điền văn bản bên trong hình chữ nhật

Tôi muốn chuỗi để phù hợp với bên trong một hình chữ nhật được xác định trước (mà không vi phạm bất kỳ dòng)

là có nào để làm điều này bên cạnh việc sử dụng TextRenderer.MeasureString() trong một vòng lặp cho đến kích thước mong muốn được quay trở lại?

cái gì đó như:

DrawScaledString(Graphics g, string myString, Rectangle rect) 
+0

Bạn có thể áp dụng biến đổi ma trận, nhưng đã nhiều năm kể từ lần cuối tôi chạm vào đó. – leppie

+0

Không phải là một chút chi phí? – Nissim

Trả lời

8

Bạn có thể sử dụng 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); 

Nhưng bạn có thể nhận được một số tác dụng bí danh.

alt text

Edit:

Nhưng nếu bạn muốn thay đổi kích thước phông chữ thay vào đó tôi đoán bạn có thể thay đổi kích thước phông chữ với scale trong đoạn code trên thay vì sử dụng quy mô biến đổi. Hãy thử cả hai và so sánh chất lượng của kết quả.

+0

Cảm ơn người đàn ông ... Tôi đã thay đổi kích thước phông chữ theo quy mô, thực hiện điều chỉnh nhỏ và nó làm việc tuyệt vời ... – Nissim

5

Đây là một giải pháp cho vấn đề này, đó là một chút chiều sâu vì nó đòi hỏi một chút công bằng của tạo phông chữ và hủy diệt, nhưng có thể làm việc tốt hơn, tùy thuộc vào hoàn cảnh của bạn và nhu cầu:

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); 
    } 
} 

Để sử dụng một cách đơn giản tạo một lớp mới và gọi Render(). Lưu ý điều này được viết cụ thể để hiển thị biểu mẫu.

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); 

Bạn nên tạo đối tượng RenderInBox trả trước do tính chất sáng tạo chuyên sâu của nó. Do đó nó không thích hợp cho mọi nhu cầu.

+0

Tuyệt vời, chính xác những gì tôi cần! – Gromer

Các vấn đề liên quan