/******************************
* 说明:绘制文本旋转类
* 创建人:龚宇超
* 创建日期: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;
}
}
}