SvgDeferredPaintServer.cs 3.55 KB
Newer Older
Eric Domke's avatar
Eric Domke committed
1
2
3
4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Eric Domke's avatar
Eric Domke committed
5
using System.Drawing;
Eric Domke's avatar
Eric Domke committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

namespace Svg
{
    /// <summary>
    /// A wrapper for a paint server which isn't defined currently in the parse process, but
    /// should be defined by the time the image needs to render.
    /// </summary>
    public class SvgDeferredPaintServer : SvgPaintServer
    {
        private bool _serverLoaded = false;
        private SvgPaintServer _concreteServer;

        public SvgDocument Document { get; set; }
        public string DeferredId { get; set; }

        public SvgDeferredPaintServer() { }
        public SvgDeferredPaintServer(SvgDocument document, string id)
        {
            this.Document = document;
            this.DeferredId = id;
        }

28
        public void EnsureServer(SvgElement styleOwner)
Eric Domke's avatar
Eric Domke committed
29
30
31
        {
            if (!_serverLoaded)
            {
32
33
34
35
36
37
                if (this.DeferredId == "currentColor" && styleOwner != null) 
                {
                    var colorElement = (from e in styleOwner.ParentsAndSelf.OfType<SvgElement>()
                                        where e.Color != SvgPaintServer.None && e.Color != SvgColourServer.NotSet && 
                                              e.Color != SvgColourServer.Inherit && e.Color != SvgColourServer.None
                                        select e).FirstOrDefault();
38
                    _concreteServer = (colorElement == null ? SvgColourServer.NotSet : colorElement.Color);
39
40
41
42
43
                }
                else 
                {
                    _concreteServer = this.Document.IdManager.GetElementById(this.DeferredId) as SvgPaintServer;
                }
Eric Domke's avatar
Eric Domke committed
44
45
46
47
                _serverLoaded = true;
            }
        }

Eric Domke's avatar
Eric Domke committed
48
        public override Brush GetBrush(SvgVisualElement styleOwner, ISvgRenderer renderer, float opacity, bool forStroke = false)
Eric Domke's avatar
Eric Domke committed
49
        {
50
            EnsureServer(styleOwner);
Eric Domke's avatar
Eric Domke committed
51
            return _concreteServer.GetBrush(styleOwner, renderer, opacity, forStroke);
Eric Domke's avatar
Eric Domke committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
        }

        public override SvgElement DeepCopy()
        {
            return DeepCopy<SvgDeferredPaintServer>();
        }

        public override SvgElement DeepCopy<T>()
        {
            var newObj = base.DeepCopy<T>() as SvgDeferredPaintServer;
            newObj.Document = this.Document;
            newObj.DeferredId = this.DeferredId;
            return newObj;
        }

        public override bool Equals(object obj)
        {
            var other = obj as SvgDeferredPaintServer;
            if (other == null)
                return false;

            return this.Document == other.Document && this.DeferredId == other.DeferredId;
        }

        public override int GetHashCode()
        {
            if (this.Document == null || this.DeferredId == null) return 0;
            return this.Document.GetHashCode() ^ this.DeferredId.GetHashCode();
        }

        public override string ToString()
        {
Eric Domke's avatar
Eric Domke committed
84
85
86
87
88
89
90
91
            if (this.DeferredId == "currentColor")
            {
                return this.DeferredId;
            }
            else
            {
                return string.Format("url({0})", this.DeferredId);
            }
Eric Domke's avatar
Eric Domke committed
92
93
        }

94
        public static T TryGet<T>(SvgPaintServer server, SvgElement parent) where T : SvgPaintServer
Eric Domke's avatar
Eric Domke committed
95
96
97
98
99
100
101
102
        {
            var deferred = server as SvgDeferredPaintServer;
            if (deferred == null)
            {
                return server as T;
            }
            else
            {
103
                deferred.EnsureServer(parent);
Eric Domke's avatar
Eric Domke committed
104
105
106
107
108
                return deferred._concreteServer as T;
            }
        }
    }
}