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
}
}