Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorConverters/SvgImageExtension.cs @ 13783

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

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

File size: 13.9 KB
Line 
1using System;
2using System.IO;
3using System.IO.Compression;
4using System.Resources;
5using System.Reflection;
6using System.Globalization;
7using System.ComponentModel;
8
9using System.Windows;
10using System.Windows.Media;
11using System.Windows.Markup;
12using System.Windows.Resources;
13
14using SharpVectors.Renderers.Wpf;
15
16namespace SharpVectors.Converters
17{
18    /// <summary>
19    /// This implements a markup extension that enables the creation
20    /// of <see cref="DrawingImage"/> from SVG files.
21    /// </summary>
22    /// <remarks>
23    /// The SVG source file can be:
24    /// <list type="bullet">
25    /// <item>
26    /// <description>From the web</description>
27    /// </item>
28    /// <item>
29    /// <description>From the local computer (relative or absolute paths)</description>
30    /// </item>
31    /// <item>
32    /// <description>From the resources.</description>
33    /// </item>
34    /// </list>
35    /// <para>
36    /// The rendering settings are provided as properties for customizations.
37    /// </para>
38    /// </remarks>
39    [MarkupExtensionReturnType(typeof(DrawingImage))]
40    public sealed class SvgImageExtension : MarkupExtension
41    {
42        #region Private Fields
43
44        private bool _textAsGeometry;
45        private bool _includeRuntime;
46        private bool _optimizePath;
47
48        private string _svgPath;
49
50        private CultureInfo _culture;
51
52        #endregion
53
54        #region Constructors and Destructor
55
56        /// <overloads>
57        /// Initializes a new instance of the <see cref="SvgImageExtension"/> class.
58        /// </overloads>
59        /// <summary>
60        /// Initializes a new instance of the <see cref="SvgImageExtension"/>
61        /// class with the default parameters.
62        /// </summary>
63        public SvgImageExtension()
64        {
65            _textAsGeometry = false;
66            _includeRuntime = true;
67            _optimizePath   = true;
68        }
69
70        /// <summary>
71        /// Initializes a new instance of the <see cref="SvgImageExtension"/>
72        /// class with the specified SVG file path.
73        /// </summary>
74        /// <param name="svgSource"></param>
75        public SvgImageExtension(string svgPath)
76            : this()
77        {
78            _svgPath = svgPath;
79        }
80
81        #endregion
82
83        #region Public Properties
84
85        /// <summary>
86        /// Gets or sets the SVG source file.
87        /// </summary>
88        /// <value>
89        /// A string specifying the path of the SVG source file.
90        /// The default is <see langword="null"/>.
91        /// </value>
92        public string Source
93        {
94            get
95            {
96                return _svgPath;
97            }
98            set
99            {
100                _svgPath = value;
101            }
102        }
103
104        /// <summary>
105        /// Gets or sets a value indicating whether the path geometry is
106        /// optimized using the <see cref="StreamGeometry"/>.
107        /// </summary>
108        /// <value>
109        /// This is <see langword="true"/> if the path geometry is optimized
110        /// using the <see cref="StreamGeometry"/>; otherwise, it is
111        /// <see langword="false"/>. The default is <see langword="true"/>.
112        /// </value>
113        public bool OptimizePath
114        {
115            get
116            {
117                return _optimizePath;
118            }
119            set
120            {
121                _optimizePath = value;
122            }
123        }
124
125        /// <summary>
126        /// Gets or sets a value indicating whether the texts are rendered as
127        /// path geometry.
128        /// </summary>
129        /// <value>
130        /// This is <see langword="true"/> if texts are rendered as path
131        /// geometries; otherwise, this is <see langword="false"/>. The default
132        /// is <see langword="false"/>.
133        /// </value>
134        public bool TextAsGeometry
135        {
136            get
137            {
138                return _textAsGeometry;
139            }
140            set
141            {
142                _textAsGeometry = value;
143            }
144        }
145
146        /// <summary>
147        /// Gets or sets a value indicating whether the <c>SharpVectors.Runtime.dll</c>
148        /// classes are used in the generated output.
149        /// </summary>
150        /// <value>
151        /// This is <see langword="true"/> if the <c>SharpVectors.Runtime.dll</c>
152        /// classes and types are used in the generated output; otherwise, it is
153        /// <see langword="false"/>. The default is <see langword="true"/>.
154        /// </value>
155        /// <remarks>
156        /// The use of the <c>SharpVectors.Runtime.dll</c> prevents the hard-coded
157        /// font path generated by the <see cref="FormattedText"/> class, support
158        /// for embedded images etc.
159        /// </remarks>
160        public bool IncludeRuntime
161        {
162            get
163            {
164                return _includeRuntime;
165            }
166            set
167            {
168                _includeRuntime = value;
169            }
170        }
171
172        /// <summary>
173        /// Gets or sets the main culture information used for rendering texts.
174        /// </summary>
175        /// <value>
176        /// An instance of the <see cref="CultureInfo"/> specifying the main
177        /// culture information for texts. The default is the English culture.
178        /// </value>
179        /// <remarks>
180        /// <para>
181        /// This is the culture information passed to the <see cref="FormattedText"/>
182        /// class instance for the text rendering.
183        /// </para>
184        /// <para>
185        /// The library does not currently provide any means of splitting texts
186        /// into its multi-language parts.
187        /// </para>
188        /// </remarks>
189        public CultureInfo CultureInfo
190        {
191            get
192            {
193                return _culture;
194            }
195            set
196            {
197                if (value != null)
198                {
199                    _culture = value;
200                }
201            }
202        }
203
204        #endregion
205
206        #region Public Methods
207
208        /// <summary>
209        /// Performs the conversion of a valid SVG source file to the
210        /// <see cref="DrawingImage"/> that is set as the value of the target
211        /// property for this markup extension.
212        /// </summary>
213        /// <param name="serviceProvider">
214        /// Object that can provide services for the markup extension.
215        /// </param>
216        /// <returns>
217        /// This returns <see cref="DrawingImage"/> if successful; otherwise, it
218        /// returns <see langword="null"/>.
219        /// </returns>
220        public override object ProvideValue(IServiceProvider serviceProvider)
221        {
222            Uri svgSource = this.GetUri(serviceProvider);
223
224            if (svgSource == null)
225            {
226                return null;
227            }
228
229            try
230            {
231                string scheme = svgSource.Scheme;
232                if (String.IsNullOrEmpty(scheme))
233                {
234                    return null;
235                }
236
237                WpfDrawingSettings settings = new WpfDrawingSettings();
238                settings.IncludeRuntime = _includeRuntime;
239                settings.TextAsGeometry = _textAsGeometry;
240                settings.OptimizePath   = _optimizePath;
241                if (_culture != null)
242                {
243                    settings.CultureInfo = _culture;
244                }
245
246                switch (scheme)
247                {
248                    case "file":
249                    //case "ftp":
250                    //case "https":
251                    case "http":
252                        using (FileSvgReader reader =
253                            new FileSvgReader(settings))
254                        {
255                            DrawingGroup drawGroup = reader.Read(svgSource);
256
257                            if (drawGroup != null)
258                            {
259                                return new DrawingImage(drawGroup);
260                            }
261                        }
262                        break;
263                    case "pack":
264                        StreamResourceInfo svgStreamInfo = null;
265                        if (svgSource.ToString().IndexOf("siteoforigin",
266                            StringComparison.OrdinalIgnoreCase) >= 0)
267                        {
268                            svgStreamInfo = Application.GetRemoteStream(svgSource);
269                        }
270                        else
271                        {
272                            svgStreamInfo = Application.GetResourceStream(svgSource);
273                        }
274
275                        Stream svgStream = (svgStreamInfo != null) ?
276                            svgStreamInfo.Stream : null;
277
278                        if (svgStream != null)
279                        {
280                            string fileExt = Path.GetExtension(svgSource.ToString());
281                            bool isCompressed = !String.IsNullOrEmpty(fileExt) &&
282                                String.Equals(fileExt, ".svgz",
283                                StringComparison.OrdinalIgnoreCase);
284
285                            if (isCompressed)
286                            {
287                                using (svgStream)
288                                {
289                                    using (GZipStream zipStream =
290                                        new GZipStream(svgStream, CompressionMode.Decompress))
291                                    {
292                                        using (FileSvgReader reader =
293                                            new FileSvgReader(settings))
294                                        {
295                                            DrawingGroup drawGroup = reader.Read(
296                                                zipStream);
297
298                                            if (drawGroup != null)
299                                            {
300                                                return new DrawingImage(drawGroup);
301                                            }
302                                        }
303                                    }
304                                }
305                            }
306                            else
307                            {
308                                using (svgStreamInfo.Stream)
309                                {
310                                    using (FileSvgReader reader =
311                                        new FileSvgReader(settings))
312                                    {
313                                        DrawingGroup drawGroup = reader.Read(
314                                            svgStreamInfo.Stream);
315
316                                        if (drawGroup != null)
317                                        {
318                                            return new DrawingImage(drawGroup);
319                                        }
320                                    }
321                                }
322                            }
323                        }
324                        break;
325                }
326
327            }
328            catch
329            {
330                if (DesignerProperties.GetIsInDesignMode(new DependencyObject()) ||
331                    LicenseManager.UsageMode == LicenseUsageMode.Designtime)
332                {
333                    return null;
334                }
335
336                throw;
337            }
338
339            return null;
340        }
341
342        #endregion
343
344        #region Private Methods
345
346        /// <summary>
347        /// Converts the SVG source file to <see cref="Uri"/>
348        /// </summary>
349        /// <param name="serviceProvider">
350        /// Object that can provide services for the markup extension.
351        /// </param>
352        /// <returns>
353        /// Returns the valid <see cref="Uri"/> of the SVG source path if
354        /// successful; otherwise, it returns <see langword="null"/>.
355        /// </returns>
356        private Uri GetUri(IServiceProvider serviceProvider)
357        {
358            if (String.IsNullOrEmpty(_svgPath))
359            {
360                return null;
361            }
362
363            Uri svgSource;
364            if (Uri.TryCreate(_svgPath, UriKind.RelativeOrAbsolute, out svgSource))
365            {
366                if (svgSource.IsAbsoluteUri)
367                {
368                    return svgSource;
369                }
370                else
371                {
372                    // Try getting a local file in the same directory....
373                    string svgPath = _svgPath;
374                    if (_svgPath[0] == '\\' || _svgPath[0] == '/')
375                    {
376                        svgPath = _svgPath.Substring(1);
377                    }
378                    svgPath = svgPath.Replace('/', '\\');
379
380                    Assembly assembly = Assembly.GetExecutingAssembly();
381                    string localFile  = Path.Combine(Path.GetDirectoryName(
382                        assembly.Location), svgPath);
383
384                    if (File.Exists(localFile))
385                    {
386                        return new Uri(localFile);
387                    }
388
389                    // Try getting it as resource file...
390                    IUriContext uriContext = serviceProvider.GetService(
391                        typeof(IUriContext)) as IUriContext;
392                    if (uriContext != null && uriContext.BaseUri != null)
393                    {
394                        return new Uri(uriContext.BaseUri, svgSource);
395                    }
396                    else
397                    {   
398                        string asmName   = assembly.GetName().Name;
399                        string uriString = String.Format(
400                            "pack://application:,,,/{0};component/{1}",
401                            asmName, _svgPath);
402
403                        return new Uri(uriString);
404                    }
405                }
406            }
407
408            return null;
409        }
410
411        #endregion
412    }
413}
Note: See TracBrowser for help on using the repository browser.