using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Drawing.Drawing2D; using Svg.Transforms; namespace Svg { /// /// Defines a path that can be used by other elements. /// [SvgElement("clipPath")] public sealed class SvgClipPath : SvgElement { private bool _pathDirty = true; /// /// Specifies the coordinate system for the clipping path. /// [SvgAttribute("clipPathUnits")] public SvgCoordinateUnits ClipPathUnits { get; set; } /// /// Initializes a new instance of the class. /// public SvgClipPath() { this.ClipPathUnits = SvgCoordinateUnits.ObjectBoundingBox; } private GraphicsPath cachedClipPath = null; /// /// Gets this 's region to be used as a clipping region. /// /// A new containing the to be used for clipping. public Region GetClipRegion(SvgVisualElement owner) { if (cachedClipPath == null || this._pathDirty) { cachedClipPath = new GraphicsPath(); foreach (SvgElement element in this.Children) { this.CombinePaths(cachedClipPath, element); } this._pathDirty = false; } return new Region(cachedClipPath); } /// /// /// /// /// private void CombinePaths(GraphicsPath path, SvgElement element) { var graphicsElement = element as SvgVisualElement; if (graphicsElement != null && graphicsElement.Path != null) { path.FillMode = (graphicsElement.ClipRule == SvgClipRule.NonZero) ? FillMode.Winding : FillMode.Alternate; GraphicsPath childPath = graphicsElement.Path; if (graphicsElement.Transforms != null) { foreach (SvgTransform transform in graphicsElement.Transforms) { childPath.Transform(transform.Matrix); } } path.AddPath(childPath, false); } foreach (SvgElement child in element.Children) { this.CombinePaths(path, child); } } /// /// Called by the underlying when an element has been added to the /// collection. /// /// The that has been added. /// An representing the index where the element was added to the collection. protected override void AddElement(SvgElement child, int index) { base.AddElement(child, index); this._pathDirty = true; } /// /// Called by the underlying when an element has been removed from the /// collection. /// /// The that has been removed. protected override void RemoveElement(SvgElement child) { base.RemoveElement(child); this._pathDirty = true; } /// /// Renders the and contents to the specified object. /// /// The object to render to. protected override void Render(SvgRenderer renderer) { // Do nothing } public override SvgElement DeepCopy() { return DeepCopy(); } public override SvgElement DeepCopy() { var newObj = base.DeepCopy() as SvgClipPath; newObj.ClipPathUnits = this.ClipPathUnits; return newObj; } } }