DrawPencil.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. using PaintDotNet.Annotation.Enum;
  2. using PaintDotNet.Base.SettingModel;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Globalization;
  8. using System.Runtime.Serialization;
  9. using System.Windows.Forms;
  10. namespace PaintDotNet.Annotation.Label
  11. {
  12. using PointEnumerator = IEnumerator<PointF>;
  13. using PointList = List<PointF>;
  14. /// <summary>
  15. /// 标注->曲线->铅笔
  16. /// </summary>
  17. public class DrawPencil : DrawObject
  18. {
  19. private PointList pointArray;
  20. private static Cursor handleCursor = new Cursor(PdnResources.GetResourceStream("Cursors.AnnotationPolyHandle.cur"));
  21. private GraphicsPath areaPath = null;
  22. private Pen areaPen = null;
  23. private Region areaRegion = null;
  24. /// <summary>
  25. /// 标注样式信息model
  26. /// </summary>
  27. private LabelStyleModel.Pencil labelStyleModel;
  28. public LabelStyleModel.Pencil LabelStyleModel
  29. {
  30. set
  31. {
  32. this.labelStyleModel = value;
  33. }
  34. }
  35. public DrawPencil() : base()
  36. {
  37. this.objectType = DrawClass.Label;
  38. this.drawToolType = DrawToolType.DrawPencil;
  39. pointArray = new PointList();
  40. Initialize();
  41. }
  42. public DrawPencil(ISurfaceBox surfaceBox, int x1, int y1) : base()
  43. {
  44. this.objectType = DrawClass.Label;
  45. this.drawToolType = DrawToolType.DrawPencil;
  46. labelStyleModel = surfaceBox.GetLabelStyleModel().pencilModel;
  47. pointArray = new PointList();
  48. pointArray.Add(new PointF(x1, y1));
  49. Initialize();
  50. }
  51. public DrawPencil(ISurfaceBox surfaceBox, List<PointF> points, ParentStyleModel parentStyleModel, Object content) : base()
  52. {
  53. this.objectType = DrawClass.Label;
  54. this.drawToolType = DrawToolType.DrawPencil;
  55. this.ISurfaceBox = surfaceBox;
  56. LabelStyleModel = (LabelStyleModel.Pencil)parentStyleModel;
  57. pointArray = points;
  58. }
  59. /// <summary>
  60. /// Clone this instance
  61. /// </summary>
  62. public override DrawObject Clone()
  63. {
  64. DrawPencil drawPencil = new DrawPencil();
  65. drawPencil.objectType = DrawClass.Label;
  66. drawPencil.drawToolType = DrawToolType.DrawPencil;
  67. drawPencil.ISurfaceBox = this.ISurfaceBox;
  68. drawPencil.labelStyleModel = this.labelStyleModel;
  69. foreach (PointF p in this.pointArray)
  70. {
  71. drawPencil.pointArray.Add(p);
  72. }
  73. FillDrawObjectFields(drawPencil);
  74. return drawPencil;
  75. }
  76. public override DrawObject Clone(ISurfaceBox surfaceBox)
  77. {
  78. DrawPencil drawPencil = new DrawPencil();
  79. drawPencil.objectType = DrawClass.Label;
  80. drawPencil.drawToolType = DrawToolType.DrawPencil;
  81. drawPencil.ISurfaceBox = surfaceBox;
  82. drawPencil.labelStyleModel = this.labelStyleModel;
  83. foreach (PointF p in this.pointArray)
  84. {
  85. drawPencil.pointArray.Add(p);
  86. }
  87. FillDrawObjectFields(drawPencil);
  88. return drawPencil;
  89. }
  90. public override void Draw(Graphics g)
  91. {
  92. if (HandleCount >= 3)
  93. {
  94. g.SmoothingMode = SmoothingMode.AntiAlias;
  95. // 从配置内取值 颜色、线宽、线样式
  96. Color color = Color.FromArgb(labelStyleModel.lineColor);
  97. int lineWidth = labelStyleModel.lineWidth;
  98. Pen pen = new Pen(color, lineWidth);
  99. pen.DashStyle = (DashStyle)this.labelStyleModel.lineStyle;
  100. g.DrawCurve(pen, pointArray.ToArray());
  101. pen.Dispose();
  102. }
  103. }
  104. public void AddPoint(PointF point)
  105. {
  106. pointArray.Add(point);
  107. }
  108. public override int HandleCount
  109. {
  110. get
  111. {
  112. return pointArray.Count;
  113. }
  114. }
  115. /// <summary>
  116. /// Get handle pointscroll by 1-based number
  117. /// </summary>
  118. /// <param name="handleNumber"></param>
  119. /// <returns></returns>
  120. public override PointF GetHandle(int handleNumber)
  121. {
  122. if (handleNumber < 1)
  123. handleNumber = 1;
  124. if (handleNumber > pointArray.Count)
  125. handleNumber = pointArray.Count;
  126. return pointArray[handleNumber - 1];
  127. }
  128. public override Cursor GetHandleCursor(int handleNumber)
  129. {
  130. return handleCursor;
  131. }
  132. public override void MoveHandleTo(Point point, int handleNumber)
  133. {
  134. if (handleNumber < 1)
  135. handleNumber = 1;
  136. if (handleNumber > pointArray.Count)
  137. handleNumber = pointArray.Count;
  138. pointArray[handleNumber - 1] = point;
  139. Invalidate();
  140. }
  141. public override void Move(int deltaX, int deltaY)
  142. {
  143. int n = pointArray.Count;
  144. for (int i = 0; i < n; i++)
  145. {
  146. PointF point = new PointF(pointArray[i].X + ISurfaceBox.UnscaleScalar(deltaX), pointArray[i].Y + ISurfaceBox.UnscaleScalar(deltaY));
  147. pointArray[i] = point;
  148. }
  149. Invalidate();
  150. }
  151. /// <summary>
  152. /// Invalidate object.
  153. /// When object is invalidated, path used for hit test
  154. /// is released and should be created again.
  155. /// </summary>
  156. protected void Invalidate()
  157. {
  158. if (AreaPath != null)
  159. {
  160. AreaPath.Dispose();
  161. AreaPath = null;
  162. }
  163. if (AreaPen != null)
  164. {
  165. AreaPen.Dispose();
  166. AreaPen = null;
  167. }
  168. if (AreaRegion != null)
  169. {
  170. AreaRegion.Dispose();
  171. AreaRegion = null;
  172. }
  173. }
  174. /// <summary>
  175. /// Create graphic object used for hit test
  176. /// </summary>
  177. protected virtual void CreateObjects()
  178. {
  179. if (AreaPath != null)
  180. return;
  181. AreaPath = new GraphicsPath();
  182. AreaPath.AddRectangle(GetBoundingBox());
  183. AreaPath.CloseFigure();
  184. AreaRegion = new Region(AreaPath);
  185. }
  186. protected GraphicsPath AreaPath
  187. {
  188. get
  189. {
  190. return areaPath;
  191. }
  192. set
  193. {
  194. areaPath = value;
  195. }
  196. }
  197. protected Pen AreaPen
  198. {
  199. get
  200. {
  201. return areaPen;
  202. }
  203. set
  204. {
  205. areaPen = value;
  206. }
  207. }
  208. protected Region AreaRegion
  209. {
  210. get
  211. {
  212. return areaRegion;
  213. }
  214. set
  215. {
  216. areaRegion = value;
  217. }
  218. }
  219. /// <summary>
  220. /// Draw tracker for selected object
  221. /// </summary>
  222. /// <param name="g"></param>
  223. public override void DrawTracker(Graphics g)
  224. {
  225. if (!Selected)
  226. return;
  227. RectangleF rectangleF = GetBoundingBox();
  228. g.DrawRectangle(new Pen(Color.White), rectangleF.X, rectangleF.Y, rectangleF.Width, rectangleF.Height);
  229. }
  230. /// <summary>
  231. /// Hit test.
  232. /// Return value: -1 - no hit
  233. /// 0 - hit anywhere
  234. /// > 1 - handle number
  235. /// </summary>
  236. /// <param name="pointscroll"></param>
  237. /// <returns></returns>
  238. public override int HitTest(Point point)
  239. {
  240. if (Selected)
  241. {
  242. /**
  243. for (int i = 1; i <= HandleCount; i++)
  244. {
  245. if (GetHandleRectangle(i).Contains(point))
  246. return i;
  247. }**/
  248. }
  249. if (PointInObject(point))
  250. return 0;
  251. return -1;
  252. }
  253. protected override bool PointInObject(Point point)
  254. {
  255. CreateObjects();
  256. return AreaRegion.IsVisible(point);
  257. }
  258. public override bool IntersectsWith(Rectangle rectangle)
  259. {
  260. CreateObjects();
  261. return AreaRegion.IsVisible(rectangle);
  262. }
  263. public override RectangleF GetBoundingBox()
  264. {
  265. RectangleF rectangle;
  266. float minx = 0, maxx = 0, miny = 0, maxy = 0;
  267. for (int i = 0; i < pointArray.Count; i++)
  268. {
  269. if (i == 0)
  270. {
  271. minx = maxx = pointArray[i].X;
  272. miny = maxy = pointArray[i].Y;
  273. }
  274. else
  275. {
  276. if (pointArray[i].X > maxx) maxx = pointArray[i].X;
  277. if (pointArray[i].X < minx) minx = pointArray[i].X;
  278. if (pointArray[i].Y > maxy) maxy = pointArray[i].Y;
  279. if (pointArray[i].Y < miny) miny = pointArray[i].Y;
  280. }
  281. }
  282. rectangle = new RectangleF(minx, miny, maxx - minx, maxy - miny);
  283. return rectangle;
  284. }
  285. public override List<PointF> GetPoints()
  286. {
  287. return pointArray;
  288. }
  289. public override ParentStyleModel GetStyle()
  290. {
  291. return labelStyleModel;
  292. }
  293. }
  294. }