Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorRenderingWpf/Wpf/WpfRenderingHelper.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: 9.5 KB
Line 
1using System;
2using System.Xml;
3using System.Linq;
4using System.Text;
5using System.Windows;
6using System.Windows.Media;
7using System.Globalization;
8using System.Collections.Generic;
9
10using SharpVectors.Dom.Css;
11using SharpVectors.Dom.Svg;
12
13namespace SharpVectors.Renderers.Wpf
14{
15    public sealed class WpfRenderingHelper : DependencyObject
16    {
17        #region Private Fields
18
19        private string _currentLang;
20        private WpfDrawingRenderer _renderer;
21        private Dictionary<ISvgElement, WpfRenderingBase> _rendererMap;
22
23        #endregion
24
25        #region Constructors and Destructor
26
27        public WpfRenderingHelper(WpfDrawingRenderer renderer)
28        {
29            _currentLang = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
30            _renderer    = renderer;
31            _rendererMap = new Dictionary<ISvgElement, WpfRenderingBase>();
32        }
33
34        #endregion
35
36        #region Public Methods
37
38        public void Render(ISvgDocument docElement)
39        {
40            SvgSvgElement root = docElement.RootElement as SvgSvgElement;
41
42            if (root != null)
43            {
44                this.Render(root);
45            }
46        }
47
48        public void Render(SvgDocument docElement)
49        {
50            SvgSvgElement root = docElement.RootElement as SvgSvgElement;
51
52            if (root != null)
53            {
54                this.Render(root);
55            }
56        }
57
58        public void Render(ISvgElement svgElement)
59        {
60            if (svgElement == null)
61            {
62                return;
63            }
64
65            string elementName = svgElement.LocalName;
66
67            if (String.Equals(elementName, "use"))
68            {
69                RenderUseElement(svgElement);
70            }
71            else
72            {
73                RenderElement(svgElement);
74            }
75        }
76
77        public void RenderChildren(ISvgElement svgElement)
78        {
79            if (svgElement == null)
80            {
81                return;
82            }
83
84            string elementName = svgElement.LocalName;
85
86            if (String.Equals(elementName, "switch"))
87            {
88                RenderSwitchChildren(svgElement);
89            }
90            else
91            {
92                RenderElementChildren(svgElement);
93            }
94        }
95
96        public void RenderMask(ISvgElement svgElement)
97        {
98            if (svgElement == null)
99            {
100                return;
101            }
102
103            string elementName = svgElement.LocalName;
104
105            if (String.Equals(elementName, "switch"))
106            {
107                RenderSwitchChildren(svgElement);
108            }
109            else
110            {
111                RenderElementChildren(svgElement);
112            }
113        }
114
115        #endregion
116
117        #region Private Methods
118
119        private void RenderElement(ISvgElement svgElement)
120        {
121            bool isNotRenderable = !svgElement.IsRenderable;
122            //bool isNotRenderable = !svgElement.IsRenderable || String.Equals(svgElement.LocalName, "a");
123
124            if (String.Equals(svgElement.LocalName, "a"))
125            {   
126            }
127            if (isNotRenderable)
128            {
129                return;
130            }
131
132            WpfRenderingBase renderingNode = WpfRendering.Create(svgElement);
133            if (renderingNode == null)
134            {
135                return;
136            }
137
138            if (!renderingNode.NeedRender(_renderer))
139            {
140                renderingNode.Dispose();
141                renderingNode = null;
142                return;
143            }
144
145            _rendererMap[svgElement] = renderingNode;
146            renderingNode.BeforeRender(_renderer);
147
148            renderingNode.Render(_renderer);
149
150            if (!renderingNode.IsRecursive && svgElement.HasChildNodes)
151            {
152                RenderChildren(svgElement);
153            }
154
155            renderingNode = _rendererMap[svgElement];
156            renderingNode.AfterRender(_renderer);
157
158            _rendererMap.Remove(svgElement);
159
160            renderingNode.Dispose();
161            renderingNode = null;
162        }
163
164        private void RenderUseElement(ISvgElement svgElement)
165        {
166            SvgUseElement useElement = (SvgUseElement)svgElement;
167
168            SvgDocument document = useElement.OwnerDocument;
169
170            XmlElement refEl = useElement.ReferencedElement;
171            if (refEl == null)
172                return;
173            bool isImported = false;
174            // For the external node, the documents are different, and we may not be
175            // able to insert this node, so we first import it...
176            if (useElement.OwnerDocument != refEl.OwnerDocument)
177            {
178                XmlElement importedNode =
179                    useElement.OwnerDocument.ImportNode(refEl, true) as XmlElement;
180
181                if (importedNode != null)
182                {
183                    SvgElement importedSvgElement = importedNode as SvgElement;
184                    if (importedSvgElement != null)
185                    {
186                        importedSvgElement.Imported       = true;
187                        importedSvgElement.ImportNode     = refEl as SvgElement;
188                        importedSvgElement.ImportDocument = refEl.OwnerDocument as SvgDocument;
189                    }
190
191                    refEl = importedNode;
192                    isImported = true;
193                }
194            }
195            XmlElement refElParent = (XmlElement)refEl.ParentNode;
196            useElement.OwnerDocument.Static = true;
197            useElement.CopyToReferencedElement(refEl);
198            if (!isImported) // if imported, we do not need to remove it...
199            {   
200                refElParent.RemoveChild(refEl);
201            }
202            useElement.AppendChild(refEl);
203
204            // Now, render the use element...
205            this.RenderElement(svgElement);
206
207            useElement.RemoveChild(refEl);
208            useElement.RestoreReferencedElement(refEl);
209            if (!isImported)
210            {
211                refElParent.AppendChild(refEl);
212            }
213            useElement.OwnerDocument.Static = false;
214        }
215
216        private void RenderElementChildren(ISvgElement svgElement)
217        {
218            foreach (XmlNode node in svgElement.ChildNodes)
219            {
220                if (node.NodeType != XmlNodeType.Element)
221                {
222                    continue;
223                }
224
225                SvgElement element = node as SvgElement;
226                if (element != null)
227                {
228                    this.Render(element);
229                }
230            }
231        }
232
233        private void RenderSwitchChildren(ISvgElement svgElement)
234        {
235            // search through all child elements and find one that passes all tests
236            foreach (XmlNode node in svgElement.ChildNodes)
237            {
238                if (node.NodeType != XmlNodeType.Element)
239                {
240                    continue;
241                }
242
243                SvgElement element = node as SvgElement;
244                ISvgTests testsElement = node as ISvgTests;
245                if (element != null && testsElement != null && PassesSwitchAllTest(testsElement))
246                {
247                    this.Render(element);
248
249                    // make sure we only render the first element that passes
250                    break;
251                }
252            }
253        }
254
255        private bool PassesSwitchAllTest(ISvgTests element)
256        {
257            SvgDocument ownerDocument = ((SvgElement)element).OwnerDocument;
258
259            bool requiredFeatures = true;
260            if (element.RequiredFeatures.NumberOfItems > 0)
261            {
262                foreach (string req in element.RequiredFeatures)
263                {
264                    if (!ownerDocument.Supports(req, String.Empty))
265                    {
266                        requiredFeatures = false;
267                        break;
268                    }
269                }
270            }
271            if (!requiredFeatures)
272            {
273                return false;
274            }
275
276            bool requiredExtensions = true;
277            if (element.RequiredExtensions.NumberOfItems > 0)
278            {
279                foreach (string req in element.RequiredExtensions)
280                {
281                    if (!ownerDocument.Supports(req, String.Empty))
282                    {
283                        requiredExtensions = false;
284                        break;
285                    }
286                }
287            }
288            if (!requiredExtensions)
289            {
290                return false;
291            }
292
293            bool systemLanguage = true;
294            if (element.SystemLanguage.NumberOfItems > 0)
295            {
296                systemLanguage = false;
297                // TODO: or if one of the languages indicated by user preferences exactly
298                // equals a prefix of one of the languages given in the value of this
299                // parameter such that the first tag character following the prefix is "-".
300
301                foreach (string req in element.SystemLanguage)
302                {
303                    if (String.Equals(req, _currentLang, StringComparison.OrdinalIgnoreCase))
304                    {
305                        systemLanguage = true;
306                    }
307                }
308            }
309
310            return systemLanguage;
311        }
312
313        #endregion
314    }
315}
Note: See TracBrowser for help on using the repository browser.