Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorModel/DocumentStructure/SvgTransformableElement.cs @ 13825

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

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

File size: 7.7 KB
Line 
1using System;
2using System.Xml;
3
4using SharpVectors.Dom.Css;
5
6namespace SharpVectors.Dom.Svg
7{
8    public class SvgTransformableElement : SvgStyleableElement, ISvgTransformable
9    {
10        #region Constructors and Destructor
11
12        public SvgTransformableElement(string prefix, string localname, string ns, SvgDocument doc)
13            : base(prefix, localname, ns, doc)
14        {
15        }
16
17        #endregion
18
19        #region ISvgTransformable Members
20
21        private ISvgAnimatedTransformList transform;
22        public ISvgAnimatedTransformList Transform
23        {
24            get
25            {
26                if (transform == null)
27                {
28                    transform = new SvgAnimatedTransformList(GetAttribute("transform"));
29                }
30                return transform;
31            }
32        }
33
34        public ISvgElement NearestViewportElement
35        {
36            get
37            {
38                XmlNode parent = this.ParentNode;
39                while (parent != null)
40                {
41                    if (parent is SvgSvgElement)
42                    {
43                        return (ISvgElement)parent;
44                    }
45                    parent = parent.ParentNode;
46                }
47                return null;
48            }
49        }
50
51        public ISvgElement FarthestViewportElement
52        {
53            get
54            {
55                ISvgDocument doc = OwnerDocument;
56                if (doc.RootElement == this) return null;
57                else return doc.RootElement;
58            }
59        }
60
61        public ISvgRect GetBBox()
62        {
63            ISvgWindow svgWnd = this.OwnerDocument.Window;
64            if (svgWnd == null || svgWnd.Renderer == null)
65            {
66                return null;
67            }
68
69            return svgWnd.Renderer.GetRenderedBounds(this, 0);
70        }
71
72        /// <summary>
73        /// For each given element, the accumulation of all transformations that have been defined
74        /// on the given element and all of its ancestors up to and including the element that
75        /// established the current viewport (usually, the 'svg' element which is the most
76        /// immediate ancestor to the given element) is called the current transformation matrix
77        /// or CTM.
78        /// </summary>
79        /// <returns>A matrix representing the mapping of current user coordinates to viewport
80        /// coordinates.</returns>
81        public ISvgMatrix GetCTM()
82        {
83            ISvgMatrix matrix = new SvgMatrix();
84            ISvgTransformList svgTList;
85            ISvgMatrix vCTM;
86            if (this is SvgSvgElement)
87            {
88                vCTM = (this as SvgSvgElement).ViewBoxTransform;
89                matrix = vCTM;
90            }
91            else if (this.Transform != null)
92            {
93                svgTList = this.Transform.AnimVal;
94                matrix = svgTList.Consolidate().Matrix;
95            }
96
97            ISvgElement nVE = this.NearestViewportElement;
98            if (nVE != null)
99            {
100                SvgTransformableElement par = ParentNode as SvgTransformableElement;
101                while (par != null && par != nVE)
102                {
103                    svgTList = par.Transform.AnimVal;
104                    matrix = svgTList.Consolidate().Matrix.Multiply(matrix);
105                    par = par.ParentNode as SvgTransformableElement;
106                }
107
108                if (par == nVE && nVE is SvgSvgElement)
109                {
110                    vCTM = (nVE as SvgSvgElement).ViewBoxTransform;
111                    matrix = vCTM.Multiply(matrix);
112                }
113            }
114            return matrix;
115        }
116
117        public ISvgMatrix GetScreenCTM()
118        {
119            ISvgMatrix matrix = new SvgMatrix();
120            ISvgTransformList svgTList;
121            ISvgMatrix vCTM;
122            if (this is SvgSvgElement)
123            {
124                vCTM = (this as SvgSvgElement).ViewBoxTransform;
125                matrix = vCTM;
126            }
127            else if (this.Transform != null)
128            {
129                svgTList = this.Transform.AnimVal;
130                matrix = svgTList.Consolidate().Matrix;
131            }
132
133            SvgTransformableElement par = ParentNode as SvgTransformableElement;
134            while (par != null)
135            {
136                // TODO: other elements can establish viewports, not just <svg>!
137                if (par is SvgSvgElement)
138                {
139                    vCTM = (par as SvgSvgElement).ViewBoxTransform;
140                    matrix = vCTM.Multiply(matrix);
141                }
142                else
143                {
144                    svgTList = par.Transform.AnimVal;
145                    matrix = svgTList.Consolidate().Matrix.Multiply(matrix);
146                }
147                par = par.ParentNode as SvgTransformableElement;
148            }
149
150            // Now scale out the pixels
151            //ISvgSvgElement root = OwnerDocument.RootElement;
152            //float innerWidth = this.OwnerDocument.Window.InnerWidth;
153            //float innerHeight = this.OwnerDocument.Window.InnerHeight;
154            //if (innerWidth != 0 && innerHeight != 0)
155            //{
156            //  float screenRatW = (float)root.Width.AnimVal.Value / innerWidth;
157            //  float screenRatH = (float)root.Height.AnimVal.Value / innerHeight;
158            //  matrix.ScaleNonUniform(screenRatW, screenRatH);
159            //}
160
161            return matrix;
162        }
163
164        public ISvgMatrix GetTransformToElement(ISvgElement element)
165        {
166            ISvgLocatable loc = element as ISvgLocatable;
167            ISvgMatrix ctm = loc.GetCTM();
168            ISvgMatrix vctm;
169            XmlNode node = element.ParentNode;
170            while (node != null && node != OwnerDocument)
171            {
172                if (node.Name == "svg")
173                {
174                    vctm = (node as SvgSvgElement).ViewBoxTransform;
175                    ctm = vctm.Multiply(ctm);
176                }
177                else
178                {
179                    loc = node as ISvgLocatable;
180                    ctm = loc.GetCTM().Multiply(ctm);
181                }
182
183                node = node.ParentNode;
184            }
185
186            return ctm;
187        }
188
189        #endregion
190
191        #region Public Methods
192
193        #region Update handling
194
195        public override void CssInvalidate()
196        {
197            base.CssInvalidate();
198
199            //string strokeWidth = this.GetPropertyValue("stroke-width");
200            //if (strokeWidth.Length == 0) strokeWidth = "1px";
201            //SvgLength strokeWidthLength = new SvgLength(this, "stroke-width", SvgLengthDirection.Viewport, strokeWidth);
202
203            //if (renderingNode != null)
204            //{
205            //    // Quick-cache
206            //    renderingNode.ScreenRegion = GetBRect((float)strokeWidthLength.Value);
207            //    OwnerDocument.Window.Renderer.InvalidateRect(renderingNode.ScreenRegion);
208            //}
209            //else
210            //{
211            //    OwnerDocument.Window.Renderer.InvalidateRect(GetBRect((float)strokeWidthLength.Value));
212            //}
213        }
214
215        public override void HandleAttributeChange(XmlAttribute attribute)
216        {
217            if (attribute.NamespaceURI.Length == 0)
218            {
219                switch (attribute.LocalName)
220                {
221                    case "transform":
222                        transform = null;
223                        //renderingNode = null;
224                        return;
225                }
226
227                base.HandleAttributeChange(attribute);
228            }
229        }
230
231        #endregion
232
233        #endregion
234    }
235}
Note: See TracBrowser for help on using the repository browser.