北子飞飞飞 2013-05-31 04:49 采纳率: 0%
浏览 987

怎么实现文字按指定的路径显示

在网上搜了一些代码表示看不太明白,粘贴到VS中运行老是出错哪位大神能指点指点using System;

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;




namespace Lgms.net.Drawing
{
public enum PathAlign //文字在路径方向的对齐方向
{
Left = 0, //从第一点开始排列
Center = 1, //居中排列
Right = 2 //居右排列
}
public enum TextPosition //文字排列在路径上的位置
{
OverPath = 0, //路径之上
CenterPath = 1, //路径中间,文字中心即路径经过区域
UnderPath = 2 //路径下方
}
//基础类
public class TextOnPath
{
private PathData _pathdataTOP;
private string _textTOP;
private Font _fontTOP;
private Color _pathcolorTOP = Color.Red;
private Color _colorTOP = Color.Black;
private Color _fillcolorTOP = Color.Black;
private PathAlign _pathalignTOP = PathAlign.Center;
private int _letterspacepercentageTOP = 100;
private bool _addsvg = false;
private System.Text.StringBuilder _SVG;
private int _currentPathID;
private TextPosition _textPathPosition = TextPosition.CenterPath;
public Exception LastError = null;
public bool ShowPath = true;
public TextPosition TextPathPosition
{
get { return _textPathPosition; }
set { _textPathPosition = value; }
}
public PathData PathDataTOP
{
get { return _pathdataTOP; }
set { _pathdataTOP = value; }
}
public string TextTOP
{
get { return _textTOP; }
set { _textTOP = value; }
}

public Font FontTOP
{
get { return _fontTOP; }
set { _fontTOP = value; }
}

public Color PathColorTOP
{
get { return _pathcolorTOP; }
set { _pathcolorTOP = value; }
}
public Color ColorTOP
{
get { return _colorTOP; }
set { _colorTOP = value; }
}

public Color FillColorTOP
{
get { return _fillcolorTOP; }
set { _fillcolorTOP = value; }
}

public PathAlign PathAlignTOP
{
get { return _pathalignTOP; }
set { _pathalignTOP = value; }
}

public int LetterSpacePercentage
{
get { return _letterspacepercentageTOP; }
set { _letterspacepercentageTOP = value; }
}

public Bitmap TextOnPathBitmap(PathData _pathdata, string _text, Font _font, Color _color, Color _fillcolor, int _letterspacepercentage)
{
_pathdataTOP = _pathdata;
_textTOP = _text;
_fontTOP = new Font(_font, _fontTOP.Style);
_colorTOP = _color;
_fillcolorTOP = _fillcolor;
_letterspacepercentageTOP = _letterspacepercentage;
return TextOnPathBitmap();
}
//核心方法
public Bitmap TextOnPathBitmap()
{
int i = 0;
PointF[] _TmpPoints = null;
PointF _TmpPoint = default(PointF);
PointF[] _Points = new PointF[25001];
//= oGP.PathPoints()
int _count = 0;
GraphicsPath _gp = new GraphicsPath(_pathdataTOP.Points, _pathdataTOP.Types);
_gp.FillMode = FillMode.Winding;
_gp.Flatten(null, 1);
try
{
_TmpPoint = _gp.PathPoints[0];
for (i = 0; i <= _gp.PathPoints.Length - 2; i++)
{
if (_gp.PathTypes[i + 1] == (byte)(PathPointType.Start) | (_gp.PathTypes[i] & ((byte)(PathPointType.CloseSubpath))) == (byte)(PathPointType.CloseSubpath))
{
_TmpPoints = GetLinePoints(_gp.PathPoints[i], _TmpPoint, 1);
Array.ConstrainedCopy(_TmpPoints, 0, _Points, _count, _TmpPoints.Length);
_count += 1;
_TmpPoint = _gp.PathPoints[i + 1];
}
else
{
_TmpPoints = GetLinePoints(_gp.PathPoints[i], _gp.PathPoints[i + 1], 1);
Array.ConstrainedCopy(_TmpPoints, 0, _Points, _count, _TmpPoints.Length);
_count += _TmpPoints.Length - 1;
}
}
_TmpPoints = new PointF[_count + 1];
Array.Copy(_Points, _TmpPoints, _count);
_Points = CleanPoints(_TmpPoints); 

_count = _Points.Length - 1;

return DrawText(_Points, _count);
}
catch (Exception ex)
{
LastError = ex;
return null;
}
}

private PointF[] CleanPoints(PointF[] _points)
{
int i = 0;
PointF[] _tmppoints = new PointF[_points.Length + 1];
PointF _lastpoint = default(PointF);
int _count = 0;
for (i = 0; i <= _points.Length - 1; i++)
{
if (i == 0 | _points[i].X != _lastpoint.X | _points[i].Y != _lastpoint.Y)
{
_tmppoints[_count] = _points[i];
_count += 1;
}
_lastpoint = _points[i];
}
_points = new PointF[_count + 1];
Array.Copy(_tmppoints, _points, _count);
return _points;
}
//排版
private Bitmap DrawText(PointF[] _Points, int _MaxPoints)
{
GraphicsPath _gp = new GraphicsPath(_pathdataTOP.Points, _pathdataTOP.Types);
_gp.FillMode = FillMode.Winding;
_gp.Flatten();
Bitmap _bitmap = new Bitmap(
Convert.ToInt32(_gp.GetBounds().Right + _fontTOP.Size * 2), 
Convert.ToInt32(_gp.GetBounds().Bottom + _fontTOP.Size * 2)
);
_gp.Dispose();
Graphics _G = Graphics.FromImage(_bitmap);
int _count = 0;
PointF _Point1 = default(PointF);
PointF _Point2 = default(PointF);
PointF _Point = default(PointF);
int _CharStep = 0;
int lStrWidth = 0;
double _Angle = default(double);
double _MaxWidthText = default(double);
int i = 0;
float[] _widths = null;
//_widths = MeasureWidths(_G)
Pen _pathpen = new Pen(_pathcolorTOP);
if (ShowPath == true)
{
foreach (PointF _Point1_loopVariable in _Points)
{
_Point1 = _Point1_loopVariable;
_G.DrawEllipse(_pathpen, _Point1.X, _Point1.Y, 1, 1);
}
}
_pathpen.Dispose();
for (i = 0; i <= _textTOP.Length - 1; i++)
{
_MaxWidthText += StringRegion(_G, i);
// _widths(i)
}
switch (_pathalignTOP)
{
case PathAlign.Left:
_Point1 = _Points[0];
_count = 0;
break;

case PathAlign.Center:
_count = (int)(_MaxPoints - _MaxWidthText) / 2;
if (_count > 0)
{
_Point1 = _Points[_count];
}
else
{
_Point1 = _Points[0];
}
break; 

case PathAlign.Right:
_count = (int)(_MaxPoints - _MaxWidthText - StringRegion(_G, _textTOP.Length - 1) * LetterSpacePercentage / 100);
if (_count > 0)
{
_Point1 = _Points[_count];
}
else
{
_Point1 = _Points[0];
}
break;
}
while (!(_CharStep > _textTOP.Length - 1))
{
lStrWidth = (int)StringRegion(_G, _CharStep) * LetterSpacePercentage / 100;
if ((_count + lStrWidth / 2) >= 0 & (_count + lStrWidth) < _MaxPoints)
{
_count += lStrWidth;
_Point2 = _Points[_count];
_Point = _Points[_count - lStrWidth / 2];
_Angle = GetAngle(_Point1, _Point2);
DrawRotatedText(_G, _textTOP[_CharStep].ToString(), (float)_Angle, _Point);
_Point1 = _Points[_count];
}
else
{
_count += lStrWidth;
}
_CharStep += 1;
}
_G.Dispose();

return _bitmap;
}
private float StringRegion(Graphics _g, int _textpos)
{
string measureString = _textTOP.Substring(_textpos, 1);
int numChars = measureString.Length;
CharacterRange[] characterRanges = new CharacterRange[numChars + 1];
StringFormat stringFormat = new StringFormat();
stringFormat.Trimming = StringTrimming.None;
stringFormat.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
SizeF size = _g.MeasureString(_textTOP, _fontTOP);
RectangleF layoutRect = new RectangleF(0f, 0f, size.Width, size.Height);
Region[] stringRegions = new Region[numChars + 1];
characterRanges[0] = new CharacterRange(0, 1);
stringFormat.FormatFlags = StringFormatFlags.NoClip;
stringFormat.SetMeasurableCharacterRanges(characterRanges);
stringFormat.Alignment = StringAlignment.Near;
stringRegions = _g.MeasureCharacterRanges(_textTOP.Substring(_textpos), _fontTOP, layoutRect, stringFormat);
return stringRegions[0].GetBounds(_g).Width;
}
private float[] MeasureWidths(Graphics graphics)
{
float[] widths = new float[_textTOP.Length + 1];
StringFormat format = StringFormat.GenericTypographic;
format.Trimming = StringTrimming.None;
format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
RectangleF layout = new RectangleF(0, 0, 10000, 10000);
int remainder = _textTOP.Length;
int start = 0;
while (remainder > 0)
{
int length = remainder;
if (length > 32)
{
length = 32;
}
CharacterRange[] ranges = new CharacterRange[length + 1];
int i = 0;
while (i < ranges.Length)
{
ranges[i] = new CharacterRange(start + i, 1);
i += 1;
}
format.SetMeasurableCharacterRanges(ranges);
Region[] regions = graphics.MeasureCharacterRanges(_textTOP, _fontTOP, layout, format);
i = 0;
while (i < regions.Length)
{
Region region = regions[i];
RectangleF cb = region.GetBounds(graphics);
widths[start + i] = cb.Width;
i += 1;
}
start += length;
remainder -= 31;
}
return widths;
} 
private double GetAngle(PointF _point1, PointF _point2)
{
double c = default(double);
c = Math.Sqrt(Math.Pow((_point2.X - _point1.X), 2) + Math.Pow((_point2.Y - _point1.Y), 2));
if (c == 0)
{
return 0;
}
if (_point1.X > _point2.X)
{
return Math.Asin((_point1.Y - _point2.Y) / c) * 180 / Math.PI - 180;
}
else
{
return Math.Asin((_point2.Y - _point1.Y) / c) * 180 / Math.PI;
}
}
private void DrawRotatedText(Graphics _gr, string _text, float _angle, PointF _PointCenter)
{
StringFormat string_format = new StringFormat();
string_format.Alignment = StringAlignment.Center;
_gr.SmoothingMode = SmoothingMode.HighQuality;
_gr.CompositingQuality = CompositingQuality.HighQuality;
_gr.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
GraphicsPath graphics_path = new GraphicsPath(System.Drawing.Drawing2D.FillMode.Winding);
int x = Convert.ToInt32(_PointCenter.X);
int y = Convert.ToInt32(_PointCenter.Y);
switch (TextPathPosition)
{
case TextPosition.OverPath:
graphics_path.AddString(_text, _fontTOP.FontFamily, (int)_fontTOP.Style, (float)_fontTOP.Size, new Point(x, y - (int)_fontTOP.Size), string_format);
break;
case TextPosition.CenterPath:
graphics_path.AddString(_text, _fontTOP.FontFamily, (int)_fontTOP.Style, (float)_fontTOP.Size, new Point(x, y - (int)_fontTOP.Size / 2), string_format);
break;
case TextPosition.UnderPath:
graphics_path.AddString(_text, _fontTOP.FontFamily, (int)_fontTOP.Style, (float)_fontTOP.Size, new Point(x, y), string_format);
break;
}
Matrix rotation_matrix = new Matrix();
rotation_matrix.RotateAt(_angle, new PointF(x, y));
graphics_path.Transform(rotation_matrix);
_gr.DrawPath(new Pen(_colorTOP), graphics_path);
_gr.FillPath(new SolidBrush(_fillcolorTOP), graphics_path);
graphics_path.Dispose();
}
public PointF[] GetLinePoints(PointF _p1, PointF _p2, int _stepWitdth)
{
int lCount = 0;
PointF[] _tmpPoints = new PointF[10001];
float _width = 0;
float _height = 0;
long d = 0;
long ix = 0;
long iy = 0;
int dd = 0;
int id = 0;
int lStep = _stepWitdth;
_p1.X = Convert.ToInt32(_p1.X);
_p1.Y = Convert.ToInt32(_p1.Y);
_p2.X = Convert.ToInt32(_p2.X);
_p2.Y = Convert.ToInt32(_p2.Y);
_width = _p2.X - _p1.X;
_height = _p2.Y - _p1.Y;
d = 0;
if (_width < 0)
{
_width = -_width;
ix = -1;
}
else
{
ix = 1;
}
if (_height < 0)
{
_height = -_height;
iy = -1;
}
else
{
iy = 1;
}
if (_width > _height)
{
dd = (int)(_width + _width);
id = (int)(_height + _height); 
do
{
if (lStep == _stepWitdth)
{
_tmpPoints[lCount].X = _p1.X;
_tmpPoints[lCount].Y = _p1.Y;
lCount += 1;
}
else
{
lStep += _stepWitdth;
}
if (Convert.ToInt32(_p1.X) == Convert.ToInt32(_p2.X))
break;
_p1.X += ix;
d += id;
if (d > _width)
{
_p1.Y += iy;
d -= dd;
}
} while (true);

}
else
{
dd = (int)(_height + _height);
id = (int)(_width + _width);
do
{
if (lStep == _stepWitdth)
{
_tmpPoints[lCount].X = _p1.X;
_tmpPoints[lCount].Y = _p1.Y;
lCount += 1;
}
else
{
lStep += _stepWitdth;
}
if (Convert.ToInt32(_p1.Y) == Convert.ToInt32(_p2.Y))
break; // TODO: might not be correct. Was : Exit Do
_p1.Y += iy;
d += id;
if (d > _height)
{
_p1.X += ix;
d -= dd;
}
} while (true);
}
PointF[] _tmpPoints2 = null;
_tmpPoints2 = new PointF[lCount + 1];
Array.Copy(_tmpPoints, _tmpPoints2, lCount);
return _tmpPoints2;
}
}
     public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            PointF[] _points = new PointF[8];
TextOnPath _top = new TextOnPath();
//初始化的相关代码:
_points[0] = new PointF(303, 485);
_points[1] = new PointF(476, 616);
_points[2] = new PointF(745, 599);
_points[3] = new PointF(876, 434);
_points[4] = new PointF(829, 179);
_points[5] = new PointF(657, 73);
_points[6] = new PointF(518, 269);
_points[7] = new PointF(308, 349);
_top.FontTOP = new Font("楷体_GB2312", 48, FontStyle.Bold);
_top.FillColorTOP = Color.Red;
_top.ColorTOP = Color.Black;
_top.TextTOP = "龙岗民生网http://www.lgms.net";
_top.ShowPath = true;
_top.PathAlignTOP = PathAlign.Left;
_top.LetterSpacePercentage = 80;
_top.TextPathPosition = TextPosition.OverPath;}
//关键的调用方法:
private Image DrawText()
{PointF[] _points = new PointF[8];
TextOnPath _top = new TextOnPath();

}
        }
    }
  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 运筹学排序问题中的在线排序
    • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
    • ¥30 求一段fortran代码用IVF编译运行的结果
    • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
    • ¥15 lammps拉伸应力应变曲线分析
    • ¥15 C++ 头文件/宏冲突问题解决
    • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
    • ¥50 安卓adb backup备份子用户应用数据失败
    • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
    • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题