ImageAnnotation.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  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: Image annotation classes.
  6. //
  7. using System;
  8. using System.ComponentModel;
  9. using System.Drawing;
  10. using System.Drawing.Design;
  11. using System.Drawing.Drawing2D;
  12. using FastReport.DataVisualization.Charting.Utilities;
  13. namespace FastReport.DataVisualization.Charting
  14. {
  15. /// <summary>
  16. /// <b>ImageAnnotation</b> is a class that represents an image annotation.
  17. /// </summary>
  18. [
  19. SRDescription("DescriptionAttributeImageAnnotation_ImageAnnotation"),
  20. ]
  21. public class ImageAnnotation : Annotation
  22. {
  23. #region Fields
  24. // Annotation image name
  25. private string _imageName = String.Empty;
  26. // Image wrapping mode
  27. private ChartImageWrapMode _imageWrapMode = ChartImageWrapMode.Scaled;
  28. // Image transparent color
  29. private Color _imageTransparentColor = Color.Empty;
  30. #endregion
  31. #region Construction and Initialization
  32. /// <summary>
  33. /// Default public constructor.
  34. /// </summary>
  35. public ImageAnnotation()
  36. : base()
  37. {
  38. }
  39. #endregion
  40. #region Properties
  41. #region Image properties
  42. /// <summary>
  43. /// Gets or sets the name of an annotation's image.
  44. /// <seealso cref="ImageTransparentColor"/>
  45. /// </summary>
  46. /// <value>
  47. /// A string value representing the name of an annotation's image.
  48. /// </value>
  49. /// <remarks>
  50. /// The name can be a file name, URL for the web control or a name from
  51. /// the <see cref="NamedImagesCollection"/> class.
  52. /// </remarks>
  53. [
  54. SRCategory("CategoryAttributeImage"),
  55. Bindable(true),
  56. DefaultValue(""),
  57. #if DESIGNER
  58. Editor(typeof(ImageValueEditor), typeof(UITypeEditor)),
  59. #endif
  60. SRDescription("DescriptionAttributeImageAnnotation_Image"),
  61. ]
  62. public virtual string Image
  63. {
  64. get
  65. {
  66. return _imageName;
  67. }
  68. set
  69. {
  70. _imageName = value;
  71. this.Invalidate();
  72. }
  73. }
  74. /// <summary>
  75. /// Gets or sets the drawing mode of the image.
  76. /// </summary>
  77. /// <value>
  78. /// A <see cref="ChartImageWrapMode"/> value that defines the drawing mode of the image.
  79. /// </value>
  80. [
  81. SRCategory("CategoryAttributeImage"),
  82. Bindable(true),
  83. DefaultValue(ChartImageWrapMode.Scaled),
  84. SRDescription("DescriptionAttributeImageWrapMode"),
  85. ]
  86. public ChartImageWrapMode ImageWrapMode
  87. {
  88. get
  89. {
  90. return _imageWrapMode;
  91. }
  92. set
  93. {
  94. _imageWrapMode = value;
  95. this.Invalidate();
  96. }
  97. }
  98. /// <summary>
  99. /// Gets or sets a color which will be replaced with a transparent color while drawing the image.
  100. /// </summary>
  101. /// <value>
  102. /// A <see cref="Color"/> value which will be replaced with a transparent color while drawing the image.
  103. /// </value>
  104. [
  105. SRCategory("CategoryAttributeImage"),
  106. Bindable(true),
  107. DefaultValue(typeof(Color), ""),
  108. SRDescription("DescriptionAttributeImageTransparentColor"),
  109. TypeConverter(typeof(ColorConverter)),
  110. #if DESIGNER
  111. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  112. #endif
  113. ]
  114. public Color ImageTransparentColor
  115. {
  116. get
  117. {
  118. return _imageTransparentColor;
  119. }
  120. set
  121. {
  122. _imageTransparentColor = value;
  123. this.Invalidate();
  124. }
  125. }
  126. /// <summary>
  127. /// Gets or sets an annotation's content alignment.
  128. /// </summary>
  129. /// <value>
  130. /// A <see cref="ContentAlignment"/> value that represents the content alignment.
  131. /// </value>
  132. /// <remarks>
  133. /// This property is used to align text for <see cref="TextAnnotation"/>, <see cref="RectangleAnnotation"/>,
  134. /// <see cref="EllipseAnnotation"/> and <see cref="CalloutAnnotation"/> objects, and to align
  135. /// a non-scaled image inside an <see cref="ImageAnnotation"/> object.
  136. /// </remarks>
  137. [
  138. SRCategory("CategoryAttributeImage"),
  139. DefaultValue(typeof(ContentAlignment), "MiddleCenter"),
  140. SRDescription("DescriptionAttributeImageAnnotation_Alignment"),
  141. ]
  142. override public ContentAlignment Alignment
  143. {
  144. get
  145. {
  146. return base.Alignment;
  147. }
  148. set
  149. {
  150. base.Alignment = value;
  151. Invalidate();
  152. }
  153. }
  154. /// <summary>
  155. /// Gets or sets an annotation's text style.
  156. /// <seealso cref="Font"/>
  157. /// <seealso cref="ForeColor"/>
  158. /// </summary>
  159. /// <value>
  160. /// A <see cref="TextStyle"/> value used to draw an annotation's text.
  161. /// </value>
  162. [Browsable(false)]
  163. [EditorBrowsable(EditorBrowsableState.Never)]
  164. public override TextStyle TextStyle
  165. {
  166. get
  167. {
  168. return base.TextStyle;
  169. }
  170. set
  171. {
  172. base.TextStyle = value;
  173. }
  174. }
  175. #endregion // Image properties
  176. #region Other
  177. /// <summary>
  178. /// Gets or sets an annotation's type name.
  179. /// </summary>
  180. /// <remarks>
  181. /// This property is used to get the name of each annotation type
  182. /// (e.g. Line, Rectangle, Ellipse).
  183. /// <para>
  184. /// This property is for internal use and is hidden at design and run time.
  185. /// </para>
  186. /// </remarks>
  187. [
  188. SRCategory("CategoryAttributeMisc"),
  189. Bindable(true),
  190. Browsable(false),
  191. EditorBrowsableAttribute(EditorBrowsableState.Never),
  192. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  193. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  194. SRDescription("DescriptionAttributeAnnotationType"),
  195. ]
  196. public override string AnnotationType
  197. {
  198. get
  199. {
  200. return "Image";
  201. }
  202. }
  203. /// <summary>
  204. /// Gets or sets annotation selection points style.
  205. /// </summary>
  206. /// <value>
  207. /// A <see cref="SelectionPointsStyle"/> value that represents annotation
  208. /// selection style.
  209. /// </value>
  210. /// <remarks>
  211. /// This property is for internal use and is hidden at design and run time.
  212. /// </remarks>
  213. [
  214. SRCategory("CategoryAttributeAppearance"),
  215. DefaultValue(SelectionPointsStyle.Rectangle),
  216. ParenthesizePropertyNameAttribute(true),
  217. Browsable(false),
  218. EditorBrowsableAttribute(EditorBrowsableState.Never),
  219. DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
  220. SerializationVisibilityAttribute(SerializationVisibility.Hidden),
  221. SRDescription("DescriptionAttributeSelectionPointsStyle"),
  222. ]
  223. override internal SelectionPointsStyle SelectionPointsStyle
  224. {
  225. get
  226. {
  227. return SelectionPointsStyle.Rectangle;
  228. }
  229. }
  230. #endregion
  231. #region Non Applicable Annotation Appearance Attributes (set as Non-Browsable)
  232. /// <summary>
  233. /// Not applicable to this type of annotation.
  234. /// <seealso cref="Font"/>
  235. /// </summary>
  236. /// <value>
  237. /// A <see cref="Color"/> value.
  238. /// </value>
  239. [
  240. SRCategory("CategoryAttributeAppearance"),
  241. Browsable(false),
  242. DefaultValue(typeof(Color), "Black"),
  243. TypeConverter(typeof(ColorConverter)),
  244. #if DESIGNER
  245. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  246. #endif
  247. ]
  248. override public Color ForeColor
  249. {
  250. get
  251. {
  252. return base.ForeColor;
  253. }
  254. set
  255. {
  256. base.ForeColor = value;
  257. }
  258. }
  259. /// <summary>
  260. /// Not applicable to this type of annotation.
  261. /// </summary>
  262. /// <value>
  263. /// A <see cref="Font"/> object.
  264. /// </value>
  265. [
  266. SRCategory("CategoryAttributeAppearance"),
  267. Browsable(false),
  268. DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
  269. ]
  270. override public Font Font
  271. {
  272. get
  273. {
  274. return base.Font;
  275. }
  276. set
  277. {
  278. base.Font = value;
  279. }
  280. }
  281. /// <summary>
  282. /// Not applicable to this annotation type.
  283. /// </summary>
  284. [
  285. SRCategory("CategoryAttributeAppearance"),
  286. Browsable(false),
  287. DefaultValue(typeof(Color), ""),
  288. NotifyParentPropertyAttribute(true),
  289. TypeConverter(typeof(ColorConverter)),
  290. #if DESIGNER
  291. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  292. #endif
  293. ]
  294. override public Color BackColor
  295. {
  296. get
  297. {
  298. return base.BackColor;
  299. }
  300. set
  301. {
  302. base.BackColor = value;
  303. }
  304. }
  305. /// <summary>
  306. /// Not applicable to this annotation type.
  307. /// </summary>
  308. [
  309. SRCategory("CategoryAttributeAppearance"),
  310. Browsable(false),
  311. DefaultValue(ChartHatchStyle.None),
  312. NotifyParentPropertyAttribute(true),
  313. #if DESIGNER
  314. Editor(typeof(HatchStyleEditor), typeof(UITypeEditor))
  315. #endif
  316. ]
  317. override public ChartHatchStyle BackHatchStyle
  318. {
  319. get
  320. {
  321. return base.BackHatchStyle;
  322. }
  323. set
  324. {
  325. base.BackHatchStyle = value;
  326. }
  327. }
  328. /// <summary>
  329. /// Not applicable to this annotation type.
  330. /// </summary>
  331. [
  332. SRCategory("CategoryAttributeAppearance"),
  333. Browsable(false),
  334. DefaultValue(GradientStyle.None),
  335. NotifyParentPropertyAttribute(true),
  336. #if DESIGNER
  337. Editor(typeof(GradientEditor), typeof(UITypeEditor))
  338. #endif
  339. ]
  340. override public GradientStyle BackGradientStyle
  341. {
  342. get
  343. {
  344. return base.BackGradientStyle;
  345. }
  346. set
  347. {
  348. base.BackGradientStyle = value;
  349. }
  350. }
  351. /// <summary>
  352. /// Not applicable to this annotation type.
  353. /// </summary>
  354. [
  355. SRCategory("CategoryAttributeAppearance"),
  356. Browsable(false),
  357. DefaultValue(typeof(Color), ""),
  358. NotifyParentPropertyAttribute(true),
  359. TypeConverter(typeof(ColorConverter)),
  360. #if DESIGNER
  361. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  362. #endif
  363. ]
  364. override public Color BackSecondaryColor
  365. {
  366. get
  367. {
  368. return base.BackSecondaryColor;
  369. }
  370. set
  371. {
  372. base.BackSecondaryColor = value;
  373. }
  374. }
  375. /// <summary>
  376. /// Not applicable to this annotation type.
  377. /// </summary>
  378. [
  379. SRCategory("CategoryAttributeAppearance"),
  380. Browsable(false),
  381. DefaultValue(typeof(Color), "Black"),
  382. TypeConverter(typeof(ColorConverter)),
  383. #if DESIGNER
  384. Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
  385. #endif
  386. ]
  387. override public Color LineColor
  388. {
  389. get
  390. {
  391. return base.LineColor;
  392. }
  393. set
  394. {
  395. base.LineColor = value;
  396. }
  397. }
  398. /// <summary>
  399. /// Not applicable to this annotation type.
  400. /// </summary>
  401. [
  402. SRCategory("CategoryAttributeAppearance"),
  403. DefaultValue(1),
  404. Browsable(false),
  405. SRDescription("DescriptionAttributeLineWidth"),
  406. ]
  407. override public int LineWidth
  408. {
  409. get
  410. {
  411. return base.LineWidth;
  412. }
  413. set
  414. {
  415. base.LineWidth = value;
  416. }
  417. }
  418. /// <summary>
  419. /// Not applicable to this annotation type.
  420. /// </summary>
  421. [
  422. SRCategory("CategoryAttributeAppearance"),
  423. Browsable(false),
  424. DefaultValue(ChartDashStyle.Solid),
  425. SRDescription("DescriptionAttributeLineDashStyle"),
  426. ]
  427. override public ChartDashStyle LineDashStyle
  428. {
  429. get
  430. {
  431. return base.LineDashStyle;
  432. }
  433. set
  434. {
  435. base.LineDashStyle = value;
  436. }
  437. }
  438. #endregion
  439. #endregion
  440. #region Methods
  441. #region Painting
  442. /// <summary>
  443. /// Paints the annotation object on the specified graphics.
  444. /// </summary>
  445. /// <param name="graphics">
  446. /// A <see cref="ChartGraphics"/> object, used to paint the annotation object.
  447. /// </param>
  448. /// <param name="chart">
  449. /// Reference to the <see cref="Chart"/> owner control.
  450. /// </param>
  451. override internal void Paint(Chart chart, ChartGraphics graphics)
  452. {
  453. // Get annotation position in relative coordinates
  454. PointF firstPoint = PointF.Empty;
  455. PointF anchorPoint = PointF.Empty;
  456. SizeF size = SizeF.Empty;
  457. GetRelativePosition(out firstPoint, out size, out anchorPoint);
  458. PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height);
  459. // Create selection rectangle
  460. RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y));
  461. // Get position
  462. RectangleF rectanglePosition = new RectangleF(selectionRect.Location, selectionRect.Size);
  463. if(rectanglePosition.Width < 0)
  464. {
  465. rectanglePosition.X = rectanglePosition.Right;
  466. rectanglePosition.Width = -rectanglePosition.Width;
  467. }
  468. if(rectanglePosition.Height < 0)
  469. {
  470. rectanglePosition.Y = rectanglePosition.Bottom;
  471. rectanglePosition.Height = -rectanglePosition.Height;
  472. }
  473. // Check if position is valid
  474. if( float.IsNaN(rectanglePosition.X) ||
  475. float.IsNaN(rectanglePosition.Y) ||
  476. float.IsNaN(rectanglePosition.Right) ||
  477. float.IsNaN(rectanglePosition.Bottom) )
  478. {
  479. return;
  480. }
  481. if(this.Common.ProcessModePaint)
  482. {
  483. // Draw "empty" image at design time
  484. if(this._imageName.Length == 0 && this.Chart.IsDesignMode() )
  485. {
  486. graphics.FillRectangleRel(
  487. rectanglePosition,
  488. this.BackColor,
  489. this.BackHatchStyle,
  490. this._imageName,
  491. this._imageWrapMode,
  492. this._imageTransparentColor,
  493. GetImageAlignment(this.Alignment),
  494. this.BackGradientStyle,
  495. this.BackSecondaryColor,
  496. this.LineColor,
  497. this.LineWidth,
  498. this.LineDashStyle,
  499. this.ShadowColor,
  500. this.ShadowOffset,
  501. PenAlignment.Center);
  502. // Draw text
  503. using( Brush textBrush = new SolidBrush(this.ForeColor) )
  504. {
  505. using (StringFormat format = new StringFormat(StringFormat.GenericTypographic))
  506. {
  507. format.Alignment = StringAlignment.Center;
  508. format.LineAlignment = StringAlignment.Center;
  509. format.FormatFlags = StringFormatFlags.LineLimit;
  510. format.Trimming = StringTrimming.EllipsisCharacter;
  511. graphics.DrawStringRel(
  512. "(no image)",
  513. this.Font,
  514. textBrush,
  515. rectanglePosition,
  516. format);
  517. }
  518. }
  519. }
  520. else
  521. {
  522. // Draw image
  523. graphics.FillRectangleRel(
  524. rectanglePosition,
  525. Color.Transparent,
  526. this.BackHatchStyle,
  527. this._imageName,
  528. this._imageWrapMode,
  529. this._imageTransparentColor,
  530. GetImageAlignment(this.Alignment),
  531. this.BackGradientStyle,
  532. Color.Transparent,
  533. Color.Transparent,
  534. 0,
  535. this.LineDashStyle,
  536. this.ShadowColor,
  537. this.ShadowOffset,
  538. PenAlignment.Center);
  539. }
  540. }
  541. if(this.Common.ProcessModeRegions)
  542. {
  543. // Add hot region
  544. this.Common.HotRegionsList.AddHotRegion(
  545. rectanglePosition,
  546. ReplaceKeywords(this.ToolTip),
  547. String.Empty,
  548. String.Empty,
  549. String.Empty,
  550. this,
  551. ChartElementType.Annotation,
  552. String.Empty);
  553. }
  554. // Paint selection handles
  555. PaintSelectionHandles(graphics, selectionRect, null);
  556. }
  557. /// <summary>
  558. /// Coverts ContentAlignment enumeration to ChartImageAlignmentStyle enumeration.
  559. /// </summary>
  560. /// <param name="alignment">Content alignment.</param>
  561. /// <returns>Image content alignment.</returns>
  562. private ChartImageAlignmentStyle GetImageAlignment(ContentAlignment alignment)
  563. {
  564. if(alignment == ContentAlignment.TopLeft)
  565. {
  566. return ChartImageAlignmentStyle.TopLeft;
  567. }
  568. else if(alignment == ContentAlignment.TopCenter)
  569. {
  570. return ChartImageAlignmentStyle.Top;
  571. }
  572. else if(alignment == ContentAlignment.TopRight)
  573. {
  574. return ChartImageAlignmentStyle.TopRight;
  575. }
  576. else if(alignment == ContentAlignment.MiddleRight)
  577. {
  578. return ChartImageAlignmentStyle.Right;
  579. }
  580. else if(alignment == ContentAlignment.BottomRight)
  581. {
  582. return ChartImageAlignmentStyle.BottomRight;
  583. }
  584. else if(alignment == ContentAlignment.BottomCenter)
  585. {
  586. return ChartImageAlignmentStyle.Bottom;
  587. }
  588. else if(alignment == ContentAlignment.BottomLeft)
  589. {
  590. return ChartImageAlignmentStyle.BottomLeft;
  591. }
  592. else if(alignment == ContentAlignment.MiddleLeft)
  593. {
  594. return ChartImageAlignmentStyle.Left;
  595. }
  596. return ChartImageAlignmentStyle.Center;
  597. }
  598. #endregion // Painting
  599. #region Content Size
  600. /// <summary>
  601. /// Gets text annotation content size based on the text and font.
  602. /// </summary>
  603. /// <returns>Annotation content position.</returns>
  604. override internal RectangleF GetContentPosition()
  605. {
  606. // Check image size
  607. if(this.Image.Length > 0)
  608. {
  609. // Try loading image and getting its size
  610. try
  611. {
  612. if(this.Chart != null)
  613. {
  614. ImageLoader imageLoader = this.Common.ImageLoader;
  615. if(imageLoader != null)
  616. {
  617. ChartGraphics chartGraphics = this.GetGraphics();
  618. if (chartGraphics != null)
  619. {
  620. SizeF absSize = new SizeF();
  621. if (imageLoader.GetAdjustedImageSize(this.Image, chartGraphics.Graphics, ref absSize))
  622. {
  623. SizeF imageSize = chartGraphics.GetRelativeSize(absSize);
  624. return new RectangleF(float.NaN, float.NaN, imageSize.Width, imageSize.Height);
  625. }
  626. }
  627. }
  628. }
  629. }
  630. catch(ArgumentException)
  631. {
  632. // ArgumentException is thrown by LoadImage in certain situations when it can't load the image
  633. }
  634. }
  635. return new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN);
  636. }
  637. #endregion
  638. #endregion
  639. }
  640. }