您的位置:首页 > 其它

使用GdipDrawDriverString实现行距及字符间距控制

2012-07-04 15:29 453 查看
前几天,一个朋友请求帮忙处理个LED图片生成问题,主要是要将一个标题和几段文字绘制到固定大小的图片上,如果一张放不下就生成多张。在使用DrawString是发现无法控制行距,请教了baidu大神找到了GdipDrawDriverString函数,但没看到完整的例子,于是将自己实现的方法发出来,以便初接触者了解,主要还是请大家批评指正。 1public class ConvertImage
2 {
3 public bool TextToImage(string title_Text, string title_FontFamily, float title_FontEmSize, FontStyle title_FontStyle, Color title_Color, int title_MarginTop, int title_MarginBottom,
4 string content_Text, string content_FontFamily, float content_FontEmSize, FontStyle content_FontStyle, Color content_Color, int content_RowSpacing, int content_WordSpacing,
5 int page_Width, int page_Height, int page_MarginLeftRight, int page_MarginTop, Color background_Color, string SavePath)
6 {
7 //TODO:检测并修正参数
8 System.Drawing.Bitmap bit = new System.Drawing.Bitmap(page_Width, page_Height);
9 System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bit);
10 g.SmoothingMode = SmoothingMode.HighQuality;
11 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
12 g.CompositingQuality = CompositingQuality.HighQuality;
13 g.Clear(background_Color);
14 //--写标题--本代码假定标题内容不会超出一页
15 Font title_font = new Font(title_FontFamily, title_FontEmSize, title_FontStyle);
16 Brush title_brush = new SolidBrush(title_Color);
17 SizeF size = g.MeasureString(title_Text, title_font, page_Width - page_MarginLeftRight * 2);
18 g.DrawString(title_Text, title_font, title_brush,
19 new RectangleF(new PointF(page_MarginLeftRight, title_MarginTop), //标题的上边距单独指定
20 new SizeF(page_Width - page_MarginLeftRight * 2, page_Height - title_MarginTop)));
21 //--计算内容每个字符的显示位置
22 Font font = new Font(content_FontFamily, content_FontEmSize, content_FontStyle);
23 Brush brush = new SolidBrush(content_Color);
24 List<PageClass> lpageClass = GetShowList(content_Text, g, font, page_Width, page_Height, content_RowSpacing, content_WordSpacing, size.Height + title_MarginTop + title_MarginBottom, page_MarginLeftRight, page_MarginTop);
25 foreach (PageClass pc in lpageClass)
26 {
27 if (pc.pageindex > 1)
28 {
29 g.Dispose();
30 bit.Dispose();
31 bit = new System.Drawing.Bitmap(page_Width, page_Height);
32 g = System.Drawing.Graphics.FromImage(bit);
33 g.Clear(background_Color);
34 g.SmoothingMode = SmoothingMode.HighQuality;
35 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
36 g.CompositingQuality = CompositingQuality.HighQuality;
37 }
38 GdiplusMethods.DrawDriverString(g, pc.txt, font, brush, pc.pos);
39 bit.RotateFlip(RotateFlipType.Rotate90FlipXY);
40 bit.Save(string.Format(SavePath, pc.pageindex), System.Drawing.Imaging.ImageFormat.Bmp);
41
42 }
43 return true;
44
45 }
46 /// <summary>
47 /// 计算内容每个字符的显示位置,根据字符大小自动分行,支持空格、换行、两边自动对齐
48 /// </summary>
49 /// <param name="txt">文本内容</param>
50 /// <param name="g">绘图区域</param>
51 /// <param name="font">字体</param>
52 /// <param name="pagewidth">页宽</param>
53 /// <param name="pageheight">页高</param>
54 /// <param name="rowspace">行距</param>
55 /// <param name="wordspace">字符间距</param>
56 /// <param name="firstPageMaginTop">首页上边距</param>
57 /// <param name="marginleftright">页左右边距</param>
58 /// <param name="margintop">普通页上边距</param>
59 /// <returns></returns>
60 public List<PageClass> GetShowList(string txt, Graphics g, Font font, int pagewidth, int pageheight,
61 float rowspace, float wordspace, float firstPageMaginTop, int marginleftright, int margintop)
62 {
63 int pageindex = 1;
64 float left = 0, top = firstPageMaginTop + font.SizeInPoints; ;
65 float lastRight = marginleftright - wordspace;
66 float lastRowBotton = top;
67 float rowheight = font.SizeInPoints + rowspace;
68 int colstart = 0, colend = 0;
69 float colspace;
70 string curTxt, measureStr;
71 SizeF size;
72 List<PointF> lpos = new List<PointF>();
73 List<PageClass> lpageClass = new List<PageClass>();
74 PageClass curPage = new PageClass();
75 System.Text.StringBuilder str = new System.Text.StringBuilder();
76 for (int i = 0; i < txt.Length; i++) //这个字在这行放不下,要放到下一行
77 {
78 curTxt = txt.Substring(i, 1);
79 switch (curTxt)
80 {
81 case " ":
82 measureStr = "2";
83 break;
84 case "\t":
85 measureStr = "2222";
86 break;
87 case " ":
88 measureStr = "国";
89 break;
90 default:
91 measureStr = curTxt;
92 break;
93 }
94 size = g.MeasureString(measureStr, font, int.MaxValue, StringFormat.GenericTypographic);
95 left = lastRight + wordspace;
96 if ((left + size.Width) > pagewidth || curTxt == "\n")
97 {
98 if (curTxt != "\n")
99 {
colspace = (pagewidth - lastRight - marginleftright) / (colend - colstart);
for (int j = colstart; j < colend; j++)//处理两边对齐
{
lpos[j] = new PointF(lpos[j].X + colspace * (j - colstart + 1), lpos[j].Y);
}
}
colstart = colend;

left = marginleftright;
top = lastRowBotton + rowheight;

lastRowBotton = top;
}
colend++;
lastRight = left + size.Width;

if (top > pageheight) //这行应该放到下一页了
{
curPage.pageindex = pageindex;
curPage.txt = str.ToString();
curPage.pos = lpos.ToArray();
lpageClass.Add(curPage);

pageindex++;
curPage = new PageClass();
lpos.Clear();
//str.Clear();
str.Remove(0, str.Length);
top = margintop + rowheight;
lastRowBotton = top;
colstart = 0;
colend = 1;
}

str.Append(curTxt);
lpos.Add(new PointF(left, top));

}
//保存最后一页
if (lpos.Count > 0)
{
curPage.pageindex = pageindex;
curPage.txt = str.ToString();
curPage.pos = lpos.ToArray();
lpageClass.Add(curPage);
}
return lpageClass;
}
}

