using FastReport.Forms; using FastReport.Utils; using System.Drawing; using System.IO; using System.Windows.Documents; using System.Windows; using System.Windows.Forms; using System.Windows.Media.Imaging; using System.Windows.Media; using System.Text; using System; namespace FastReport { partial class RichObject : IHasEditor { private string cachedText; private SizeF cachedSize; private FlowDocument cachedDocument; private Image cachedImage; private BitmapSource FlowDocumentToBitmap(FlowDocument document, System.Windows.Size size) { document.ColumnWidth = size.Width; document.PagePadding = new Thickness(Padding.Left, Padding.Top, Padding.Right, Padding.Bottom); var paginator = ((IDocumentPaginatorSource)document).DocumentPaginator; paginator.PageSize = size; var visual = new DrawingVisual(); using (var ctx = visual.RenderOpen()) { // draw white background ctx.DrawRectangle(System.Windows.Media.Brushes.White, null, new Rect(size)); } visual.Children.Add(paginator.GetPage(0).Visual); var dpi = Report.Designer.ZoomDpi; var bitmap = new RenderTargetBitmap((int)(size.Width * dpi), (int)(size.Height * dpi), 96 * dpi, 96 * dpi, PixelFormats.Pbgra32); bitmap.Render(visual); visual.Children.Clear(); return bitmap; } private FlowDocument RtfToFlowDocument(string text) { var document = new FlowDocument(); var textRange = new TextRange(document.ContentStart, document.ContentEnd); using (var stream = new MemoryStream(Encoding.Default.GetBytes(text))) textRange.Load(stream, System.Windows.DataFormats.Rtf); return document; } private void DrawRich(FRPaintEventArgs e) { if (Width <= 0 || Height <= 0) return; if (Text != cachedText || cachedDocument == null) { cachedDocument = RtfToFlowDocument(Text); cachedText = Text; cachedSize = System.Drawing.Size.Empty; } var width = Width * e.ScaleX - Padding.Horizontal; var height = Height * e.ScaleY - Padding.Vertical; if (width != cachedSize.Width || height != cachedSize.Height || cachedImage == null) { var bitmap = FlowDocumentToBitmap(cachedDocument, new System.Windows.Size(Width, Height)); cachedImage?.Dispose(); cachedImage = Helper.GetImage(bitmap); cachedSize = new SizeF(width, height); } e.Graphics.DrawImage(cachedImage, AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY); } #region Public Methods internal void DrawDesign(FRPaintEventArgs e) { if (IsDesigning) { if (string.IsNullOrEmpty(this.Text)) { e.Graphics.DrawString(Res.Get("Forms,RichTextEditor,Invoke"), DrawUtils.DefaultReportFont, System.Drawing.Brushes.Gray, new RectangleF(AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY)); } else { try { DrawRich(e); } catch (Exception ex) { e.Graphics.DrawString(ex.Message, DrawUtils.DefaultReportFont, System.Drawing.Brushes.Red, new RectangleF(AbsLeft * e.ScaleX, AbsTop * e.ScaleY, Width * e.ScaleX, Height * e.ScaleY)); } } DrawMarkers(e); } } /// public bool InvokeEditor() { using (var form = new RichEditorForm(this)) { if (form.ShowDialog() == DialogResult.OK) { actualTextStart = 0; actualTextLength = 0; return true; } } return false; } /// public override SmartTagBase GetSmartTag() { return new RichObjectSmartTag(this); } /// public override ContextMenuBase GetContextMenu() { return new TextObjectBaseMenu(Report.Designer); } #endregion } }