Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorRenderingGdi/Gdi/GdiSvgPaint.cs @ 13349

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

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

File size: 9.9 KB
Line 
1using System;
2using System.Drawing;
3using System.Drawing.Drawing2D;
4
5using SharpVectors.Dom.Svg;
6using SharpVectors.Dom.Css;
7
8namespace SharpVectors.Renderers.Gdi
9{
10    public sealed class GdiSvgPaint : SvgPaint
11    {
12        #region Private Fields
13
14        private GdiFill _paintFill;
15        private SvgStyleableElement _element;
16
17        #endregion
18
19        #region Constructors and Destructor
20
21        public GdiSvgPaint(SvgStyleableElement elm, string propName)
22            : base(elm.GetComputedStyle("").GetPropertyValue(propName))
23        {
24            _element = elm;
25        }
26
27        #endregion
28
29        #region Public Properties
30
31        public GdiFill PaintFill
32        {
33            get
34            {
35                return _paintFill;
36            }
37        }
38
39        #endregion
40
41        #region Public Methods
42
43        public Brush GetBrush(GraphicsPath gp)
44        {
45            return GetBrush(gp, "fill");
46        }
47
48        public Pen GetPen(GraphicsPath gp)
49        {
50            float strokeWidth = GetStrokeWidth();
51            if (strokeWidth == 0) return null;
52
53            GdiSvgPaint stroke;
54            if (PaintType == SvgPaintType.None)
55            {
56                return null;
57            }
58            else if (PaintType == SvgPaintType.CurrentColor)
59            {
60                stroke = new GdiSvgPaint(_element, "color");
61            }
62            else
63            {
64                stroke = this;
65            }
66
67            Pen pen = new Pen(stroke.GetBrush(gp, "stroke"), strokeWidth);
68
69            pen.StartCap = pen.EndCap = GetLineCap();
70            pen.LineJoin = GetLineJoin();
71            pen.MiterLimit = GetMiterLimit();
72
73            float[] fDashArray = GetDashArray(strokeWidth);
74            if (fDashArray != null)
75            {
76                // Do not draw if dash array had a zero value in it
77
78                for (int i = 0; i < fDashArray.Length; i++)
79                {
80                    if (fDashArray[i] == 0)
81                        return null;
82                }
83
84                pen.DashPattern = fDashArray;
85            }
86
87            pen.DashOffset = GetDashOffset(strokeWidth);
88
89            return pen;
90        }
91
92        #endregion
93
94        #region Private Methods
95
96        private int GetOpacity(string fillOrStroke)
97        {
98            double alpha = 255;
99            string opacity;
100
101            opacity = _element.GetPropertyValue(fillOrStroke + "-opacity");
102            if (opacity.Length > 0) alpha *= SvgNumber.ParseNumber(opacity);
103
104            opacity = _element.GetPropertyValue("opacity");
105            if (opacity.Length > 0) alpha *= SvgNumber.ParseNumber(opacity);
106
107            alpha = Math.Min(alpha, 255);
108            alpha = Math.Max(alpha, 0);
109
110            return Convert.ToInt32(alpha);
111        }
112
113        private LineCap GetLineCap()
114        {
115            switch (_element.GetPropertyValue("stroke-linecap"))
116            {
117                case "round":
118                    return LineCap.Round;
119                case "square":
120                    return LineCap.Square;
121                default:
122                    return LineCap.Flat;
123            }
124        }
125
126        private LineJoin GetLineJoin()
127        {
128            switch (_element.GetPropertyValue("stroke-linejoin"))
129            {
130                case "round":
131                    return LineJoin.Round;
132                case "bevel":
133                    return LineJoin.Bevel;
134                default:
135                    return LineJoin.Miter;
136            }
137        }
138
139        private float GetStrokeWidth()
140        {
141            string strokeWidth = _element.GetPropertyValue("stroke-width");
142            if (strokeWidth.Length == 0) strokeWidth = "1px";
143
144            SvgLength strokeWidthLength = new SvgLength(_element, "stroke-width", SvgLengthDirection.Viewport, strokeWidth);
145            return (float)strokeWidthLength.Value;
146        }
147
148        private float GetMiterLimit()
149        {
150            string miterLimitStr = _element.GetPropertyValue("stroke-miterlimit");
151            if (miterLimitStr.Length == 0) miterLimitStr = "4";
152
153            float miterLimit = (float)SvgNumber.ParseNumber(miterLimitStr);
154            if (miterLimit < 1) throw new SvgException(SvgExceptionType.SvgInvalidValueErr, "stroke-miterlimit can not be less then 1");
155
156            return miterLimit;
157        }
158
159        private float[] GetDashArray(float strokeWidth)
160        {
161            string dashArray = _element.GetPropertyValue("stroke-dasharray");
162
163            if (dashArray.Length == 0 || dashArray == "none")
164            {
165                return null;
166            }
167            else
168            {
169                SvgNumberList list = new SvgNumberList(dashArray);
170
171                uint len = list.NumberOfItems;
172                float[] fDashArray = new float[len];
173
174                for (uint i = 0; i < len; i++)
175                {
176                    //divide by strokeWidth to take care of the difference between Svg and GDI+
177                    fDashArray[i] = (float)(list.GetItem(i).Value / strokeWidth);
178                }
179
180                if (len % 2 == 1)
181                {
182                    //odd number of values, duplicate
183                    float[] tmpArray = new float[len * 2];
184                    fDashArray.CopyTo(tmpArray, 0);
185                    fDashArray.CopyTo(tmpArray, (int)len);
186
187                    fDashArray = tmpArray;
188                }
189
190                return fDashArray;
191            }
192        }
193
194        private float GetDashOffset(float strokeWidth)
195        {
196            string dashOffset = _element.GetPropertyValue("stroke-dashoffset");
197            if (dashOffset.Length > 0)
198            {
199                //divide by strokeWidth to take care of the difference between Svg and GDI+
200                SvgLength dashOffsetLength = new SvgLength(_element, "stroke-dashoffset", SvgLengthDirection.Viewport, dashOffset);
201                return (float)dashOffsetLength.Value;
202            }
203            else
204            {
205                return 0;
206            }
207        }
208
209        private GdiFill GetPaintFill(string uri)
210        {
211            string absoluteUri = _element.ResolveUri(uri);
212
213            return GdiFill.CreateFill(_element.OwnerDocument, absoluteUri);
214        }
215
216        private Brush GetBrush(GraphicsPath gp, string propPrefix)
217        {
218            SvgPaint painter;
219            SvgPaintType curPaintType = this.PaintType;
220            if (curPaintType == SvgPaintType.None)
221            {
222                return null;
223            }
224            else if (curPaintType == SvgPaintType.CurrentColor)
225            {
226                painter = new GdiSvgPaint(_element, "color");
227            }
228            else
229            {
230                painter = this;
231            }
232
233            SvgPaintType paintType = painter.PaintType;
234            if (paintType == SvgPaintType.Uri     || paintType == SvgPaintType.UriCurrentColor ||
235                paintType == SvgPaintType.UriNone || paintType == SvgPaintType.UriRgbColor     ||
236                paintType == SvgPaintType.UriRgbColorIccColor)
237            {
238                _paintFill = GetPaintFill(painter.Uri);
239                if (_paintFill != null)
240                {
241                    Brush br = _paintFill.GetBrush(gp.GetBounds());
242
243                    LinearGradientBrush lgb = br as LinearGradientBrush;
244                    if (lgb != null)
245                    {
246                        int opacityl = GetOpacity(propPrefix);
247                        for (int i = 0; i < lgb.InterpolationColors.Colors.Length; i++)
248                        {
249                            lgb.InterpolationColors.Colors[i] =
250                                Color.FromArgb(opacityl, lgb.InterpolationColors.Colors[i]);
251                        }
252                        for (int i = 0; i < lgb.LinearColors.Length; i++)
253                        {
254                            lgb.LinearColors[i] = Color.FromArgb(opacityl, lgb.LinearColors[i]);
255                        }
256
257                        return br;
258                    }
259
260                    PathGradientBrush pgb = br as PathGradientBrush;
261                    if (pgb != null)
262                    {
263                        int opacityl = GetOpacity(propPrefix);
264                        for (int i = 0; i < pgb.InterpolationColors.Colors.Length; i++)
265                        {
266                            pgb.InterpolationColors.Colors[i] =
267                                Color.FromArgb(opacityl, pgb.InterpolationColors.Colors[i]);
268                        }
269                        for (int i = 0; i < pgb.SurroundColors.Length; i++)
270                        {
271                            pgb.SurroundColors[i] = Color.FromArgb(opacityl, pgb.SurroundColors[i]);
272                        }
273
274                        return br;
275                    }
276                }
277                else
278                {
279                    if (curPaintType == SvgPaintType.UriNone ||
280                        curPaintType == SvgPaintType.Uri)
281                    {
282                        return null;
283                    }
284                    else if (curPaintType == SvgPaintType.UriCurrentColor)
285                    {
286                        painter = new GdiSvgPaint(_element, "color");
287                    }
288                    else
289                    {
290                        painter = this;
291                    }
292                }
293            }
294
295            if (painter == null || painter.RgbColor == null)
296            {
297                return null;
298            }
299                                                           
300            SolidBrush brush = new SolidBrush(GdiConverter.ToColor(painter.RgbColor));
301            int opacity = GetOpacity(propPrefix);
302            brush.Color = Color.FromArgb(opacity, brush.Color);
303            return brush;
304        }
305
306        #endregion
307    }
308}
Note: See TracBrowser for help on using the repository browser.