using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; namespace Svg { /// /// A collection of Scalable Vector Attributes that can be inherited from the owner elements ancestors. /// public sealed class SvgAttributeCollection : Dictionary { private SvgElement _owner; /// /// Initialises a new instance of a with the given as the owner. /// /// The owner of the collection. public SvgAttributeCollection(SvgElement owner) { this._owner = owner; } /// /// Gets the attribute with the specified name. /// /// The type of the attribute value. /// A containing the name of the attribute. /// The attribute value if available; otherwise the default value of . public TAttributeType GetAttribute(string attributeName) { if (this.ContainsKey(attributeName) && base[attributeName] != null) { return (TAttributeType)base[attributeName]; } return this.GetAttribute(attributeName, default(TAttributeType)); } /// /// Gets the attribute with the specified name. /// /// The type of the attribute value. /// A containing the name of the attribute. /// The value to return if a value hasn't already been specified. /// The attribute value if available; otherwise the default value of . public T GetAttribute(string attributeName, T defaultValue) { if (this.ContainsKey(attributeName) && base[attributeName] != null) { return (T)base[attributeName]; } return defaultValue; } /// /// Gets the attribute with the specified name and inherits from ancestors if there is no attribute set. /// /// The type of the attribute value. /// A containing the name of the attribute. /// The attribute value if available; otherwise the ancestors value for the same attribute; otherwise the default value of . public TAttributeType GetInheritedAttribute(string attributeName) { if (this.ContainsKey(attributeName) && !IsInheritValue(base[attributeName])) { var result = (TAttributeType)base[attributeName]; var deferred = result as SvgDeferredPaintServer; if (deferred != null) deferred.EnsureServer(_owner); return result; } if (this._owner.Parent != null) { var parentAttribute = this._owner.Parent.Attributes[attributeName]; if (parentAttribute != null) { return (TAttributeType)parentAttribute; } } return default(TAttributeType); } private bool IsInheritValue(object value) { return (value == null || (value is SvgFontWeight && (SvgFontWeight)value == SvgFontWeight.Inherit) || (value is SvgTextAnchor && (SvgTextAnchor)value == SvgTextAnchor.Inherit) || (value is SvgFontVariant && (SvgFontVariant)value == SvgFontVariant.Inherit) || (value is SvgTextDecoration && (SvgTextDecoration)value == SvgTextDecoration.Inherit) || (value is XmlSpaceHandling && (XmlSpaceHandling)value == XmlSpaceHandling.inherit) || (value is SvgOverflow && (SvgOverflow)value == SvgOverflow.Inherit) || (value is SvgColourServer && (SvgColourServer)value == SvgColourServer.Inherit) || (value is SvgShapeRendering && (SvgShapeRendering)value == SvgShapeRendering.Inherit) || (value is SvgTextRendering && (SvgTextRendering)value == SvgTextRendering.Inherit) || (value is SvgImageRendering && (SvgImageRendering)value == SvgImageRendering.Inherit) || (value is string && ((string)value).ToLower() == "inherit") ); } /// /// Gets the attribute with the specified name. /// /// A containing the attribute name. /// The attribute value associated with the specified name; If there is no attribute the parent's value will be inherited. public new object this[string attributeName] { get { return this.GetInheritedAttribute(attributeName); } set { if(base.ContainsKey(attributeName)) { var oldVal = base[attributeName]; if(TryUnboxedCheck(oldVal, value)) { base[attributeName] = value; OnAttributeChanged(attributeName, value); } } else { base[attributeName] = value; OnAttributeChanged(attributeName, value); } } } private bool TryUnboxedCheck(object a, object b) { if(IsValueType(a)) { if(a is SvgUnit) return UnboxAndCheck(a, b); else if(a is bool) return UnboxAndCheck(a, b); else if(a is int) return UnboxAndCheck(a, b); else if(a is float) return UnboxAndCheck(a, b); else if(a is SvgViewBox) return UnboxAndCheck(a, b); else return true; } else { return a != b; } } private bool UnboxAndCheck(object a, object b) { return !((T)a).Equals((T)b); } private bool IsValueType(object obj) { return obj != null && obj.GetType().IsValueType; } /// /// Fired when an Atrribute has changed /// public event EventHandler AttributeChanged; private void OnAttributeChanged(string attribute, object value) { var handler = AttributeChanged; if(handler != null) { handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value }); } } } /// /// A collection of Custom Attributes /// public sealed class SvgCustomAttributeCollection : Dictionary { private SvgElement _owner; /// /// Initialises a new instance of a with the given as the owner. /// /// The owner of the collection. public SvgCustomAttributeCollection(SvgElement owner) { this._owner = owner; } /// /// Gets the attribute with the specified name. /// /// A containing the attribute name. /// The attribute value associated with the specified name; If there is no attribute the parent's value will be inherited. public new string this[string attributeName] { get { return base[attributeName]; } set { if(base.ContainsKey(attributeName)) { var oldVal = base[attributeName]; base[attributeName] = value; if(oldVal != value) OnAttributeChanged(attributeName, value); } else { base[attributeName] = value; OnAttributeChanged(attributeName, value); } } } /// /// Fired when an Atrribute has changed /// public event EventHandler AttributeChanged; private void OnAttributeChanged(string attribute, object value) { var handler = AttributeChanged; if(handler != null) { handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value }); } } } }