SvgAttributeCollection.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. #pragma warning disable
  7. namespace Svg
  8. {
  9. /// <summary>
  10. /// A collection of Scalable Vector Attributes that can be inherited from the owner elements ancestors.
  11. /// </summary>
  12. public sealed class SvgAttributeCollection : Dictionary<string, object>
  13. {
  14. private SvgElement _owner;
  15. /// <summary>
  16. /// Initialises a new instance of a <see cref="SvgAttributeCollection"/> with the given <see cref="SvgElement"/> as the owner.
  17. /// </summary>
  18. /// <param name="owner">The <see cref="SvgElement"/> owner of the collection.</param>
  19. public SvgAttributeCollection(SvgElement owner)
  20. {
  21. this._owner = owner;
  22. }
  23. /// <summary>
  24. /// Gets the attribute with the specified name.
  25. /// </summary>
  26. /// <typeparam name="TAttributeType">The type of the attribute value.</typeparam>
  27. /// <param name="attributeName">A <see cref="string"/> containing the name of the attribute.</param>
  28. /// <returns>The attribute value if available; otherwise the default value of <typeparamref name="TAttributeType"/>.</returns>
  29. public TAttributeType GetAttribute<TAttributeType>(string attributeName)
  30. {
  31. if (this.ContainsKey(attributeName) && base[attributeName] != null)
  32. {
  33. return (TAttributeType)base[attributeName];
  34. }
  35. return this.GetAttribute<TAttributeType>(attributeName, default(TAttributeType));
  36. }
  37. /// <summary>
  38. /// Gets the attribute with the specified name.
  39. /// </summary>
  40. /// <typeparam name="T">The type of the attribute value.</typeparam>
  41. /// <param name="attributeName">A <see cref="string"/> containing the name of the attribute.</param>
  42. /// <param name="defaultValue">The value to return if a value hasn't already been specified.</param>
  43. /// <returns>The attribute value if available; otherwise the default value of <typeparamref name="T"/>.</returns>
  44. public T GetAttribute<T>(string attributeName, T defaultValue)
  45. {
  46. if (this.ContainsKey(attributeName) && base[attributeName] != null)
  47. {
  48. return (T)base[attributeName];
  49. }
  50. return defaultValue;
  51. }
  52. /// <summary>
  53. /// Gets the attribute with the specified name and inherits from ancestors if there is no attribute set.
  54. /// </summary>
  55. /// <typeparam name="TAttributeType">The type of the attribute value.</typeparam>
  56. /// <param name="attributeName">A <see cref="string"/> containing the name of the attribute.</param>
  57. /// <returns>The attribute value if available; otherwise the ancestors value for the same attribute; otherwise the default value of <typeparamref name="TAttributeType"/>.</returns>
  58. public TAttributeType GetInheritedAttribute<TAttributeType>(string attributeName)
  59. {
  60. if (this.ContainsKey(attributeName) && !IsInheritValue(base[attributeName]))
  61. {
  62. var result = (TAttributeType)base[attributeName];
  63. var deferred = result as SvgDeferredPaintServer;
  64. if (deferred != null) deferred.EnsureServer(_owner);
  65. return result;
  66. }
  67. if (this._owner.Parent != null)
  68. {
  69. var parentAttribute = this._owner.Parent.Attributes[attributeName];
  70. if (parentAttribute != null)
  71. {
  72. return (TAttributeType)parentAttribute;
  73. }
  74. }
  75. return default(TAttributeType);
  76. }
  77. private bool IsInheritValue(object value)
  78. {
  79. return (value == null ||
  80. (value is SvgFontWeight && (SvgFontWeight)value == SvgFontWeight.Inherit) ||
  81. (value is SvgTextAnchor && (SvgTextAnchor)value == SvgTextAnchor.Inherit) ||
  82. (value is SvgFontVariant && (SvgFontVariant)value == SvgFontVariant.Inherit) ||
  83. (value is SvgTextDecoration && (SvgTextDecoration)value == SvgTextDecoration.Inherit) ||
  84. (value is XmlSpaceHandling && (XmlSpaceHandling)value == XmlSpaceHandling.inherit) ||
  85. (value is SvgOverflow && (SvgOverflow)value == SvgOverflow.Inherit) ||
  86. (value is SvgColourServer && (SvgColourServer)value == SvgColourServer.Inherit) ||
  87. (value is SvgShapeRendering && (SvgShapeRendering)value == SvgShapeRendering.Inherit) ||
  88. (value is SvgTextRendering && (SvgTextRendering)value == SvgTextRendering.Inherit) ||
  89. (value is SvgImageRendering && (SvgImageRendering)value == SvgImageRendering.Inherit) ||
  90. (value is string && ((string)value).ToLower() == "inherit")
  91. );
  92. }
  93. /// <summary>
  94. /// Gets the attribute with the specified name.
  95. /// </summary>
  96. /// <param name="attributeName">A <see cref="string"/> containing the attribute name.</param>
  97. /// <returns>The attribute value associated with the specified name; If there is no attribute the parent's value will be inherited.</returns>
  98. public new object this[string attributeName]
  99. {
  100. get { return this.GetInheritedAttribute<object>(attributeName); }
  101. set
  102. {
  103. if (base.ContainsKey(attributeName))
  104. {
  105. var oldVal = base[attributeName];
  106. if (TryUnboxedCheck(oldVal, value))
  107. {
  108. base[attributeName] = value;
  109. OnAttributeChanged(attributeName, value);
  110. }
  111. }
  112. else
  113. {
  114. base[attributeName] = value;
  115. OnAttributeChanged(attributeName, value);
  116. }
  117. }
  118. }
  119. private bool TryUnboxedCheck(object a, object b)
  120. {
  121. if (IsValueType(a))
  122. {
  123. if (a is SvgUnit)
  124. return UnboxAndCheck<SvgUnit>(a, b);
  125. else if (a is bool)
  126. return UnboxAndCheck<bool>(a, b);
  127. else if (a is int)
  128. return UnboxAndCheck<int>(a, b);
  129. else if (a is float)
  130. return UnboxAndCheck<float>(a, b);
  131. else if (a is SvgViewBox)
  132. return UnboxAndCheck<SvgViewBox>(a, b);
  133. else
  134. return true;
  135. }
  136. else
  137. {
  138. return a != b;
  139. }
  140. }
  141. private bool UnboxAndCheck<T>(object a, object b)
  142. {
  143. return !((T)a).Equals((T)b);
  144. }
  145. private bool IsValueType(object obj)
  146. {
  147. return obj != null && obj.GetType().IsValueType;
  148. }
  149. /// <summary>
  150. /// Fired when an Atrribute has changed
  151. /// </summary>
  152. public event EventHandler<AttributeEventArgs> AttributeChanged;
  153. private void OnAttributeChanged(string attribute, object value)
  154. {
  155. var handler = AttributeChanged;
  156. if (handler != null)
  157. {
  158. handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value });
  159. }
  160. }
  161. }
  162. /// <summary>
  163. /// A collection of Custom Attributes
  164. /// </summary>
  165. public sealed class SvgCustomAttributeCollection : Dictionary<string, string>
  166. {
  167. private SvgElement _owner;
  168. /// <summary>
  169. /// Initialises a new instance of a <see cref="SvgAttributeCollection"/> with the given <see cref="SvgElement"/> as the owner.
  170. /// </summary>
  171. /// <param name="owner">The <see cref="SvgElement"/> owner of the collection.</param>
  172. public SvgCustomAttributeCollection(SvgElement owner)
  173. {
  174. this._owner = owner;
  175. }
  176. /// <summary>
  177. /// Gets the attribute with the specified name.
  178. /// </summary>
  179. /// <param name="attributeName">A <see cref="string"/> containing the attribute name.</param>
  180. /// <returns>The attribute value associated with the specified name; If there is no attribute the parent's value will be inherited.</returns>
  181. public new string this[string attributeName]
  182. {
  183. get { return base[attributeName]; }
  184. set
  185. {
  186. if (base.ContainsKey(attributeName))
  187. {
  188. var oldVal = base[attributeName];
  189. base[attributeName] = value;
  190. if (oldVal != value) OnAttributeChanged(attributeName, value);
  191. }
  192. else
  193. {
  194. base[attributeName] = value;
  195. OnAttributeChanged(attributeName, value);
  196. }
  197. }
  198. }
  199. /// <summary>
  200. /// Fired when an Atrribute has changed
  201. /// </summary>
  202. public event EventHandler<AttributeEventArgs> AttributeChanged;
  203. private void OnAttributeChanged(string attribute, object value)
  204. {
  205. var handler = AttributeChanged;
  206. if (handler != null)
  207. {
  208. handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value });
  209. }
  210. }
  211. }
  212. }
  213. #pragma warning restore