Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorConverters/SvgCanvas.cs @ 13046

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

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

File size: 16.0 KB
Line 
1using System;
2using System.IO;
3using System.IO.Compression;
4using System.Xml;
5using System.Reflection;
6using System.Globalization;
7using System.ComponentModel;
8
9using System.Windows;
10using System.Windows.Media;
11using System.Windows.Markup;
12using System.Windows.Controls;
13using System.Windows.Resources;
14
15using SharpVectors.Runtime;
16using SharpVectors.Renderers.Wpf;
17
18namespace SharpVectors.Converters
19{
20    /// <summary>
21    /// This is a <see cref="Canvas"/> control for viewing SVG file in WPF
22    /// applications.
23    /// </summary>
24    /// <remarks>
25    /// It extends the drawing canvas, <see cref="SvgDrawingCanvas"/>, instead of
26    /// generic <see cref="Canvas"/> control, therefore any interactivity support
27    /// implemented in the drawing canvas will be available in the
28    /// <see cref="Canvas"/>.
29    /// </remarks>
30    public class SvgCanvas : SvgDrawingCanvas, IUriContext
31    {
32        #region Private Fields
33
34        private bool _isAutoSized;
35        private bool _autoSize;
36        private bool _textAsGeometry;
37        private bool _includeRuntime;
38        private bool _optimizePath;
39
40        private DrawingGroup _svgDrawing;
41
42        private CultureInfo _culture;
43
44        private Uri _baseUri;
45        private Uri _sourceUri;
46
47        #endregion
48
49        #region Constructors and Destructor
50
51        /// <summary>
52        /// Initializes a new instance of the <see cref="SvgCanvas"/> class.
53        /// </summary>
54        public SvgCanvas()
55        {
56            _textAsGeometry = false;
57            _includeRuntime = true;
58            _optimizePath   = true;
59        }
60
61        #endregion
62
63        #region Public Properties
64
65        /// <summary>
66        /// Gets or sets the path to the SVG file to load into this
67        /// <see cref="Canvas"/>.
68        /// </summary>
69        /// <value>
70        /// A <see cref="System.Uri"/> specifying the path to the SVG source file.
71        /// The file can be located on a computer, network or assembly resources.
72        /// Settings this to <see langword="null"/> will close any opened diagram.
73        /// </value>
74        public Uri Source
75        {
76            get
77            {
78                return _sourceUri;
79            }
80            set
81            {
82                _sourceUri = value;
83
84                if (_sourceUri == null)
85                {
86                    this.OnUnloadDiagram();
87                }
88                else
89                {
90                    this.OnSettingsChanged();
91                }
92            }
93        }
94
95        /// <summary>
96        /// Gets or sets a value indicating whether to automatically resize this
97        /// <see cref="Canvas"/> based on the size of the loaded drawing.
98        /// </summary>
99        /// <value>
100        /// This is <see langword="true"/> if this <see cref="Canvas"/> is
101        /// automatically resized based on the size of the loaded drawing;
102        /// otherwise, it is <see langword="false"/>. The default is
103        /// <see langword="false"/>, and the user-defined size or the parent assigned
104        /// layout size is used.
105        /// </value>
106        public bool AutoSize
107        {
108            get
109            {
110                return _autoSize;
111            }
112            set
113            {
114                _autoSize = value;
115
116                this.OnAutoSizeChanged();
117            }
118        }
119
120        /// <summary>
121        /// Gets or sets a value indicating whether the path geometry is
122        /// optimized using the <see cref="StreamGeometry"/>.
123        /// </summary>
124        /// <value>
125        /// This is <see langword="true"/> if the path geometry is optimized
126        /// using the <see cref="StreamGeometry"/>; otherwise, it is
127        /// <see langword="false"/>. The default is <see langword="true"/>.
128        /// </value>
129        public bool OptimizePath
130        {
131            get
132            {
133                return _optimizePath;
134            }
135            set
136            {
137                _optimizePath = value;
138
139                this.OnSettingsChanged();
140            }
141        }
142
143        /// <summary>
144        /// Gets or sets a value indicating whether the texts are rendered as
145        /// path geometry.
146        /// </summary>
147        /// <value>
148        /// This is <see langword="true"/> if texts are rendered as path
149        /// geometries; otherwise, this is <see langword="false"/>. The default
150        /// is <see langword="false"/>.
151        /// </value>
152        public bool TextAsGeometry
153        {
154            get
155            {
156                return _textAsGeometry;
157            }
158            set
159            {
160                _textAsGeometry = value;
161
162                this.OnSettingsChanged();
163            }
164        }
165
166        /// <summary>
167        /// Gets or sets a value indicating whether the <c>SharpVectors.Runtime.dll</c>
168        /// classes are used in the generated output.
169        /// </summary>
170        /// <value>
171        /// This is <see langword="true"/> if the <c>SharpVectors.Runtime.dll</c>
172        /// classes and types are used in the generated output; otherwise, it is
173        /// <see langword="false"/>. The default is <see langword="true"/>.
174        /// </value>
175        /// <remarks>
176        /// The use of the <c>SharpVectors.Runtime.dll</c> prevents the hard-coded
177        /// font path generated by the <see cref="FormattedText"/> class, support
178        /// for embedded images etc.
179        /// </remarks>
180        public bool IncludeRuntime
181        {
182            get
183            {
184                return _includeRuntime;
185            }
186            set
187            {
188                _includeRuntime = value;
189
190                this.OnSettingsChanged();
191            }
192        }
193
194        /// <summary>
195        /// Gets or sets the main culture information used for rendering texts.
196        /// </summary>
197        /// <value>
198        /// An instance of the <see cref="CultureInfo"/> specifying the main
199        /// culture information for texts. The default is the English culture.
200        /// </value>
201        /// <remarks>
202        /// <para>
203        /// This is the culture information passed to the <see cref="FormattedText"/>
204        /// class instance for the text rendering.
205        /// </para>
206        /// <para>
207        /// The library does not currently provide any means of splitting texts
208        /// into its multi-language parts.
209        /// </para>
210        /// </remarks>
211        public CultureInfo CultureInfo
212        {
213            get
214            {
215                return _culture;
216            }
217            set
218            {
219                if (value != null)
220                {
221                    _culture = value;
222
223                    this.OnSettingsChanged();
224                }
225            }
226        }
227
228        #endregion
229
230        #region Public Methods
231
232        #endregion
233
234        #region Protected Methods
235
236        /// <summary>
237        /// Raises the Initialized event. This method is invoked whenever IsInitialized is set to true.
238        /// </summary>
239        /// <param name="e">Event data for the event.</param>
240        protected override void OnInitialized(EventArgs e)
241        {
242            base.OnInitialized(e);
243
244            if (_sourceUri != null)
245            {
246                if (_svgDrawing == null)
247                {
248                    DrawingGroup drawing = this.CreateDrawing();
249                    if (drawing != null)
250                    {
251                        this.OnLoadDrawing(drawing);
252                    }
253                }
254            }
255        }
256
257        /// <summary>
258        /// This handles changes in the rendering settings of this control.
259        /// </summary>
260        protected virtual void OnSettingsChanged()
261        {   
262            if (!this.IsInitialized || _sourceUri == null)
263            {
264                return;
265            }
266
267            DrawingGroup drawing = this.CreateDrawing();
268            if (drawing != null)
269            {
270                this.OnLoadDrawing(drawing);
271            }
272        }
273
274        /// <summary>
275        /// This handles changes in the automatic resizing property of this control.
276        /// </summary>
277        protected virtual void OnAutoSizeChanged()
278        {   
279            if (_autoSize)
280            {
281                if (this.IsInitialized && _svgDrawing != null)
282                {
283                    Rect rectDrawing = _svgDrawing.Bounds;
284                    if (!rectDrawing.IsEmpty)
285                    {
286                        this.Width   = rectDrawing.Width;
287                        this.Height  = rectDrawing.Height;
288
289                        _isAutoSized = true;
290                    }
291                }
292            }
293            else
294            {
295                if (_isAutoSized)
296                {
297                    this.Width  = Double.NaN;
298                    this.Height = Double.NaN;
299                }
300            }
301        }
302
303        /// <summary>
304        /// Performs the conversion of a valid SVG source file to the
305        /// <see cref="DrawingGroup"/>.
306        /// </summary>
307        /// <returns>
308        /// This returns <see cref="DrawingGroup"/> if successful; otherwise, it
309        /// returns <see langword="null"/>.
310        /// </returns>
311        protected virtual DrawingGroup CreateDrawing()
312        {
313            Uri svgSource = this.GetAbsoluteUri();
314
315            DrawingGroup drawing = null;
316
317            if (svgSource == null)
318            {
319                return drawing;
320            }
321
322            try
323            {
324                string scheme = svgSource.Scheme;
325                if (String.IsNullOrEmpty(scheme))
326                {
327                    return null;
328                }
329
330                WpfDrawingSettings settings = new WpfDrawingSettings();
331                settings.IncludeRuntime = _includeRuntime;
332                settings.TextAsGeometry = _textAsGeometry;
333                settings.OptimizePath   = _optimizePath;
334                if (_culture != null)
335                {
336                    settings.CultureInfo = _culture;
337                }
338
339                switch (scheme)
340                {
341                    case "file":
342                    //case "ftp":
343                    //case "https":
344                    case "http":
345                        using (FileSvgReader reader =
346                            new FileSvgReader(settings))
347                        {
348                            drawing = reader.Read(svgSource);
349                        }
350                        break;
351                    case "pack":
352                        StreamResourceInfo svgStreamInfo = null;
353                        if (svgSource.ToString().IndexOf("siteoforigin",
354                            StringComparison.OrdinalIgnoreCase) >= 0)
355                        {
356                            svgStreamInfo = Application.GetRemoteStream(svgSource);
357                        }
358                        else
359                        {
360                            svgStreamInfo = Application.GetResourceStream(svgSource);
361                        }
362
363                        Stream svgStream = (svgStreamInfo != null) ?
364                            svgStreamInfo.Stream : null;
365
366                        if (svgStream != null)
367                        {
368                            string fileExt = Path.GetExtension(svgSource.ToString());
369                            bool isCompressed = !String.IsNullOrEmpty(fileExt) &&
370                                String.Equals(fileExt, ".svgz",
371                                StringComparison.OrdinalIgnoreCase);
372
373                            if (isCompressed)
374                            {
375                                using (svgStream)
376                                {
377                                    using (GZipStream zipStream =
378                                        new GZipStream(svgStream, CompressionMode.Decompress))
379                                    {
380                                        using (FileSvgReader reader =
381                                            new FileSvgReader(settings))
382                                        {
383                                            drawing = reader.Read(zipStream);
384                                        }
385                                    }
386                                }
387                            }
388                            else
389                            {
390                                using (svgStream)
391                                {
392                                    using (FileSvgReader reader =
393                                        new FileSvgReader(settings))
394                                    {
395                                        drawing = reader.Read(svgStream);
396                                    }
397                                }
398                            }
399                        }
400                        break;
401                }
402
403            }
404            catch
405            {
406                if (DesignerProperties.GetIsInDesignMode(new DependencyObject()) ||
407                    LicenseManager.UsageMode == LicenseUsageMode.Designtime)
408                {
409                    return drawing;
410                }
411
412                throw;
413            }
414
415            return drawing;
416        }
417
418        #endregion
419
420        #region Private Methods
421
422        private void OnLoadDrawing(DrawingGroup drawing)
423        {   
424            if (drawing == null)
425            {
426                return;
427            }
428
429            this.OnUnloadDiagram();
430
431            this.RenderDiagrams(drawing);
432
433            _svgDrawing = drawing;
434
435            this.OnAutoSizeChanged();
436        }
437
438        private void OnUnloadDiagram()
439        {
440            this.UnloadDiagrams();
441
442            if (_isAutoSized)
443            {
444                this.Width  = Double.NaN;
445                this.Height = Double.NaN;
446            }
447        }
448
449        private Uri GetAbsoluteUri()
450        {
451            if (_sourceUri == null)
452            {
453                return null;
454            }
455            Uri svgSource = _sourceUri;
456
457            if (svgSource.IsAbsoluteUri)
458            {
459                return svgSource;
460            }
461            else
462            {
463                // Try getting a local file in the same directory....
464                string svgPath = svgSource.ToString();
465                if (svgPath[0] == '\\' || svgPath[0] == '/')
466                {
467                    svgPath = svgPath.Substring(1);
468                }
469                svgPath = svgPath.Replace('/', '\\');
470
471                Assembly assembly = Assembly.GetExecutingAssembly();
472                string localFile = Path.Combine(Path.GetDirectoryName(
473                    assembly.Location), svgPath);
474
475                if (File.Exists(localFile))
476                {
477                    return new Uri(localFile);
478                }
479
480                // Try getting it as resource file...
481                if (_baseUri != null)
482                {
483                    return new Uri(_baseUri, svgSource);
484                }
485                else
486                {
487                    string asmName = assembly.GetName().Name;
488                    string uriString = String.Format(
489                        "pack://application:,,,/{0};component/{1}",
490                        asmName, svgPath);
491
492                    return new Uri(uriString);
493                }
494            }
495        }
496
497        #endregion
498
499        #region IUriContext Members
500
501        /// <summary>
502        /// Gets or sets the base URI of the current application context.
503        /// </summary>
504        /// <value>
505        /// The base URI of the application context.
506        /// </value>
507        public Uri BaseUri
508        {
509            get
510            {
511                return _baseUri;
512            }
513            set
514            {
515                _baseUri = value;
516            }
517        }
518
519        #endregion
520    }
521}
Note: See TracBrowser for help on using the repository browser.