EmbedBorder.cs 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. //
  5. // Purpose: Classes that implement different 3D border styles.
  6. //
  7. using System;
  8. using System.Drawing;
  9. using System.Drawing.Drawing2D;
  10. namespace FastReport.DataVisualization.Charting.Borders3D
  11. {
  12. /// <summary>
  13. /// Implements frame border.
  14. /// </summary>
  15. internal class FrameTitle1Border : FrameThin1Border
  16. {
  17. #region Border properties and methods
  18. /// <summary>
  19. /// Default constructor
  20. /// </summary>
  21. public FrameTitle1Border()
  22. {
  23. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f);
  24. }
  25. /// <summary>
  26. /// Chart type name
  27. /// </summary>
  28. public override string Name { get{ return "FrameTitle1";}}
  29. public override float Resolution
  30. {
  31. set
  32. {
  33. base.Resolution = value;
  34. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f);
  35. }
  36. }
  37. /// <summary>
  38. /// Returns the position of the rectangular area in the border where
  39. /// title should be displayed. Returns empty rect if title can't be shown in the border.
  40. /// </summary>
  41. /// <returns>Title position in border.</returns>
  42. public override RectangleF GetTitlePositionInBorder()
  43. {
  44. return new RectangleF(
  45. defaultRadiusSize * 0.25f,
  46. defaultRadiusSize * 0.25f,
  47. defaultRadiusSize * 0.25f,
  48. defaultRadiusSize * 1.6f);
  49. }
  50. #endregion
  51. }
  52. /// <summary>
  53. /// Implements frame border.
  54. /// </summary>
  55. internal class FrameTitle2Border : FrameThin2Border
  56. {
  57. #region Border properties and methods
  58. /// <summary>
  59. /// Default constructor
  60. /// </summary>
  61. public FrameTitle2Border()
  62. {
  63. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f);
  64. }
  65. /// <summary>
  66. /// Chart type name
  67. /// </summary>
  68. public override string Name { get{ return "FrameTitle2";}}
  69. public override float Resolution
  70. {
  71. set
  72. {
  73. base.Resolution = value;
  74. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f);
  75. }
  76. }
  77. /// <summary>
  78. /// Returns the position of the rectangular area in the border where
  79. /// title should be displayed. Returns empty rect if title can't be shown in the border.
  80. /// </summary>
  81. /// <returns>Title position in border.</returns>
  82. public override RectangleF GetTitlePositionInBorder()
  83. {
  84. return new RectangleF(
  85. defaultRadiusSize * 0.25f,
  86. defaultRadiusSize * 0.25f,
  87. defaultRadiusSize * 0.25f,
  88. defaultRadiusSize * 1.6f);
  89. }
  90. #endregion
  91. }
  92. /// <summary>
  93. /// Implements frame border.
  94. /// </summary>
  95. internal class FrameTitle3Border : FrameThin3Border
  96. {
  97. #region Border properties and methods
  98. /// <summary>
  99. /// Default constructor
  100. /// </summary>
  101. public FrameTitle3Border()
  102. {
  103. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f);
  104. }
  105. /// <summary>
  106. /// Chart type name
  107. /// </summary>
  108. public override string Name { get{ return "FrameTitle3";}}
  109. public override float Resolution
  110. {
  111. set
  112. {
  113. base.Resolution = value;
  114. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f);
  115. }
  116. }
  117. /// <summary>
  118. /// Returns the position of the rectangular area in the border where
  119. /// title should be displayed. Returns empty rect if title can't be shown in the border.
  120. /// </summary>
  121. /// <returns>Title position in border.</returns>
  122. public override RectangleF GetTitlePositionInBorder()
  123. {
  124. return new RectangleF(
  125. defaultRadiusSize * 0.25f,
  126. defaultRadiusSize * 0.25f,
  127. defaultRadiusSize * 0.25f,
  128. defaultRadiusSize * 1.6f);
  129. }
  130. #endregion
  131. }
  132. /// <summary>
  133. /// Implements frame border.
  134. /// </summary>
  135. internal class FrameTitle4Border : FrameThin4Border
  136. {
  137. #region Border properties and methods
  138. /// <summary>
  139. /// Default constructor
  140. /// </summary>
  141. public FrameTitle4Border()
  142. {
  143. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f);
  144. }
  145. /// <summary>
  146. /// Chart type name
  147. /// </summary>
  148. public override string Name { get{ return "FrameTitle4";}}
  149. public override float Resolution
  150. {
  151. set
  152. {
  153. base.Resolution = value;
  154. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f);
  155. }
  156. }
  157. /// <summary>
  158. /// Returns the position of the rectangular area in the border where
  159. /// title should be displayed. Returns empty rect if title can't be shown in the border.
  160. /// </summary>
  161. /// <returns>Title position in border.</returns>
  162. public override RectangleF GetTitlePositionInBorder()
  163. {
  164. return new RectangleF(
  165. defaultRadiusSize * 0.25f,
  166. defaultRadiusSize * 0.25f,
  167. defaultRadiusSize * 0.25f,
  168. defaultRadiusSize * 1.6f);
  169. }
  170. #endregion
  171. }
  172. /// <summary>
  173. /// Implements frame border.
  174. /// </summary>
  175. internal class FrameTitle5Border : FrameThin5Border
  176. {
  177. #region Border properties and methods
  178. /// <summary>
  179. /// Default constructor
  180. /// </summary>
  181. public FrameTitle5Border()
  182. {
  183. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f);
  184. this.drawScrews = true;
  185. }
  186. /// <summary>
  187. /// Chart type name
  188. /// </summary>
  189. public override string Name { get{ return "FrameTitle5";}}
  190. public override float Resolution
  191. {
  192. set
  193. {
  194. base.Resolution = value;
  195. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f);
  196. }
  197. }
  198. /// <summary>
  199. /// Returns the position of the rectangular area in the border where
  200. /// title should be displayed. Returns empty rect if title can't be shown in the border.
  201. /// </summary>
  202. /// <returns>Title position in border.</returns>
  203. public override RectangleF GetTitlePositionInBorder()
  204. {
  205. return new RectangleF(
  206. defaultRadiusSize * 0.25f,
  207. defaultRadiusSize * 0.25f,
  208. defaultRadiusSize * 0.25f,
  209. defaultRadiusSize * 1.6f);
  210. }
  211. #endregion
  212. }
  213. /// <summary>
  214. /// Implements frame border.
  215. /// </summary>
  216. internal class FrameTitle6Border : FrameThin6Border
  217. {
  218. #region Border properties and methods
  219. /// <summary>
  220. /// Default constructor
  221. /// </summary>
  222. public FrameTitle6Border()
  223. {
  224. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f);
  225. }
  226. /// <summary>
  227. /// Chart type name
  228. /// </summary>
  229. public override string Name { get{ return "FrameTitle6";}}
  230. public override float Resolution
  231. {
  232. set
  233. {
  234. base.Resolution = value;
  235. sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f);
  236. }
  237. }
  238. /// <summary>
  239. /// Returns the position of the rectangular area in the border where
  240. /// title should be displayed. Returns empty rect if title can't be shown in the border.
  241. /// </summary>
  242. /// <returns>Title position in border.</returns>
  243. public override RectangleF GetTitlePositionInBorder()
  244. {
  245. return new RectangleF(
  246. defaultRadiusSize * 0.25f,
  247. defaultRadiusSize * 0.25f,
  248. defaultRadiusSize * 0.25f,
  249. defaultRadiusSize * 1.6f);
  250. }
  251. #endregion
  252. }
  253. /// <summary>
  254. /// Implements frame border.
  255. /// </summary>
  256. internal class FrameTitle7Border : FrameTitle1Border
  257. {
  258. #region Border properties and methods
  259. /// <summary>
  260. /// Default constructor
  261. /// </summary>
  262. public FrameTitle7Border()
  263. {
  264. this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height);
  265. float[] corners = {15f, 1f, 1f, 1f, 1f, 15f, 15f, 15f};
  266. innerCorners = corners;
  267. }
  268. /// <summary>
  269. /// Chart type name
  270. /// </summary>
  271. public override string Name { get{ return "FrameTitle7";}}
  272. public override float Resolution
  273. {
  274. set
  275. {
  276. base.Resolution = value;
  277. this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height);
  278. float largeRadius = 15f * resolution / 96.0f;
  279. float smallRadius = 1 * resolution / 96.0f;
  280. float[] corners = { largeRadius, smallRadius, smallRadius, smallRadius, smallRadius, largeRadius, largeRadius, largeRadius };
  281. innerCorners = corners;
  282. }
  283. }
  284. #endregion
  285. }
  286. /// <summary>
  287. /// Implements frame border.
  288. /// </summary>
  289. internal class FrameTitle8Border : FrameTitle1Border
  290. {
  291. #region Border properties and methods
  292. /// <summary>
  293. /// Default constructor
  294. /// </summary>
  295. public FrameTitle8Border()
  296. {
  297. this.sizeLeftTop = new SizeF(0, sizeLeftTop.Height);
  298. this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height);
  299. float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f};
  300. innerCorners = corners;
  301. }
  302. /// <summary>
  303. /// Chart type name
  304. /// </summary>
  305. public override string Name { get{ return "FrameTitle8";}}
  306. public override float Resolution
  307. {
  308. set
  309. {
  310. base.Resolution = value;
  311. this.sizeLeftTop = new SizeF(0, sizeLeftTop.Height);
  312. this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height);
  313. float radius = 1 * resolution / 96.0f;
  314. float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius };
  315. innerCorners = corners;
  316. }
  317. }
  318. #endregion
  319. }
  320. /// <summary>
  321. /// Implements frame border.
  322. /// </summary>
  323. internal class FrameThin2Border : FrameThin1Border
  324. {
  325. #region Border properties and methods
  326. /// <summary>
  327. /// Default constructor
  328. /// </summary>
  329. public FrameThin2Border()
  330. {
  331. float[] corners = {15f, 15f, 15f, 1f, 1f, 1f, 1f, 15f};
  332. cornerRadius = corners;
  333. innerCorners = corners;
  334. }
  335. /// <summary>
  336. /// Chart type name
  337. /// </summary>
  338. public override string Name { get{ return "FrameThin2";}}
  339. public override float Resolution
  340. {
  341. set
  342. {
  343. base.Resolution = value;
  344. float largeRadius = 15f * resolution / 96.0f;
  345. float smallRadius = 1 * resolution / 96.0f;
  346. float[] corners = { largeRadius, largeRadius, largeRadius, smallRadius, smallRadius, smallRadius, smallRadius, largeRadius };
  347. cornerRadius = corners;
  348. innerCorners = corners;
  349. }
  350. }
  351. #endregion
  352. }
  353. /// <summary>
  354. /// Implements frame border.
  355. /// </summary>
  356. internal class FrameThin3Border : FrameThin1Border
  357. {
  358. #region Border properties and methods
  359. /// <summary>
  360. /// Default constructor
  361. /// </summary>
  362. public FrameThin3Border()
  363. {
  364. float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f};
  365. cornerRadius = corners;
  366. innerCorners = corners;
  367. }
  368. /// <summary>
  369. /// Chart type name
  370. /// </summary>
  371. public override string Name { get{ return "FrameThin3";}}
  372. public override float Resolution
  373. {
  374. set
  375. {
  376. base.Resolution = value;
  377. float radius = resolution / 96.0f;
  378. float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius };
  379. cornerRadius = corners;
  380. innerCorners = corners;
  381. }
  382. }
  383. #endregion
  384. }
  385. /// <summary>
  386. /// Implements frame border.
  387. /// </summary>
  388. internal class FrameThin4Border : FrameThin1Border
  389. {
  390. #region Border properties and methods
  391. /// <summary>
  392. /// Default constructor
  393. /// </summary>
  394. public FrameThin4Border()
  395. {
  396. float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f};
  397. cornerRadius = corners;
  398. }
  399. /// <summary>
  400. /// Chart type name
  401. /// </summary>
  402. public override string Name { get{ return "FrameThin4";}}
  403. public override float Resolution
  404. {
  405. set
  406. {
  407. base.Resolution = value;
  408. float radius = 1f * resolution / 96.0f;
  409. cornerRadius = new float[] { radius, radius, radius, radius, radius, radius, radius, radius };
  410. }
  411. }
  412. #endregion
  413. }
  414. /// <summary>
  415. /// Implements frame border.
  416. /// </summary>
  417. internal class FrameThin5Border : FrameThin1Border
  418. {
  419. #region Border properties and methods
  420. /// <summary>
  421. /// Default constructor
  422. /// </summary>
  423. public FrameThin5Border()
  424. {
  425. drawScrews = true;
  426. }
  427. /// <summary>
  428. /// Chart type name
  429. /// </summary>
  430. public override string Name { get{ return "FrameThin5";}}
  431. #endregion
  432. }
  433. /// <summary>
  434. /// Implements frame border.
  435. /// </summary>
  436. internal class FrameThin6Border : FrameThin1Border
  437. {
  438. #region Border properties and methods
  439. /// <summary>
  440. /// Default constructor
  441. /// </summary>
  442. public FrameThin6Border()
  443. {
  444. float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f};
  445. innerCorners = corners;
  446. }
  447. /// <summary>
  448. /// Chart type name
  449. /// </summary>
  450. public override string Name { get{ return "FrameThin6";}}
  451. public override float Resolution
  452. {
  453. set
  454. {
  455. base.Resolution = value;
  456. float radius = resolution / 96.0f;
  457. float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius };
  458. innerCorners = corners;
  459. }
  460. }
  461. #endregion
  462. }
  463. /// <summary>
  464. /// Implements frame border.
  465. /// </summary>
  466. internal class FrameThin1Border : RaisedBorder
  467. {
  468. #region Border properties and methods
  469. /// <summary>
  470. /// Inner corners radius array
  471. /// </summary>
  472. internal float[] innerCorners = { 15f, 15f, 15f, 15f, 15f, 15f, 15f, 15f };
  473. /// <summary>
  474. /// Default constructor
  475. /// </summary>
  476. public FrameThin1Border()
  477. {
  478. sizeLeftTop = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f);
  479. sizeRightBottom = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f);
  480. }
  481. /// <summary>
  482. /// Chart type name
  483. /// </summary>
  484. public override string Name { get{ return "FrameThin1";}}
  485. public override float Resolution
  486. {
  487. set
  488. {
  489. base.Resolution = value;
  490. float radius = 15.0f * resolution / 96.0f;
  491. innerCorners = new float[] { radius, radius, radius, radius, radius, radius, radius, radius };
  492. sizeLeftTop = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f);
  493. sizeRightBottom = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f);
  494. }
  495. }
  496. /// <summary>
  497. /// Draws 3D border.
  498. /// </summary>
  499. /// <param name="graph">Graphics to draw the border on.</param>
  500. /// <param name="borderSkin">Border skin object.</param>
  501. /// <param name="rect">Rectangle of the border.</param>
  502. /// <param name="backColor">Color of rectangle</param>
  503. /// <param name="backHatchStyle">Hatch style</param>
  504. /// <param name="backImage">Back Image</param>
  505. /// <param name="backImageWrapMode">Image mode</param>
  506. /// <param name="backImageTransparentColor">Image transparent color.</param>
  507. /// <param name="backImageAlign">Image alignment</param>
  508. /// <param name="backGradientStyle">Gradient type</param>
  509. /// <param name="backSecondaryColor">Gradient End Color</param>
  510. /// <param name="borderColor">Border Color</param>
  511. /// <param name="borderWidth">Border Width</param>
  512. /// <param name="borderDashStyle">Border Style</param>
  513. public override void DrawBorder(
  514. ChartGraphics graph,
  515. BorderSkin borderSkin,
  516. RectangleF rect,
  517. Color backColor,
  518. ChartHatchStyle backHatchStyle,
  519. string backImage,
  520. ChartImageWrapMode backImageWrapMode,
  521. Color backImageTransparentColor,
  522. ChartImageAlignmentStyle backImageAlign,
  523. GradientStyle backGradientStyle,
  524. Color backSecondaryColor,
  525. Color borderColor,
  526. int borderWidth,
  527. ChartDashStyle borderDashStyle)
  528. {
  529. drawBottomShadow = true;
  530. sunken = false;
  531. outsideShadowRate = .9f;
  532. drawOutsideTopLeftShadow = false;
  533. bool oldScrewsFlag = this.drawScrews;
  534. this.drawScrews = false;
  535. base.DrawBorder(
  536. graph,
  537. borderSkin,
  538. rect,
  539. borderSkin.BackColor,
  540. borderSkin.BackHatchStyle,
  541. borderSkin.BackImage,
  542. borderSkin.BackImageWrapMode,
  543. borderSkin.BackImageTransparentColor,
  544. borderSkin.BackImageAlignment,
  545. borderSkin.BackGradientStyle,
  546. borderSkin.BackSecondaryColor,
  547. borderSkin.BorderColor,
  548. borderSkin.BorderWidth,
  549. borderSkin.BorderDashStyle);
  550. this.drawScrews = oldScrewsFlag;
  551. rect.X += sizeLeftTop.Width;
  552. rect.Y += sizeLeftTop.Height;
  553. rect.Width -= sizeRightBottom.Width + sizeLeftTop.Width;
  554. rect.Height -= sizeRightBottom.Height + sizeLeftTop.Height;
  555. if(rect.Width > 0 && rect.Height > 0 )
  556. {
  557. float[] oldCorners = new float[8];
  558. oldCorners = (float[])cornerRadius.Clone();
  559. cornerRadius = innerCorners;
  560. drawBottomShadow = false;
  561. sunken = true;
  562. drawOutsideTopLeftShadow = true;
  563. outsideShadowRate = 1.4f;
  564. Color oldPageColor = borderSkin.PageColor;
  565. borderSkin.PageColor = Color.Transparent;
  566. base.DrawBorder(
  567. graph,
  568. borderSkin,
  569. rect,
  570. backColor,
  571. backHatchStyle,
  572. backImage,
  573. backImageWrapMode,
  574. backImageTransparentColor,
  575. backImageAlign,
  576. backGradientStyle,
  577. backSecondaryColor,
  578. borderColor,
  579. borderWidth,
  580. borderDashStyle );
  581. borderSkin.PageColor = oldPageColor;
  582. cornerRadius = oldCorners;
  583. }
  584. }
  585. #endregion
  586. }
  587. /// <summary>
  588. /// Implements raised border.
  589. /// </summary>
  590. internal class RaisedBorder : SunkenBorder
  591. {
  592. #region Border properties and methods
  593. /// <summary>
  594. /// Public constructor
  595. /// </summary>
  596. public RaisedBorder()
  597. {
  598. sunken = false;
  599. }
  600. /// <summary>
  601. /// Chart type name
  602. /// </summary>
  603. public override string Name { get{ return "Raised";}}
  604. #endregion
  605. }
  606. /// <summary>
  607. /// Implements embed 3D border.
  608. /// </summary>
  609. internal class SunkenBorder : IBorderType
  610. {
  611. #region Border properties and methods
  612. /// <summary>
  613. /// Radius for rounded rectangle
  614. /// </summary>
  615. internal float defaultRadiusSize = 15f;
  616. /// <summary>
  617. /// Outside shadow rate
  618. /// </summary>
  619. internal float outsideShadowRate = .9f;
  620. /// <summary>
  621. /// Indicates that sunken shadows should be drawn
  622. /// </summary>
  623. internal bool sunken = true;
  624. /// <summary>
  625. /// Indicates that bottom shadow should be drawn
  626. /// </summary>
  627. internal bool drawBottomShadow = true;
  628. /// <summary>
  629. /// Indicates that top left outside dark shadow must be drawn
  630. /// </summary>
  631. internal bool drawOutsideTopLeftShadow = false;
  632. /// <summary>
  633. /// Array of corner radius
  634. /// </summary>
  635. internal float[] cornerRadius = { 15f, 15f, 15f, 15f, 15f, 15f, 15f, 15f };
  636. /// <summary>
  637. /// Border top/left size
  638. /// </summary>
  639. internal SizeF sizeLeftTop = SizeF.Empty;
  640. /// <summary>
  641. /// Border right/bottom size
  642. /// </summary>
  643. internal SizeF sizeRightBottom = SizeF.Empty;
  644. /// <summary>
  645. /// Indicates that screws should be drawn in the corners of the frame
  646. /// </summary>
  647. internal bool drawScrews = false;
  648. internal float resolution = 96f;
  649. /// <summary>
  650. /// Public constructor
  651. /// </summary>
  652. public SunkenBorder()
  653. {
  654. }
  655. /// <summary>
  656. /// Chart type name
  657. /// </summary>
  658. public virtual string Name { get{ return "Sunken";}}
  659. public virtual float Resolution
  660. {
  661. set
  662. {
  663. resolution = value;
  664. defaultRadiusSize = 15 * resolution / 96;
  665. //X = defaultRadiusSize;
  666. //Y = defaultRadiusSize;
  667. cornerRadius = new float[] { defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize };
  668. }
  669. }
  670. /// <summary>
  671. /// Returns the position of the rectangular area in the border where
  672. /// title should be displayed. Returns empty rect if title can't be shown in the border.
  673. /// </summary>
  674. /// <returns>Title position in border.</returns>
  675. public virtual RectangleF GetTitlePositionInBorder()
  676. {
  677. return RectangleF.Empty;
  678. }
  679. /// <summary>
  680. /// Adjust areas rectangle coordinate to fit the 3D border
  681. /// </summary>
  682. /// <param name="graph">Graphics to draw the border on.</param>
  683. /// <param name="areasRect">Position to adjust.</param>
  684. public virtual void AdjustAreasPosition(ChartGraphics graph, ref RectangleF areasRect)
  685. {
  686. SizeF relSizeLeftTop = new SizeF(sizeLeftTop);
  687. SizeF relSizeRightBottom = new SizeF(sizeRightBottom);
  688. relSizeLeftTop.Width += defaultRadiusSize * 0.7f;
  689. relSizeLeftTop.Height += defaultRadiusSize * 0.85f;
  690. relSizeRightBottom.Width += defaultRadiusSize * 0.7f;
  691. relSizeRightBottom.Height += defaultRadiusSize * 0.7f;
  692. relSizeLeftTop = graph.GetRelativeSize(relSizeLeftTop);
  693. relSizeRightBottom = graph.GetRelativeSize(relSizeRightBottom);
  694. if(relSizeLeftTop.Width > 30f)
  695. relSizeLeftTop.Width = 0;
  696. if(relSizeLeftTop.Height > 30f)
  697. relSizeLeftTop.Height = 0;
  698. if(relSizeRightBottom.Width > 30f)
  699. relSizeRightBottom.Width = 0;
  700. if(relSizeRightBottom.Height > 30f)
  701. relSizeRightBottom.Height = 0;
  702. areasRect.X += relSizeLeftTop.Width;
  703. areasRect.Width -= (float)Math.Min(areasRect.Width, relSizeLeftTop.Width + relSizeRightBottom.Width);
  704. areasRect.Y += relSizeLeftTop.Height;
  705. areasRect.Height -= (float)Math.Min(areasRect.Height, relSizeLeftTop.Height + relSizeRightBottom.Height);
  706. if(areasRect.Right > 100f)
  707. {
  708. if(areasRect.Width > 100f - areasRect.Right)
  709. areasRect.Width -= 100f - areasRect.Right;
  710. else
  711. areasRect.X -= 100f - areasRect.Right;
  712. }
  713. if(areasRect.Bottom > 100f)
  714. {
  715. if(areasRect.Height > 100f - areasRect.Bottom)
  716. areasRect.Height -= 100f - areasRect.Bottom;
  717. else
  718. areasRect.Y -= 100f - areasRect.Bottom;
  719. }
  720. }
  721. /// <summary>
  722. /// Draws 3D border
  723. /// </summary>
  724. /// <param name="graph">Graphics to draw the border on.</param>
  725. /// <param name="borderSkin">Border skin object.</param>
  726. /// <param name="rect">Rectangle of the border.</param>
  727. /// <param name="backColor">Color of rectangle</param>
  728. /// <param name="backHatchStyle">Hatch style</param>
  729. /// <param name="backImage">Back Image</param>
  730. /// <param name="backImageWrapMode">Image mode</param>
  731. /// <param name="backImageTransparentColor">Image transparent color.</param>
  732. /// <param name="backImageAlign">Image alignment</param>
  733. /// <param name="backGradientStyle">Gradient type</param>
  734. /// <param name="backSecondaryColor">Gradient End Color</param>
  735. /// <param name="borderColor">Border Color</param>
  736. /// <param name="borderWidth">Border Width</param>
  737. /// <param name="borderDashStyle">Border Style</param>
  738. public virtual void DrawBorder(
  739. ChartGraphics graph,
  740. BorderSkin borderSkin,
  741. RectangleF rect,
  742. Color backColor,
  743. ChartHatchStyle backHatchStyle,
  744. string backImage,
  745. ChartImageWrapMode backImageWrapMode,
  746. Color backImageTransparentColor,
  747. ChartImageAlignmentStyle backImageAlign,
  748. GradientStyle backGradientStyle,
  749. Color backSecondaryColor,
  750. Color borderColor,
  751. int borderWidth,
  752. ChartDashStyle borderDashStyle)
  753. {
  754. RectangleF absolute = graph.Round( rect );
  755. RectangleF shadowRect = absolute;
  756. // Calculate shadow colors (0.2 - 0.6)
  757. float colorDarkeningIndex = 0.3f + (0.4f * (borderSkin.PageColor.R + borderSkin.PageColor.G + borderSkin.PageColor.B) / 765f);
  758. Color shadowColor = Color.FromArgb(
  759. (int)(backColor.R*colorDarkeningIndex),
  760. (int)(backColor.G*colorDarkeningIndex),
  761. (int)(backColor.B*colorDarkeningIndex));
  762. colorDarkeningIndex += 0.2f;
  763. Color shadowLightColor = Color.FromArgb(
  764. (int)(borderSkin.PageColor.R*colorDarkeningIndex),
  765. (int)(borderSkin.PageColor.G*colorDarkeningIndex),
  766. (int)(borderSkin.PageColor.B*colorDarkeningIndex));
  767. if(borderSkin.PageColor == Color.Transparent)
  768. {
  769. shadowLightColor = Color.FromArgb(60, 0, 0, 0);
  770. }
  771. // Calculate rounded rect radius
  772. float radius = defaultRadiusSize;
  773. radius = (float)Math.Max(radius, 2f * resolution / 96.0f);
  774. radius = (float)Math.Min(radius, rect.Width/2f);
  775. radius = (float)Math.Min(radius, rect.Height/2f);
  776. radius = (float)Math.Ceiling(radius);
  777. // Fill page background color
  778. using (Brush brush = new SolidBrush(borderSkin.PageColor))
  779. {
  780. graph.FillRectangle(brush, rect);
  781. }
  782. if(drawOutsideTopLeftShadow)
  783. {
  784. // Top/Left outside shadow
  785. shadowRect = absolute;
  786. shadowRect.X -= radius * 0.3f;
  787. shadowRect.Y -= radius * 0.3f;
  788. shadowRect.Width -= radius * .3f;
  789. shadowRect.Height -= radius * .3f;
  790. graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius, Color.FromArgb(128, Color.Black), borderSkin.PageColor, outsideShadowRate);
  791. }
  792. // Bottom/Right outside shadow
  793. shadowRect = absolute;
  794. shadowRect.X += radius * 0.3f;
  795. shadowRect.Y += radius * 0.3f;
  796. shadowRect.Width -= radius * .3f;
  797. shadowRect.Height -= radius * .3f;
  798. graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius, shadowLightColor, borderSkin.PageColor, outsideShadowRate);
  799. // Background
  800. shadowRect = absolute;
  801. shadowRect.Width -= radius * .3f;
  802. shadowRect.Height -= radius * .3f;
  803. GraphicsPath path = graph.CreateRoundedRectPath(shadowRect, cornerRadius);
  804. graph.DrawPathAbs(
  805. path,
  806. backColor,
  807. backHatchStyle,
  808. backImage,
  809. backImageWrapMode,
  810. backImageTransparentColor,
  811. backImageAlign,
  812. backGradientStyle,
  813. backSecondaryColor,
  814. borderColor,
  815. borderWidth,
  816. borderDashStyle,
  817. PenAlignment.Inset );
  818. // Dispose Graphic path
  819. if( path != null )
  820. path.Dispose();
  821. // Draw screws imitation in the corners of the farame
  822. if(drawScrews)
  823. {
  824. // Left/Top screw
  825. RectangleF screwRect = RectangleF.Empty;
  826. float offset = radius * 0.4f;
  827. screwRect.X = shadowRect.X + offset;
  828. screwRect.Y = shadowRect.Y + offset;
  829. screwRect.Width = radius * 0.55f;
  830. screwRect.Height = screwRect.Width;
  831. DrawScrew(graph, screwRect);
  832. // Right/Top screw
  833. screwRect.X = shadowRect.Right - offset - screwRect.Width;
  834. DrawScrew(graph, screwRect);
  835. // Right/Bottom screw
  836. screwRect.X = shadowRect.Right - offset - screwRect.Width;
  837. screwRect.Y = shadowRect.Bottom - offset - screwRect.Height;
  838. DrawScrew(graph, screwRect);
  839. // Left/Bottom screw
  840. screwRect.X = shadowRect.X + offset;
  841. screwRect.Y = shadowRect.Bottom - offset - screwRect.Height;
  842. DrawScrew(graph, screwRect);
  843. }
  844. // Bottom/Right inner shadow
  845. Region innerShadowRegion = null;
  846. if(drawBottomShadow)
  847. {
  848. shadowRect = absolute;
  849. shadowRect.Width -= radius * .3f;
  850. shadowRect.Height -= radius * .3f;
  851. innerShadowRegion = new Region(
  852. graph.CreateRoundedRectPath(
  853. new RectangleF(
  854. shadowRect.X - radius,
  855. shadowRect.Y - radius,
  856. shadowRect.Width + 0.5f*radius,
  857. shadowRect.Height + 0.5f*radius),
  858. cornerRadius));
  859. innerShadowRegion.Complement(graph.CreateRoundedRectPath(shadowRect, cornerRadius));
  860. graph.Clip = innerShadowRegion;
  861. shadowRect.X -= 0.5f*radius;
  862. shadowRect.Width += 0.5f*radius;
  863. shadowRect.Y -= 0.5f*radius;
  864. shadowRect.Height += 0.5f*radius;
  865. graph.DrawRoundedRectShadowAbs(
  866. shadowRect,
  867. cornerRadius,
  868. radius,
  869. Color.Transparent,
  870. Color.FromArgb(175, (sunken) ? Color.White : shadowColor),
  871. 1.0f);
  872. graph.Clip = new Region();
  873. }
  874. // Top/Left inner shadow
  875. shadowRect = absolute;
  876. shadowRect.Width -= radius * .3f;
  877. shadowRect.Height -= radius * .3f;
  878. innerShadowRegion = new Region(
  879. graph.CreateRoundedRectPath(
  880. new RectangleF(
  881. shadowRect.X + radius*.5f,
  882. shadowRect.Y + radius*.5f,
  883. shadowRect.Width - .2f*radius,
  884. shadowRect.Height - .2f*radius),
  885. cornerRadius));
  886. RectangleF shadowWithOffset = shadowRect;
  887. shadowWithOffset.Width += radius;
  888. shadowWithOffset.Height += radius;
  889. innerShadowRegion.Complement(graph.CreateRoundedRectPath(shadowWithOffset, cornerRadius));
  890. innerShadowRegion.Intersect(graph.CreateRoundedRectPath(shadowRect, cornerRadius));
  891. graph.Clip = innerShadowRegion;
  892. graph.DrawRoundedRectShadowAbs(
  893. shadowWithOffset,
  894. cornerRadius,
  895. radius,
  896. Color.Transparent,
  897. Color.FromArgb(175, (sunken) ? shadowColor : Color.White),
  898. 1.0f);
  899. graph.Clip = new Region();
  900. }
  901. /// <summary>
  902. /// Helper function, which draws a screw on the frame
  903. /// </summary>
  904. /// <param name="graph">Chart graphics to use.</param>
  905. /// <param name="rect">Screw position.</param>
  906. private void DrawScrew(ChartGraphics graph, RectangleF rect)
  907. {
  908. // Draw screw
  909. Pen screwPen = new Pen(Color.FromArgb(128,255,255,255), 1);
  910. graph.DrawEllipse(screwPen, rect.X, rect.Y, rect.Width, rect.Height);
  911. graph.DrawLine(screwPen, rect.X + 2 * resolution / 96.0f, rect.Y + rect.Height - 2 * resolution / 96.0f, rect.Right - 2 * resolution / 96.0f, rect.Y + 2 * resolution / 96.0f);
  912. screwPen = new Pen(Color.FromArgb(128, Color.Black), 1);
  913. graph.DrawEllipse(screwPen, rect.X + 1 * resolution / 96.0f, rect.Y + 1 * resolution / 96.0f, rect.Width, rect.Height);
  914. graph.DrawLine(screwPen, rect.X + 3 * resolution / 96.0f, rect.Y + rect.Height - 1 * resolution / 96.0f, rect.Right - 1 * resolution / 96.0f, rect.Y + 3 * resolution / 96.0f);
  915. }
  916. #endregion
  917. }
  918. }