using System; using System.Drawing; using System.Drawing.Drawing2D; namespace ZeroLevel.Services.Drawing { public static class TextPainter { #region Drawing text along lines public static void DrawOnSegment(Graphics gr, Font font, PointF start_point, PointF end_point, string txt, bool text_above_segment) { int start_ch = 0; // gr.DrawLine(Pens.Green, start_point, end_point); DrawTextOnSegment(gr, Brushes.Black, font, txt, ref start_ch, ref start_point, end_point, text_above_segment); } // Draw some text along a line segment. // Leave char_num pointing to the next character to be drawn. // Leave start_point holding the last point used. private static void DrawTextOnSegment(Graphics gr, Brush brush, Font font, string txt, ref int first_ch, ref PointF start_point, PointF end_point, bool text_above_segment) { float dx = end_point.X - start_point.X; float dy = end_point.Y - start_point.Y; float dist = (float)Math.Sqrt(dx * dx + dy * dy); dx /= dist; dy /= dist; // See how many characters will fit. int last_ch = first_ch; while (last_ch < txt.Length) { string test_string = txt.Substring(first_ch, last_ch - first_ch + 1); if (gr.MeasureString(test_string, font).Width > dist) { // This is one too many characters. last_ch--; break; } last_ch++; } if (last_ch < first_ch) return; if (last_ch >= txt.Length) last_ch = txt.Length - 1; string chars_that_fit = txt.Substring(first_ch, last_ch - first_ch + 1); // Rotate and translate to position the characters. GraphicsState state = gr.Save(); if (text_above_segment) { gr.TranslateTransform(0, -gr.MeasureString(chars_that_fit, font).Height, MatrixOrder.Append); } float angle = (float)(180 * Math.Atan2(dy, dx) / Math.PI); if (float.IsNaN(angle)) angle = 0; gr.RotateTransform(angle, MatrixOrder.Append); gr.TranslateTransform(start_point.X, start_point.Y, MatrixOrder.Append); // Draw the characters that fit. gr.DrawString(chars_that_fit, font, brush, 0, 0); // Restore the saved state. gr.Restore(state); // Update first_ch and start_point. first_ch = last_ch + 1; float text_width = gr.MeasureString(chars_that_fit, font).Width; start_point = new PointF( start_point.X + dx * text_width, start_point.Y + dy * text_width); } #endregion } }