OpticalDensityLine.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. using PaintDotNet.Base.SettingModel;
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Globalization;
  6. using System.Runtime.Serialization;
  7. using System.Windows.Forms;
  8. using PaintDotNet.Base.CommTool;
  9. using PaintDotNet.Annotation.Enum;
  10. using System.Collections.Generic;
  11. using PaintDotNet.Annotation.Measure;
  12. namespace PaintDotNet.Annotation.Other
  13. {
  14. /// <summary>
  15. /// 光密度测量直线
  16. /// </summary>
  17. public class OpticalDensityLine : MeasureDrawObject
  18. {
  19. /// <summary>
  20. /// 可能最后用不到
  21. /// </summary>
  22. private const string entryStart = "Start";
  23. /// <summary>
  24. /// 可能最后用不到
  25. /// </summary>
  26. private const string entryEnd = "End";
  27. /// <summary>
  28. /// Graphic objects for hit test
  29. /// </summary>
  30. private GraphicsPath areaPath = null;
  31. private Pen areaPen = null;
  32. private Region areaRegion = null;
  33. /// <summary>
  34. /// 样式信息model
  35. /// </summary>
  36. public MeasureStyleModel.MeasureLine measureLineStyleModel;
  37. public OpticalDensityLine(ISurfaceBox surfaceBox, int x1, int y1, int x2, int y2) : base()
  38. {
  39. this.objectType = DrawClass.Other;
  40. this.drawToolType = DrawToolType.OpticalDensityLine;
  41. measureLineStyleModel = surfaceBox.GetMeasureStyleModel().measureLine;
  42. startPoint.X = x1;
  43. startPoint.Y = y1;
  44. endPoint.X = x2;
  45. endPoint.Y = y2;
  46. Initialize();
  47. }
  48. public OpticalDensityLine(ISurfaceBox surfaceBox, List<Point> points, ParentStyleModel parentStyleModel, Object content) : base()
  49. {
  50. this.objectType = DrawClass.Other;
  51. this.drawToolType = DrawToolType.OpticalDensityLine;
  52. this.ISurfaceBox = surfaceBox;
  53. measureLineStyleModel = (MeasureStyleModel.MeasureLine)parentStyleModel;
  54. startPoint.X = points[0].X;
  55. startPoint.Y = points[0].Y;
  56. endPoint.X = points[1].X;
  57. endPoint.Y = points[1].Y;
  58. }
  59. /// <summary>
  60. /// Clone this instance
  61. /// </summary>
  62. public override DrawObject Clone()
  63. {
  64. OpticalDensityLine opticalDensityLine = new OpticalDensityLine(ISurfaceBox, 0, 0, 1, 0);
  65. opticalDensityLine.objectType = DrawClass.Label;
  66. opticalDensityLine.drawToolType = DrawToolType.OpticalDensityLine;
  67. opticalDensityLine.ISurfaceBox = this.ISurfaceBox;
  68. opticalDensityLine.startPoint = this.startPoint;
  69. opticalDensityLine.endPoint = this.endPoint;
  70. FillDrawObjectFields(opticalDensityLine);
  71. return opticalDensityLine;
  72. }
  73. public override void Draw(Graphics g)
  74. {
  75. g.SmoothingMode = SmoothingMode.AntiAlias;
  76. Color color = Color.FromArgb(this.measureLineStyleModel.lineColor);
  77. Pen pen = new Pen(color, this.measureLineStyleModel.lineWidth);
  78. pen.DashStyle = (DashStyle)this.measureLineStyleModel.lineStyle;
  79. double length = BasicCalculationHelper.GetDistance(this.startPoint, this.endPoint, 2);
  80. double angle = Math.Round(BasicCalculationHelper.AngleText(this.startPoint, this.endPoint, new PointF(this.startPoint.X + 10, this.startPoint.Y)), 10);
  81. //判断第二个点相对于第一个点的象限
  82. int x2 = (int)(this.endPoint.X - this.startPoint.X);
  83. if (x2 == 0)
  84. x2 = 1;
  85. int y2 = (int)(this.endPoint.Y - this.startPoint.Y);
  86. if (y2 == 0)
  87. y2 = 1;
  88. int i2 = 0;
  89. if (x2 > 0 && y2 > 0) //第4象限
  90. {
  91. i2 = 4;
  92. }
  93. else if (x2 > 0 && y2 < 0) //第1象限
  94. {
  95. i2 = 1;
  96. }
  97. else if (x2 < 0 && y2 < 0) //第2象限
  98. {
  99. i2 = 2;
  100. }
  101. else if (x2 < 0 && y2 > 0) //第3象限
  102. {
  103. i2 = 3;
  104. }
  105. double sAngle1;
  106. double eAngle1;
  107. double sAngle2;
  108. double eAngle2;
  109. if (i2 == 1 || i2 == 2)
  110. {
  111. sAngle1 = 360 - angle;
  112. eAngle1 = 180 - angle;
  113. sAngle2 = 270 - angle;
  114. eAngle2 = 90 - angle;
  115. }
  116. else
  117. {
  118. sAngle1 = angle;
  119. eAngle1 = 180 + angle;
  120. sAngle2 = 270 + angle;
  121. eAngle2 = 90 + angle;
  122. }
  123. Point point1 = new Point();
  124. Point point2 = new Point();
  125. Point point3 = new Point();
  126. Point point4 = new Point();
  127. Point point5 = new Point();
  128. Point point6 = new Point();
  129. if (sAngle1 is double.NaN && eAngle1 is double.NaN && sAngle2 is double.NaN && eAngle2 is double.NaN)
  130. {
  131. }
  132. else
  133. {
  134. point1 = BasicCalculationHelper.GetAnglePoint(new Point((int)this.startPoint.X + (int)(length * kS), (int)this.startPoint.Y), new Point((int)this.startPoint.X, (int)this.startPoint.Y), sAngle1);
  135. point2 = BasicCalculationHelper.GetAnglePoint(new Point((int)this.endPoint.X + (int)(length * kE), (int)this.endPoint.Y), new Point((int)this.endPoint.X, (int)this.endPoint.Y), eAngle1);
  136. point3 = BasicCalculationHelper.GetAnglePoint(new Point((point1.X + 20), point1.Y), point1, sAngle2);
  137. point4 = BasicCalculationHelper.GetAnglePoint(new Point((point1.X + 20), point1.Y), point1, eAngle2);
  138. point5 = BasicCalculationHelper.GetAnglePoint(new Point((point2.X + 20), point2.Y), point2, sAngle2);
  139. point6 = BasicCalculationHelper.GetAnglePoint(new Point((point2.X + 20), point2.Y), point2, eAngle2);
  140. }
  141. g.DrawLine(pen, point3, point4);
  142. g.DrawLine(pen, point5, point6);
  143. g.DrawLine(pen, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y);
  144. pen.Dispose();
  145. }
  146. public override int HandleCount
  147. {
  148. get
  149. {
  150. return 2;
  151. }
  152. }
  153. /// <summary>
  154. /// Get handle pointscroll by 1-based number
  155. /// </summary>
  156. /// <param name="handleNumber"></param>
  157. /// <returns></returns>
  158. public override PointF GetHandle(int handleNumber)
  159. {
  160. if (handleNumber == 1)
  161. return startPoint;
  162. else
  163. return endPoint;
  164. }
  165. /// <summary>
  166. /// Hit test.
  167. /// Return value: -1 - no hit
  168. /// 0 - hit anywhere
  169. /// > 1 - handle number
  170. /// </summary>
  171. /// <param name="pointscroll"></param>
  172. /// <returns></returns>
  173. public override int HitTest(Point point)
  174. {
  175. if (Selected)
  176. {
  177. for (int i = 1; i <= HandleCount; i++)
  178. {
  179. if (GetHandleRectangle(i).Contains(point))
  180. return i;
  181. }
  182. }
  183. if (PointInObject(point))
  184. return 0;
  185. return -1;
  186. }
  187. protected override bool PointInObject(Point point)
  188. {
  189. CreateObjects();
  190. return AreaRegion.IsVisible(point);
  191. }
  192. public override bool IntersectsWith(Rectangle rectangle)
  193. {
  194. CreateObjects();
  195. return AreaRegion.IsVisible(rectangle);
  196. }
  197. public override Cursor GetHandleCursor(int handleNumber)
  198. {
  199. switch (handleNumber)
  200. {
  201. case 1:
  202. case 2:
  203. return handleCursor;// Cursors.SizeAll;
  204. default:
  205. return Cursors.Default;
  206. }
  207. }
  208. public override void MoveHandleTo(Point point, int handleNumber)
  209. {
  210. if (handleNumber == 1)
  211. startPoint = point;
  212. else
  213. endPoint = point;
  214. Invalidate();
  215. }
  216. public override void Move(int deltaX, int deltaY)
  217. {
  218. int x = ISurfaceBox.UnscaleScalar(deltaX);
  219. int y = ISurfaceBox.UnscaleScalar(deltaY);
  220. startPoint.X += x;
  221. startPoint.Y += y;
  222. endPoint.X += x;
  223. endPoint.Y += y;
  224. Invalidate();
  225. }
  226. public override void SaveToStream(SerializationInfo info, int orderNumber)
  227. {
  228. info.AddValue(
  229. String.Format(CultureInfo.InvariantCulture,
  230. "{0}{1}",
  231. entryStart, orderNumber),
  232. startPoint);
  233. info.AddValue(
  234. String.Format(CultureInfo.InvariantCulture,
  235. "{0}{1}",
  236. entryEnd, orderNumber),
  237. endPoint);
  238. base.SaveToStream(info, orderNumber);
  239. }
  240. public override void LoadFromStream(SerializationInfo info, int orderNumber)
  241. {
  242. startPoint = (Point)info.GetValue(
  243. String.Format(CultureInfo.InvariantCulture,
  244. "{0}{1}",
  245. entryStart, orderNumber),
  246. typeof(Point));
  247. endPoint = (Point)info.GetValue(
  248. String.Format(CultureInfo.InvariantCulture,
  249. "{0}{1}",
  250. entryEnd, orderNumber),
  251. typeof(Point));
  252. base.LoadFromStream(info, orderNumber);
  253. }
  254. /// <summary>
  255. /// Invalidate object.
  256. /// When object is invalidated, path used for hit test
  257. /// is released and should be created again.
  258. /// </summary>
  259. protected void Invalidate()
  260. {
  261. if (AreaPath != null)
  262. {
  263. AreaPath.Dispose();
  264. AreaPath = null;
  265. }
  266. if (AreaPen != null)
  267. {
  268. AreaPen.Dispose();
  269. AreaPen = null;
  270. }
  271. if (AreaRegion != null)
  272. {
  273. AreaRegion.Dispose();
  274. AreaRegion = null;
  275. }
  276. }
  277. /// <summary>
  278. /// Create graphic objects used from hit test.
  279. /// </summary>
  280. protected virtual void CreateObjects()
  281. {
  282. if (AreaPath != null)
  283. return;
  284. // Create path which contains wide line
  285. // for easy mouse selection
  286. AreaPath = new GraphicsPath();
  287. AreaPen = new Pen(Color.Black, 7);
  288. AreaPath.AddLine(startPoint.X-1, startPoint.Y-1, endPoint.X+1, endPoint.Y+1);
  289. AreaPath.Widen(AreaPen);
  290. // Create region from the path
  291. AreaRegion = new Region(AreaPath);
  292. }
  293. protected GraphicsPath AreaPath
  294. {
  295. get
  296. {
  297. return areaPath;
  298. }
  299. set
  300. {
  301. areaPath = value;
  302. }
  303. }
  304. protected Pen AreaPen
  305. {
  306. get
  307. {
  308. return areaPen;
  309. }
  310. set
  311. {
  312. areaPen = value;
  313. }
  314. }
  315. protected Region AreaRegion
  316. {
  317. get
  318. {
  319. return areaRegion;
  320. }
  321. set
  322. {
  323. areaRegion = value;
  324. }
  325. }
  326. public override RectangleF GetBoundingBox()
  327. {
  328. RectangleF rectangle = GetNotmalizedRectangle(startPoint, endPoint);
  329. return rectangle;
  330. }
  331. public static RectangleF GetNotmalizedRectangle(PointF a, PointF b)
  332. {
  333. RectangleF rect = new RectangleF();
  334. if (a.X < b.X)
  335. {
  336. rect.X = a.X;
  337. rect.Width = b.X - a.X;
  338. }
  339. else
  340. {
  341. rect.X = b.X;
  342. rect.Width = a.X - b.X;
  343. }
  344. if (a.Y < b.Y)
  345. {
  346. rect.Y = a.Y;
  347. rect.Height = b.Y - a.Y;
  348. }
  349. else
  350. {
  351. rect.Y = b.Y;
  352. rect.Height = a.Y - b.Y;
  353. }
  354. return rect;
  355. }
  356. /// <summary>
  357. /// Draw tracker for selected object
  358. /// </summary>
  359. /// <param name="g"></param>
  360. public override void DrawTracker(Graphics g)
  361. {
  362. if (!Selected)
  363. return;
  364. SolidBrush brush = new SolidBrush(Color.Black);
  365. for (int i = 1; i <= HandleCount; i++)
  366. {
  367. g.FillRectangle(brush, GetHandleRectangle(i));
  368. }
  369. brush.Dispose();
  370. }
  371. public override List<PointF> GetPoints()
  372. {
  373. List<PointF> points = new List<PointF>();
  374. points.Add(startPoint);
  375. points.Add(endPoint);
  376. return points;
  377. }
  378. public override ParentStyleModel GetStyle()
  379. {
  380. return measureLineStyleModel;
  381. }
  382. }
  383. }