DisplayParticle.cs 24 KB

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