public class PageClass
{
public int pageindex;
public string txt;
public PointF[] pos;
}
public class GdiplusMethods
{
private GdiplusMethods() { }

private enum DriverStringOptions
{
CmapLookup = 1,
Vertical = 2,
Advance = 4,
LimitSubpixel = 8,
}

public static void DrawDriverString(Graphics graphics, string text,
Font font, Brush brush, PointF[] positions)
{
DrawDriverString(graphics, text, font, brush, positions, null);
}

public static void DrawDriverString(Graphics graphics, string text,
Font font, Brush brush, PointF[] positions, Matrix matrix)
{
if (graphics == null)
throw new ArgumentNullException("graphics");
if (text == null)
throw new ArgumentNullException("text");
if (font == null)
throw new ArgumentNullException("font");
if (brush == null)
throw new ArgumentNullException("brush");
if (positions == null)
throw new ArgumentNullException("positions");

// Get hGraphics
FieldInfo field = typeof(Graphics).GetField("nativeGraphics",
BindingFlags.Instance | BindingFlags.NonPublic);
IntPtr hGraphics = (IntPtr)field.GetValue(graphics);

// Get hFont
field = typeof(Font).GetField("nativeFont",
BindingFlags.Instance | BindingFlags.NonPublic);
IntPtr hFont = (IntPtr)field.GetValue(font);

// Get hBrush
field = typeof(Brush).GetField("nativeBrush",
BindingFlags.Instance | BindingFlags.NonPublic);
IntPtr hBrush = (IntPtr)field.GetValue(brush);

// Get hMatrix
IntPtr hMatrix = IntPtr.Zero;
if (matrix != null)
{
field = typeof(Matrix).GetField("nativeMatrix",
BindingFlags.Instance | BindingFlags.NonPublic);
hMatrix = (IntPtr)field.GetValue(matrix);
}

int result = GdipDrawDriverString(hGraphics, text, text.Length,
hFont, hBrush, positions, (int)DriverStringOptions.CmapLookup, hMatrix);
}

[DllImport("Gdiplus.dll", CharSet = CharSet.Unicode)]
internal extern static int GdipMeasureDriverString(IntPtr graphics,
string text, int length, IntPtr font, PointF[] positions,
int flags, IntPtr matrix, ref RectangleF bounds);

[DllImport("Gdiplus.dll", CharSet = CharSet.Unicode)]
internal extern static int GdipDrawDriverString(IntPtr graphics,
string text, int length, IntPtr font, IntPtr brush,
PointF[] positions, int flags, IntPtr matrix);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