// 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);
}
}
}
}