RichObject.DesignExt.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using FastReport.Forms;
  2. using FastReport.Utils;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Windows.Documents;
  6. using System.Windows;
  7. using System.Windows.Forms;
  8. using System.Windows.Media.Imaging;
  9. using System.Windows.Media;
  10. using System.Text;
  11. using System;
  12. namespace FastReport
  13. {
  14. partial class RichObject : IHasEditor
  15. {
  16. private string cachedText;
  17. private SizeF cachedSize;
  18. private FlowDocument cachedDocument;
  19. private Image cachedImage;
  20. private BitmapSource FlowDocumentToBitmap(FlowDocument document, System.Windows.Size size)
  21. {
  22. document.ColumnWidth = size.Width;
  23. document.PagePadding = new Thickness(Padding.Left, Padding.Top, Padding.Right, Padding.Bottom);
  24. var paginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
  25. paginator.PageSize = size;
  26. var visual = new DrawingVisual();
  27. using (var ctx = visual.RenderOpen())
  28. {
  29. // draw white background
  30. ctx.DrawRectangle(System.Windows.Media.Brushes.White, null, new Rect(size));
  31. }
  32. visual.Children.Add(paginator.GetPage(0).Visual);
  33. var dpi = Report.Designer.ZoomDpi;
  34. var bitmap = new RenderTargetBitmap((int)(size.Width * dpi), (int)(size.Height * dpi), 96 * dpi, 96 * dpi, PixelFormats.Pbgra32);
  35. bitmap.Render(visual);
  36. visual.Children.Clear();
  37. return bitmap;
  38. }
  39. private FlowDocument RtfToFlowDocument(string text)
  40. {
  41. var document = new FlowDocument();
  42. var textRange = new TextRange(document.ContentStart, document.ContentEnd);
  43. using (var stream = new MemoryStream(Encoding.Default.GetBytes(text)))
  44. textRange.Load(stream, System.Windows.DataFormats.Rtf);
  45. return document;
  46. }
  47. private void DrawRich(FRPaintEventArgs e)
  48. {
  49. if (Width <= 0 || Height <= 0)
  50. return;
  51. if (Text != cachedText || cachedDocument == null)
  52. {
  53. cachedDocument = RtfToFlowDocument(Text);
  54. cachedText = Text;
  55. cachedSize = System.Drawing.Size.Empty;
  56. }
  57. var width = Width * e.ScaleX - Padding.Horizontal;
  58. var height = Height * e.ScaleY - Padding.Vertical;
  59. if (width != cachedSize.Width || height != cachedSize.Height || cachedImage == null)
  60. {
  61. var bitmap = FlowDocumentToBitmap(cachedDocument, new System.Windows.Size(Width, Height));
  62. cachedImage?.Dispose();
  63. cachedImage = Helper.GetImage(bitmap);
  64. cachedSize = new SizeF(width, height);
  65. }
  66. e.Graphics.DrawImage(cachedImage, AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY);
  67. }
  68. #region Public Methods
  69. internal void DrawDesign(FRPaintEventArgs e)
  70. {
  71. if (IsDesigning)
  72. {
  73. if (string.IsNullOrEmpty(this.Text))
  74. {
  75. e.Graphics.DrawString(Res.Get("Forms,RichTextEditor,Invoke"), DrawUtils.DefaultReportFont, System.Drawing.Brushes.Gray,
  76. new RectangleF(AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY));
  77. }
  78. else
  79. {
  80. try
  81. {
  82. DrawRich(e);
  83. }
  84. catch (Exception ex)
  85. {
  86. e.Graphics.DrawString(ex.Message, DrawUtils.DefaultReportFont, System.Drawing.Brushes.Red,
  87. new RectangleF(AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY));
  88. }
  89. }
  90. DrawMarkers(e);
  91. }
  92. }
  93. /// <inheritdoc/>
  94. public bool InvokeEditor()
  95. {
  96. using (var form = new RichEditorForm(this))
  97. {
  98. if (form.ShowDialog() == DialogResult.OK)
  99. {
  100. actualTextStart = 0;
  101. actualTextLength = 0;
  102. return true;
  103. }
  104. }
  105. return false;
  106. }
  107. /// <inheritdoc/>
  108. public override SmartTagBase GetSmartTag()
  109. {
  110. return new RichObjectSmartTag(this);
  111. }
  112. /// <inheritdoc/>
  113. public override ContextMenuBase GetContextMenu()
  114. {
  115. return new TextObjectBaseMenu(Report.Designer);
  116. }
  117. #endregion
  118. }
  119. }