Los comentarios anteriores son precisos-- TextRenderer.DrawText
, al ser GDI, tiene soporte limitado para la transformación de coordenadas dada su dependencia de resolución. Como habrás notado, la traducción de coordenadas es compatible, pero la escala no lo es (ni tampoco la rotación de coordenadas).
La solución que hemos utilizado (y el único recurso que hemos sido capaces de encontrar en internet) es escalar manualmente los Font
Rectangle
y objetos para reflejar la escala aplicada por Matrix.Scale(float, float)
conjuntamente 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));
}
Aquí está toda la forma de la prueba:
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));
}
}
es probable que no va a pasar. La diferencia es que 'Graphics.DrawString' utiliza GDI + para dibujar el texto, mientras que' TextRenderer.DrawText' utiliza GDI (nota, no más). Es por eso que este último produce un resultado que se parece a los controles nativos, porque dibujan con GDI. Pero GDI no cuenta con el respaldo suficiente para las transformaciones visuales de pelusa, y una pequeña parte está encapsulada en la clase 'Graphics', que es un contenedor .NET para GDI +. –
@CodyGray: esto es casi una respuesta. Gracias. –
No lo publiqué como respuesta porque no estoy seguro de que tales transformaciones sean imposibles con 'TextRenderer.DrawText'. Simplemente no van a suceder de la manera en que intentas alcanzarlos. Necesitarás usar otro mecanismo. Creo que hay algunas sobrecargas de la función 'DrawText' que aceptan banderas de formato que pueden ser útiles. –