DisplayParticle.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. using OTSIncAReportApp.DataOperation.Model;
  2. using OTSIncAReportGraph.Class;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. namespace OTSIncAReportGraph
  12. {
  13. /// <summary>
  14. /// Particle对象上操作状态的枚举,显示,不显示,已删除,已选择
  15. /// </summary>
  16. public enum DisplayState
  17. {
  18. NORMALDISPLAY = 0,
  19. NODISPLAY = 1,
  20. CONCISEDISPLAY=2,// display as a "+"
  21. }
  22. /// <summary>
  23. /// Particle对象上操作xray的枚举状态,显示xray数据,不显示
  24. /// </summary>
  25. public enum ParticleOperatorShowXray
  26. {
  27. SELECTANDDISPLAYXRAY = 0,
  28. NODISPLAY = 1,
  29. }
  30. /// <summary>
  31. /// Segment对象绘制的枚举,以点绘制,还是以线绘制
  32. /// </summary>
  33. public enum SegmentShowMode
  34. {
  35. DRAWPOINT = 0,
  36. DRAWLINE = 1,
  37. }
  38. /// <summary>
  39. /// 颗粒类
  40. /// </summary>
  41. public class DisplayParticle : BaseObject, ICloneable, IComparable<DisplayParticle>
  42. {
  43. private const float m_zoom_displaymultiplier = 0.5f;
  44. public Particle objParticleData;
  45. private Guid m_id;
  46. private RectangleF m_rect;
  47. private PointF m_OTSPointF;
  48. private RectangleF m_small_rect;
  49. private bool m_isSelected_smallrect;
  50. private bool m_showSmallx;
  51. private bool m_isSelected;
  52. private bool m_isDeleted;
  53. private bool m_isMouseOver;
  54. private DisplayState m_displayState = DisplayState.NORMALDISPLAY;//显示,不显示,删除,选择,默认应为(不显示)
  55. private ParticleOperatorShowXray m_operator_showxray = ParticleOperatorShowXray.NODISPLAY;//选定显示XRAY,不显示XRAY,默认应为(不显示XRAY)
  56. private bool m_isdragging;
  57. private PointF m_dragingpoint;
  58. private Color m_color;
  59. private Color m_backcolor;
  60. private GraphicsPath m_gpath;
  61. private List<DisplaySegment> m_listdsegment = new List<DisplaySegment>();
  62. private string m_sort_type = "从大到小";
  63. private float m_f_size = 0;
  64. private string m_str_lj = "颗粒粒级";
  65. private string m_str_klzl = "颗粒种类";
  66. private string m_str_klfl = "颗粒分类";
  67. public int TypeId
  68. {
  69. get
  70. {
  71. return objParticleData.TypeId;
  72. }
  73. }
  74. //TypeName
  75. public string TypeName
  76. {
  77. get
  78. {
  79. return objParticleData.TypeName;
  80. }
  81. }
  82. //XRayId
  83. public int XRayId
  84. {
  85. get
  86. {
  87. return objParticleData.XrayId;
  88. }
  89. }
  90. public int SEMPosX
  91. {
  92. get
  93. {
  94. return objParticleData.SEMPosX;
  95. }
  96. }
  97. public int SEMPosY
  98. {
  99. get
  100. {
  101. return objParticleData.SEMPosY;
  102. }
  103. }
  104. public DisplayParticle()
  105. {
  106. m_id = System.Guid.NewGuid();
  107. }
  108. public DisplayParticle(Particle part)
  109. {
  110. m_id = System.Guid.NewGuid();
  111. objParticleData = part;
  112. this.Color = GetColorBySTDTypeIDForBSEAndSorImage(part.TypeColor, part.TypeId);
  113. }
  114. public DisplayParticle(List<DisplaySegment> in_list_segment, DisplayParticle in_particle)
  115. {
  116. // m_id = System.Guid.NewGuid().ToString();
  117. objParticleData = in_particle.objParticleData;
  118. m_id = in_particle.m_id;
  119. //m_zoom_displaymultiplier = in_particle.m_zoom_displaymultiplier;
  120. m_displayState = in_particle.m_displayState;
  121. m_operator_showxray = in_particle.m_operator_showxray;
  122. foreach (DisplaySegment e in in_list_segment)
  123. {
  124. m_listdsegment.Add(e.Clone() as DisplaySegment);
  125. }
  126. }
  127. /// <summary>
  128. /// [目前也不使用该方法了,因为该方法每次排序都有不同的结果]多边形排序,按传入的sort_type的排序类型行排序,但需要两个list做一致性排序
  129. /// </summary>
  130. /// <param name="in_ap"></param>
  131. /// <returns></returns>
  132. public int CompareTo(DisplayParticle in_particle)
  133. {
  134. int r_b = 0;//排序返回值
  135. switch (m_sort_type)
  136. {
  137. case "从大到小":
  138. r_b = in_particle.m_f_size.CompareTo(this.m_f_size);
  139. break;
  140. case "从小到大":
  141. //与上面的从大到小正好相反即可
  142. r_b = in_particle.m_f_size.CompareTo(this.m_f_size);
  143. if (r_b == 1)
  144. r_b = -1;
  145. else
  146. r_b = 1;
  147. break;
  148. default:
  149. break;
  150. }
  151. return r_b;
  152. }
  153. public Color GetColorBySTDTypeIDForBSEAndSorImage(string in_partcolor, int in_stdtypeid)
  154. {
  155. Color ret_c = new Color();
  156. if (in_stdtypeid < 1000)
  157. {
  158. //OTSSysSTDMgrClass osc = new OTSSysSTDMgrClass();
  159. ////小于1000,使用系统默认分类
  160. ret_c = GetColorByEnum(in_stdtypeid);
  161. }
  162. else if (in_stdtypeid >= 1000)
  163. {
  164. //大于等于1000,并且小于10000时,使用用户标准库来分析夹杂物名称
  165. if (!in_partcolor.Contains("#"))
  166. {
  167. ret_c = DrawFunction.colorHx16toRGB("#" + in_partcolor);//接收必须是#000000的格式
  168. }
  169. else
  170. {
  171. ret_c = DrawFunction.colorHx16toRGB(in_partcolor);//接收必须是#000000的格式
  172. }
  173. }
  174. return ret_c;
  175. }
  176. public Color GetColorByEnum(int STDID)
  177. {
  178. Color ret_c = new Color();
  179. switch (STDID)
  180. {
  181. case -1:
  182. //INVALID = -1,
  183. //stdName = "无效颗粒";
  184. ret_c = Color.Black;
  185. break;
  186. case 0:
  187. //small = 0;
  188. //stdName = "过小颗粒";
  189. ret_c = Color.Black;
  190. break;
  191. case 1:
  192. //OVERSIZE = 1,
  193. //stdName = "过大颗粒";
  194. ret_c = Color.Black;
  195. break;
  196. case 2:
  197. //AVE_GRAY_NOT_INRANRE = 2,
  198. //stdName = "亮度不在分析范围内的颗粒";
  199. ret_c = Color.Black;
  200. break;
  201. case 3:
  202. //SEARCH_X_RAY = 3,
  203. //stdName = "不进行搜索x-ray分析的颗粒";
  204. ret_c = Color.Black;
  205. break;
  206. case 4:
  207. //LOW_COUNT = 4,
  208. //stdName = "低x-ray计数颗粒";
  209. ret_c = Color.Black;
  210. break;
  211. case 5:
  212. //NO_INTEREST_ELEMENTS = 5,
  213. //stdName = "不含分析元素的颗粒";
  214. ret_c = Color.Black;
  215. break;
  216. case 6:
  217. //ALAYSIS_X_RAY = 6,
  218. //stdName = "不进行x-ray分析的颗粒";
  219. ret_c = Color.Black;
  220. break;
  221. case 7:
  222. //NOT_IDENTIFIED = 7,
  223. //stdName = "未识别颗粒";
  224. ret_c = Color.Black;
  225. break;
  226. case 8:
  227. //NOT_IDENTIFIED = 8,
  228. //stdName = "未识别颗粒";
  229. ret_c = Color.Black;
  230. break;
  231. case 9:
  232. //NOT_IDENTIFIED = 9,
  233. //stdName = "未识别颗粒";
  234. ret_c = Color.Black;
  235. break;
  236. default:
  237. ret_c = Color.Black;
  238. break;
  239. }
  240. return ret_c;
  241. }
  242. /// <summary>
  243. /// 克隆方法
  244. /// </summary>
  245. /// <returns></returns>
  246. public override object Clone()
  247. {
  248. return new DisplayParticle(this.m_listdsegment, this);
  249. }
  250. /// <summary>
  251. /// ID
  252. /// </summary>
  253. public override Guid guid
  254. {
  255. get { return m_id; }
  256. set { m_id = value; }
  257. }
  258. /// <summary>
  259. /// 颗粒的外边框大小
  260. /// </summary>
  261. public override RectangleF Rect
  262. {
  263. get { return m_rect; }
  264. set { m_rect = value; }
  265. }
  266. /// <summary>
  267. /// OTSPointF
  268. /// </summary>
  269. public override PointF OTSPointF
  270. {
  271. get { return m_OTSPointF; }
  272. set { m_OTSPointF = value; }
  273. }
  274. /// <summary>
  275. /// 颗粒里+号位置的外边框大小
  276. /// </summary>
  277. public RectangleF SmallRect
  278. {
  279. get { return m_small_rect; }
  280. set { m_small_rect = value; }
  281. }
  282. /// <summary>
  283. /// 颗粒是否被选择
  284. /// </summary>
  285. public override bool IsSelect
  286. {
  287. get { return m_isSelected; }
  288. set { m_isSelected = value; }
  289. }
  290. /// <summary>
  291. /// 该颗粒是否被设置成,选中状态
  292. /// </summary>
  293. public DisplayState displayState
  294. {
  295. get { return m_displayState; }
  296. set { m_displayState = value; }
  297. }
  298. /// <summary>
  299. /// 是否对该颗粒选定显示X-Ray能谱图
  300. /// </summary>
  301. public ParticleOperatorShowXray Operator_ShowXRay
  302. {
  303. get { return m_operator_showxray; }
  304. set { m_operator_showxray = value; }
  305. }
  306. /// <summary>
  307. /// 鼠标是否在该矩形上
  308. /// </summary>
  309. //public bool IsMouseMove
  310. //{
  311. // get { return m_IsMouseMove; }
  312. // set { m_IsMouseMove = value; }
  313. //}
  314. /// <summary>
  315. /// 是否显示x号
  316. /// </summary>
  317. public bool IsShowSmallX
  318. {
  319. get { return m_showSmallx; }
  320. set { m_showSmallx = value; }
  321. }
  322. /// <summary>
  323. /// 颗粒的x-ray的点,是否被选择上了
  324. /// </summary>
  325. public bool IsSelectedSmallRect
  326. {
  327. get { return m_isSelected_smallrect; }
  328. set { m_isSelected_smallrect = value; }
  329. }
  330. /// <summary>
  331. /// 是否在被拖动
  332. /// </summary>
  333. public override bool IsDragging
  334. {
  335. get { return m_isdragging; }
  336. set { m_isdragging = value; }
  337. }
  338. /// <summary>
  339. /// 被拖动到的位置坐标
  340. /// </summary>
  341. public override PointF DraggingPoint
  342. {
  343. get { return m_dragingpoint; }
  344. set { m_dragingpoint = value; }
  345. }
  346. /// <summary>
  347. /// 线的颜色
  348. /// </summary>
  349. public override Color Color
  350. {
  351. get { return m_color; }
  352. set { m_color = value; }
  353. }
  354. /// <summary>
  355. /// 背景色
  356. /// </summary>
  357. public override Color BackColor
  358. {
  359. get { return m_backcolor; }
  360. set { m_backcolor = value; }
  361. }
  362. /// <summary>
  363. /// 多边形的图形路径边缘
  364. /// </summary>
  365. public override GraphicsPath GPath
  366. {
  367. get { return m_gpath; }
  368. set { m_gpath = value; }
  369. }
  370. /// <summary>
  371. /// 里面包含的多个线的集合
  372. /// </summary>
  373. public List<DisplaySegment> DSegments
  374. {
  375. get { return m_listdsegment; }
  376. set { m_listdsegment = value; }
  377. }
  378. /// <summary>
  379. /// 控制多边形在进行缩放到多少倍时进行显示
  380. /// </summary>
  381. public float Zoom_DisPlayThreshold
  382. {
  383. get { return m_zoom_displaymultiplier; }
  384. }
  385. /// <summary>
  386. /// 临时的变量,控制进行缩放时,是显示+号,还是显示多边形
  387. /// </summary>
  388. //public bool Zoom_DisPlay
  389. //{
  390. // get { return m_zoom_display; }
  391. // set { m_zoom_display = value; }
  392. //}
  393. /// <summary>
  394. /// 设置排序的类型
  395. /// </summary>
  396. public string SortType
  397. {
  398. get { return m_sort_type; }
  399. set { m_sort_type = value; }
  400. }
  401. /// <summary>
  402. /// 设置该多边形的尺寸大小
  403. /// </summary>
  404. public float FSize
  405. {
  406. get { return m_f_size; }
  407. set { m_f_size = value; }
  408. }
  409. /// <summary>
  410. /// 设置粒级
  411. /// </summary>
  412. public string ParticleLJ
  413. {
  414. get { return m_str_lj; }
  415. set { m_str_lj = value; }
  416. }
  417. /// <summary>
  418. /// 设置种类
  419. /// </summary>
  420. public string ParticleZL
  421. {
  422. get { return m_str_klzl; }
  423. set { m_str_klzl = value; }
  424. }
  425. /// <summary>
  426. /// 设置分类
  427. /// </summary>
  428. public string ParticleFL
  429. {
  430. get { return m_str_klfl; }
  431. set { m_str_klfl = value; }
  432. }
  433. /// <summary>
  434. /// 获取或设置该Particle对应底层的FieldID值
  435. /// </summary>
  436. public int FieldId
  437. {
  438. get { return objParticleData.FieldId; }
  439. }
  440. /// <summary>
  441. /// 获取或设置该Particle对应底层的ParticleID值
  442. /// </summary>
  443. public int ParticleId
  444. {
  445. get { return objParticleData.ParticleId; }
  446. }
  447. public bool IsDeleted { get => m_isDeleted; set => m_isDeleted = value; }
  448. public bool IsMouseOver { get => m_isMouseOver; set => m_isMouseOver = value; }
  449. ///// <summary>
  450. ///// 获取或设置STD分析物的ID
  451. ///// </summary>
  452. //public int STDTypeID
  453. //{
  454. // get { return m_stdtypeid; }
  455. // set { m_stdtypeid = value; }
  456. //}
  457. /// <summary>
  458. /// 绘制函数
  459. /// </summary>
  460. /// <param name="e"></param>
  461. public override void OnPaint(PaintEventArgs e)
  462. {
  463. Graphics g = e.Graphics;
  464. //绘制鼠标移动到颗粒上时的边框,需要判断当前鼠标在颗粒上,及颗粒的操作为正常显示
  465. if (m_isMouseOver == true)
  466. {
  467. //如果有鼠标在该矩形上,那么进行描边
  468. ControlPaint.DrawBorder(g,
  469. Rectangle.Round(this.Rect),
  470. Color.Lime,
  471. 1,
  472. ButtonBorderStyle.Solid,
  473. Color.Lime,
  474. 1,
  475. ButtonBorderStyle.Solid,
  476. Color.Lime,
  477. 1,
  478. ButtonBorderStyle.Solid,
  479. Color.Lime,
  480. 1,
  481. ButtonBorderStyle.Solid);
  482. }
  483. //只有正常和选择中的颗粒才进行绘制显示
  484. if (m_displayState == DisplayState.NORMALDISPLAY)
  485. {
  486. //调用绘制基本线
  487. foreach (DisplaySegment item in m_listdsegment)
  488. {
  489. item.OnPaint(e);
  490. }
  491. }
  492. if (m_displayState == DisplayState.CONCISEDISPLAY)
  493. {
  494. g.DrawString("+", new Font("黑体", 6), new SolidBrush(Color.DarkSlateBlue), new PointF(m_small_rect.X, m_small_rect.Y));
  495. }
  496. if (m_isSelected)
  497. {
  498. //如果説该矩形被选择上了的话,那么也显示边框
  499. ControlPaint.DrawBorder(g,
  500. Rectangle.Round(this.Rect),
  501. Color.Blue,
  502. 1,
  503. ButtonBorderStyle.Solid,
  504. Color.Blue,
  505. 1,
  506. ButtonBorderStyle.Solid,
  507. Color.Blue,
  508. 1,
  509. ButtonBorderStyle.Solid,
  510. Color.Blue,
  511. 1,
  512. ButtonBorderStyle.Solid);
  513. }
  514. if (ParticleOperatorShowXray.SELECTANDDISPLAYXRAY == m_operator_showxray && DisplayState.NODISPLAY != m_displayState)
  515. {
  516. //当鼠标在该颗粒上进行点击,则对颗粒状态更改为选定状态,用来显示X-ray能谱表
  517. ControlPaint.DrawBorder(g,
  518. Rectangle.Round(this.Rect),
  519. Color.DeepSkyBlue,
  520. 1,
  521. ButtonBorderStyle.Solid,
  522. Color.DeepSkyBlue,
  523. 1,
  524. ButtonBorderStyle.Solid,
  525. Color.DeepSkyBlue,
  526. 1,
  527. ButtonBorderStyle.Solid,
  528. Color.DeepSkyBlue,
  529. 1,
  530. ButtonBorderStyle.Solid);
  531. }
  532. }
  533. /// <summary>
  534. /// 从Line中获取矩形的边缘闭合路径
  535. /// </summary>
  536. /// <returns></returns>
  537. public GraphicsPath GetRegionFromDSegments()
  538. {
  539. GraphicsPath gpath = new GraphicsPath();
  540. List<PointF> list_leftpointf = new List<PointF>();
  541. List<PointF> list_rightpointf = new List<PointF>();
  542. //从y循环,这里假设y轴会按lines集合来计算,然后将所有的左x,和右x取出排成两个队列
  543. foreach (DisplaySegment ds in this.m_listdsegment)
  544. {
  545. list_leftpointf.Add(new PointF(ds.Rect.X, ds.Rect.Y));
  546. list_rightpointf.Add(new PointF(ds.Rect.X + ds.Rect.Width, ds.Rect.Y));
  547. }
  548. PointF[] lsp = new PointF[list_leftpointf.Count + list_rightpointf.Count];
  549. //再将两个x,y点依次添加到闭合路径中
  550. for (int i = 0; i < list_leftpointf.Count(); i++)
  551. {
  552. lsp[i] = list_leftpointf[i];
  553. }
  554. //右节点
  555. for (int i = 0; i < list_rightpointf.Count(); i++)
  556. {
  557. //这边倒着存入
  558. lsp[list_rightpointf.Count() + i] = list_rightpointf[list_rightpointf.Count() - i - 1];
  559. }
  560. //防止从低层拿到无数据的外边路径,在我的程序里却需要计算,而防止程序报死,这里做一下特殊处理。
  561. if (lsp.Count() >= 3)
  562. {
  563. gpath.AddPolygon(lsp);
  564. }
  565. else
  566. {
  567. //有时居然有颗粒,有没有segment的时候,防止报错
  568. if (this.DSegments.Count == 0)
  569. {
  570. lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0, 0) };
  571. gpath.AddPolygon(lsp);
  572. return gpath;
  573. }
  574. //有2条数据
  575. if (lsp[1].X != 0 && lsp[1].Y != 0)
  576. {
  577. lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[1].X, lsp[1].Y), new PointF(lsp[1].X, lsp[1].Y) };
  578. }
  579. //有1条数据
  580. else if (lsp[0].X != 0 && lsp[0].Y != 0)
  581. {
  582. lsp = new PointF[3] { new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y), new PointF(lsp[0].X, lsp[0].Y) };
  583. }
  584. //剩下的情况
  585. else
  586. {
  587. lsp = new PointF[3] { new PointF(0, 0), new PointF(0, 0), new PointF(0,0) };
  588. }
  589. gpath.AddPolygon(lsp);
  590. }
  591. return gpath;
  592. }
  593. /// <summary>
  594. /// 从已经确定的外边框来计算出里面的+号小框位置
  595. /// </summary>
  596. /// <returns></returns>
  597. public RectangleF GetSmallRectangleFromRect()
  598. {
  599. RectangleF rect = new RectangleF();
  600. //用外边框的坐标,除2获得中心点,然后再分别+,- 4
  601. float x = 0, y = 0;
  602. x = m_rect.X + (m_rect.Width / 2);
  603. y = m_rect.Y + (m_rect.Height / 2);
  604. rect.X = x - 4;
  605. rect.Y = y - 4;
  606. rect.Width = 8;
  607. rect.Height = 4;
  608. return rect;
  609. }
  610. /// <summary>
  611. /// 根据该多边形所有包含的线长度,计算出,该多边形的面积大小
  612. /// </summary>
  613. /// <returns></returns>
  614. public float GetSizeFormSegmentsAllWidth()
  615. {
  616. float f_size_sum = 0;
  617. foreach (DisplaySegment ls_ds in this.m_listdsegment)
  618. {
  619. f_size_sum = f_size_sum + ls_ds.Rect.Width;
  620. }
  621. return f_size_sum;
  622. }
  623. /// <summary>
  624. /// 从基本线中获取整个矩形的Rectangle
  625. /// </summary>
  626. /// <returns></returns>
  627. public RectangleF GetRectFromDSegment()
  628. {
  629. RectangleF rect = new RectangleF();
  630. float x1 = 0, y1 = 0;
  631. float i_width = 0, i_height = 0;
  632. //先从自身中初始化x,y,和宽,高
  633. if (this.m_listdsegment.Count > 0)
  634. {
  635. x1 = this.m_listdsegment[0].Rect.X;
  636. y1 = this.m_listdsegment[0].Rect.Y;
  637. i_width = x1 + this.m_listdsegment[0].Rect.Width;
  638. i_height = this.m_listdsegment[0].Rect.Y;
  639. }
  640. foreach (DisplaySegment ds in this.m_listdsegment)
  641. {
  642. //分别取出,最小的x,y,
  643. if (ds.Rect.X < x1)
  644. {
  645. x1 = ds.Rect.X;
  646. }
  647. if (ds.Rect.Y < y1)
  648. {
  649. y1 = ds.Rect.Y;
  650. }
  651. //最大的x,y
  652. if (ds.Rect.X + ds.Rect.Width > i_width)
  653. {
  654. i_width = ds.Rect.X + ds.Rect.Width;
  655. }
  656. if (ds.Rect.Y > i_height)
  657. {
  658. i_height = ds.Rect.Y;
  659. }
  660. }
  661. //对矩形Rect大小位置进行修补,因为画线是内边框,并且计算出来的位置也是向内占用一像素的,
  662. //正常应该是 +2,但实际效果,+3也才勉强够用,因为放大缩小画笔宽度影响的
  663. rect.X = x1 - 2;
  664. rect.Y = y1 - 3;
  665. rect.Width = i_width - rect.X + 2;
  666. rect.Height = i_height - rect.Y + 3;
  667. //判断如果太小,就给个最小值吧
  668. if (rect.Width < 8)
  669. rect.Width = 8;
  670. if (rect.Height < 8)
  671. rect.Height = 8;
  672. return rect;
  673. }
  674. }
  675. }