2012-01-13 16 views
6

Sto utilizzando il ridimensionamento e la trasformazione del mio oggetto grafico quando si dipinge un controllo personalizzato, per applicare lo zoom e lo scorrimento. Io uso il seguente:Come applicare la scala grafica e tradurre in 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; 

Poi quando dipingo le mie corde usando:

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

Lo scalling e trasformazione corretta applicazione alle corde, hanno ingrandito ed in e così via.

Tuttavia se utilizzare il seguente per dipingere le mie corde:

TextRenderer.DrawText(...) 

Il testo non è correttamente ridimensionato e trasformato.

Sapete come applicare questi concetti allo TextRenderer?

+2

probabilmente non accadrà. La differenza è che 'Graphics.DrawString' usa GDI + per disegnare il testo, mentre' TextRenderer.DrawText' usa GDI (nota, non più). Ecco perché quest'ultimo produce un output che assomiglia ai controlli nativi, perché disegnano con GDI. Ma GDI non ha abbastanza il supporto per lanci visivi come le trasformazioni, e poco è incapsulato nella classe 'Graphics', che è un wrapper .NET per GDI +. –

+0

@CodyGray: questa è quasi una risposta. Grazie. –

+0

Non l'ho postato come risposta perché non sono sicuro che tali trasformazioni siano impossibili con 'TextRenderer.DrawText'. Semplicemente non succederanno nel modo in cui stai cercando di raggiungerli. Avrai bisogno di usare un altro meccanismo. Credo che ci siano alcuni sovraccarichi della funzione 'DrawText' che accettano i flag di formattazione che potrebbero essere utili. –

risposta

6

I commenti sopra sono accurati - TextRenderer.DrawText, essendo GDI, ha un supporto limitato per la trasformazione delle coordinate data la sua dipendenza dalla risoluzione. Come hai notato, la traduzione coordinata è supportata ma il ridimensionamento non lo è (e nemmeno la rotazione delle coordinate).

La soluzione che abbiamo usato (e l'unica risorsa che ho potuto trovare su internet) è quello di scalare manualmente le Font e Rectangle oggetti in modo da riflettere il ridimensionamento applicato da Matrix.Scale(float, float) in collaborazione con 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)); 
    } 

Ecco l'intera forma di test:

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