LayoutUtility.cs 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. //#define DRAWTEST
  2. /*******************************************************************************
  3. * Copyright(c) 2012 dongke All rights reserved. / Confidential
  4. * 类的信息:
  5. * 1.程序名称:LayoutUtility.cs
  6. * 2.功能描述:Layout工具类
  7. * 编辑履历:
  8. * 作者 日期 版本 修改内容
  9. * 欧阳涛 2012/09/11 1.00 新建
  10. *******************************************************************************/
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Drawing;
  14. using System.Drawing.Drawing2D;
  15. //using Microsoft.VisualBasic.PowerPacks;
  16. namespace Dongke.WinForm.Controls.InvoiceLayout
  17. {
  18. public static class LayoutUtility
  19. {
  20. #region 函数
  21. ///// <summary>
  22. ///// 获取图形实例
  23. ///// </summary>
  24. ///// <param name="item"></param>
  25. ///// <returns></returns>
  26. //public static Shape GetNewShape(LayoutItem item)
  27. //{
  28. // Shape shape = null;
  29. // switch (item.ItemType)
  30. // {
  31. // case ItemType.Ellipse:
  32. // OvalShape eShape = new OvalShape();
  33. // eShape.SelectionColor = Color.Transparent;
  34. // eShape.BorderStyle = DashStyle.Solid;
  35. // eShape.BorderColor = Color.Black;
  36. // shape = eShape;
  37. // break;
  38. // case ItemType.Rectangle:
  39. // RectangleShape rShape = new RectangleShape();
  40. // rShape.SelectionColor = Color.Transparent;
  41. // rShape.BorderStyle = DashStyle.Solid;
  42. // rShape.BorderColor = Color.Black;
  43. // shape = rShape;
  44. // break;
  45. // case ItemType.Image:
  46. // case ItemType.Text:
  47. // case ItemType.Grid:
  48. // case ItemType.PageNum:
  49. // default:
  50. // RectangleShape dShape = new RectangleShape();
  51. // dShape.SelectionColor = Color.Transparent;
  52. // dShape.BorderStyle = DashStyle.Custom;
  53. // dShape.BorderColor = Color.Transparent;
  54. // shape = dShape;
  55. // break;
  56. // }
  57. // return shape;
  58. //}
  59. #region 绘制直线
  60. /// <summary>
  61. /// 绘制直线
  62. /// </summary>
  63. /// <param name="graphics">Graphics</param>
  64. /// <param name="startPoint">起点</param>
  65. /// <param name="endPoint">终点</param>
  66. /// <param name="lineColor">线的颜色</param>
  67. /// <param name="lineWidth">线宽(mm)</param>
  68. public static void DrawLine(
  69. Graphics graphics,
  70. PointF startPoint,
  71. PointF endPoint,
  72. Color lineColor,
  73. float lineWidth)
  74. {
  75. DrawLine(graphics, graphics.PageUnit, startPoint, endPoint, lineColor, lineWidth);
  76. }
  77. /// <summary>
  78. /// 绘制直线
  79. /// </summary>
  80. /// <param name="graphics">Graphics</param>
  81. /// <param name="unit">GraphicsUnit</param>
  82. /// <param name="startPoint">起点</param>
  83. /// <param name="endPoint">终点</param>
  84. /// <param name="lineColor">线的颜色</param>
  85. /// <param name="lineWidth">线宽(mm)</param>
  86. public static void DrawLine(
  87. Graphics graphics,
  88. GraphicsUnit unit,
  89. PointF startPoint,
  90. PointF endPoint,
  91. Color lineColor,
  92. float lineWidth)
  93. {
  94. if (lineWidth == 0 || ((startPoint.X == endPoint.X) && (startPoint.Y == endPoint.Y)))
  95. {
  96. return;
  97. }
  98. GraphicsContainer containerState = graphics.BeginContainer();
  99. graphics.PageUnit = unit;
  100. SmoothingMode smoothingMode = graphics.SmoothingMode;
  101. try
  102. {
  103. using (Pen pen = new Pen(lineColor))
  104. {
  105. graphics.SmoothingMode = SmoothingMode.AntiAlias;
  106. pen.Width = Math.Max(LayoutCommon.PixelToMillimeter(1), lineWidth);
  107. graphics.DrawLine(pen, startPoint, endPoint);
  108. }
  109. }
  110. finally
  111. {
  112. graphics.SmoothingMode = smoothingMode;
  113. graphics.EndContainer(containerState);
  114. }
  115. }
  116. #endregion 绘制直线
  117. #region 绘制椭圆
  118. /// <summary>
  119. /// 绘制椭圆
  120. /// </summary>
  121. /// <param name="graphics">Graphics</param>
  122. /// <param name="rectangle">图形范围</param>
  123. /// <param name="lineColor">边线颜色</param>
  124. /// <param name="fillColor">填充颜色</param>
  125. /// <param name="lineWidth">边线宽(mm)</param>
  126. /// <param name="isTransparent">背景是否透明</param>
  127. public static void DrawEllipse(
  128. Graphics graphics,
  129. RectangleF rectangle,
  130. Color lineColor,
  131. Color fillColor,
  132. float lineWidth,
  133. bool isTransparent)
  134. {
  135. DrawEllipse(graphics, graphics.PageUnit, rectangle,
  136. lineColor, fillColor, lineWidth, isTransparent);
  137. }
  138. /// <summary>
  139. /// 绘制椭圆
  140. /// </summary>
  141. /// <param name="graphics">Graphics</param>
  142. /// <param name="unit">GraphicsUnit</param>
  143. /// <param name="rectangle">图形范围</param>
  144. /// <param name="lineColor">边线颜色</param>
  145. /// <param name="fillColor">填充颜色</param>
  146. /// <param name="lineWidth">边线宽(mm)</param>
  147. /// <param name="isTransparent">背景是否透明</param>
  148. public static void DrawEllipse(
  149. Graphics graphics,
  150. GraphicsUnit unit,
  151. RectangleF rectangle,
  152. Color lineColor,
  153. Color fillColor,
  154. float lineWidth,
  155. bool isTransparent)
  156. {
  157. if ((rectangle.Width < 0) || (rectangle.Height < 0))
  158. {
  159. return;
  160. }
  161. GraphicsContainer containerState = graphics.BeginContainer();
  162. graphics.PageUnit = unit;
  163. SmoothingMode smoothingMode = graphics.SmoothingMode;
  164. try
  165. {
  166. if (!isTransparent && (rectangle.Width > 0) && (rectangle.Height > 0))
  167. {
  168. graphics.SmoothingMode = SmoothingMode.Default;
  169. using (Brush brush = new SolidBrush(fillColor))
  170. {
  171. graphics.FillEllipse(brush, rectangle);
  172. }
  173. }
  174. if (lineWidth != 0)
  175. {
  176. float minWidth = LayoutCommon.PixelToMillimeter(1);
  177. using (Pen pen = new Pen(lineColor))
  178. {
  179. if ((rectangle.Width > 0) && (rectangle.Height == 0))
  180. {
  181. pen.Width = minWidth;
  182. graphics.SmoothingMode = SmoothingMode.AntiAlias;
  183. graphics.DrawLine(pen, rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Top);
  184. }
  185. else if ((rectangle.Width == 0) && (rectangle.Height > 0))
  186. {
  187. pen.Width = minWidth;
  188. graphics.SmoothingMode = SmoothingMode.AntiAlias;
  189. graphics.DrawLine(pen, rectangle.Left, rectangle.Top, rectangle.Left, rectangle.Bottom);
  190. }
  191. else
  192. {
  193. float num = Math.Min(rectangle.Width, rectangle.Height) / 2;
  194. num = Math.Min(num, lineWidth);
  195. pen.Width = Math.Max(minWidth, num);
  196. graphics.SmoothingMode = SmoothingMode.Default;
  197. graphics.DrawEllipse(pen, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
  198. }
  199. }
  200. }
  201. }
  202. finally
  203. {
  204. graphics.SmoothingMode = smoothingMode;
  205. graphics.EndContainer(containerState);
  206. }
  207. }
  208. #endregion 绘制椭圆
  209. #region 绘制矩形
  210. /// <summary>
  211. /// 绘制矩形
  212. /// </summary>
  213. /// <param name="graphics">Graphics</param>
  214. /// <param name="unit">GraphicsUnit</param>
  215. /// <param name="rectangle">图形范围</param>
  216. /// <param name="lineColor">边线颜色</param>
  217. /// <param name="fillColor">填充颜色</param>
  218. /// <param name="lineWidth">边线宽(mm)</param>
  219. /// <param name="isTransparent">背景是否透明</param>
  220. public static void DrawRectangle(
  221. Graphics graphics,
  222. RectangleF rectangle,
  223. Color lineColor,
  224. Color fillColor,
  225. float lineWidth,
  226. bool isTransparent)
  227. {
  228. DrawRectangle(graphics, graphics.PageUnit, rectangle,
  229. lineColor, fillColor, lineWidth, isTransparent);
  230. }
  231. /// <summary>
  232. /// 绘制矩形
  233. /// </summary>
  234. /// <param name="graphics">Graphics</param>
  235. /// <param name="unit">GraphicsUnit</param>
  236. /// <param name="rectangle">图形范围</param>
  237. /// <param name="lineColor">边线颜色</param>
  238. /// <param name="fillColor">填充颜色</param>
  239. /// <param name="lineWidth">边线宽(mm)</param>
  240. /// <param name="isTransparent">背景是否透明</param>
  241. public static void DrawRectangle(
  242. Graphics graphics,
  243. GraphicsUnit unit,
  244. RectangleF rectangle,
  245. Color lineColor,
  246. Color fillColor,
  247. float lineWidth,
  248. bool isTransparent)
  249. {
  250. if ((rectangle.Width < 0) || (rectangle.Height < 0))
  251. {
  252. return;
  253. }
  254. GraphicsContainer containerState = graphics.BeginContainer();
  255. graphics.PageUnit = unit;
  256. SmoothingMode smoothingMode = graphics.SmoothingMode;
  257. try
  258. {
  259. if (!isTransparent && (rectangle.Width > 0) && (rectangle.Height > 0))
  260. {
  261. graphics.SmoothingMode = SmoothingMode.Default;
  262. using (Brush brush = new SolidBrush(fillColor))
  263. {
  264. graphics.FillRectangle(brush, rectangle);
  265. }
  266. }
  267. if (lineWidth != 0)
  268. {
  269. float minWidth = LayoutCommon.PixelToMillimeter(1);
  270. using (Pen pen = new Pen(lineColor))
  271. {
  272. if ((rectangle.Width > 0) && (rectangle.Height == 0))
  273. {
  274. pen.Width = minWidth;
  275. graphics.SmoothingMode = SmoothingMode.AntiAlias;
  276. graphics.DrawLine(pen, rectangle.Left, rectangle.Top, rectangle.Right, rectangle.Top);
  277. }
  278. else if ((rectangle.Width == 0) && (rectangle.Height > 0))
  279. {
  280. pen.Width = minWidth;
  281. graphics.SmoothingMode = SmoothingMode.AntiAlias;
  282. graphics.DrawLine(pen, rectangle.Left, rectangle.Top, rectangle.Left, rectangle.Bottom);
  283. }
  284. else
  285. {
  286. float num = Math.Min(rectangle.Width, rectangle.Height) / 2;
  287. num = Math.Min(num, lineWidth);
  288. pen.Width = Math.Max(minWidth, num);
  289. graphics.SmoothingMode = SmoothingMode.Default;
  290. graphics.DrawRectangle(pen, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height);
  291. }
  292. }
  293. }
  294. }
  295. finally
  296. {
  297. graphics.SmoothingMode = smoothingMode;
  298. graphics.EndContainer(containerState);
  299. }
  300. }
  301. #endregion 绘制矩形
  302. #region 绘制图片
  303. /// <summary>
  304. /// 绘制图片
  305. /// </summary>
  306. /// <param name="graphics">Graphics</param>
  307. /// <param name="rectangle">图片范围</param>
  308. /// <param name="image">图片</param>
  309. public static void DrawImage(
  310. Graphics graphics,
  311. RectangleF rectangle,
  312. Image image)
  313. {
  314. DrawImage(graphics, graphics.PageUnit, rectangle, image);
  315. }
  316. /// <summary>
  317. /// 绘制图片
  318. /// </summary>
  319. /// <param name="graphics">Graphics</param>
  320. /// <param name="unit">GraphicsUnit</param>
  321. /// <param name="rectangle">图片范围</param>
  322. /// <param name="image">图片</param>
  323. public static void DrawImage(
  324. Graphics graphics,
  325. GraphicsUnit unit,
  326. RectangleF rectangle,
  327. Image image)
  328. {
  329. if (image == null || (rectangle.Width < 0) || (rectangle.Height < 0))
  330. {
  331. return;
  332. }
  333. GraphicsContainer containerState = graphics.BeginContainer();
  334. graphics.PageUnit = unit;
  335. graphics.DrawImage(image, rectangle);
  336. graphics.EndContainer(containerState);
  337. }
  338. #endregion 绘制图片
  339. #region 绘制文本
  340. /// <summary>
  341. /// 绘制文本
  342. /// </summary>
  343. /// <param name="graphics">Graphics</param>
  344. /// <param name="rectangleM">绘制范围(余白)</param>
  345. /// <param name="rectangle">绘制范围</param>
  346. /// <param name="context">文本</param>
  347. /// <param name="font">字体</param>
  348. /// <param name="foreColor">字体颜色</param>
  349. /// <param name="lineSpace">行间隔</param>
  350. /// <param name="characterSpace">字间隔</param>
  351. /// <param name="charCount">行文字数</param>
  352. /// <param name="alignment">文本对齐方式</param>
  353. /// <param name="alignmentVertical">文本垂直对齐方式</param>
  354. /// <param name="wrap">是否自动文本换行</param>
  355. /// <param name="clip">是否剪裁延伸到边框外侧的文本</param>
  356. /// <param name="selected">是否选择</param>
  357. public static void DrawText(
  358. Graphics graphics,
  359. RectangleF rectangleM,
  360. RectangleF rectangle,
  361. string context,
  362. Font font,
  363. Color foreColor,
  364. float lineSpace,
  365. float charSpace,
  366. int charCount,
  367. TextAlignment alignment,
  368. // 文本垂直对齐方式 modify by chenxy 2014-03-28 begin
  369. TextAlignment alignmentVertical,
  370. // 文本垂直对齐方式 modify by chenxy 2014-03-28 end
  371. bool wrap,
  372. bool clip,
  373. bool selected)
  374. {
  375. // 文本垂直对齐方式 modify by chenxy 2014-03-28 begin
  376. //DrawText(graphics, graphics.PageUnit, rectangleM, rectangle, context, font, foreColor,
  377. // lineSpace, charSpace, charCount, alignment, wrap, clip, selected);
  378. DrawText(graphics, graphics.PageUnit, rectangleM, rectangle, context, font, foreColor,
  379. lineSpace, charSpace, charCount, alignment, alignmentVertical, wrap, clip, selected);
  380. // 文本垂直对齐方式 modify by chenxy 2014-03-28 end
  381. }
  382. /// <summary>
  383. /// 绘制文本
  384. /// </summary>
  385. /// <param name="graphics">Graphics</param>
  386. /// <param name="unit">GraphicsUnit</param>
  387. /// <param name="rectangleM">绘制范围(余白)</param>
  388. /// <param name="rectangle">绘制范围</param>
  389. /// <param name="context">文本</param>
  390. /// <param name="font">字体</param>
  391. /// <param name="foreColor">字体颜色</param>
  392. /// <param name="lineSpace">行间隔</param>
  393. /// <param name="characterSpace">字间隔</param>
  394. /// <param name="charCount">行文字数</param>
  395. /// <param name="alignment">文本对齐方式</param>
  396. /// <param name="alignmentVertical">文本垂直对齐方式</param>
  397. /// <param name="wrap">是否自动文本换行</param>
  398. /// <param name="clip">是否剪裁延伸到边框外侧的文本</param>
  399. /// <param name="selected">是否选择</param>
  400. public static void DrawText(
  401. Graphics graphics,
  402. GraphicsUnit unit,
  403. RectangleF rectangleM,
  404. RectangleF rectangle,
  405. string context,
  406. Font font,
  407. Color foreColor,
  408. float lineSpace,
  409. float charSpace,
  410. int charCount,
  411. TextAlignment alignment,
  412. // 文本垂直对齐方式 modify by chenxy 2014-03-28 begin
  413. TextAlignment alignmentVertical,
  414. // 文本垂直对齐方式 modify by chenxy 2014-03-28 end
  415. bool wrap,
  416. bool clip,
  417. bool selected)
  418. {
  419. clip = false;
  420. selected = false;
  421. if (string.IsNullOrEmpty(context)
  422. || rectangle.Width <= 0
  423. || rectangle.Height <= 0)
  424. {
  425. return;
  426. }
  427. GraphicsContainer containerState = graphics.BeginContainer();
  428. graphics.PageUnit = unit;
  429. graphics.SetClip(rectangleM, CombineMode.Intersect);
  430. string[] lines = System.Text.RegularExpressions.Regex
  431. .Split(context, System.Environment.NewLine);
  432. using (SolidBrush textBrush = new SolidBrush(foreColor))
  433. {
  434. #if DRAWTEST
  435. graphics.DrawRectangle(new Pen(Color.Red, 0.1f), rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
  436. #endif
  437. // 文本垂直对齐方式 modify by chenxy 2014-03-28 begin
  438. //DrawString(graphics, lines, font, textBrush, lineSpace, charSpace,
  439. // charCount, rectangle, alignment, wrap, clip, selected);
  440. DrawString(graphics, lines, font, textBrush, lineSpace, charSpace,
  441. charCount, rectangle, alignment, alignmentVertical, wrap, clip, selected);
  442. // 文本垂直对齐方式 modify by chenxy 2014-03-28 end
  443. }
  444. graphics.EndContainer(containerState);
  445. }
  446. /// <summary>
  447. /// 横向绘制文本
  448. /// </summary>
  449. /// <param name="graphics">Graphics</param>
  450. /// <param name="lines">多行文本</param>
  451. /// <param name="font">字体</param>
  452. /// <param name="textBrush">字体笔刷</param>
  453. /// <param name="lineSpace">行间隔</param>
  454. /// <param name="characterSpace">字间隔</param>
  455. /// <param name="charCount">行文字数</param>
  456. /// <param name="rectangle">文本范围</param>
  457. /// <param name="alignment">文本对齐方式</param>
  458. /// <param name="wrap">是否自动文本换行</param>
  459. /// <param name="clip">是否剪裁延伸到边框外侧的文本</param>
  460. /// <param name="selected">是否选择</param>
  461. private static void DrawString(
  462. Graphics graphics,
  463. string[] lines,
  464. Font font,
  465. SolidBrush textBrush,
  466. float lineSpace,
  467. float charSpace,
  468. int charCount,
  469. RectangleF rectangle,
  470. TextAlignment alignment,
  471. // 文本垂直对齐方式 modify by chenxy 2014-03-28 begin
  472. TextAlignment alignmentVertical,
  473. // 文本垂直对齐方式 modify by chenxy 2014-03-28 end
  474. bool wrap,
  475. bool clip,
  476. bool selected)
  477. {
  478. SizeF fullSizeF = graphics.MeasureString(LayoutConsts.FULLSHAPE_TEXT,
  479. font,
  480. PointF.Empty,
  481. LayoutCommon.StringFormatHorizontal);
  482. // 单行文字数限制。
  483. if (0 < charCount)
  484. {
  485. System.Text.StringBuilder sbLine = new System.Text.StringBuilder();
  486. List<string> newLines = new List<string>();
  487. foreach (string line in lines)
  488. {
  489. char[] chars = line.ToCharArray();
  490. int index = 0;
  491. while (index < chars.Length)
  492. {
  493. int nextIndex = index + charCount;
  494. if (nextIndex <= chars.Length)
  495. {
  496. for (int i = index; i < nextIndex; i++)
  497. {
  498. sbLine.Append(chars[i]);
  499. }
  500. }
  501. else
  502. {
  503. for (int i = index; i < chars.Length; i++)
  504. {
  505. sbLine.Append(chars[i]);
  506. }
  507. }
  508. newLines.Add(sbLine.ToString());
  509. sbLine.Length = 0;
  510. index = nextIndex;
  511. }
  512. }
  513. lines = newLines.ToArray();
  514. if (charCount == 1)
  515. {
  516. alignment = TextAlignment.Evenness;
  517. }
  518. else
  519. {
  520. alignment = TextAlignment.LeftOrTop;
  521. charSpace = (rectangle.Width - fullSizeF.Width * charCount)
  522. / (charCount - 1);
  523. }
  524. }
  525. SizeF halfSizeF = graphics.MeasureString(LayoutConsts.HALFSHAPE_TEXT,
  526. font,
  527. PointF.Empty,
  528. LayoutCommon.StringFormatHorizontal);
  529. // 单行文字绘制开始
  530. bool isRowStart = false;
  531. // 单行文字绘制结束
  532. bool isRowEnd = false;
  533. // 一行文字绘制开始
  534. //bool isLineStart = true;
  535. // 一行文字绘制结束
  536. bool isLineEnd = false;
  537. // 多行文字绘制开始
  538. bool isLinesStart = true;
  539. // 多行文字绘制结束
  540. bool isLinesEnd = false;
  541. // 文字整体(字间隔,行间隔)范围
  542. float pointerTop = rectangle.Top;
  543. float pointerBottom = rectangle.Top + fullSizeF.Height;
  544. float pointerLeft = rectangle.Left;
  545. // 文字范围
  546. float textTop = rectangle.Top;
  547. float textLeft = rectangle.Left;
  548. //// 选择状态行间隔范围
  549. //RectangleF lineSpaceSelectedRectangleF = RectangleF.Empty;
  550. // 文字范围
  551. List<TextRectangleF> textRectangleFs = new List<TextRectangleF>();
  552. // 文本垂直对齐方式 modify by chenxy 2014-03-28 begin
  553. List<TextRectangleF[]> allTextRectFs = new List<TextRectangleF[]>();
  554. // 文本垂直对齐方式 modify by chenxy 2014-03-28 end
  555. // 文本绘制
  556. for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
  557. {
  558. // 一行文本绘制
  559. //isLineStart = true;
  560. isLineEnd = false;
  561. int colIndex = 0;
  562. int lineCharCount = lines[lineIndex].Length;
  563. char[] chars = lines[lineIndex].ToCharArray();
  564. while (true)
  565. {
  566. isRowStart = true;
  567. isRowEnd = false;
  568. textLeft = rectangle.Left;
  569. pointerLeft = rectangle.Left;
  570. if (colIndex < lineCharCount)
  571. {
  572. // 单行文字绘制
  573. for (int charIndex = colIndex; charIndex < lineCharCount; charIndex++, colIndex++)
  574. {
  575. SizeF nextTeatSizeF;
  576. TextRectangleF nextTextRectangleF = new TextRectangleF();
  577. nextTextRectangleF.Text = chars[charIndex].ToString();
  578. // 单行文字数限制
  579. if (0 < charCount)
  580. {
  581. nextTeatSizeF = fullSizeF;
  582. }
  583. else
  584. {
  585. // 半角空格的时候
  586. if (LayoutConsts.SPACE_HALFSHAPE_CHAR.Equals(chars[charIndex]))
  587. {
  588. nextTeatSizeF = halfSizeF;
  589. nextTeatSizeF.Height = fullSizeF.Height;
  590. }
  591. // 全角空格的时候
  592. else if (LayoutConsts.SPACE_FULLSHAPE_CHAR.Equals(chars[charIndex]))
  593. {
  594. nextTeatSizeF = fullSizeF;
  595. }
  596. // 其他
  597. else
  598. {
  599. nextTeatSizeF = graphics.MeasureString(nextTextRectangleF.Text,
  600. font, PointF.Empty, LayoutCommon.StringFormatHorizontal);
  601. nextTeatSizeF.Height = fullSizeF.Height;
  602. }
  603. }
  604. if (isRowStart)
  605. {
  606. float bottom = textTop;
  607. if (!isLinesStart)
  608. {
  609. bottom += lineSpace;
  610. }
  611. // 剪裁
  612. if (clip)
  613. {
  614. bottom += nextTeatSizeF.Height;
  615. }
  616. // 多行绘制结束
  617. if (rectangle.Bottom < bottom)
  618. {
  619. isLinesEnd = true;
  620. break;
  621. }
  622. //// 选择状态行间隔范围填充
  623. //if (selected
  624. // && 0 < lineSpace
  625. // && lineSpaceSelectedRectangleF != RectangleF.Empty)
  626. //{
  627. // lineSpaceSelectedRectangleF.Height = lineSpace;
  628. // graphics.FillRectangle(LayoutCommon.SelectedBrush, lineSpaceSelectedRectangleF);
  629. // lineSpaceSelectedRectangleF = RectangleF.Empty;
  630. //}
  631. if (0 == charCount)
  632. {
  633. // 自动换行
  634. float right = textLeft;
  635. if (rectangle.Right < right)
  636. {
  637. if (wrap)
  638. {
  639. // 单行结束
  640. isRowEnd = true;
  641. break;
  642. }
  643. else
  644. {
  645. if (clip)
  646. {
  647. // 一行结束
  648. isLineEnd = true;
  649. break;
  650. }
  651. }
  652. }
  653. }
  654. }
  655. else
  656. {
  657. if (0 == charCount)
  658. {
  659. float right = textLeft + charSpace + nextTeatSizeF.Width;
  660. // 自动换行
  661. if (wrap)
  662. {
  663. if (rectangle.Right < right)
  664. {
  665. // 文本对齐方式
  666. float correcting = 0;
  667. if (alignment == TextAlignment.RightOrBottom)
  668. {
  669. correcting = rectangle.Right - textLeft;
  670. if (0 < correcting)
  671. {
  672. foreach (TextRectangleF rf in textRectangleFs)
  673. {
  674. rf.RectangleX = rf.RectangleF.X + correcting;
  675. }
  676. }
  677. }
  678. else if (alignment == TextAlignment.Center)
  679. {
  680. correcting = (rectangle.Right - textLeft) / 2;
  681. if (0 < correcting)
  682. {
  683. foreach (TextRectangleF rf in textRectangleFs)
  684. {
  685. rf.RectangleX = rf.RectangleF.X + correcting;
  686. }
  687. }
  688. }
  689. else if (alignment == TextAlignment.Evenness)
  690. {
  691. if (1 < textRectangleFs.Count)
  692. {
  693. correcting = (rectangle.Right - textLeft)
  694. / (textRectangleFs.Count - 1);
  695. if (0 < correcting)
  696. {
  697. for (int j = 0; j < textRectangleFs.Count; j++)
  698. {
  699. textRectangleFs[j].RectangleX +=
  700. correcting * j;
  701. }
  702. }
  703. }
  704. else
  705. {
  706. textRectangleFs[0].RectangleX +=
  707. (rectangle.Right - textLeft) / 2;
  708. }
  709. }
  710. // 单行结束
  711. isRowEnd = true;
  712. break;
  713. }
  714. }
  715. else if (alignment == TextAlignment.LeftOrTop || alignment == TextAlignment.Evenness)
  716. {
  717. if (clip)
  718. {
  719. if (rectangle.Right < right)
  720. {
  721. // 一行结束
  722. isLineEnd = true;
  723. break;
  724. }
  725. }
  726. else
  727. {
  728. if (rectangle.Right < textLeft + charSpace)
  729. {
  730. // 一行结束
  731. isLineEnd = true;
  732. break;
  733. }
  734. }
  735. }
  736. }
  737. }
  738. nextTextRectangleF.RectangleF = new RectangleF(pointerLeft, pointerTop,
  739. nextTeatSizeF.Width, nextTeatSizeF.Height);
  740. textRectangleFs.Add(nextTextRectangleF);
  741. // 一行绘制结束
  742. if (isLineEnd)
  743. {
  744. break;
  745. }
  746. // 下一个文字位置计算
  747. if (isRowStart)
  748. {
  749. textLeft = textLeft + nextTeatSizeF.Width;
  750. isRowStart = false;
  751. }
  752. else
  753. {
  754. textLeft = textLeft + charSpace + nextTeatSizeF.Width;
  755. }
  756. pointerLeft = pointerLeft + nextTeatSizeF.Width + charSpace;
  757. }
  758. // 多行绘制结束
  759. if (isLinesEnd)
  760. {
  761. break;
  762. }
  763. // 一行绘制结束
  764. if (isLineEnd)
  765. {
  766. break;
  767. }
  768. // 单行绘制结束
  769. if (isRowEnd)
  770. {
  771. if (isLinesStart)
  772. {
  773. textTop = textTop + fullSizeF.Height;
  774. isLinesStart = false;
  775. }
  776. else
  777. {
  778. textTop = textTop + lineSpace + fullSizeF.Height;
  779. }
  780. pointerTop = pointerTop + fullSizeF.Height + lineSpace;
  781. pointerBottom = pointerTop + fullSizeF.Height;
  782. // 单行文字绘制
  783. if (textRectangleFs.Count > 0)
  784. {
  785. //lineSpaceSelectedRectangleF = DrawStringRow(graphics, textRectangleFs, font, textBrush, selected);
  786. TextRectangleF[] trfs = new TextRectangleF[textRectangleFs.Count];
  787. for (int i = 0; i < textRectangleFs.Count; i++)
  788. {
  789. trfs[i] = textRectangleFs[i];
  790. }
  791. textRectangleFs.Clear();
  792. allTextRectFs.Add(trfs);
  793. }
  794. }
  795. }
  796. else
  797. {
  798. // 空白行
  799. if (0 == lineCharCount)
  800. {
  801. float bottom = textTop;
  802. if (!isLinesStart)
  803. {
  804. bottom += lineSpace;
  805. }
  806. // 剪裁
  807. if (clip)
  808. {
  809. bottom += fullSizeF.Height;
  810. }
  811. // 多行绘制结束
  812. if (rectangle.Bottom < bottom)
  813. {
  814. isLinesEnd = true;
  815. break;
  816. }
  817. //// 选择状态行间隔范围填充
  818. //if (selected && 0 < lineSpace && lineSpaceSelectedRectangleF != RectangleF.Empty)
  819. //{
  820. // lineSpaceSelectedRectangleF.Height = lineSpace;
  821. // graphics.FillRectangle(LayoutCommon.SelectedBrush,
  822. // lineSpaceSelectedRectangleF);
  823. // lineSpaceSelectedRectangleF = RectangleF.Empty;
  824. //}
  825. //// 选择状态文本背景绘制
  826. //if (selected)
  827. //{
  828. // float correcting = 0;
  829. // if (alignment == TextAlignment.RightOrBottom)
  830. // {
  831. // correcting = rectangle.Right - textLeft;
  832. // }
  833. // else if (alignment == TextAlignment.Center)
  834. // {
  835. // correcting = (rectangle.Right - textLeft) / 2;
  836. // }
  837. // else if (alignment == TextAlignment.Evenness)
  838. // {
  839. // correcting = (rectangle.Right - textLeft) / 2;
  840. // }
  841. // RectangleF textRectangleF =
  842. // new RectangleF(pointerLeft + correcting,
  843. // pointerTop,
  844. // fullSizeF.Width / 4,
  845. // fullSizeF.Height + lineSpace);
  846. // graphics.FillRectangle(LayoutCommon.SelectedBrush, textRectangleF);
  847. //}
  848. }
  849. // 一行结束
  850. isLineEnd = true;
  851. break;
  852. }
  853. }
  854. // 多行绘制结束
  855. if (isLinesEnd)
  856. {
  857. break;
  858. }
  859. // 一行绘制结束
  860. if (isLineEnd)
  861. {
  862. // 下一个文字位置计算
  863. if (isLinesStart)
  864. {
  865. textTop = textTop + fullSizeF.Height;
  866. isLinesStart = false;
  867. }
  868. else
  869. {
  870. textTop = textTop + lineSpace + fullSizeF.Height;
  871. }
  872. pointerTop = pointerTop + fullSizeF.Height + lineSpace;
  873. pointerBottom = pointerTop + fullSizeF.Height;
  874. // 一行文本绘制
  875. //lineSpaceSelectedRectangleF = DrawLineHorizontal(graphics, textRectangleFs,
  876. // font, underline, strikeout, textBrush, rectangle, alignment, selected);
  877. if (textRectangleFs.Count > 0)
  878. {
  879. SetStringAlignmentH(textRectangleFs, rectangle, alignment, wrap, clip);
  880. //lineSpaceSelectedRectangleF = DrawStringRow(graphics, textRectangleFs, font, textBrush, selected);
  881. TextRectangleF[] trfs = new TextRectangleF[textRectangleFs.Count];
  882. for (int i = 0; i < textRectangleFs.Count; i++)
  883. {
  884. trfs[i] = textRectangleFs[i];
  885. }
  886. textRectangleFs.Clear();
  887. allTextRectFs.Add(trfs);
  888. }
  889. }
  890. }
  891. // 文本绘制结束
  892. if (isLinesEnd)
  893. {
  894. //if (selected && isLinesStart && isLinesEnd)
  895. //{
  896. // // 选择状态空文本背景绘制
  897. // graphics.FillRectangle(LayoutCommon.SelectedBrush, rectangle);
  898. //}
  899. if (textRectangleFs.Count > 0)
  900. {
  901. SetStringAlignmentH(textRectangleFs, rectangle, alignment, wrap, clip);
  902. //DrawStringRow(graphics, textRectangleFs, font, textBrush, selected);
  903. TextRectangleF[] trfs = new TextRectangleF[textRectangleFs.Count];
  904. for (int i = 0; i < textRectangleFs.Count; i++)
  905. {
  906. trfs[i] = textRectangleFs[i];
  907. }
  908. textRectangleFs.Clear();
  909. allTextRectFs.Add(trfs);
  910. }
  911. }
  912. // 垂直方向文本位置设定
  913. float correctingV = 0;
  914. if (alignmentVertical == TextAlignment.RightOrBottom)
  915. {
  916. float bottom = allTextRectFs[allTextRectFs.Count - 1][0].RectangleF.Bottom;
  917. correctingV = rectangle.Bottom - bottom;
  918. if (correctingV < 0)
  919. {
  920. correctingV = 0;
  921. }
  922. foreach (TextRectangleF[] rfs in allTextRectFs)
  923. {
  924. foreach (TextRectangleF rf in rfs)
  925. {
  926. rf.RectangleY = rf.RectangleY + correctingV;
  927. graphics.DrawString(rf.Text, font, textBrush, rf.RectangleF,
  928. LayoutCommon.StringFormatHorizontal);
  929. }
  930. }
  931. }
  932. else if (alignmentVertical == TextAlignment.Center)
  933. {
  934. float bottom = allTextRectFs[allTextRectFs.Count - 1][0].RectangleF.Bottom;
  935. correctingV = (rectangle.Bottom - bottom) / 2;
  936. if (correctingV < 0)
  937. {
  938. correctingV = 0;
  939. }
  940. foreach (TextRectangleF[] rfs in allTextRectFs)
  941. {
  942. foreach (TextRectangleF rf in rfs)
  943. {
  944. rf.RectangleY = rf.RectangleY + correctingV;
  945. graphics.DrawString(rf.Text, font, textBrush, rf.RectangleF,
  946. LayoutCommon.StringFormatHorizontal);
  947. }
  948. }
  949. }
  950. else
  951. {
  952. foreach (TextRectangleF[] rfs in allTextRectFs)
  953. {
  954. foreach (TextRectangleF rf in rfs)
  955. {
  956. graphics.DrawString(rf.Text, font, textBrush, rf.RectangleF,
  957. LayoutCommon.StringFormatHorizontal);
  958. }
  959. }
  960. }
  961. }
  962. /// <summary>
  963. /// 根据横向文本对齐方式,设定文本位子
  964. /// </summary>
  965. /// <param name="textRectangleFs">每个文字的范围</param>
  966. /// <param name="rectangleF">文本范围</param>
  967. /// <param name="alignment">文本对齐方式</param>
  968. /// <param name="wrap">是否自动文本换行</param>
  969. /// <param name="clip">是否剪裁延伸到边框外侧的文本</param>
  970. private static void SetStringAlignmentH(
  971. List<TextRectangleF> textRectangleFs,
  972. RectangleF rectangleF,
  973. TextAlignment alignment,
  974. bool wrap,
  975. bool clip)
  976. {
  977. //if (0 < textRectangleFs.Count)
  978. {
  979. float correcting = 0;
  980. float right = textRectangleFs[textRectangleFs.Count - 1].RectangleF.Right;
  981. // 文本对齐方式
  982. if (alignment == TextAlignment.RightOrBottom)
  983. {
  984. correcting = rectangleF.Right - right;
  985. if (wrap)
  986. {
  987. if (0 < correcting)
  988. {
  989. foreach (TextRectangleF rf in textRectangleFs)
  990. {
  991. rf.RectangleX += correcting;
  992. }
  993. }
  994. }
  995. // 不自动换行
  996. else
  997. {
  998. // 剪裁
  999. if (clip)
  1000. {
  1001. int count = 0;
  1002. foreach (TextRectangleF rf in textRectangleFs)
  1003. {
  1004. rf.RectangleX += correcting;
  1005. if (rf.RectangleX < rectangleF.Left)
  1006. {
  1007. count++;
  1008. }
  1009. }
  1010. if (count > 0)
  1011. {
  1012. textRectangleFs.RemoveRange(0, count);
  1013. }
  1014. }
  1015. // 不剪裁
  1016. else
  1017. {
  1018. int count = 0;
  1019. foreach (TextRectangleF rf in textRectangleFs)
  1020. {
  1021. rf.RectangleX += correcting;
  1022. if (rf.RectangleF.Right < rectangleF.Left)
  1023. {
  1024. count++;
  1025. }
  1026. }
  1027. if (count > 0)
  1028. {
  1029. textRectangleFs.RemoveRange(0, count);
  1030. }
  1031. }
  1032. }
  1033. }
  1034. else if (alignment == TextAlignment.Center)
  1035. {
  1036. correcting = (rectangleF.Right - right) / 2;
  1037. if (wrap)
  1038. {
  1039. if (0 < correcting)
  1040. {
  1041. foreach (TextRectangleF rf in textRectangleFs)
  1042. {
  1043. rf.RectangleX += correcting;
  1044. }
  1045. }
  1046. }
  1047. // 不自动换行
  1048. else
  1049. {
  1050. // 剪裁
  1051. if (clip)
  1052. {
  1053. int index = -1;
  1054. int count = 0;
  1055. int start = -1;
  1056. int length = 0;
  1057. foreach (TextRectangleF rf in textRectangleFs)
  1058. {
  1059. index++;
  1060. rf.RectangleX += correcting;
  1061. if (rf.RectangleX < rectangleF.Left)
  1062. {
  1063. count++;
  1064. }
  1065. else if (rectangleF.Right < rf.RectangleF.Right)
  1066. {
  1067. if (start < 0)
  1068. {
  1069. start = index;
  1070. }
  1071. length++;
  1072. }
  1073. }
  1074. if (length > 0)
  1075. {
  1076. textRectangleFs.RemoveRange(start, length);
  1077. }
  1078. if (count > 0)
  1079. {
  1080. textRectangleFs.RemoveRange(0, count);
  1081. }
  1082. }
  1083. else
  1084. {
  1085. int index = -1;
  1086. int count = 0;
  1087. int start = -1;
  1088. int length = 0;
  1089. foreach (TextRectangleF rf in textRectangleFs)
  1090. {
  1091. index++;
  1092. rf.RectangleX += correcting;
  1093. if (rf.RectangleF.Right < rectangleF.Left)
  1094. {
  1095. count++;
  1096. }
  1097. else if (rectangleF.Right < rf.RectangleX)
  1098. {
  1099. if (start < 0)
  1100. {
  1101. start = index;
  1102. }
  1103. length++;
  1104. }
  1105. }
  1106. if (length > 0)
  1107. {
  1108. textRectangleFs.RemoveRange(start, length);
  1109. }
  1110. if (count > 0)
  1111. {
  1112. textRectangleFs.RemoveRange(0, count);
  1113. }
  1114. }
  1115. }
  1116. }
  1117. else if (alignment == TextAlignment.Evenness)
  1118. {
  1119. if (1 < textRectangleFs.Count)
  1120. {
  1121. correcting = (rectangleF.Right - right) / (textRectangleFs.Count - 1);
  1122. if (correcting > 0)
  1123. {
  1124. for (int i = 0; i < textRectangleFs.Count; i++)
  1125. {
  1126. textRectangleFs[i].RectangleX += correcting * i;
  1127. }
  1128. }
  1129. }
  1130. else
  1131. {
  1132. textRectangleFs[0].RectangleX += (rectangleF.Right - right) / 2;
  1133. }
  1134. }
  1135. }
  1136. }
  1137. // /// <summary>
  1138. // /// 横向绘制单行文本
  1139. // /// </summary>
  1140. // /// <param name="graphics">Graphics</param>
  1141. // /// <param name="textRectangleFs">每个文字的范围</param>
  1142. // /// <param name="font">字体</param>
  1143. // /// <param name="textBrush">文本笔刷</param>
  1144. // /// <param name="selected">是否选择</param>
  1145. // /// <returns>文本行间隔范围</returns>
  1146. // private static RectangleF DrawStringRow(
  1147. // Graphics graphics,
  1148. // List<TextRectangleF> textRectangleFs,
  1149. // Font font,
  1150. // SolidBrush textBrush,
  1151. // bool selected)
  1152. // {
  1153. // //if (0 < textRectangleFs.Count)
  1154. // {
  1155. // //// 文字绘制范围
  1156. // //float width = textRectangleFs[textRectangleFs.Count - 1].RectangleF.Right
  1157. // // - textRectangleFs[0].RectangleF.Left;
  1158. // //RectangleF selectedRectangleF =
  1159. // // new RectangleF(textRectangleFs[0].RectangleF.Left,
  1160. // // textRectangleFs[0].RectangleF.Top,
  1161. // // width,
  1162. // // textRectangleFs[0].RectangleF.Height);
  1163. // //RectangleF lineSpaceSelectedRectangleF = RectangleF.Empty;
  1164. // //if (selected)
  1165. // //{
  1166. // // // 选择状态文字的背景绘制
  1167. // // graphics.FillRectangle(LayoutCommon.SelectedBrush, selectedRectangleF);
  1168. // // lineSpaceSelectedRectangleF.X = selectedRectangleF.Left;
  1169. // // lineSpaceSelectedRectangleF.Y = selectedRectangleF.Bottom;
  1170. // // lineSpaceSelectedRectangleF.Width = selectedRectangleF.Width;
  1171. // //}
  1172. // foreach (TextRectangleF rf in textRectangleFs)
  1173. // {
  1174. //#if DRAWTEST
  1175. // graphics.DrawRectangle(new Pen(Color.Blue, 0.1f), rf.RectangleF.X, rf.RectangleF.Y, rf.RectangleF.Width, rf.RectangleF.Height);
  1176. //#endif
  1177. // graphics.DrawString(rf.Text, font, textBrush, rf.RectangleF,
  1178. // LayoutCommon.StringFormatHorizontal);
  1179. // }
  1180. // textRectangleFs.Clear();
  1181. // //return lineSpaceSelectedRectangleF;
  1182. // }
  1183. // }
  1184. #endregion 绘制文本
  1185. #endregion 函数
  1186. }
  1187. }