From 837aa784f3892c49d7268a69bfd79d8ed472ac13 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sat, 3 Feb 2018 06:12:57 +0100 Subject: [PATCH] share Picture resource data among widgets --- src/BmpPicture.cs | 44 +++++++++++++++++++++++---- src/Picture.cs | 75 +++++++++++++++++++++++++++++++++++++++-------- src/SvgPicture.cs | 42 ++++++++++++++++++++++---- 3 files changed, 138 insertions(+), 23 deletions(-) diff --git a/src/BmpPicture.cs b/src/BmpPicture.cs index ea83095c..79302354 100644 --- a/src/BmpPicture.cs +++ b/src/BmpPicture.cs @@ -30,20 +30,47 @@ using Cairo; namespace Crow { + + /// + /// Derived from FILL for loading and drawing bitmaps in the interface + /// public class BmpPicture : Picture { - byte[] image; + byte[] image = null; + #region CTOR + /// + /// Initializes a new instance of BmpPicture. + /// public BmpPicture () {} + /// + /// Initializes a new instance of BmpPicture by loading the image pointed by the path argument + /// + /// image path, may be embedded public BmpPicture (string path) : base(path) {} - protected override void loadFromStream (Stream stream) + #endregion + /// + /// load the image for rendering from the path given as argument + /// + /// image path, may be embedded + public override void Load (string path) { - using (MemoryStream ms = new MemoryStream ()) { - stream.CopyTo (ms); - loadBitmap (new System.Drawing.Bitmap (ms)); + Path = path; + if (sharedResources.ContainsKey (path)) { + sharedPicture sp = sharedResources [path]; + image = (byte[])sp.Data; + Dimensions = sp.Dims; + return; + } + using (Stream stream = Interface.GetStreamFromPath (path)) { + using (MemoryStream ms = new MemoryStream ()) { + stream.CopyTo (ms); + loadBitmap (new System.Drawing.Bitmap (ms)); + } } + sharedResources [path] = new sharedPicture (image, Dimensions); } //load image via System.Drawing.Bitmap, cairo load png only @@ -103,6 +130,13 @@ namespace Crow } #endregion + /// + /// paint the image in the rectangle given in arguments according + /// to the Scale and keepProportion parameters. + /// + /// drawing Backend context + /// bounds of the target surface to paint + /// used for svg only public override void Paint (Cairo.Context gr, Rectangle rect, string subPart = "") { float widthRatio = 1f; diff --git a/src/Picture.cs b/src/Picture.cs index 0e5212ab..fe7007c7 100644 --- a/src/Picture.cs +++ b/src/Picture.cs @@ -27,38 +27,88 @@ using System; using System.IO; using Cairo; +using System.Collections.Generic; namespace Crow { + /// + /// store data and dimensions for resource sharing + /// + internal class sharedPicture { + //TODO: restructure this whith clever conceptual classes + public object Data; + public Size Dims; + public sharedPicture (object _data, Size _dims){ + Data = _data; + Dims = _dims; + } + } + /// + /// virtual class for loading and drawing picture in the interface + /// + /// Every loaded resources are stored in a dictonary with their path as key and shared + /// among interface elements + /// public abstract class Picture : Fill { + /// + /// share a single store for picture resources among usage in different controls + /// + internal static Dictionary sharedResources = new Dictionary(); + + /// + /// path of the picture + /// public string Path; + /// + /// unscaled dimensions fetched on loading + /// public Size Dimensions; + /// + /// if true and image has to be scalled, it will be scaled in both direction + /// equaly + /// public bool KeepProportions = false; + /// + /// allow or not the picture to be scalled on request by the painter + /// public bool Scaled = true; + #region CTOR + /// + /// Initializes a new instance of Picture. + /// public Picture () { } + /// + /// Initializes a new instance of Picture by loading the image pointed by the path argument + /// + /// image path, may be embedded public Picture (string path) { - LoadImage (path); + Load (path); } + #endregion #region Image Loading - public void LoadImage (string path) - { - loadFromStream (Interface.GetStreamFromPath (path)); - - Path = path; - } - - protected abstract void loadFromStream(Stream stream); + /// + /// load the image for rendering from the stream given as argument + /// + /// picture stream + public abstract void Load(string path); #endregion + /// + /// abstract method to paint the image in the rectangle given in arguments according + /// to the Scale and keepProportion parameters. + /// + /// drawing Backend context + /// bounds of the target surface to paint + /// used for svg only public abstract void Paint(Context ctx, Rectangle rect, string subPart = ""); - + #region Operators public static implicit operator Picture(string path) { if (string.IsNullOrEmpty (path)) @@ -71,7 +121,7 @@ namespace Crow else _pic = new BmpPicture (); - _pic.LoadImage (path); + _pic.Load (path); return _pic; } @@ -79,6 +129,7 @@ namespace Crow { return _pic == null ? null : _pic.Path; } + #endregion public static object Parse(string path) { @@ -92,7 +143,7 @@ namespace Crow else _pic = new BmpPicture (); - _pic.LoadImage (path); + _pic.Load (path); return _pic; } diff --git a/src/SvgPicture.cs b/src/SvgPicture.cs index b398d523..b4026852 100644 --- a/src/SvgPicture.cs +++ b/src/SvgPicture.cs @@ -30,22 +30,45 @@ using Cairo; namespace Crow { + /// + /// Derived from FILL for loading and drawing SVG images in the interface + /// public class SvgPicture : Picture { Rsvg.Handle hSVG; + #region CTOR + /// + /// Initializes a new instance of SvgPicture. + /// public SvgPicture () {} + /// + /// Initializes a new instance of SvgPicture by loading the SVG file pointed by the path argument + /// + /// image path, may be embedded public SvgPicture (string path) : base(path) {} - protected override void loadFromStream (Stream stream) + #endregion + + public override void Load (string path) { - using (MemoryStream ms = new MemoryStream ()) { - stream.CopyTo (ms); + Path = path; + if (sharedResources.ContainsKey (path)) { + sharedPicture sp = sharedResources [path]; + hSVG = (Rsvg.Handle)sp.Data; + Dimensions = sp.Dims; + return; + } + using (Stream stream = Interface.GetStreamFromPath (path)) { + using (MemoryStream ms = new MemoryStream ()) { + stream.CopyTo (ms); - hSVG = new Rsvg.Handle (ms.ToArray ()); - Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height); + hSVG = new Rsvg.Handle (ms.ToArray ()); + Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height); + } } + sharedResources [path] = new sharedPicture (hSVG, Dimensions); } #region implemented abstract members of Fill @@ -79,7 +102,14 @@ namespace Crow } } #endregion - + + /// + /// paint the image in the rectangle given in arguments according + /// to the Scale and keepProportion parameters. + /// + /// drawing Backend context + /// bounds of the target surface to paint + /// limit rendering to svg part named 'subPart' public override void Paint (Cairo.Context gr, Rectangle rect, string subPart = "") { float widthRatio = 1f; -- 2.47.3