概述
在 GDI+ 中使文字沿着圆周进行排列,有两种实现方法。
使用基本变换方法
①.概述
拆分字符串中的每个文字逐个进行输出,计算出每个文字输出的起始角度,然后分别进行平移变换和旋转变换后输出文字。
②.代码示例
void DemoGDI::DrawUser(HDC hdc)
{
Graphics graphics(hdc);//构造 Graphics 对象
Font font(L"宋体", 20, FontStyleRegular, UnitPixel);
SolidBrush solidBrush(Color::Blue);
StringFormat stringFormat;
stringFormat.SetLineAlignment(StringAlignmentCenter);
PointF cp(200,200);
Pen m_pen(Color::Black);
graphics.DrawEllipse(&m_pen, 50, 50, 300, 300);//圆周
graphics.TranslateTransform(cp.X, cp.Y); //平移坐标原点
QString m_text = "GDI+弧形文字绘制示例";
float dStepAngle = 20.0f / 150.0f;//每个文字对应的角度:弧长/半径
int wCount = m_text.toStdWString().size();
for (int i = 0; i < wCount; i++)
{
float dAngle = (i - wCount / 2 + 0.5)*dStepAngle;//与正北方向偏离
float rAngle = 270 + qRadiansToDegrees(dAngle);//每个文字对应的起始角度
float a = qDegreesToRadians(rAngle);
graphics.TranslateTransform(150 * qCos(a), 150 * qSin(a));//平移坐标原点
graphics.RotateTransform(REAL(rAngle + 90)); // 旋转至切线方向
graphics.DrawString(m_text.toStdWString().c_str()+i, 1, &font, PointF(-10.0f, -10.0f), &stringFormat, &solidBrush);//输出文字
graphics.RotateTransform(REAL(-(rAngle + 90))); // 还原
graphics.TranslateTransform(-150 * qCos(a), -150 * qSin(a));
}
}
使用路径变换方法
①.概述
先获取路径中的点信息,然后变换点的坐标后创建新的路径,用新的路径绘制文本。
②.代码示例
void DemoGDI::DrawUser(HDC hdc)
{
Graphics graphics(hdc);//构造 Graphics 对象
SolidBrush solidBrush(Color::Blue);
PointF cp(200,200);
Pen m_pen(Color::Black);
graphics.DrawEllipse(&m_pen, 50, 50, 300, 300);//圆周
graphics.TranslateTransform(cp.X, cp.Y); //平移坐标原点
GraphicsPath path; //定义路径对象
path.AddString(L"GDI+弧形文字绘制示例", -1,&FontFamily(L"黑体"), FontStyleRegular, 25, Point(0, 0), NULL);
RectF boundRect;
path.GetBounds(&boundRect);//获取外接矩形
Matrix M; //定义单位矩阵
M.Translate(-(boundRect.X + boundRect.Width / 2),-( boundRect.Y + boundRect.Height));//平移原点到路径的底部中心
path.Transform(&M); //更改路径的中心点
int n = path.GetPointCount(); // 获取路径中的点数
PointF *points = new PointF[n]; // 动态创建点数组
path.GetPathPoints(points, n); // 获取路径的点数组
BYTE *types = new BYTE[n]; // 动态创建类型数组
path.GetPathTypes(types, n); // 获取路径类型数组
for (int i = 0; i < n; i++) //根据路径点到中心的距离,按比例修改点的 y 值
{
points[i].Y -= sqrt(150*150 - points[i].X*points[i].X);
}
GraphicsPath newPath(points, types, n); //用新的路径点构造新路径
graphics.FillPath(&SolidBrush(Color::Green), &newPath);//填充路径
}