Inheritance: SvgGradientElement, ISvgLinearGradientElement
        private LinearGradientBrush GetLinearGradientBrush(Rect elementBounds, 
            SvgLinearGradientElement res)
        {
            double x1 = res.X1.AnimVal.Value;
            double x2 = res.X2.AnimVal.Value;
            double y1 = res.Y1.AnimVal.Value;
            double y2 = res.Y2.AnimVal.Value;

            GradientStopCollection gradientStops = GetGradientStops(res.Stops);

            //LinearGradientBrush brush = new LinearGradientBrush(gradientStops);
            LinearGradientBrush brush = new LinearGradientBrush(gradientStops,
                new Point(x1, y1), new Point(x2, y2));

            SvgSpreadMethod spreadMethod = SvgSpreadMethod.Pad;
            if (res.SpreadMethod != null)
            {
                spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal;

                if (spreadMethod != SvgSpreadMethod.None)
                {
                    brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod);
                }
            }

            Transform viewBoxTransform = null;

            SvgUnitType mappingMode = SvgUnitType.ObjectBoundingBox;
            if (res.GradientUnits != null)
            {
                mappingMode = (SvgUnitType)res.GradientUnits.AnimVal;
                if (mappingMode == SvgUnitType.ObjectBoundingBox)
                {
                    brush.MappingMode = BrushMappingMode.RelativeToBoundingBox;
                }
                else if (mappingMode == SvgUnitType.UserSpaceOnUse)
                {
                    brush.MappingMode = BrushMappingMode.Absolute;

                    viewBoxTransform = FitToViewbox(new SvgRect(x1, y1,
                        Math.Abs(x2 - x1), Math.Abs(y2 - y1)),
                        elementBounds);
                }
            }

            MatrixTransform transform = GetTransformMatrix(res);
            if (transform != null && !transform.Matrix.IsIdentity)
            {
                if (viewBoxTransform != null)
                {
                    TransformGroup group = new TransformGroup();
                    group.Children.Add(viewBoxTransform);
                    group.Children.Add(transform);

                    brush.Transform = group;
                }
                else
                {
                    brush.Transform = transform;
                    //brush.StartPoint = new Point(0, 0.5);
                    //brush.EndPoint = new Point(1, 0.5);
                }

                //brush.StartPoint = new Point(0, 0);
                //brush.EndPoint = new Point(1, 1);
            }
            else
            {
                float fLeft   = (float)res.X1.AnimVal.Value;
                float fRight  = (float)res.X2.AnimVal.Value;
                float fTop    = (float)res.Y1.AnimVal.Value;
                float fBottom = (float)res.Y2.AnimVal.Value;

                if (fTop == fBottom)
                {
                    //mode = LinearGradientMode.Horizontal;

                    //brush.StartPoint = new Point(0, 0.5);
                    //brush.EndPoint = new Point(1, 0.5);
                }
                else
                {
                    if (fLeft == fRight)
                    {
                        //mode = LinearGradientMode.Vertical;

                        //brush.StartPoint = new Point(0.5, 0);
                        //brush.EndPoint = new Point(0.5, 1);
                    }
                    else
                    {
                        if (fLeft < fRight)
                        {
                            if (viewBoxTransform != null)
                            {
                                TransformGroup group = new TransformGroup();
                                group.Children.Add(viewBoxTransform);
                                group.Children.Add(new RotateTransform(45, 0.5, 0.5));

                                brush.Transform = group;
                            }
                            else
                            {
                                brush.RelativeTransform = new RotateTransform(45, 0.5, 0.5);
                            }

                            //mode = LinearGradientMode.ForwardDiagonal;
                            //brush.EndPoint = new Point(x1, y1 + 1);

                            //brush.StartPoint = new Point(0, 0);
                            //brush.EndPoint = new Point(1, 1);
                        }
                        else
                        {
                            //mode = LinearGradientMode.BackwardDiagonal;
                            if (viewBoxTransform != null)
                            {
                                TransformGroup group = new TransformGroup();
                                group.Children.Add(viewBoxTransform);
                                group.Children.Add(new RotateTransform(-45, 0.5, 0.5));

                                brush.Transform = group;
                            }
                            else
                            {
                                brush.RelativeTransform = new RotateTransform(-45, 0.5, 0.5);
                            }

                            //brush.StartPoint = new Point(0, 0);
                            //brush.EndPoint = new Point(1, 1);
                        }
                    }
                }
            }

            string colorInterpolation = res.GetPropertyValue("color-interpolation");
            if (!String.IsNullOrEmpty(colorInterpolation))
            {
                if (colorInterpolation == "linearRGB")
                {
                    brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation;
                }
                else
                {
                    brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation;
                }
            }

            return brush;
        }
        private LinearGradientBrush GetLinearGradientBrush(SvgLinearGradientElement res, RectangleF bounds)
        {
            float fLeft   = (float)res.X1.AnimVal.Value;
            float fRight  = (float)res.X2.AnimVal.Value;
            float fTop    = (float)res.Y1.AnimVal.Value;
            float fBottom = (float)res.Y2.AnimVal.Value;

            bool bForceUserSpaceOnUse = (fLeft > 1 || fRight > 1 || fTop > 1 || fBottom > 1);

            float fEffectiveLeft   = fLeft;
            float fEffectiveRight  = fRight;
            float fEffectiveTop    = fTop;
            float fEffectiveBottom = fBottom;

            if (res.GradientUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox) && !bForceUserSpaceOnUse)
            {
                if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad))
                {
                    fEffectiveRight = bounds.Right;
                    fEffectiveLeft = bounds.Left;
                }
                else
                {
                    fEffectiveLeft = bounds.Left + fLeft * (bounds.Width);
                    fEffectiveRight = bounds.Left + fRight * (bounds.Width);
                }

                fEffectiveTop    = bounds.Top + fTop * (bounds.Height);
                fEffectiveBottom = bounds.Top + fBottom * (bounds.Height);
            }

            LinearGradientMode mode = LinearGradientMode.Horizontal;

            if (fTop == fBottom)
            {
                mode = LinearGradientMode.Horizontal;
            }
            else
            {
                if (fLeft == fRight)
                {
                    mode = LinearGradientMode.Vertical;
                }
                else
                {
                    if (fLeft < fRight)
                        mode = LinearGradientMode.ForwardDiagonal;
                    else
                        mode = LinearGradientMode.BackwardDiagonal;
                }
            }

            float fEffectiveWidth = fEffectiveRight - fEffectiveLeft;

            if (fEffectiveWidth <= 0)
                fEffectiveWidth = bounds.Width;

            float fEffectiveHeight = fEffectiveBottom - fEffectiveTop;

            if (fEffectiveHeight <= 0)
                fEffectiveHeight = bounds.Height;

            LinearGradientBrush brush = new LinearGradientBrush(new RectangleF(fEffectiveLeft - 1,
                fEffectiveTop - 1, fEffectiveWidth + 2, fEffectiveHeight + 2),
                Color.White, Color.White, mode);

            XmlNodeList stops = res.Stops;

            ColorBlend cb = new ColorBlend();

            List<Color> adjcolors    = new List<Color>();
            List<float> adjpositions = new List<float>();
            GetColorsAndPositions(stops, adjpositions, adjcolors);

            if (res.GradientUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox) && !bForceUserSpaceOnUse)
            {
                if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad))
                {
                    for (int i = 0; i < adjpositions.Count; i++)
                    {
                        if (fLeft == fRight)
                            adjpositions[i] = fTop + adjpositions[i] * (fBottom - fTop);
                        else
                            adjpositions[i] = fLeft + adjpositions[i] * (fRight - fLeft);
                    }

                    // this code corrects the values again... fix
                    int nSize = adjcolors.Count;

                    if (adjpositions[0] > 0.0)
                        ++nSize;

                    if (adjpositions[adjcolors.Count - 1] < 1)
                        ++nSize;

                    Color[] readjcolors    = new Color[nSize];
                    float[] readjpositions = new float[nSize];

                    if (adjpositions[0] > 0.0)
                    {
                        adjpositions.CopyTo(readjpositions, 1);
                        adjcolors.CopyTo(readjcolors, 1);

                        readjcolors[0]    = readjcolors[1];
                        readjpositions[0] = 0;
                    }
                    else
                    {
                        adjpositions.CopyTo(readjpositions, 0);
                        adjcolors.CopyTo(readjcolors, 0);
                    }

                    if (adjpositions[adjcolors.Count - 1] < 1)
                    {
                        readjcolors[nSize - 1]    = readjcolors[nSize - 2];
                        readjpositions[nSize - 1] = 1;
                    }

                    cb.Colors    = readjcolors;
                    cb.Positions = readjpositions;
                }
                else
                {
                    cb.Colors    = adjcolors.ToArray();
                    cb.Positions = adjpositions.ToArray();
                }
            }
            else
            {
                cb.Colors    = adjcolors.ToArray();
                cb.Positions = adjpositions.ToArray();
            }

            brush.InterpolationColors = cb;

            if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Reflect))
            {
                brush.WrapMode = WrapMode.TileFlipXY;
            }
            else if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Repeat))
            {
                brush.WrapMode = WrapMode.Tile;
            }
            else if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad))
            {
                brush.WrapMode = WrapMode.Tile;
            }

            brush.Transform = GetTransformMatrix(res);

            if (res.GetPropertyValue("color-interpolation") == "linearRGB")
            {
                brush.GammaCorrection = true;
            }
            else
            {
                brush.GammaCorrection = false;
            }

            return brush;
        }