// THIS FILE IS PART OF SVG PROJECT // THE SVG PROJECT IS AN OPENSOURCE LIBRARY LICENSED UNDER THE MS-PL License. // COPYRIGHT (C) svg-net. ALL RIGHTS RESERVED. // GITHUB: https://github.com/svg-net/SVG using AntdUI.Svg.DataTypes; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; namespace AntdUI.Svg.FilterEffects { /// /// A filter effect consists of a series of graphics operations that are applied to a given source graphic to produce a modified graphical result. /// public sealed class SvgFilter : SvgElement { public override string ClassName { get => "filter"; } /// /// Gets or sets the position where the left point of the filter. /// [SvgAttribute("x")] public SvgUnit X { get { return Attributes.GetAttribute("x"); } set { Attributes["x"] = value; } } /// /// Gets or sets the position where the top point of the filter. /// [SvgAttribute("y")] public SvgUnit Y { get { return Attributes.GetAttribute("y"); } set { Attributes["y"] = value; } } /// /// Gets or sets the width of the resulting filter graphic. /// [SvgAttribute("width")] public SvgUnit Width { get { return Attributes.GetAttribute("width"); } set { Attributes["width"] = value; } } /// /// Gets or sets the height of the resulting filter graphic. /// [SvgAttribute("height")] public SvgUnit Height { get { return Attributes.GetAttribute("height"); } set { Attributes["height"] = value; } } /// /// Gets or sets the color-interpolation-filters of the resulting filter graphic. /// NOT currently mapped through to bitmap /// [SvgAttribute("color-interpolation-filters")] public SvgColourInterpolation ColorInterpolationFilters { get { return Attributes.GetAttribute("color-interpolation-filters"); } set { Attributes["color-interpolation-filters"] = value; } } /// /// Initializes a new instance of the class. /// public SvgFilter() { } /// /// Renders the and contents to the specified object. /// /// The object to render to. protected override void Render(ISvgRenderer renderer) { base.RenderChildren(renderer); } /// /// Creates a new object that is a copy of the current instance. /// /// /// A new object that is a copy of this instance. /// public override object Clone() { return (SvgFilter)MemberwiseClone(); } private Matrix GetTransform(SvgVisualElement element) { var transformMatrix = new Matrix(); foreach (var transformation in element.Transforms) { transformMatrix.Multiply(transformation.Matrix(0, 0)); } return transformMatrix; } private RectangleF GetPathBounds(SvgVisualElement element, ISvgRenderer renderer, Matrix transform) { var bounds = element.Path(renderer).GetBounds(); var pts = new PointF[] { bounds.Location, new PointF(bounds.Right, bounds.Bottom) }; transform.TransformPoints(pts); return new RectangleF(Math.Min(pts[0].X, pts[1].X), Math.Min(pts[0].Y, pts[1].Y), Math.Abs(pts[0].X - pts[1].X), Math.Abs(pts[0].Y - pts[1].Y)); } public void ApplyFilter(SvgVisualElement element, ISvgRenderer renderer, Action renderMethod) { var inflate = 0.5f; var transform = GetTransform(element); var bounds = GetPathBounds(element, renderer, transform); if (bounds.Width == 0 || bounds.Height == 0) return; var buffer = new ImageBuffer(bounds, inflate, renderer, renderMethod) { Transform = transform }; IEnumerable primitives = Children.OfType(); if (primitives.Count() > 0) { foreach (var primitive in primitives) { primitive.Process(buffer); } // Render the final filtered image var bufferImg = buffer.Buffer; //bufferImg.Save(@"C:\test.png"); var imgDraw = RectangleF.Inflate(bounds, inflate * bounds.Width, inflate * bounds.Height); var prevClip = renderer.GetClip(); renderer.SetClip(new Region(imgDraw)); renderer.DrawImage(bufferImg, imgDraw, new RectangleF(bounds.X, bounds.Y, imgDraw.Width, imgDraw.Height), GraphicsUnit.Pixel); renderer.SetClip(prevClip); } } } }