This is a follow-on to a question I asked here: WinForms: Measure Text With No Padding. The question is, given this code ...
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
DrawIt(e.Graphics);
}
private void DrawIt(Graphics graphics) {
var text = "123";
var font = new Font("Arial", 72);
// Build a path containing the text in the desired font, and get its bounds.
GraphicsPath path = new GraphicsPath();
path.AddString(text, font.FontFamily, (int)font.Style, font.Size, new Point(0, 0), StringFormat.GenericDefault);
var bounds = path.GetBounds();
// Find center of the form.
var cx = this.ClientRectangle.Left + this.ClientRectangle.Width / 2;
var cy = this.ClientRectangle.Top + this.ClientRectangle.Height / 2;
// Move it where I want it.
var xlate = new Matrix();
xlate.Translate(cx - bounds.Width / 2, cy - bounds.Height / 2);
path.Transform(xlate);
// Draw the path (and a bounding rectangle).
graphics.DrawPath(Pens.Black, path);
bounds = path.GetBounds();
graphics.DrawRectangle(Pens.Blue, bounds.Left, bounds.Top, bounds.Width, bounds.Height);
// This rectangle doesn't use the positioning from Translate but does use the same size.
graphics.DrawRectangle(Pens.Red, cx - bounds.Width / 2, cy - bounds.Height / 2, bounds.Width, bounds.Height);
}
... why don't the rectangles overlap?
Clearly, when I'm translating the path, I'm not translating by the same units that I'm later drawing them in, but I'm at a loss how to fix it. Any ideas?
You have a wrong assumption about Bounds
of the path. Since you added the string to the path, starting from point (0,0)
, you are assuming the location of the bounds of the path is (0,0)
. That's not correct.
The following illustration shows the relation between the origin that you added string, (0,0)
and bounds of the path, blue rectangle:
To fix it, after adding the string and getting its bounds, store the location of the bounds:
var p = bounds.Location;
And then after applying the transformations, draw the rectangle this way:
graphics.DrawRectangle(Pens.Red,
p.X + cx - bounds.Width / 2, p.Y + cy - bounds.Height / 2,
bounds.Width, bounds.Height);