DXFExportDraw.cs 20 KB

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