| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 | using FastReport;using FastReport.DevComponents.DotNetBar;using FastReport.Utils;using InABox.Core;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.Wpf.Reports.CustomObjects{    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();        }    }}
 |