This code will give you an idea:
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); }
The following is a method for measuring text rotary bounds using GraphicsPath. The logic is simple, GraphicsPath converts the text to a list of points, and then calculates a rectangle of borders.
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(); }
Test code:
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); }