2012-01-13 5 views
6

Tôi đang sử dụng tỷ lệ và chuyển đổi đối tượng đồ họa của mình khi vẽ điều khiển tùy chỉnh để áp dụng thu phóng và cuộn. Tôi sử dụng như sau:Cách áp dụng tỷ lệ Đồ họa và dịch sang TextRenderer

  Matrix mx = new Matrix(); 
      mx.Scale(mZoomFactor, mZoomFactor); 
      mx.Translate(-clip.X + mGraphicsOffsetx, -clip.Y + mGraphicsOffsety); 

      e.Graphics.Clip = new Region(this.Bounds); 
      e.Graphics.Transform = mx; 

Sau đó, khi tôi vẽ chuỗi của tôi sử dụng:

Graphics g = ... 
g.DrawString(...) 

Các scalling và biến đổi được áp dụng một cách chính xác để các dây, họ đang thu nhỏ và vân vân.

Tuy nhiên nếu tôi sử dụng những điều sau đây để vẽ chuỗi của tôi:

TextRenderer.DrawText(...) 

Văn bản không quy mô một cách chính xác và chuyển đổi.

Bạn có biết cách áp dụng các khái niệm này cho TextRenderer không?

+2

Nó có lẽ sẽ không xảy ra. Sự khác biệt là 'Graphics.DrawString' sử dụng GDI + để vẽ văn bản, trong khi' TextRenderer.DrawText' sử dụng GDI (lưu ý, không cộng). Đó là lý do tại sao sau này tạo ra đầu ra trông giống như các điều khiển gốc, vì chúng vẽ bằng GDI. Nhưng GDI không có sự hỗ trợ khá phong phú cho các fluff trực quan như các phép biến đổi, và phần nhỏ của nó được đóng gói trong lớp 'Graphics', là một trình bao bọc .NET cho GDI +. –

+0

@CodyGray: Đây gần như là một câu trả lời. Cảm ơn. –

+0

Tôi đã không đăng nó như là một câu trả lời bởi vì tôi không chắc chắn rằng biến đổi như vậy là không thể với 'TextRenderer.DrawText'. Chúng sẽ không xảy ra theo cách mà bạn đang cố gắng đạt được chúng. Bạn sẽ cần phải sử dụng một cơ chế khác. Tôi tin rằng có một số tình trạng quá tải của chức năng 'DrawText' chấp nhận các cờ định dạng có thể hữu ích. –

Trả lời

6

Các nhận xét ở trên là chính xác - TextRenderer.DrawText, là GDI, đã hỗ trợ giới hạn cho chuyển đổi tọa độ do phụ thuộc vào độ phân giải của nó. Như bạn đã nhận thấy, điều phối bản dịch được hỗ trợ nhưng tỷ lệ không phải là (và không xoay vòng tọa độ).

Các giải pháp chúng tôi đã sử dụng (và các tài nguyên duy nhất mà tôi đã có thể tìm thấy trên internet) là để tự mở rộng các FontRectangle đối tượng để phản ánh sự mở rộng quy mô áp dụng bởi Matrix.Scale(float, float) kết hợp với Graphics.Transform:

private Font GetScaledFont(Graphics g, Font f, float scale) 
    { 
     return new Font(f.FontFamily, 
         f.SizeInPoints * scale, 
         f.Style, 
         GraphicsUnit.Point, 
         f.GdiCharSet, 
         f.GdiVerticalFont); 
    } 

    private Rectangle GetScaledRect(Graphics g, Rectangle r, float scale) 
    { 
     return new Rectangle((int)Math.Ceiling(r.X * scale), 
          (int)Math.Ceiling(r.Y * scale), 
          (int)Math.Ceiling(r.Width * scale), 
          (int)Math.Ceiling(r.Height * scale)); 
    } 

Dưới đây là toàn bộ hình thức kiểm tra:

public partial class Form1 : Form 
{ 
    private PictureBox box = new PictureBox(); 

    public Form1() 
    { 
     InitializeComponent(); 
     this.Load += new EventHandler(Form1_Load); 
    } 

    public void Form1_Load(object sender, EventArgs e) 
    { 
     box.Dock = DockStyle.Fill; 
     box.BackColor = Color.White; 

     box.Paint += new PaintEventHandler(DrawTest); 
     this.Controls.Add(box); 
    } 

    public void DrawTest(object sender, PaintEventArgs e) 
    { 
     Graphics g = e.Graphics; 

     string text = "Test Text"; 
     float scale = 1.5F; 
     float translate = 200F; 

     var flags = TextFormatFlags.PreserveGraphicsClipping | TextFormatFlags.PreserveGraphicsTranslateTransform; 

     var mx = new Matrix(); 
     mx.Scale(scale, scale); 
     mx.Translate(translate, translate); 

     g.Clip = new Region(Bounds); 
     g.Transform = mx; 

     Size rendererPSize = Bounds.Size; 
     Font f = GetScaledFont(g, new Font("Arial", 12), scale); 
     Size rendererRSize = TextRenderer.MeasureText(g, text, f, rendererPSize, flags); 

     Rectangle rendererRect = new Rectangle(0, 0, rendererRSize.Width, rendererRSize.Height); 
     Rectangle r = GetScaledRect(g, rendererRect, scale); 

     TextRenderer.DrawText(g, text, f, realRect, Color.Black, flags); 
    } 

    private Font GetScaledFont(Graphics g, Font f, float scale) 
    { 
     return new Font(f.FontFamily, 
         f.SizeInPoints * scale, 
         f.Style, 
         GraphicsUnit.Point, 
         f.GdiCharSet, 
         f.GdiVerticalFont); 
    } 

    private Rectangle GetScaledRect(Graphics g, Rectangle r, float scale) 
    { 
     return new Rectangle((int)Math.Ceiling(r.X * scale), 
          (int)Math.Ceiling(r.Y * scale), 
          (int)Math.Ceiling(r.Width * scale), 
          (int)Math.Ceiling(r.Height * scale)); 
    } 
}