Этот код даст вам представление:
public void DrawText(bool debug, Graphics g, string text, Font font, Brush brush, StringFormat format, float x, float y, float width, float height, float rotation)
{
float centerX = width / 2;
float centerY = height / 2;
if (debug)
{
g.FillEllipse(Brushes.Green, centerX - 5f, centerY - 5f, 10f, 10f);
}
GraphicsState gs = g.Save();
Matrix mat = new Matrix();
mat.RotateAt(rotation, new PointF(centerX, centerY), MatrixOrder.Append);
g.Transform = mat;
SizeF szf = g.MeasureString(text, font);
g.DrawString(text, font, brush, (width / 2) - (szf.Width / 2), (height / 2) - (szf.Height / 2), format);
g.Restore(gs);
}
Вот метод измерения границ повернутого текста с использованием GraphicsPath.Логика проста, GraphicsPath преобразует текст в список точек, а затем вычисляет границы прямоугольника.
public RectangleF GetRotatedTextBounds(string text, Font font, StringFormat format, float rotation, float dpiY)
{
GraphicsPath gp = new GraphicsPath();
float emSize = dpiY * font.Size / 72;
gp.AddString(text, font.FontFamily, (int)font.Style, emSize, new PointF(0, 0), format);
Matrix mat = new Matrix();
mat.Rotate(rotation, MatrixOrder.Append);
gp.Transform(mat);
return gp.GetBounds();
}
Тестовый код:
float fontSize = 25f;
float rotation = 30f;
RectangleF txBounds = GetRotatedTextBounds("TEST TEXT", new Font("Verdana", fontSize, System.Drawing.FontStyle.Bold), StringFormat.GenericDefault, rotation, 96f);
float inflateValue = 10 * (fontSize / 100f);
txBounds.Inflate(inflateValue, inflateValue);
Bitmap bmp = new System.Drawing.Bitmap((int)txBounds.Width, (int)txBounds.Height);
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.Clear(Color.White);
DrawText(true, gr, "TEST TEXT", new Font("Verdana", fontSize, System.Drawing.FontStyle.Bold), Brushes.Red, new StringFormat(System.Drawing.StringFormatFlags.DisplayFormatControl), 0, 0, txBounds.Width, txBounds.Height, rotation);
}