MeasureBrokenLine.cs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. using PaintDotNet.Annotation.Enum;
  2. using PaintDotNet.Base.CommTool;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Globalization;
  8. using System.Windows.Forms;
  9. using PaintDotNet.Base.SettingModel;
  10. using System.Linq;
  11. namespace PaintDotNet.Annotation.Measure
  12. {
  13. using PointEnumerator = IEnumerator<PointF>;
  14. using PointList = List<PointF>;
  15. /// <summary>
  16. /// 测量->曲线->折线
  17. /// </summary>
  18. class MeasureBrokenLine : MeasureDrawObject
  19. {
  20. /// <summary>
  21. /// 点集合
  22. /// </summary>
  23. public PointList pointArray;
  24. /// <summary>
  25. /// 属性绘制点
  26. /// </summary>
  27. private PointF rotationPoint;
  28. /// <summary>
  29. /// 折线长度
  30. /// </summary>
  31. private double Length = 0.0;
  32. /// <summary>
  33. /// Graphic objects for hit test
  34. /// </summary>
  35. private GraphicsPath areaPath = null;
  36. private Pen areaPen = null;
  37. private Region areaRegion = null;
  38. /// <summary>
  39. /// 测量信息矩形定义
  40. /// </summary>
  41. private RectangleF rectangleF1 = new RectangleF();
  42. private RectangleF rectangleF2 = new RectangleF();
  43. private RectangleF rectangleF3 = new RectangleF();
  44. private RectangleF rectangleF4 = new RectangleF();
  45. private RectangleF rectangleF5 = new RectangleF();
  46. private RectangleF rectangleF6 = new RectangleF();
  47. private RectangleF rectangleF7 = new RectangleF();
  48. private RectangleF rectangleF8 = new RectangleF();
  49. private RectangleF rectangleF9 = new RectangleF();
  50. private RectangleF rectangleF10 = new RectangleF();
  51. /// <summary>
  52. /// 文本上用于拖动的点
  53. /// </summary>
  54. private Point pointL = new Point();
  55. /// <summary>
  56. /// 绘制限制(第一次绘制时)
  57. /// </summary>
  58. public bool pointChange = true;
  59. /// <summary>
  60. /// 区分移动文本
  61. /// </summary>
  62. private int moveKb;
  63. /// <summary>
  64. /// 绘制限制(从配置文件加载)
  65. /// </summary>
  66. public bool configurationFile = false;
  67. /// <summary>
  68. /// 限制绘制(绘制中)
  69. /// </summary>
  70. public bool mouseUpPointChange = false;
  71. /// <summary>
  72. /// 绘制限制(更改属性时)
  73. /// </summary>
  74. private bool SavePointChange;
  75. /// <summary>
  76. /// 绘制属性
  77. /// </summary>
  78. private string[] drawingPropertiesList;
  79. /// <summary>
  80. /// 绘制属性(克隆)
  81. /// </summary>
  82. private string[] drawingPropertiesListClone;
  83. /// <summary>
  84. /// 旋转角度
  85. /// </summary>
  86. private double angle;
  87. /// <summary>
  88. /// 标注样式信息model
  89. /// </summary>
  90. private MeasureStyleModel.MeasureBrokenLine measurePolylineStyleModel;
  91. public MeasureStyleModel.MeasureBrokenLine MeasurePolylineStyleModel
  92. {
  93. set
  94. {
  95. this.measurePolylineStyleModel = value;
  96. }
  97. }
  98. public MeasureBrokenLine() : base()
  99. {
  100. this.objectType = DrawClass.Measure;
  101. this.drawToolType = DrawToolType.MeasureBrokenLine;
  102. pointArray = new PointList();
  103. Initialize();
  104. }
  105. public MeasureBrokenLine(ISurfaceBox surfaceBox, int x1, int y1, bool clone) : base()
  106. {
  107. this.objectType = DrawClass.Measure;
  108. this.drawToolType = DrawToolType.MeasureBrokenLine;
  109. MeasurePolylineStyleModel = surfaceBox.GetMeasureStyleModel().measureBrokenLine;
  110. pointArray = new PointList();
  111. startPoint.X = x1;
  112. startPoint.Y = y1;
  113. if (clone)
  114. pointArray.Add(new Point(x1, y1));
  115. this.measurementUnit = (MeasurementUnit)System.Enum.Parse(typeof(MeasurementUnit), surfaceBox.GetPxPerUnit()[0]);
  116. this.unitString = surfaceBox.GetPxPerUnit()[1];
  117. this.unit = surfaceBox.GetPxPerUnit()[2];
  118. surfaceBox.getMeasureInfo().TryGetValue(measurementUnit, out unitLength);
  119. Initialize();
  120. }
  121. public MeasureBrokenLine(ISurfaceBox surfaceBox, List<PointF> points, ParentStyleModel parentStyleModel, Object content) : base()
  122. {
  123. this.objectType = DrawClass.Measure;
  124. this.drawToolType = DrawToolType.MeasureBrokenLine;
  125. this.ISurfaceBox = surfaceBox;
  126. measurePolylineStyleModel = (MeasureStyleModel.MeasureBrokenLine)parentStyleModel;
  127. pointArray = DrawRulerHelper.DeepCopyListByReflect(points);
  128. this.measurementUnit = (MeasurementUnit)System.Enum.Parse(typeof(MeasurementUnit), surfaceBox.GetPxPerUnit()[0]);
  129. this.unitString = surfaceBox.GetPxPerUnit()[1];
  130. this.unit = surfaceBox.GetPxPerUnit()[2];
  131. surfaceBox.getMeasureInfo().TryGetValue(measurementUnit, out unitLength);
  132. this.configurationFile = true;
  133. }
  134. /// <summary>
  135. /// Clone this instance
  136. /// </summary>
  137. public override DrawObject Clone()
  138. {
  139. MeasureBrokenLine drawPolygon = new MeasureBrokenLine(ISurfaceBox, (int)pointArray[0].X, (int)pointArray[0].Y, false);
  140. drawPolygon.ISurfaceBox = ISurfaceBox;
  141. drawPolygon.pointArray.Clear();
  142. foreach (PointF p in this.pointArray)
  143. {
  144. drawPolygon.pointArray.Add(p);
  145. }
  146. if (drawingPropertiesList != null)
  147. drawPolygon.drawingPropertiesListClone = drawingPropertiesList;
  148. FillDrawObjectFields(drawPolygon);
  149. return drawPolygon;
  150. }
  151. public override DrawObject Clone(ISurfaceBox surfaceBox)
  152. {
  153. MeasureBrokenLine drawPolygon = new MeasureBrokenLine(surfaceBox, this.GetPoints(), this.measurePolylineStyleModel, null);
  154. if (drawingPropertiesList != null)
  155. drawPolygon.drawingPropertiesListClone = drawingPropertiesList;
  156. FillDrawObjectFields(drawPolygon);
  157. return drawPolygon;
  158. }
  159. /// <summary>
  160. /// 测量属性
  161. /// </summary>
  162. /// <returns></returns>
  163. public override Dictionary<System.Enum, object> GetData()
  164. {
  165. if (data.ContainsKey(MeasureAttributes.MeasureMethod))
  166. data[MeasureAttributes.MeasureMethod] = PdnResources.GetString("Menu.MeasureAction.CurveLength.Text");
  167. else
  168. data.Add(MeasureAttributes.MeasureMethod, PdnResources.GetString("Menu.MeasureAction.CurveLength.Text"));
  169. if (data.ContainsKey(MeasureAttributes.MeasureUnitCN))
  170. data[MeasureAttributes.MeasureUnitCN] = this.unitString;
  171. else
  172. data.Add(MeasureAttributes.MeasureUnitCN, this.unitString);
  173. if (data.ContainsKey(MeasureAttributes.MeasureUnitEN))
  174. data[MeasureAttributes.MeasureUnitEN] = this.unit;
  175. else
  176. data.Add(MeasureAttributes.MeasureUnitEN, this.unit);
  177. if (data.ContainsKey(MeasureAttributes.PixelStartX))
  178. data[MeasureAttributes.PixelStartX] = startPoint.X;
  179. else
  180. data.Add(MeasureAttributes.PixelStartX, startPoint.X);
  181. if (data.ContainsKey(MeasureAttributes.PixelStartY))
  182. data[MeasureAttributes.PixelStartY] = startPoint.Y;
  183. else
  184. data.Add(MeasureAttributes.PixelStartY, startPoint.Y);
  185. if (data.ContainsKey(MeasureAttributes.PhysicalStartX))
  186. data[MeasureAttributes.PhysicalStartX] = Math.Round(startPoint.X * unitLength, decimalPlaces);
  187. else
  188. data.Add(MeasureAttributes.PhysicalStartX, Math.Round(startPoint.X * unitLength, decimalPlaces));
  189. if (data.ContainsKey(MeasureAttributes.PhysicalStartY))
  190. data[MeasureAttributes.PhysicalStartY] = Math.Round(startPoint.Y * unitLength, decimalPlaces);
  191. else
  192. data.Add(MeasureAttributes.PhysicalStartY, Math.Round(startPoint.Y * unitLength, decimalPlaces));
  193. if (data.ContainsKey(MeasureAttributes.PixelLength))
  194. data[MeasureAttributes.PixelLength] = Math.Round(Length, decimalPlaces);
  195. else
  196. data.Add(MeasureAttributes.PixelLength, Math.Round(Length, decimalPlaces));
  197. string s = Math.Round(Length * unitLength, decimalPlaces).ToString();
  198. if (s.IndexOf(".") == -1)
  199. {
  200. for (int i = 0; i < decimalPlaces; i++)
  201. {
  202. if (i == 0)
  203. s += ".";
  204. s += "0";
  205. }
  206. }
  207. else
  208. {
  209. int a = s.Length - s.IndexOf(".") - 1;
  210. if (a < decimalPlaces)
  211. {
  212. for (int i = 0; i < decimalPlaces - a; i++)
  213. {
  214. s += "0";
  215. }
  216. }
  217. }
  218. if (data.ContainsKey(MeasureAttributes.PhysicalLength))
  219. data[MeasureAttributes.PhysicalLength] = s;
  220. else
  221. data.Add(MeasureAttributes.PhysicalLength, s);
  222. if (data.ContainsKey(MeasureAttributes.NumberOfSegments))
  223. data[MeasureAttributes.NumberOfSegments] = this.pointArray.Count - 1;
  224. else
  225. data.Add(MeasureAttributes.NumberOfSegments, this.pointArray.Count - 1);
  226. return data;
  227. }
  228. public override void Draw(Graphics g)
  229. {
  230. drawingProperties.TryGetValue(this.drawToolType, out drawingPropertiesList);
  231. pointChangeObject.TryGetValue(this.drawToolType, out SavePointChange);
  232. double length = 0f;
  233. float x1 = 0, y1 = 0;
  234. float x2, y2;
  235. PointF firstPoint = new PointF();
  236. PointF secondPoint = new PointF();
  237. Matrix mtxSave = g.Transform;
  238. Matrix matrix = g.Transform;
  239. if (pointArray.Count >= 2)
  240. {
  241. if (drawingPropertiesList == null)
  242. {
  243. drawingPropertiesList = drawingPropertiesListClone;
  244. this.configurationFile = true;
  245. }
  246. //计算需要旋转的角度
  247. if (measurePolylineStyleModel.linePosition == 0)
  248. {
  249. angle = BasicCalculationHelper.Angle(pointArray[0], pointArray[1], new PointF(pointArray[0].X, pointArray[1].Y));
  250. rotationPoint = pointArray[0];
  251. }
  252. else if (measurePolylineStyleModel.linePosition == 1)
  253. {
  254. angle = BasicCalculationHelper.Angle(pointArray[pointArray.Count - 2], pointArray[pointArray.Count - 1], new PointF(pointArray[pointArray.Count - 2].X, pointArray[pointArray.Count - 1].Y));
  255. rotationPoint = pointArray[pointArray.Count - 1];
  256. }
  257. // 画布旋转
  258. if (angle < 90)
  259. {
  260. matrix.RotateAt((float)angle, rotationPoint);
  261. g.Transform = matrix;
  262. }
  263. else
  264. {
  265. if (measurePolylineStyleModel.linePosition == 0)
  266. {
  267. angle = BasicCalculationHelper.Angle(pointArray[1], pointArray[0], new PointF(pointArray[1].X, pointArray[0].Y));
  268. }
  269. else if (measurePolylineStyleModel.linePosition == 1)
  270. {
  271. angle = BasicCalculationHelper.Angle(pointArray[pointArray.Count - 1], pointArray[pointArray.Count - 2], new PointF(pointArray[pointArray.Count - 1].X, pointArray[pointArray.Count - 2].Y));
  272. }
  273. matrix.RotateAt((float)angle, rotationPoint);
  274. g.Transform = matrix;
  275. }
  276. }
  277. SizeF sizeF = new SizeF();
  278. g.SmoothingMode = SmoothingMode.AntiAlias;
  279. Color color = Color.FromArgb(measurePolylineStyleModel.lineColor);
  280. int lineWidth = measurePolylineStyleModel.lineWidth;
  281. Font textfont = new Font(measurePolylineStyleModel.font, measurePolylineStyleModel.fontSize);
  282. Brush textbrush = new SolidBrush(Color.FromArgb(measurePolylineStyleModel.textColor));
  283. // 是否绘制
  284. if (this.pointChange || this.SavePointChange || this.mouseUpPointChange || this.mouseUpAttribute)
  285. {
  286. // 属性文本的间隔定义
  287. int offsetValue = measurePolylineStyleModel.fontSize + measurePolylineStyleModel.fontSize / 2;
  288. int offsetValue1 = measurePolylineStyleModel.lineWidth * 2 / 3;
  289. int offset = offsetValue1;
  290. this.pointL = new Point((int)rotationPoint.X, (int)rotationPoint.Y);
  291. if (drawingPropertiesList != null)
  292. {
  293. // 像素长度
  294. if (drawingPropertiesList.Contains(MeasureAttributes.PixelLength.ToString()))
  295. {
  296. sizeF = g.MeasureString("" + Math.Round(length, decimalPlaces) + "px", textfont);
  297. rectangleF8.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  298. offset += offsetValue;
  299. }
  300. // 物理长度
  301. if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalLength.ToString()))
  302. {
  303. string s = Math.Round(length * unitLength, decimalPlaces).ToString();
  304. if (s.IndexOf(".") == -1)
  305. {
  306. for (int i = 0; i < decimalPlaces; i++)
  307. {
  308. if (i == 0)
  309. s += ".";
  310. s += "0";
  311. }
  312. }
  313. else
  314. {
  315. int a = s.Length - s.IndexOf(".") - 1;
  316. if (a < decimalPlaces)
  317. {
  318. for (int i = 0; i < decimalPlaces - a; i++)
  319. {
  320. s += "0";
  321. }
  322. }
  323. }
  324. sizeF = g.MeasureString(s + this.unit, textfont);
  325. rectangleF9.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  326. offset += offsetValue;
  327. }
  328. // 线段数
  329. if (drawingPropertiesList.Contains(MeasureAttributes.NumberOfSegments.ToString()))
  330. {
  331. sizeF = g.MeasureString("" + (this.pointArray.Count - 1), textfont);
  332. rectangleF10.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  333. offset += offsetValue;
  334. }
  335. // 测量方式
  336. if (drawingPropertiesList.Contains(MeasureAttributes.MeasureMethod.ToString()))
  337. {
  338. sizeF = g.MeasureString("" + PdnResources.GetString("Menu.MeasureAction.CurveLength.Text"), textfont);
  339. rectangleF1.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  340. offset += offsetValue;
  341. }
  342. // 测量单位(中文)
  343. if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitCN.ToString()))
  344. {
  345. sizeF = g.MeasureString("" + this.unitString, textfont);
  346. rectangleF2.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  347. offset += offsetValue;
  348. }
  349. // 测量单位(英文)
  350. if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitEN.ToString()))
  351. {
  352. sizeF = g.MeasureString("" + this.unit, textfont);
  353. rectangleF3.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  354. offset += offsetValue;
  355. }
  356. // 像素起始点X
  357. if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartX.ToString()))
  358. {
  359. sizeF = g.MeasureString("" + startPoint.X, textfont);
  360. rectangleF4.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  361. offset += offsetValue;
  362. }
  363. // 像素起始点Y
  364. if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartY.ToString()))
  365. {
  366. sizeF = g.MeasureString("" + startPoint.Y, textfont);
  367. rectangleF5.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  368. offset += offsetValue;
  369. }
  370. // 物理起始点X
  371. if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartX.ToString()))
  372. {
  373. sizeF = g.MeasureString("" + Math.Round(startPoint.X * unitLength, decimalPlaces), textfont);
  374. rectangleF6.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  375. offset += offsetValue;
  376. }
  377. // 物理起始点Y
  378. if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartY.ToString()))
  379. {
  380. sizeF = g.MeasureString("" + Math.Round(startPoint.Y * unitLength, decimalPlaces), textfont);
  381. rectangleF7.Location = new Point((int)rotationPoint.X - (int)sizeF.Width / 2, (int)rotationPoint.Y + offset);
  382. offset += offsetValue;
  383. }
  384. }
  385. }
  386. if (pointArray.Count >= 2)
  387. {
  388. PointEnumerator enumerator = pointArray.GetEnumerator();
  389. firstPoint = pointArray[0];
  390. secondPoint = pointArray[1];
  391. if (enumerator.MoveNext())
  392. {
  393. x1 = ((PointF)enumerator.Current).X;
  394. y1 = ((PointF)enumerator.Current).Y;
  395. }
  396. while (enumerator.MoveNext())
  397. {
  398. x2 = ((PointF)enumerator.Current).X;
  399. y2 = ((PointF)enumerator.Current).Y;
  400. length += BasicCalculationHelper.GetDistance(new PointF(x1, y1), new PointF(x2, y2), decimalPlaces);
  401. x1 = x2;
  402. y1 = y2;
  403. }
  404. if (drawingPropertiesList != null)
  405. {
  406. // 测量方式
  407. if (drawingPropertiesList.Contains(MeasureAttributes.MeasureMethod.ToString()))
  408. {
  409. sizeF = g.MeasureString("" + PdnResources.GetString("Menu.MeasureAction.CurveLength.Text"), textfont);
  410. rectangleF1.Width = sizeF.Width;
  411. rectangleF1.Height = sizeF.Height;
  412. g.DrawString("" + PdnResources.GetString("Menu.MeasureAction.CurveLength.Text"), textfont, textbrush, rectangleF1);
  413. }
  414. else
  415. {
  416. rectangleF1 = new RectangleF();
  417. }
  418. // 测量单位(中文)
  419. if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitCN.ToString()))
  420. {
  421. sizeF = g.MeasureString("" + this.unitString, textfont);
  422. rectangleF2.Width = sizeF.Width;
  423. rectangleF2.Height = sizeF.Height;
  424. g.DrawString("" + this.unitString, textfont, textbrush, rectangleF2);
  425. }
  426. else
  427. {
  428. rectangleF2 = new RectangleF();
  429. }
  430. // 测量单位(英文)
  431. if (drawingPropertiesList.Contains(MeasureAttributes.MeasureUnitEN.ToString()))
  432. {
  433. sizeF = g.MeasureString("" + this.unit, textfont);
  434. rectangleF3.Width = sizeF.Width;
  435. rectangleF3.Height = sizeF.Height;
  436. g.DrawString("" + this.unit, textfont, textbrush, rectangleF3);
  437. }
  438. else
  439. {
  440. rectangleF3 = new RectangleF();
  441. }
  442. // 像素起始点X
  443. if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartX.ToString()))
  444. {
  445. sizeF = g.MeasureString("" + startPoint.X, textfont);
  446. rectangleF4.Width = sizeF.Width;
  447. rectangleF4.Height = sizeF.Height;
  448. g.DrawString("" + startPoint.X, textfont, textbrush, rectangleF4);
  449. }
  450. else
  451. {
  452. rectangleF4 = new RectangleF();
  453. }
  454. // 像素起始点Y
  455. if (drawingPropertiesList.Contains(MeasureAttributes.PixelStartY.ToString()))
  456. {
  457. sizeF = g.MeasureString("" + startPoint.Y, textfont);
  458. rectangleF5.Width = sizeF.Width;
  459. rectangleF5.Height = sizeF.Height;
  460. g.DrawString("" + startPoint.Y, textfont, textbrush, rectangleF5);
  461. }
  462. else
  463. {
  464. rectangleF5 = new RectangleF();
  465. }
  466. // 物理起始点X
  467. if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartX.ToString()))
  468. {
  469. sizeF = g.MeasureString("" + Math.Round(startPoint.X * unitLength, decimalPlaces), textfont);
  470. rectangleF6.Width = sizeF.Width;
  471. rectangleF6.Height = sizeF.Height;
  472. g.DrawString("" + Math.Round(startPoint.X * unitLength, decimalPlaces), textfont, textbrush, rectangleF6);
  473. }
  474. else
  475. {
  476. rectangleF6 = new RectangleF();
  477. }
  478. // 物理起始点Y
  479. if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalStartY.ToString()))
  480. {
  481. sizeF = g.MeasureString("" + Math.Round(startPoint.Y * unitLength, decimalPlaces), textfont);
  482. rectangleF7.Width = sizeF.Width;
  483. rectangleF7.Height = sizeF.Height;
  484. g.DrawString("" + Math.Round(startPoint.Y * unitLength, decimalPlaces), textfont, textbrush, rectangleF7);
  485. }
  486. else
  487. {
  488. rectangleF7 = new RectangleF();
  489. }
  490. // 像素长度
  491. if (drawingPropertiesList.Contains(MeasureAttributes.PixelLength.ToString()))
  492. {
  493. sizeF = g.MeasureString("" + Math.Round(length, decimalPlaces) + "px", textfont);
  494. rectangleF8.Width = sizeF.Width;
  495. rectangleF8.Height = sizeF.Height;
  496. g.DrawString("" + Math.Round(length, decimalPlaces) + "px", textfont, textbrush, rectangleF8);
  497. }
  498. else
  499. {
  500. rectangleF8 = new RectangleF();
  501. }
  502. // 物理长度
  503. if (drawingPropertiesList.Contains(MeasureAttributes.PhysicalLength.ToString()))
  504. {
  505. string s = Math.Round(length * unitLength, decimalPlaces).ToString();
  506. if (s.IndexOf(".") == -1)
  507. {
  508. for (int i = 0; i < decimalPlaces; i++)
  509. {
  510. if (i == 0)
  511. s += ".";
  512. s += "0";
  513. }
  514. }
  515. else
  516. {
  517. int a = s.Length - s.IndexOf(".") - 1;
  518. if (a < decimalPlaces)
  519. {
  520. for (int i = 0; i < decimalPlaces - a; i++)
  521. {
  522. s += "0";
  523. }
  524. }
  525. }
  526. sizeF = g.MeasureString(s + this.unit, textfont);
  527. rectangleF9.Width = sizeF.Width;
  528. rectangleF9.Height = sizeF.Height;
  529. g.DrawString(s + this.unit, textfont, textbrush, rectangleF9);
  530. }
  531. else
  532. {
  533. rectangleF9 = new RectangleF();
  534. }
  535. // 线段数
  536. if (drawingPropertiesList.Contains(MeasureAttributes.NumberOfSegments.ToString()))
  537. {
  538. sizeF = g.MeasureString("" + (this.pointArray.Count - 1), textfont);
  539. rectangleF10.Width = sizeF.Width;
  540. rectangleF10.Height = sizeF.Height;
  541. g.DrawString("" + (this.pointArray.Count - 1), textfont, textbrush, rectangleF10);
  542. }
  543. else
  544. {
  545. rectangleF10 = new RectangleF();
  546. }
  547. }
  548. //还原为原始旋转矩阵
  549. g.Transform = mtxSave;
  550. // 折线长度
  551. this.Length = length;
  552. Pen pen = new Pen(color, lineWidth);
  553. pen.DashStyle = (DashStyle)this.measurePolylineStyleModel.lineStyle;
  554. g.DrawLines(pen, pointArray.ToArray()); //.DrawLine(pen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
  555. pen.Dispose();
  556. matrix.Dispose();
  557. if (this.configurationFile)
  558. this.pointChange = false;
  559. this.mouseUpAttribute = false;
  560. pointChangeObject.Remove(this.drawToolType);
  561. }
  562. }
  563. /// <summary>
  564. /// 停止绘制时
  565. /// </summary>
  566. /// <param name="up"></param>
  567. public override void MouseUp(bool up)
  568. {
  569. mouseUpPointChange = up;
  570. }
  571. public void AddPoint(Point point)
  572. {
  573. pointArray.Add(point);
  574. }
  575. public override int HandleCount
  576. {
  577. get
  578. {
  579. return pointArray.Count + 1;
  580. }
  581. }
  582. /// <summary>
  583. /// Get handle pointscroll by 1-based number
  584. /// </summary>
  585. /// <param name="handleNumber"></param>
  586. /// <returns></returns>
  587. public override PointF GetHandle(int handleNumber)
  588. {
  589. if (handleNumber < 1)
  590. handleNumber = 1;
  591. if (handleNumber > pointArray.Count && handleNumber != pointArray.Count + 1)
  592. handleNumber = pointArray.Count;
  593. if (handleNumber == pointArray.Count + 1)
  594. return this.pointL;
  595. else
  596. return pointArray[handleNumber - 1];
  597. }
  598. public override Cursor GetHandleCursor(int handleNumber)
  599. {
  600. return handleCursor;
  601. }
  602. public override void MoveHandleTo(Point point, int handleNumber)
  603. {
  604. if (handleNumber < 1)
  605. handleNumber = 1;
  606. if (handleNumber > pointArray.Count && handleNumber != pointArray.Count + 1)
  607. handleNumber = pointArray.Count;
  608. if (handleNumber == pointArray.Count + 1)
  609. {
  610. point = SetOffsetAfterRotation(point, rotationPoint, angle);
  611. if (this.moveKb == 1)
  612. this.rectangleF1.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  613. else if (this.moveKb == 2)
  614. this.rectangleF2.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  615. else if (this.moveKb == 3)
  616. this.rectangleF3.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  617. else if (this.moveKb == 4)
  618. this.rectangleF4.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  619. else if (this.moveKb == 5)
  620. this.rectangleF5.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  621. else if (this.moveKb == 6)
  622. this.rectangleF6.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  623. else if (this.moveKb == 7)
  624. this.rectangleF7.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  625. else if (this.moveKb == 8)
  626. this.rectangleF8.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  627. else if (this.moveKb == 9)
  628. this.rectangleF9.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  629. else if (this.moveKb == 10)
  630. this.rectangleF10.Offset(point.X - this.pointL.X, point.Y - this.pointL.Y);
  631. this.pointL = point;
  632. }
  633. else
  634. {
  635. this.mouseUpPointChange = true;
  636. if (handleNumber == 1)
  637. {
  638. this.rectangleF1.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  639. this.rectangleF2.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  640. this.rectangleF3.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  641. this.rectangleF4.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  642. this.rectangleF5.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  643. this.rectangleF6.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  644. this.rectangleF7.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  645. this.rectangleF8.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  646. this.rectangleF9.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  647. this.rectangleF10.Offset(point.X - this.rotationPoint.X, point.Y - this.rotationPoint.Y);
  648. }
  649. pointArray[handleNumber - 1] = point;
  650. }
  651. this.startPoint = pointArray[0];
  652. Invalidate();
  653. }
  654. public override void Move(int deltaX, int deltaY)
  655. {
  656. int n = pointArray.Count;
  657. PointF point;
  658. for (int i = 0; i < n; i++)
  659. {
  660. point = new PointF(pointArray[i].X + ISurfaceBox.UnscaleScalar(deltaX), pointArray[i].Y + ISurfaceBox.UnscaleScalar(deltaY));
  661. pointArray[i] = point;
  662. }
  663. this.startPoint = pointArray[0];
  664. int x = ISurfaceBox.UnscaleScalar(deltaX);
  665. int y = ISurfaceBox.UnscaleScalar(deltaY);
  666. pointL.X += x;
  667. pointL.Y += y;
  668. this.rectangleF1.Offset(x, y);
  669. this.rectangleF2.Offset(x, y);
  670. this.rectangleF3.Offset(x, y);
  671. this.rectangleF4.Offset(x, y);
  672. this.rectangleF5.Offset(x, y);
  673. this.rectangleF6.Offset(x, y);
  674. this.rectangleF7.Offset(x, y);
  675. this.rectangleF8.Offset(x, y);
  676. this.rectangleF9.Offset(x, y);
  677. this.rectangleF10.Offset(x, y);
  678. Invalidate();
  679. }
  680. /// <summary>
  681. /// 用于创建一个路径或者是闭合的范围
  682. /// 用于响应点击选中
  683. /// 需要咨询用户是仅点击线还是矩形选择
  684. /// </summary>
  685. protected virtual void CreateObjects()
  686. {
  687. if (AreaPath != null)
  688. return;
  689. AreaPath = new GraphicsPath();
  690. AreaPath.AddRectangle(GetBoundingBox());
  691. AreaPath.CloseFigure();
  692. AreaRegion = new Region(AreaPath);
  693. }
  694. /// <summary>
  695. /// Invalidate object.
  696. /// When object is invalidated, path used for hit test
  697. /// is released and should be created again.
  698. /// </summary>
  699. protected void Invalidate()
  700. {
  701. if (AreaPath != null)
  702. {
  703. AreaPath.Dispose();
  704. AreaPath = null;
  705. }
  706. if (AreaPen != null)
  707. {
  708. AreaPen.Dispose();
  709. AreaPen = null;
  710. }
  711. if (AreaRegion != null)
  712. {
  713. AreaRegion.Dispose();
  714. AreaRegion = null;
  715. }
  716. }
  717. protected GraphicsPath AreaPath
  718. {
  719. get
  720. {
  721. return areaPath;
  722. }
  723. set
  724. {
  725. areaPath = value;
  726. }
  727. }
  728. protected Pen AreaPen
  729. {
  730. get
  731. {
  732. return areaPen;
  733. }
  734. set
  735. {
  736. areaPen = value;
  737. }
  738. }
  739. protected Region AreaRegion
  740. {
  741. get
  742. {
  743. return areaRegion;
  744. }
  745. set
  746. {
  747. areaRegion = value;
  748. }
  749. }
  750. /// <summary>
  751. /// Draw tracker for selected object
  752. /// </summary>
  753. /// <param name="g"></param>
  754. public override void DrawTracker(Graphics g)
  755. {
  756. if (!Selected)
  757. return;
  758. SolidBrush brush = new SolidBrush(Color.Black);
  759. for (int i = 1; i <= HandleCount; i++)
  760. {
  761. if (i == HandleCount)
  762. brush = new SolidBrush(Color.Transparent);
  763. g.FillRectangle(brush, GetHandleRectangle(i));
  764. }
  765. brush.Dispose();
  766. RectangleF r = GetBoundingBox();
  767. //g.DrawRectangle(new Pen(Color.White), r.X, r.Y, r.Width, r.Height);
  768. }
  769. /// <summary>
  770. /// Hit test.
  771. /// Return value: -1 - no hit
  772. /// 0 - hit anywhere
  773. /// > 1 - handle number
  774. /// </summary>
  775. /// <param name="pointscroll"></param>
  776. /// <returns></returns>
  777. public override int HitTest(Point point)
  778. {
  779. if (Selected)
  780. {
  781. for (int i = 1; i <= HandleCount; i++)
  782. {
  783. if (GetHandleRectangle(i).Contains(point))
  784. return i;
  785. }
  786. if (GetRectanglePosition(this.rectangleF1, point, rotationPoint, angle))
  787. {
  788. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  789. moveKb = 1;
  790. return this.pointArray.Count + 1;
  791. }
  792. else if (GetRectanglePosition(this.rectangleF2, point, rotationPoint, angle))
  793. {
  794. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  795. moveKb = 2;
  796. return this.pointArray.Count + 1;
  797. }
  798. else if (GetRectanglePosition(this.rectangleF3, point, rotationPoint, angle))
  799. {
  800. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  801. moveKb = 3;
  802. return this.pointArray.Count + 1;
  803. }
  804. else if (GetRectanglePosition(this.rectangleF4, point, rotationPoint, angle))
  805. {
  806. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  807. moveKb = 4;
  808. return this.pointArray.Count + 1;
  809. }
  810. else if (GetRectanglePosition(this.rectangleF5, point, rotationPoint, angle))
  811. {
  812. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  813. moveKb = 5;
  814. return this.pointArray.Count + 1;
  815. }
  816. else if (GetRectanglePosition(this.rectangleF6, point, rotationPoint, angle))
  817. {
  818. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  819. moveKb = 6;
  820. return this.pointArray.Count + 1;
  821. }
  822. else if (GetRectanglePosition(this.rectangleF7, point, rotationPoint, angle))
  823. {
  824. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  825. moveKb = 7;
  826. return this.pointArray.Count + 1;
  827. }
  828. else if (GetRectanglePosition(this.rectangleF8, point, rotationPoint, angle))
  829. {
  830. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  831. moveKb = 8;
  832. return this.pointArray.Count + 1;
  833. }
  834. else if (GetRectanglePosition(this.rectangleF9, point, rotationPoint, angle))
  835. {
  836. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  837. moveKb = 9;
  838. return this.pointArray.Count + 1;
  839. }
  840. else if (GetRectanglePosition(this.rectangleF10, point, rotationPoint, angle))
  841. {
  842. this.pointL = SetOffsetAfterRotation(point, rotationPoint, angle);
  843. moveKb = 10;
  844. return this.pointArray.Count + 1;
  845. }
  846. }
  847. if (PointInObject(point))
  848. return 0;
  849. return -1;
  850. }
  851. protected override bool PointInObject(Point point)
  852. {
  853. CreateObjects();
  854. return AreaRegion.IsVisible(point);
  855. }
  856. public override bool IntersectsWith(Rectangle rectangle)
  857. {
  858. CreateObjects();
  859. return AreaRegion.IsVisible(rectangle);
  860. }
  861. public override RectangleF GetBoundingBox()
  862. {
  863. float minx = 0, maxx = 0, miny = 0, maxy = 0;
  864. for (int i = 0; i < pointArray.Count; i++)
  865. {
  866. if (i == 0)
  867. {
  868. minx = maxx = pointArray[i].X;
  869. miny = maxy = pointArray[i].Y;
  870. }
  871. else
  872. {
  873. if (pointArray[i].X > maxx) maxx = pointArray[i].X;
  874. if (pointArray[i].X < minx) minx = pointArray[i].X;
  875. if (pointArray[i].Y > maxy) maxy = pointArray[i].Y;
  876. if (pointArray[i].Y < miny) miny = pointArray[i].Y;
  877. }
  878. }
  879. return new RectangleF(minx, miny, maxx - minx, maxy - miny);
  880. }
  881. internal void setNextPoint(Point p)
  882. {
  883. AddPoint(p);
  884. //startPoint = endPoint;
  885. //endPoint = p;
  886. }
  887. internal void setEndPoint(Point p)
  888. {
  889. endPoint = p;
  890. }
  891. public override List<PointF> GetPoints()
  892. {
  893. return pointArray;
  894. }
  895. public override ParentStyleModel GetStyle()
  896. {
  897. return measurePolylineStyleModel;
  898. }
  899. }
  900. }