Files
lserp_cs_6.0/插件库/Lskj.Util/GraphicsText.cs
T
cyf ab56a9bcf7 基线 SVN r240
SVN-Revision: r240
2025-02-06 06:46:06 +00:00

264 lines
9.5 KiB
C#

/******************************
* 说明:绘制文本旋转类
* 创建人:龚宇超
* 创建日期: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
{
/// <summary>
/// 绘制文本旋转
/// </summary>
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" };
/// <summary>
/// GDI+ 绘图图面
/// </summary>
public Graphics Graphics;
/// <summary>
/// <para>说明:绘制文本旋转</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-07-24 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="s">文本</param>
/// <param name="font">字体</param>
/// <param name="brush">填充</param>
/// <param name="layoutRectangle">局部矩形</param>
/// <param name="format">布局方式</param>
/// <param name="angle">角度</param>
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);
}
/// <summary>
/// <para>说明:绘制文本旋转</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-07-24 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="s">文本</param>
/// <param name="font">字体</param>
/// <param name="brush">填充</param>
/// <param name="point">绘制坐标</param>
/// <param name="format">布局方式</param>
/// <param name="angle">角度</param>
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;
}
/// <summary>
/// <para>说明:计算文本宽度</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-04-10 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="graphics">The graphics.</param>
/// <param name="text">The text.</param>
/// <returns>System.Int32.</returns>
public static int GetTextWidth(string text)
{
if (string.IsNullOrEmpty(text)) return 0;
return CutStrBytesLen(text) * 6 + GetWords(text) + 25;
}
/// <summary>
/// 计算文本宽度
/// </summary>
/// <para>创建人:tdx</para>
/// <para>创建日期:2024-04-09 </para>
/// <param name="control"></param>
/// <param name="text"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 截断字符串 1个汉字长度为2 (超过则截断 拼上…)
/// </summary>
/// <param name="strInput"></param>
/// <param name="intlen"></param>
/// <returns></returns>
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;
}
/// <summary>
/// <para>说明:大小转换</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-07-24 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="size">The size.</param>
/// <param name="angle">The angle.</param>
/// <returns>SizeF.</returns>
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;
}
/// <summary>
/// <para>说明:获取控件Point</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-04-10 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="size">The size.</param>
/// <param name="layoutRectangle">The layout rectangle.</param>
/// <param name="format">The format.</param>
/// <returns>PointF.</returns>
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;
}
}
}