/****************************** * 说明:绘制文本旋转类 * 创建人:龚宇超 * 创建日期:2017-07-24 * 修改人: * 修改日期: * 修改备注: * 版本:1.0.0.0 ******************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.Drawing.Drawing2D; using System.Text.RegularExpressions; namespace Lskj.Util { /// /// 绘制文本旋转 /// public class GraphicsText { private static string[] words = { "A", "B", "C", "D", "E", "F", "G", " H", " I", " J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; /// /// GDI+ 绘图图面 /// public Graphics Graphics; /// /// 说明:绘制文本旋转 /// 创建人:龚宇超 /// 创建日期:2017-07-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// 文本 /// 字体 /// 填充 /// 局部矩形 /// 布局方式 /// 角度 public void DrawString(string s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format, float angle) { // 求取字符串大小 SizeF size = Graphics.MeasureString(s, font); // 根据旋转角度,求取旋转后字符串大小 SizeF sizeRotate = ConvertSize(size, angle); // 根据旋转后尺寸、布局矩形、布局方式计算文本旋转点 PointF rotatePt = GetRotatePoint(sizeRotate, layoutRectangle, format); // 重设布局方式都为Center StringFormat newFormat = new StringFormat(format); newFormat.Alignment = StringAlignment.Center; newFormat.LineAlignment = StringAlignment.Center; // 绘制旋转后文本 DrawString(s, font, brush, rotatePt, newFormat, angle); } /// /// 说明:绘制文本旋转 /// 创建人:龚宇超 /// 创建日期:2017-07-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// 文本 /// 字体 /// 填充 /// 绘制坐标 /// 布局方式 /// 角度 public void DrawString(string s, Font font, Brush brush, PointF point, StringFormat format, float angle) { // Save the matrix Matrix mtxSave = Graphics.Transform; Matrix mtxRotate = Graphics.Transform; mtxRotate.RotateAt(angle, point); Graphics.Transform = mtxRotate; Graphics.DrawString(s, font, brush, point, format); // Reset the matrix Graphics.Transform = mtxSave; } /// /// 说明:计算文本宽度 /// 创建人:龚宇超 /// 创建日期:2018-04-10 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The graphics. /// The text. /// System.Int32. public static int GetTextWidth(string text) { if (string.IsNullOrEmpty(text)) return 0; return CutStrBytesLen(text) * 6 + GetWords(text) + 25; } /// /// 计算文本宽度 /// /// 创建人:tdx /// 创建日期:2024-04-09 /// /// /// public static int GetTextWidth(System.Windows.Forms.Control control, string text) { Graphics g = control.CreateGraphics(); SizeF sizeF = g.MeasureString(text, control.Font); return (int)sizeF.Width; } private static int GetWords(string source) { int len = 0; Regex reg = new Regex("[A-Z]"); MatchCollection mcs = reg.Matches(source); foreach (Match item in mcs) { if (words.Contains(item.Value)) len += 2; } return len; } /// /// 截断字符串 1个汉字长度为2 (超过则截断 拼上…) /// /// /// /// private static int CutStrBytesLen(string strInput)//截取字符串 { strInput = strInput.Trim(); ASCIIEncoding ascii = new ASCIIEncoding(); int intLength = 0; byte[] s = ascii.GetBytes(strInput); for (int i = 0; i < s.Length; i++) { //中文字符转化ASCII吗后不能识别全部都变成63,才回出现这样结果,但是如何碰上日文就麻烦了,全半角假名全部都是63无法识别!所以该方法谨慎使用! if ((int)s[i] == 63) { intLength += 2; } else { intLength += 1; } } return intLength; } /// /// 说明:大小转换 /// 创建人:龚宇超 /// 创建日期:2017-07-24 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The size. /// The angle. /// SizeF. private SizeF ConvertSize(SizeF size, float angle) { Matrix matrix = new Matrix(); matrix.Rotate(angle); // 旋转矩形四个顶点 PointF[] pts = new PointF[4]; pts[0].X = -size.Width / 2f; pts[0].Y = -size.Height / 2f; pts[1].X = -size.Width / 2f; pts[1].Y = size.Height / 2f; pts[2].X = size.Width / 2f; pts[2].Y = size.Height / 2f; pts[3].X = size.Width / 2f; pts[3].Y = -size.Height / 2f; matrix.TransformPoints(pts); // 求取四个顶点的包围盒 float left = float.MaxValue; float right = float.MinValue; float top = float.MaxValue; float bottom = float.MinValue; foreach (PointF pt in pts) { // 求取并集 if (pt.X < left) left = pt.X; if (pt.X > right) right = pt.X; if (pt.Y < top) top = pt.Y; if (pt.Y > bottom) bottom = pt.Y; } SizeF result = new SizeF(right - left, bottom - top); return result; } /// /// 说明:获取控件Point /// 创建人:龚宇超 /// 创建日期:2018-04-10 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The size. /// The layout rectangle. /// The format. /// PointF. private PointF GetRotatePoint(SizeF size, RectangleF layoutRectangle, StringFormat format) { PointF pt = new PointF(); switch (format.Alignment) { case StringAlignment.Near: pt.X = layoutRectangle.Left + size.Width / 2f; break; case StringAlignment.Center: pt.X = (layoutRectangle.Left + layoutRectangle.Right) / 2f; break; case StringAlignment.Far: pt.X = layoutRectangle.Right - size.Width / 2f; break; default: break; } switch (format.LineAlignment) { case StringAlignment.Near: pt.Y = layoutRectangle.Top + size.Height / 2f; break; case StringAlignment.Center: pt.Y = (layoutRectangle.Top + layoutRectangle.Bottom) / 2f; break; case StringAlignment.Far: pt.Y = layoutRectangle.Bottom - size.Height / 2f; break; default: break; } return pt; } } }