HpglExportDraw.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. using FastReport.Export.Hpgl.Commands;
  2. using FastReport.Export.Hpgl.Utils;
  3. using FastReport.Utils;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. using System.Text;
  9. namespace FastReport.Export.Hpgl
  10. {
  11. public partial class HpglExport
  12. {
  13. private void AddRectangleFill(float x, float y, float width, float height, Brush brush)
  14. {
  15. if (fillMode == HpglFillMode.Solid)
  16. hpglDocument.FillRectangle(x / Units.Millimeters, (y - height) / Units.Millimeters, width / Units.Millimeters, height / Units.Millimeters, brush);
  17. else
  18. {
  19. PointF startPoint = new PointF(0, 0);
  20. PointF[] points = new PointF[6];
  21. byte[] pTypes = new byte[4];
  22. points[0] = startPoint;
  23. points[1] = new PointF(startPoint.X + width, startPoint.Y);
  24. points[2] = new PointF(startPoint.X + width, startPoint.Y - height);
  25. points[3] = new PointF(startPoint.X, startPoint.Y - height);
  26. AddPath(points, pTypes, (brush as SolidBrush).Color, 1, LineStyle.Solid, x, y, true, brush);
  27. }
  28. }
  29. private void AddRectangleFill(float x, float y, float width, float height, Color color)
  30. {
  31. AddRectangleFill(x, y, width, height, new SolidBrush(color));
  32. }
  33. private void AddBorder(Border border, float left, float top, float width, float height)
  34. {
  35. //float mWidth = width / Units.Millimeters;
  36. //float mHeight = height / Units.Millimeters;
  37. //float mTop = top / Units.Millimeters;
  38. //float mLeft = left / Units.Millimeters;
  39. //float borderWidth = border.Width / Units.Millimeters;
  40. //float shadowrWidth = border.ShadowWidth / Units.Millimeters;
  41. float oTop = pageHeight * Units.Millimeters - top;
  42. if (border.Shadow)
  43. {
  44. PointF startPoint = new PointF(width + border.ShadowWidth, -height - border.ShadowWidth);
  45. PointF[] points = new PointF[6];
  46. points[0] = startPoint;
  47. points[1] = new PointF(startPoint.X - width, startPoint.Y);
  48. points[2] = new PointF(startPoint.X - width, startPoint.Y + border.ShadowWidth);
  49. points[3] = new PointF(startPoint.X - border.ShadowWidth, startPoint.Y + border.ShadowWidth);
  50. points[4] = new PointF(startPoint.X - border.ShadowWidth, startPoint.Y + height);
  51. points[5] = new PointF(startPoint.X, startPoint.Y + height);
  52. byte[] pTypes = new byte[6];
  53. AddPath(points, pTypes, border.ShadowColor, 1, LineStyle.Solid, left, oTop, true, null);
  54. // shadows fill
  55. AddRectangleFill(left + width, oTop - border.ShadowWidth, border.ShadowWidth, height, border.ShadowColor);
  56. AddRectangleFill(left + border.ShadowWidth, oTop - height, width, border.ShadowWidth, border.ShadowColor);
  57. }
  58. if (border.Lines != BorderLines.None)
  59. {
  60. if (border.Lines == BorderLines.All &&
  61. border.LeftLine.Equals(border.RightLine) &&
  62. border.TopLine.Equals(border.BottomLine) &&
  63. border.LeftLine.Equals(border.TopLine))
  64. {
  65. if (border.Width > 0 && border.Color != Color.Transparent)
  66. {
  67. PointF[] points = new PointF[4];
  68. points[0] = new PointF(0, 0);
  69. points[1] = new PointF(width, 0);
  70. points[2] = new PointF(width, height);
  71. points[3] = new PointF(0, height);
  72. byte[] pTypes = new byte[6];
  73. AddPath(points, pTypes, border.Color, 1, border.Style, left, oTop - height, true, null);
  74. if (border.LeftLine.Style == LineStyle.Double)
  75. {
  76. points = new PointF[4];
  77. points[0] = new PointF(0, 0);
  78. points[1] = new PointF(width - 2 * 2, 0);
  79. points[2] = new PointF(width - 2 * 2, height - 2 * 2);
  80. points[3] = new PointF(0, height - 2 * 2);
  81. pTypes = new byte[6];
  82. AddPath(points, pTypes, border.Color, 1, border.Style, left + 2,
  83. oTop - height + 2, true, null);
  84. }
  85. }
  86. }
  87. else
  88. {
  89. float Left = left;
  90. float Top = top;
  91. float Right = left + width;
  92. float Bottom = top + height;
  93. Top -= 0.1f;
  94. Bottom += 0.1f;
  95. if ((border.Lines & BorderLines.Left) > 0)
  96. {
  97. LineObject line = new LineObject();
  98. line.Left = Left;
  99. line.Top = Top;
  100. line.Width = 0;
  101. line.Height = height;
  102. line.Border.Color = border.LeftLine.Color;
  103. line.Border.Width = border.LeftLine.Width;
  104. line.Border.Style = border.LeftLine.Style;
  105. AddLine(line);
  106. if (border.LeftLine.Style == LineStyle.Double)
  107. {
  108. LineObject lineD = new LineObject();
  109. lineD.Left = Left + 2;
  110. lineD.Top = Top;
  111. lineD.Width = 0;
  112. lineD.Height = height;
  113. lineD.Border.Color = border.LeftLine.Color;
  114. lineD.Border.Width = border.LeftLine.Width;
  115. lineD.Border.Style = border.LeftLine.Style;
  116. AddLine(lineD);
  117. }
  118. }
  119. if ((border.Lines & BorderLines.Right) > 0)
  120. {
  121. LineObject line = new LineObject();
  122. line.Left = Right;
  123. line.Top = Top;
  124. line.Width = 0;
  125. line.Height = height;
  126. line.Border.Color = border.RightLine.Color;
  127. line.Border.Width = border.RightLine.Width;
  128. line.Border.Style = border.RightLine.Style;
  129. AddLine(line);
  130. if (border.RightLine.Style == LineStyle.Double)
  131. {
  132. LineObject lineD = new LineObject();
  133. lineD.Left = Right - 2;
  134. lineD.Top = Top;
  135. lineD.Width = 0;
  136. lineD.Height = height;
  137. lineD.Border.Color = border.RightLine.Color;
  138. lineD.Border.Width = border.RightLine.Width;
  139. lineD.Border.Style = border.RightLine.Style;
  140. AddLine(lineD);
  141. }
  142. }
  143. if ((border.Lines & BorderLines.Top) > 0)
  144. {
  145. LineObject line = new LineObject();
  146. line.Left = Left;
  147. line.Top = Top;
  148. line.Width = width;
  149. line.Height = 0;
  150. line.Border.Color = border.TopLine.Color;
  151. line.Border.Width = border.TopLine.Width;
  152. line.Border.Style = border.TopLine.Style;
  153. AddLine(line);
  154. if (border.RightLine.Style == LineStyle.Double)
  155. {
  156. LineObject lineD = new LineObject();
  157. lineD.Left = Left - 2;
  158. lineD.Top = Top;
  159. lineD.Width = width;
  160. lineD.Height = 0;
  161. lineD.Border.Color = border.TopLine.Color;
  162. lineD.Border.Width = border.TopLine.Width;
  163. lineD.Border.Style = border.TopLine.Style;
  164. AddLine(lineD);
  165. }
  166. }
  167. if ((border.Lines & BorderLines.Bottom) > 0)
  168. {
  169. LineObject line = new LineObject();
  170. line.Left = Left;
  171. line.Top = Top + height;
  172. line.Width = width;
  173. line.Height = 0;
  174. line.Border.Color = border.BottomLine.Color;
  175. line.Border.Width = border.BottomLine.Width;
  176. line.Border.Style = border.BottomLine.Style;
  177. AddLine(line);
  178. if (border.RightLine.Style == LineStyle.Double)
  179. {
  180. LineObject lineD = new LineObject();
  181. lineD.Left = Left;
  182. lineD.Top = Top + height + 2;
  183. lineD.Width = width;
  184. lineD.Height = 0;
  185. lineD.Border.Color = border.BottomLine.Color;
  186. lineD.Border.Width = border.BottomLine.Width;
  187. lineD.Border.Style = border.BottomLine.Style;
  188. AddLine(lineD);
  189. }
  190. }
  191. }
  192. }
  193. }
  194. private void AddUnderlines(TextObject obj)
  195. {
  196. float lineHeight = obj.LineHeight == 0 ? obj.Font.GetHeight() : obj.LineHeight;
  197. float curY = obj.AbsTop + lineHeight;
  198. float bottom = obj.AbsBottom;
  199. float left = obj.AbsLeft;
  200. float right = obj.AbsRight;
  201. float width = obj.Border.Width;
  202. while (curY < bottom)
  203. {
  204. LineObject underline = new LineObject();
  205. underline.Left = left;
  206. underline.Top = curY;
  207. underline.Width = obj.Width;
  208. underline.Height = 0;
  209. underline.Border = obj.Border;
  210. AddLine(underline);
  211. curY += lineHeight;
  212. }
  213. }
  214. private void AddArrow(CapSettings Arrow, float lineWidth, float x1, float y1, float x2, float y2, out float x3, out float y3, out float x4, out float y4)
  215. {
  216. float k1, a, b, c, d;
  217. float xp, yp;
  218. float wd = Arrow.Width * lineWidth;
  219. float ld = Arrow.Height * lineWidth;
  220. if (Math.Abs(x2 - x1) > 0)
  221. {
  222. k1 = (y2 - y1) / (x2 - x1);
  223. a = (float)(Math.Pow(k1, 2) + 1);
  224. b = 2 * (k1 * ((x2 * y1 - x1 * y2) / (x2 - x1) - y2) - x2);
  225. c = (float)(Math.Pow(x2, 2) + Math.Pow(y2, 2) - Math.Pow(ld, 2) +
  226. Math.Pow((x2 * y1 - x1 * y2) / (x2 - x1), 2) -
  227. 2 * y2 * (x2 * y1 - x1 * y2) / (x2 - x1));
  228. d = (float)(Math.Pow(b, 2) - 4 * a * c);
  229. xp = (float)((-b + Math.Sqrt(d)) / (2 * a));
  230. if ((xp > x1) && (xp > x2) || (xp < x1) && (xp < x2))
  231. xp = (float)((-b - Math.Sqrt(d)) / (2 * a));
  232. yp = xp * k1 + (x2 * y1 - x1 * y2) / (x2 - x1);
  233. if (y2 != y1)
  234. {
  235. x3 = (float)(xp + wd * Math.Sin(Math.Atan(k1)));
  236. y3 = (float)(yp - wd * Math.Cos(Math.Atan(k1)));
  237. x4 = (float)(xp - wd * Math.Sin(Math.Atan(k1)));
  238. y4 = (float)(yp + wd * Math.Cos(Math.Atan(k1)));
  239. }
  240. else
  241. {
  242. x3 = xp; y3 = yp - wd;
  243. x4 = xp; y4 = yp + wd;
  244. }
  245. }
  246. else
  247. {
  248. xp = x2; yp = y2 - ld;
  249. if ((yp > y1) && (yp > y2) || (yp < y1) && (yp < y2))
  250. yp = y2 + ld;
  251. x3 = xp - wd; y3 = yp;
  252. x4 = xp + wd; y4 = yp;
  253. }
  254. }
  255. /// <summary>
  256. /// Add Line.
  257. /// </summary>
  258. private void AddLine(LineObject line)
  259. {
  260. float x1 = line.AbsLeft / Units.Millimeters;
  261. float y1 = pageHeight - line.AbsTop / Units.Millimeters;
  262. float x2 = x1 + line.Width / Units.Millimeters;
  263. float y2 = y1 - line.Height / Units.Millimeters;
  264. float Border = line.Border.Width / Units.Millimeters;
  265. if (line.StartCap.Style == CapStyle.Arrow)
  266. {
  267. float x3, y3, x4, y4;
  268. AddArrow(line.StartCap, Border, x2, y2, x1, y1, out x3, out y3, out x4, out y4);
  269. hpglDocument.DrawLine(x1, y1, x3, y3, line.Border.Color, Border, line.Border.Style);
  270. hpglDocument.DrawLine(x1, y1, x4, y4, line.Border.Color, Border, line.Border.Style);
  271. }
  272. if (line.EndCap.Style == CapStyle.Arrow)
  273. {
  274. float x3, y3, x4, y4;
  275. AddArrow(line.EndCap, Border, x1, y1, x2, y2, out x3, out y3, out x4, out y4);
  276. hpglDocument.DrawLine(x2, y2, x3, y3, line.Border.Color, Border, line.Border.Style);
  277. hpglDocument.DrawLine(x2, y2, x4, y4, line.Border.Color, Border, line.Border.Style);
  278. }
  279. hpglDocument.DrawLine(x1, y1, x2, y2, line.Border.Color, Border, line.Border.Style);
  280. }
  281. private void AddPolyLine(PolyLineObject p)
  282. {
  283. bool isClosed = (p is PolygonObject) ? true : false;
  284. Brush fillBrush = isClosed ? p.Fill.CreateBrush(new RectangleF(0, 0, p.Width, p.Height)) : null;
  285. AddPath(p.PointsArray.InvertY(), p.PointTypesArray, p.Border.Color, p.Border.Width,
  286. p.Border.Style, p.AbsLeft + p.CenterX, pageHeight * Units.Millimeters - p.AbsTop - p.CenterY, isClosed, fillBrush);
  287. }
  288. private void AddPath(PointF[] points, byte[] pointTypes, Color borderColor, float borderWidth,
  289. LineStyle borderLineStyle, float left, float top, bool isClosed, Brush fillBrush, PolygonType mode)
  290. {
  291. float x = left / Units.Millimeters;
  292. float y = top / Units.Millimeters; ;
  293. for (int i = 0; i < points.Length; i++)
  294. {
  295. points[i].X /= Units.Millimeters;
  296. points[i].Y /= Units.Millimeters;
  297. }
  298. if (FillMode == HpglFillMode.Border)
  299. fillBrush = null;
  300. hpglDocument.DrawPolyLine(x, y, points, pointTypes, borderColor, borderWidth / Units.Millimeters,
  301. borderLineStyle, isClosed, fillBrush, mode);
  302. }
  303. private void AddPath(PointF[] points, byte[] pointTypes, Color borderColor, float borderWidth,
  304. LineStyle borderLineStyle, float left, float top, bool isClosed, Brush fillBrush)
  305. {
  306. AddPath(points, pointTypes, borderColor, borderWidth,
  307. borderLineStyle, left, top, isClosed, fillBrush, PolygonType.Cleared);
  308. }
  309. public static PointF[] RotateVector(PointF[] vector, double angle, PointF center)
  310. {
  311. PointF[] rotatedVector = new PointF[vector.Length];
  312. for (int i = 0; i < vector.Length; i++)
  313. {
  314. rotatedVector[i].X = (float)(center.X + (vector[i].X - center.X) * Math.Cos(angle) + (center.Y - vector[i].Y) * Math.Sin(angle));
  315. rotatedVector[i].Y = (float)(center.Y + (vector[i].X - center.X) * Math.Sin(angle) + (vector[i].Y - center.Y) * Math.Cos(angle));
  316. }
  317. return rotatedVector;
  318. }
  319. private void AddGraphicsPath(GraphicsPath path, Color borderColor, float borderWith,
  320. LineStyle borderLineStyle, float left, float top, bool isClosed, bool invertY, float angle, PointF center)
  321. {
  322. List<PointF> points = new List<PointF>();
  323. List<byte> pTypes = new List<byte>();
  324. byte[] pathTypes = path.PathTypes;
  325. PointF[] pathPoints = path.PathPoints;
  326. if (angle != 0)
  327. {
  328. // rotate
  329. pathPoints = RotateVector(pathPoints, angle, center);
  330. }
  331. if (invertY)
  332. pathPoints = pathPoints.InvertY();
  333. PolygonType mode = PolygonType.Cleared;
  334. for (int i = 0; i < pathTypes.Length; i++)
  335. {
  336. byte pType = pathTypes[i];
  337. PointF point = pathPoints[i];
  338. mode = i > 0 && pathTypes[i - 1] == 163 ? PolygonType.Cleared : PolygonType.Closed;
  339. if (pType == 0 && points.Count > 0)
  340. {
  341. AddPath(points.ToArray(), pTypes.ToArray(), borderColor, borderWith,
  342. borderLineStyle, left, top, isClosed, null, mode);
  343. points.Clear();
  344. pTypes.Clear();
  345. }
  346. points.Add(point);
  347. pTypes.Add(pType);
  348. if (i == pathTypes.Length - 1)
  349. {
  350. AddPath(points.ToArray(), pTypes.ToArray(), borderColor, borderWith,
  351. borderLineStyle, left, top, isClosed, null, mode);
  352. }
  353. }
  354. }
  355. private void AddPolygon(PolygonObject polygonObject)
  356. {
  357. AddPolyLine(polygonObject);
  358. }
  359. private void AddShape(ShapeObject shapeObject)
  360. {
  361. float shapeWidth = shapeObject.Width;// / Units.Millimeters;
  362. float shapeHeight = shapeObject.Height;// / Units.Millimeters;
  363. float shapeTop = shapeObject.AbsTop;// / Units.Millimeters;
  364. float shapeLeft = shapeObject.AbsLeft;// / Units.Millimeters;
  365. float shapeBorderWidth = shapeObject.Border.Width;// / Units.Millimeters;
  366. Brush fillBrush = shapeObject.Fill.CreateBrush(new RectangleF(0, 0, shapeObject.Width, shapeObject.Height));
  367. switch (shapeObject.Shape)
  368. {
  369. case ShapeKind.Rectangle:
  370. {
  371. PointF[] points = new PointF[4];
  372. points[0] = new PointF(0, 0);
  373. points[1] = new PointF(shapeWidth, 0);
  374. points[2] = new PointF(shapeWidth, shapeHeight);
  375. points[3] = new PointF(0, shapeHeight);
  376. byte[] pTypes = new byte[4];
  377. AddPath(points, new byte[4], shapeObject.Border.Color, shapeBorderWidth,
  378. shapeObject.Border.Style, shapeLeft, pageHeight * Units.Millimeters - shapeTop - shapeHeight, true, fillBrush);
  379. }
  380. break;
  381. case ShapeKind.Triangle:
  382. {
  383. PointF[] points = new PointF[3];
  384. points[0] = new PointF(shapeWidth / 2, 0);
  385. points[1] = new PointF(shapeWidth, shapeHeight);
  386. points[2] = new PointF(0, shapeHeight);
  387. byte[] pTypes = new byte[3];
  388. AddPath(points, new byte[3], shapeObject.Border.Color, shapeBorderWidth,
  389. shapeObject.Border.Style, shapeLeft, pageHeight * Units.Millimeters - shapeTop - shapeHeight, true, fillBrush);
  390. }
  391. break;
  392. case ShapeKind.Diamond:
  393. {
  394. PointF[] points = new PointF[4];
  395. points[0] = new PointF(shapeWidth / 2, 0);
  396. points[1] = new PointF(shapeWidth, shapeHeight / 2);
  397. points[2] = new PointF(shapeWidth / 2, shapeHeight);
  398. points[3] = new PointF(0, shapeHeight / 2);
  399. byte[] pTypes = new byte[4];
  400. AddPath(points, new byte[4], shapeObject.Border.Color, shapeBorderWidth,
  401. shapeObject.Border.Style, shapeLeft, pageHeight * Units.Millimeters - shapeTop - shapeHeight, true, fillBrush);
  402. }
  403. break;
  404. case ShapeKind.Ellipse:
  405. {
  406. hpglDocument.DrawEllipse(shapeLeft / Units.Millimeters, pageHeight - shapeTop / Units.Millimeters, shapeWidth / Units.Millimeters,
  407. shapeHeight / Units.Millimeters, shapeObject.Border.Color, shapeBorderWidth / Units.Millimeters, shapeObject.Border.Style);
  408. break;
  409. }
  410. }
  411. }
  412. }
  413. }