Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorModel/BasicTypes/SvgLength.cs @ 12762

Last change on this file since 12762 was 12762, checked in by aballeit, 9 years ago

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File size: 12.2 KB
Line 
1using System;
2using System.Collections;
3using System.Xml;
4using System.Text.RegularExpressions;
5
6using SharpVectors.Dom.Css;
7
8namespace SharpVectors.Dom.Svg
9{
10    /// <summary>
11    /// Defines the direction of a SvgLength
12    /// </summary>
13    public enum SvgLengthDirection { Vertical, Horizontal, Viewport }
14
15    /// <summary>
16    /// Defines the origin type of the SvgLength value
17    /// </summary>
18    public enum SvgLengthSource { Css, Xml, String }
19
20    public sealed class SvgLength : ISvgLength
21    {
22        #region Private Fields
23
24        private static Regex reUnit = new Regex(CssValue.LengthUnitPattern + "$");
25
26        private string defaultValue;
27        private string propertyName;
28
29        private SvgLengthSource source;
30        private SvgElement ownerElement;
31        private SvgLengthDirection direction;
32        private CssAbsPrimitiveLengthValue cssLength;
33
34        #endregion
35
36        #region Constructors
37
38        public SvgLength(SvgElement ownerElement, string propertyName, SvgLengthSource source,
39            SvgLengthDirection direction, string defaultValue)
40        {
41            this.ownerElement = ownerElement;
42            this.propertyName = propertyName;
43            this.direction = direction;
44            this.defaultValue = defaultValue;
45            this.source = source;
46
47            if (this.source == SvgLengthSource.Xml || this.source == SvgLengthSource.Css)
48            {
49                GetCssXmlValue();
50            }
51        }
52
53        public SvgLength(SvgElement ownerElement, string propertyName, SvgLengthDirection direction,
54            string baseVal)
55            : this(ownerElement, propertyName, direction, baseVal, String.Empty)
56        {
57        }
58
59        public SvgLength(SvgElement ownerElement, string propertyName, SvgLengthDirection direction,
60            string baseVal, string defaultValue)
61            : this(ownerElement, propertyName,
62                SvgLengthSource.String, direction, defaultValue)
63        {
64            if (baseVal == null || baseVal.Length == 0)
65            {
66                baseVal = defaultValue;
67            }
68
69            baseVal = SvgNumber.ScientificToDec(baseVal);
70            cssLength = new CssAbsPrimitiveLengthValue(new CssPrimitiveLengthValue(baseVal, false),
71                propertyName, ownerElement);
72        }
73
74
75        /// <summary>
76        /// Creates a SvgLength value
77        /// </summary>
78        /// <param name="baseVal">String to be parsed into a length</param>
79        /// <param name="ownerElement">The associated element</param>
80        /// <param name="direction">Direction of the length, used for percentages</param>
81        public SvgLength(string propertyName, string baseVal, SvgElement ownerElement, SvgLengthDirection direction)
82        {
83            this.ownerElement = ownerElement;
84            this.direction = direction;
85
86            baseVal = SvgNumber.ScientificToDec(baseVal);
87
88            this.cssLength = new CssAbsPrimitiveLengthValue(new CssPrimitiveLengthValue(baseVal, false), propertyName, ownerElement);
89        }
90
91        public SvgLength(string propertyName, string baseVal, string defaultValue, SvgElement ownerElement, SvgLengthDirection direction)
92        {
93            this.ownerElement = ownerElement;
94            this.direction = direction;
95
96            if (baseVal == null || baseVal.Length == 0)
97            {
98                baseVal = defaultValue;
99            }
100
101            baseVal = SvgNumber.ScientificToDec(baseVal);
102
103            this.cssLength = new CssAbsPrimitiveLengthValue(new CssPrimitiveLengthValue(baseVal, false), propertyName, ownerElement);
104        }
105
106        public SvgLength(string propertyName, SvgStyleableElement ownerElement, SvgLengthDirection direction, string defaultValue)
107        {
108            this.ownerElement = ownerElement;
109            this.direction = direction;
110
111            string baseVal = ownerElement.GetPropertyValue(propertyName);
112            if (baseVal == null || baseVal == "")
113            {
114                baseVal = defaultValue;
115            }
116
117            baseVal = SvgNumber.ScientificToDec(baseVal);
118
119            this.cssLength = new CssAbsPrimitiveLengthValue(new CssPrimitiveLengthValue(baseVal, false), propertyName, ownerElement);
120        }
121
122        #endregion
123
124        #region Public Properties
125
126        public string PropertyName
127        {
128            get
129            {
130                return propertyName;
131            }
132        }
133
134        /// <summary>
135        /// The type of the value as specified by one of the constants specified above.
136        /// </summary>
137        public SvgLengthType UnitType
138        {
139            get
140            {
141                return (SvgLengthType)cssLength.PrimitiveType;
142            }
143        }
144
145        /// <summary>
146        /// The value as an floating point value, in user units. Setting this attribute will cause valueInSpecifiedUnits and valueAsString to be updated automatically to reflect this setting.
147        /// </summary>
148        /// <exception cref="DomException"> NO_MODIFICATION_ALLOWED_ERR: Raised on an attempt to change the value of a readonly attribute.</exception>
149        public double Value
150        {
151            get
152            {
153                double ret = 0;
154                switch (UnitType)
155                {
156                    case SvgLengthType.Number:
157                    case SvgLengthType.Px:
158                    case SvgLengthType.Cm:
159                    case SvgLengthType.Mm:
160                    case SvgLengthType.In:
161                    case SvgLengthType.Pt:
162                    case SvgLengthType.Pc:
163                    case SvgLengthType.Ems:
164                    case SvgLengthType.Exs:
165                        ret = cssLength.GetFloatValue(CssPrimitiveType.Px);
166                        break;
167                    case SvgLengthType.Percentage:
168                        double valueInSpecifiedUnits = cssLength.GetFloatValue(CssPrimitiveType.Percentage);
169                        if (ownerElement is SvgGradientElement)
170                        {
171                            ret = valueInSpecifiedUnits / 100F;
172                        }
173                        else
174                        {
175                            double w = 0;
176                            double h = 0;
177                            if (ownerElement.ViewportElement != null)
178                            {
179                                ISvgFitToViewBox ftv = (ISvgFitToViewBox)ownerElement.ViewportElement;
180                                w = ftv.ViewBox.AnimVal.Width;
181                                h = ftv.ViewBox.AnimVal.Height;
182                            }
183                            else
184                            {
185                                w = ownerElement.OwnerDocument.Window.InnerWidth;
186                                h = ownerElement.OwnerDocument.Window.InnerHeight;
187                            }
188
189                            if (direction == SvgLengthDirection.Horizontal)
190                            {
191                                ret = valueInSpecifiedUnits * w / 100;
192                            }
193                            else if (direction == SvgLengthDirection.Vertical)
194                            {
195                                ret = valueInSpecifiedUnits * h / 100;
196                            }
197                            else
198                            {
199                                ret = Math.Sqrt(w * w + h * h) / Math.Sqrt(2) * valueInSpecifiedUnits / 100;
200                            }
201                        }
202                        break;
203                    case SvgLengthType.Unknown:
204                        throw new SvgException(SvgExceptionType.SvgInvalidValueErr, "Bad length unit");
205                }
206                if (double.IsNaN(ret))
207                {
208                    ret = 10;
209                }
210                return ret;
211            }
212            set
213            {
214                CssPrimitiveType oldType = cssLength.PrimitiveType;
215                cssLength.SetFloatValue(CssPrimitiveType.Px, value);
216                ConvertToSpecifiedUnits((SvgLengthType)oldType);
217            }
218        }
219
220        /// <summary>
221        /// The value as an floating point value, in the units expressed by unitType. Setting this attribute will cause value and valueAsString to be updated automatically to reflect this setting.
222        /// </summary>
223        /// <exception cref="DomException"> NO_MODIFICATION_ALLOWED_ERR: Raised on an attempt to change the value of a readonly attribute.</exception>
224        public double ValueInSpecifiedUnits
225        {
226            get
227            {
228                return cssLength.GetFloatValue(cssLength.PrimitiveType);
229            }
230            set
231            {
232                cssLength.SetFloatValue(cssLength.PrimitiveType, value);
233            }
234        }
235
236        /// <summary>
237        /// The value as a string value, in the units expressed by unitType. Setting this attribute will cause value and valueInSpecifiedUnits to be updated automatically to reflect this setting.
238        /// </summary>
239        /// <exception cref="DomException">NO_MODIFICATION_ALLOWED_ERR: Raised on an attempt to change the value of a readonly attribute.</exception>
240        public string ValueAsString
241        {
242            get
243            {
244                return cssLength.CssText;
245            }
246            set
247            {
248                cssLength = new CssAbsPrimitiveLengthValue(new CssPrimitiveLengthValue(value, false), "", ownerElement);
249            }
250        }
251
252        #endregion
253
254        #region Public Methods
255
256        /// <summary>
257        /// Reset the value as a number with an associated unitType, thereby replacing the values for all of the attributes on the object.
258        /// </summary>
259        /// <param name="unitType">The unitType for the value (e.g., MM). </param>
260        /// <param name="valueInSpecifiedUnits">The new value</param>
261        public void NewValueSpecifiedUnits(SvgLengthType unitType, double valueInSpecifiedUnits)
262        {
263            cssLength.SetFloatValue((CssPrimitiveType)unitType, valueInSpecifiedUnits);
264        }
265
266        /// <summary>
267        /// Preserve the same underlying stored value, but reset the stored unit identifier to the given unitType. Object attributes unitType, valueAsSpecified and valueAsString might be modified as a result of this method. For example, if the original value were "0.5cm" and the method was invoked to convert to millimeters, then the unitType would be changed to MM, valueAsSpecified would be changed to the numeric value 5 and valueAsString would be changed to "5mm".
268        /// </summary>
269        /// <param name="unitType">The unitType to switch to (e.g., MM).</param>
270        public void ConvertToSpecifiedUnits(SvgLengthType unitType)
271        {
272            double newValue = cssLength.GetFloatValue((CssPrimitiveType)unitType);
273            cssLength.SetFloatValue((CssPrimitiveType)unitType, newValue);
274        }
275
276        #endregion
277
278        #region Private Methods
279
280        private void GetCssXmlValue()
281        {
282            if (source == SvgLengthSource.Css)
283            {
284                ICssStyleDeclaration csd = this.ownerElement.GetComputedStyle(String.Empty);
285                CssPrimitiveLengthValue cssValue = csd.GetPropertyCssValue(propertyName) as CssPrimitiveLengthValue;
286
287                if (cssValue != null)
288                {
289                    cssLength = new CssAbsPrimitiveLengthValue(cssValue, propertyName, ownerElement);
290                }
291                else
292                {
293                    throw new DomException(DomExceptionType.SyntaxErr, "Not a length value");
294                }
295            }
296            else
297            {
298                string baseVal = ownerElement.GetAttribute(propertyName);
299
300                if (baseVal == null || baseVal.Length == 0)
301                {
302                    baseVal = defaultValue;
303                }
304                baseVal   = SvgNumber.ScientificToDec(baseVal);
305                cssLength = new CssAbsPrimitiveLengthValue(new CssPrimitiveLengthValue(baseVal, false),
306                    propertyName, ownerElement);
307            }
308        }
309
310        #endregion
311    }
312}
Note: See TracBrowser for help on using the repository browser.