123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- using FastReport;
- using FastReport.DevComponents.DotNetBar;
- using FastReport.Utils;
- using InABox.Core;
- using InABox.Reports.CustomObjects;
- using netDxf;
- using Syncfusion.Windows.PdfViewer;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Design;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace InABox.Reports
- {
- public class MultiSignatureObject : MultiItemObject
- {
- private FillBase textFill;
- private IDictionary<string, byte[]>? signatureData { get; set; }
- [Category("Data")]
- public string? DataColumn { get; set; }
- [Category("Data")]
- public Dictionary<string, Image>? Signatures { get; set; }
- [Category("Layout")]
- public float LabelHeight { get; set; }
- [Category("Appearance")]
- [Editor("FastReport.TypeEditors.FillEditor, FastReport", typeof(UITypeEditor))]
- public FillBase TextFill
- {
- get { return textFill; }
- set
- {
- if (value == null)
- throw new ArgumentNullException("TextFill");
- textFill = value;
- if (!String.IsNullOrEmpty(Style))
- Style = "";
- }
- }
- [Category("Appearance")]
- public Font Font { get; set; }
- public MultiSignatureObject()
- {
- LabelHeight = 20;
- textFill = new SolidFill(Color.Black);
- Font = DrawUtils.DefaultReportFont;
- }
- public override void GetData()
- {
- base.GetData();
- if (!string.IsNullOrEmpty(DataColumn))
- {
- signatureData = null;
- Signatures = null;
- object data = Report.GetColumnValueNullable(DataColumn);
- if (data is IDictionary<string, byte[]> dict)
- {
- SetSignatureData(dict);
- }
- }
- }
- private void SetSignatureData(IDictionary<string, byte[]> signatureData)
- {
- this.signatureData = signatureData;
- }
- private class SignatureItem : Item
- {
- public string Name;
- public Image Image;
- public float Width => Image.Width;
- public float Height { get; }
- public SignatureItem(string name, Image image, float labelHeight)
- {
- Name = name;
- Image = image;
- Height = image.Height + labelHeight;
- }
- }
- #region Serialization
- public override void Serialize(FRWriter writer)
- {
- base.Serialize(writer);
- MultiSignatureObject c = writer.DiffObject as MultiSignatureObject;
- if (DataColumn != c.DataColumn)
- writer.WriteValue("DataColumn", DataColumn);
- if ((writer.SerializeTo != SerializeTo.Preview || Font != c.Font) && writer.ItemName != "inherited")
- writer.WriteValue("Font", Font);
- if(TextFill != c.TextFill)
- TextFill.Serialize(writer, "TextFill", c.TextFill);
- if (writer.SerializeTo != SerializeTo.SourcePages)
- {
- if (writer.SerializeTo == SerializeTo.Preview || String.IsNullOrEmpty(DataColumn))
- {
- if (Signatures == null && signatureData != null)
- writer.WriteStr("Images", Serialization.Serialize(signatureData));
- else if (!writer.AreEqual(Signatures, c.Signatures))
- writer.WriteValue("Images", Signatures);
- }
- }
- }
- public override void Deserialize(FRReader reader)
- {
- base.Deserialize(reader);
- if (reader.HasProperty("TextFill"))
- {
- TextFill.Deserialize(reader, "TextFill");
- }
- if (reader.HasProperty("Images"))
- {
- SetSignatureData(Serialization.Deserialize<Dictionary<string, byte[]>>(reader.ReadStr("Images")));
- }
- switch (reader.DeserializeFrom)
- {
- case SerializeTo.Undo:
- case SerializeTo.Preview:
- case SerializeTo.Clipboard:
- // skip
- break;
- default:
- if (!reader.HasProperty("Font") && reader.ItemName != "inherited")
- {
- string creatorVersion = reader.Root.GetProp("ReportInfo.CreatorVersion");
- if (!String.IsNullOrEmpty(creatorVersion))
- {
- try
- {
- string[] versions = creatorVersion.Split('.');
- int major = 0;
- if (Int32.TryParse(versions[0], out major))
- {
- if (major < 2016)
- {
- Font = new Font("Arial", 10);
- }
- }
- }
- catch
- {
- }
- }
- }
- break;
- }
- }
- #endregion
- public override void Assign(Base source)
- {
- base.Assign(source);
- if (source is MultiSignatureObject src)
- {
- DataColumn = src.DataColumn;
- TextFill = src.TextFill;
- Font = src.Font;
- Signatures = src.Signatures == null ? null : src.Signatures.ToDictionary(x => x.Key, x => x.Value.Clone() as Image);
- if (src.Signatures == null && src.signatureData != null)
- {
- signatureData = src.signatureData;
- }
- }
- }
- public static Image? Load(byte[] bytes)
- {
- if (bytes != null && bytes.Length > 0)
- {
- try
- {
- #if CROSSPLATFORM
- // TODO memory leaks image converter
- return Image.FromStream(new MemoryStream(bytes));
- #else
- return new ImageConverter().ConvertFrom(bytes) as Image;
- #endif
- }
- catch
- {
- Bitmap errorBmp = new Bitmap(10, 10);
- using (Graphics g = Graphics.FromImage(errorBmp))
- {
- g.DrawLine(Pens.Red, 0, 0, 10, 10);
- g.DrawLine(Pens.Red, 0, 10, 10, 0);
- }
- return errorBmp;
- }
- }
- return null;
- }
- private void LoadSignatures()
- {
- if (signatureData == null) return;
- Signatures = new();
- var oldData = new Dictionary<string, byte[]>();
- foreach(var (name, data) in signatureData)
- {
- var saveImageData = data;
- // FImageData will be reset after this line, keep it
- var newImage = Load(data);
- if (newImage != null)
- {
- Signatures.Add(name, newImage);
- }
- oldData[name] = saveImageData;
- }
- signatureData = oldData;
- }
- internal StringFormat GetStringFormat(GraphicCache cache, StringFormatFlags flags, float scale)
- {
- StringAlignment align = StringAlignment.Near;
- if (HorizontalAlignment == System.Windows.HorizontalAlignment.Center)
- align = StringAlignment.Center;
- else if (HorizontalAlignment == System.Windows.HorizontalAlignment.Right)
- align = StringAlignment.Far;
- StringAlignment lineAlign = StringAlignment.Near;
- if (VerticalAlignment == System.Windows.VerticalAlignment.Center)
- lineAlign = StringAlignment.Center;
- else if (VerticalAlignment == System.Windows.VerticalAlignment.Bottom)
- lineAlign = StringAlignment.Far;
- return cache.GetStringFormat(align, lineAlign, StringTrimming.None, flags, 0f, 0f);
- }
- protected override void DrawItem(FRPaintEventArgs e, Item item, float x, float y, float w, float h)
- {
- if (item is SignatureItem signature)
- {
- var imageBoxWidth = w;
- var imageBoxHeight = h - LabelHeight;
- var aspectRatio = signature.Image.Width / signature.Image.Height;
- float imageWidth;
- float imageHeight;
- if (aspectRatio < imageBoxWidth / imageBoxHeight)
- {
- imageHeight = imageBoxHeight;
- imageWidth = imageHeight * aspectRatio;
- }
- else
- {
- imageWidth = imageBoxWidth;
- imageHeight = imageWidth / aspectRatio;
- }
- float imageX = x;
- float imageY = y;
- switch (HorizontalAlignment)
- {
- case System.Windows.HorizontalAlignment.Center:
- imageX += imageBoxWidth / 2 - imageWidth / 2;
- break;
- case System.Windows.HorizontalAlignment.Right:
- imageX += imageBoxWidth - imageWidth;
- break;
- case System.Windows.HorizontalAlignment.Stretch:
- imageWidth = imageBoxWidth;
- break;
- }
- switch (VerticalAlignment)
- {
- case System.Windows.VerticalAlignment.Center:
- imageY += imageBoxHeight / 2 - imageHeight / 2;
- break;
- case System.Windows.VerticalAlignment.Top:
- imageY += imageBoxHeight - imageHeight;
- break;
- case System.Windows.VerticalAlignment.Stretch:
- imageHeight = imageBoxHeight;
- break;
- }
- RectangleF textRect = new RectangleF(
- x * e.ScaleX,
- (y + h - LabelHeight) * e.ScaleY,
- w * e.ScaleX,
- h * e.ScaleY);
- Brush textBrush = null;
- if (TextFill is SolidFill)
- textBrush = e.Cache.GetBrush((TextFill as SolidFill).Color);
- else
- textBrush = TextFill.CreateBrush(textRect, e.ScaleX, e.ScaleY);
- Font font = e.Cache.GetFont(Font.FontFamily,
- IsPrinting ? Font.Size : Font.Size * e.ScaleX * 96f / DrawUtils.ScreenDpi,
- Font.Style);
- e.Graphics.DrawImage(signature.Image, imageX * e.ScaleX, imageY * e.ScaleY, imageWidth * e.ScaleX, imageHeight * e.ScaleY);
- var horz = HorizontalAlignment switch
- {
- System.Windows.HorizontalAlignment.Right => HorzAlign.Right,
- System.Windows.HorizontalAlignment.Center => HorzAlign.Center,
- System.Windows.HorizontalAlignment.Stretch => HorzAlign.Justify,
- _ => HorzAlign.Left
- };
- var vert = VerticalAlignment switch
- {
- System.Windows.VerticalAlignment.Bottom => VertAlign.Bottom,
- System.Windows.VerticalAlignment.Center => VertAlign.Center,
- System.Windows.VerticalAlignment.Stretch => VertAlign.Top,
- _ => VertAlign.Top
- };
-
- StringFormat format = GetStringFormat(e.Cache, 0, e.ScaleX);
- // use advanced rendering
- AdvancedTextRenderer advancedRenderer = new AdvancedTextRenderer(signature.Name, e.Graphics, font, textBrush,
- null, textRect, format, horz, vert, LabelHeight * e.ScaleY, 0,
- 1, false, false, false, false,
- e.ScaleX * 96f / DrawUtils.ScreenDpi,
- IsPrinting ? 1 : e.ScaleX * 96f / DrawUtils.ScreenDpi, null, IsPrinting);
- advancedRenderer.Draw();
- }
- }
- protected override IList<Item>? LoadItems()
- {
- if (Signatures == null)
- {
- LoadSignatures();
- }
- if (Signatures == null)
- {
- return null;
- }
- return Signatures.Select(x => new SignatureItem(x.Key, x.Value, LabelHeight) as Item).ToList();
- }
- }
- }
|