SvgPatternServer.cs 7.26 KB
Newer Older
davescriven's avatar
davescriven committed
1
2
3
4
5
6
7
8
9
10
11
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.ComponentModel;

using Svg.Transforms;

namespace Svg
{
12
13
14
15
    /// <summary>
    /// A pattern is used to fill or stroke an object using a pre-defined graphic object which can be replicated ("tiled") at fixed intervals in x and y to cover the areas to be painted.
    /// </summary>
    [SvgElement("pattern")]
16
    public sealed class SvgPatternServer : SvgPaintServer, ISvgViewPort, ISvgSupportsCoordinateUnits
davescriven's avatar
davescriven committed
17
18
19
20
21
22
    {
        private SvgUnit _width;
        private SvgUnit _height;
        private SvgUnit _x;
        private SvgUnit _y;
        private SvgViewBox _viewBox;
Eric Domke's avatar
Eric Domke committed
23
24
        private SvgCoordinateUnits _patternUnits = SvgCoordinateUnits.ObjectBoundingBox;
        private SvgCoordinateUnits _patternContentUnits = SvgCoordinateUnits.UserSpaceOnUse;
davescriven's avatar
davescriven committed
25

26
27
28
29
30
31
32
33
		[SvgAttribute("overflow")]
		public SvgOverflow Overflow
		{
			get { return this.Attributes.GetAttribute<SvgOverflow>("overflow"); }
			set { this.Attributes["overflow"] = value; }
		}


34
35
36
37
        /// <summary>
        /// Specifies a supplemental transformation which is applied on top of any 
        /// transformations necessary to create a new pattern coordinate system.
        /// </summary>
davescriven's avatar
davescriven committed
38
39
40
41
42
43
        [SvgAttribute("viewBox")]
        public SvgViewBox ViewBox
        {
            get { return this._viewBox; }
            set { this._viewBox = value; }
        }
Tebjan Halm's avatar
Tebjan Halm committed
44
45
46
47
48
49
50
51
52
53
54
        
        /// <summary>
        /// Gets or sets the aspect of the viewport.
        /// </summary>
        /// <value></value>
        [SvgAttribute("preserveAspectRatio")]
        public SvgAspectRatio AspectRatio 
		{
			get;
			set;
		}
davescriven's avatar
davescriven committed
55

56
57
58
        /// <summary>
        /// Gets or sets the width of the pattern.
        /// </summary>
davescriven's avatar
davescriven committed
59
60
61
62
63
64
65
        [SvgAttribute("width")]
        public SvgUnit Width
        {
            get { return this._width; }
            set { this._width = value; }
        }

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
        /// <summary>
        /// Gets or sets the width of the pattern.
        /// </summary>
        [SvgAttribute("patternUnits")]
        public SvgCoordinateUnits PatternUnits
        {
            get { return this._patternUnits; }
            set { this._patternUnits = value; }
        }

        /// <summary>
        /// Gets or sets the width of the pattern.
        /// </summary>
        [SvgAttribute("patternUnits")]
        public SvgCoordinateUnits PatternContentUnits
        {
            get { return this._patternContentUnits; }
            set { this._patternContentUnits = value; }
        }

86
87
88
        /// <summary>
        /// Gets or sets the height of the pattern.
        /// </summary>
davescriven's avatar
davescriven committed
89
90
91
92
93
94
95
        [SvgAttribute("height")]
        public SvgUnit Height
        {
            get { return this._height; }
            set { this._height = value; }
        }

96
97
98
        /// <summary>
        /// Gets or sets the X-axis location of the pattern.
        /// </summary>
davescriven's avatar
davescriven committed
99
100
101
102
103
104
105
        [SvgAttribute("x")]
        public SvgUnit X
        {
            get { return this._x; }
            set { this._x = value; }
        }

106
107
108
        /// <summary>
        /// Gets or sets the Y-axis location of the pattern.
        /// </summary>
davescriven's avatar
davescriven committed
109
110
111
112
113
114
115
        [SvgAttribute("y")]
        public SvgUnit Y
        {
            get { return this._y; }
            set { this._y = value; }
        }

116
117
118
        /// <summary>
        /// Initializes a new instance of the <see cref="SvgPatternServer"/> class.
        /// </summary>
davescriven's avatar
davescriven committed
119
120
121
122
123
124
125
126
        public SvgPatternServer()
        {
            this._x = new SvgUnit(0.0f);
            this._y = new SvgUnit(0.0f);
            this._width = new SvgUnit(0.0f);
            this._height = new SvgUnit(0.0f);
        }

127
128
129
        /// <summary>
        /// Gets a <see cref="Brush"/> representing the current paint server.
        /// </summary>
130
        /// <param name="renderingElement">The owner <see cref="SvgVisualElement"/>.</param>
131
        /// <param name="opacity">The opacity of the brush.</param>
Eric Domke's avatar
Eric Domke committed
132
        public override Brush GetBrush(SvgVisualElement renderingElement, ISvgRenderer renderer, float opacity)
davescriven's avatar
davescriven committed
133
134
135
136
137
138
139
140
141
        {
            // If there aren't any children, return null
            if (this.Children.Count == 0)
                return null;

            // Can't render if there are no dimensions
            if (this._width.Value == 0.0f || this._height.Value == 0.0f)
                return null;

142
            try
davescriven's avatar
davescriven committed
143
            {
Eric Domke's avatar
Eric Domke committed
144
                if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.SetBoundable(renderingElement);
145
146
147

                float width = this._width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
                float height = this._height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
davescriven's avatar
davescriven committed
148

149
                Matrix patternMatrix = new Matrix();
davescriven's avatar
davescriven committed
150
151
152
                // Apply a translate if needed
                if (this._x.Value > 0.0f || this._y.Value > 0.0f)
                {
153
154
155
                    float x = this._x.ToDeviceValue(renderer, UnitRenderingType.HorizontalOffset, this);
                    float y = this._y.ToDeviceValue(renderer, UnitRenderingType.VerticalOffset, this);

Eric Domke's avatar
Eric Domke committed
156
                    patternMatrix.Translate(x, y);
davescriven's avatar
davescriven committed
157
158
159
160
                }

                if (this.ViewBox.Height > 0 || this.ViewBox.Width > 0)
                {
161
162
                    patternMatrix.Scale(this.Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) / this.ViewBox.Width,
                                        this.Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this) / this.ViewBox.Height);
davescriven's avatar
davescriven committed
163
164
                }

165
                Bitmap image = new Bitmap((int)width, (int)height);
Eric Domke's avatar
Eric Domke committed
166
                using (var iRenderer = SvgRenderer.FromImage(image))
davescriven's avatar
davescriven committed
167
                {
Eric Domke's avatar
Eric Domke committed
168
                    iRenderer.SetBoundable((_patternContentUnits == SvgCoordinateUnits.ObjectBoundingBox) ? new GenericBoundable(0, 0, width, height) : renderer.GetBoundable());
169
170
                    iRenderer.Transform = patternMatrix;
                    iRenderer.SmoothingMode = SmoothingMode.AntiAlias;
Eric Domke's avatar
Eric Domke committed
171
                    
172
173
174
175
                    foreach (SvgElement child in this.Children)
                    {
                        child.RenderElement(iRenderer);
                    }
davescriven's avatar
davescriven committed
176
177
                }

178
                image.Save(string.Format(@"C:\test{0:D3}.png", imgNumber++));
davescriven's avatar
davescriven committed
179

180
                TextureBrush textureBrush = new TextureBrush(image);
davescriven's avatar
davescriven committed
181

182
183
184
185
186
187
                return textureBrush;
            }
            finally
            {
                if (this.PatternUnits == SvgCoordinateUnits.ObjectBoundingBox) renderer.PopBoundable();
            }
davescriven's avatar
davescriven committed
188
        }
189

190
        private static int imgNumber = 0;
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212



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


		public override SvgElement DeepCopy<T>()
		{
			var newObj = base.DeepCopy<T>() as SvgPatternServer;
			newObj.Overflow = this.Overflow;
			newObj.ViewBox = this.ViewBox;
			newObj.AspectRatio = this.AspectRatio;
			newObj.X = this.X;
			newObj.Y = this.Y;
			newObj.Width = this.Width;
			newObj.Height = this.Height;
			return newObj;

		}
213
214
215
216
217

        public SvgCoordinateUnits GetUnits()
        {
            return _patternUnits;
        }
davescriven's avatar
davescriven committed
218
219
    }
}