public GdiLinearGradientFill(SvgLinearGradientElement gradientElement) : base(gradientElement) { }
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; 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(); Color[] adjcolors = null; float[] adjpositions = null; getColorsAndPositions(stops, ref adjpositions, ref adjcolors); if (res.GradientUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox) && !bForceUserSpaceOnUse) { if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad)) { for (int i = 0; i < adjpositions.Length; 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.Length; if (adjpositions[0] > 0.0) { ++nSize; } if (adjpositions[adjcolors.Length - 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.Length - 1] < 1) { readjcolors[nSize - 1] = readjcolors[nSize - 2]; readjpositions[nSize - 1] = 1; } cb.Colors = readjcolors; cb.Positions = readjpositions; } else { cb.Colors = adjcolors; cb.Positions = adjpositions; } } else { cb.Colors = adjcolors; cb.Positions = adjpositions; } 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); }
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); }
public static LinearGradientBrush ConstructBrush(SvgLinearGradientElement gradient, Rect bounds, Matrix transform) { if (gradient.Stops.Count == 0) { return(null); } double x1 = gradient.X1.AnimVal.Value; double x2 = gradient.X2.AnimVal.Value; double y1 = gradient.Y1.AnimVal.Value; double y2 = gradient.Y2.AnimVal.Value; GradientStopCollection gradientStops = ToGradientStops(gradient.Stops); LinearGradientBrush brush = new LinearGradientBrush(gradientStops, new Point(x1, y1), new Point(x2, y2)); SvgSpreadMethod spreadMethod = SvgSpreadMethod.Pad; if (gradient.SpreadMethod != null) { spreadMethod = (SvgSpreadMethod)gradient.SpreadMethod.AnimVal; if (TryGetSpreadMethod(spreadMethod, out GradientSpreadMethod sm)) { brush.SpreadMethod = sm; } } SvgUnitType mappingMode = SvgUnitType.ObjectBoundingBox; if (gradient.GradientUnits != null) { mappingMode = (SvgUnitType)gradient.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; brush.StartPoint.Offset(bounds.X, bounds.Y); brush.EndPoint.Offset(bounds.X, bounds.Y); } } Matrix brushTransform = ToWpfMatrix(((SvgTransformList)gradient.GradientTransform.AnimVal).TotalMatrix); if (mappingMode == SvgUnitType.UserSpaceOnUse) { brushTransform *= transform; } if (!brushTransform.IsIdentity) { brush.Transform = new MatrixTransform(brushTransform); } string colorInterpolation = gradient.GetPropertyValue("color-interpolation"); if (!String.IsNullOrEmpty(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } } return(brush); }
private LinearGradientBrush GetBrush(SvgLinearGradientElement res, RectangleF bounds) { //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); var gradientStops = this.GetGradientStops(stops); if (gradientStops == null || gradientStops.Count == 0) { return(null); } 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; } int stopCount = gradientStops.Count; var colors = new Color[stopCount]; var positions = new float[stopCount]; for (int i = 0; i < stopCount; i++) { var gradientStop = gradientStops[i]; colors[i] = gradientStop.Color; positions[i] = gradientStop.Offset; Trace.WriteLine(string.Format("color,position = {0}, {1}", colors[i], positions[i])); } //LinearGradientBrush brush = new LinearGradientBrush(new PointF(fLeft, fTop), // new PointF(fRight, fBottom), gradientStops[0].Color, gradientStops[stopCount - 1].Color); LinearGradientBrush brush = new LinearGradientBrush(new RectangleF(fEffectiveLeft - 1, fEffectiveTop - 1, fEffectiveWidth + 2, fEffectiveHeight + 2), Color.Transparent, Color.Transparent, mode); if (res.GradientUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox) && !bForceUserSpaceOnUse) { if (res.SpreadMethod.AnimVal.Equals((ushort)SvgSpreadMethod.Pad)) { for (int i = 0; i < stopCount; i++) { if (fLeft == fRight) { positions[i] = fTop + positions[i] * (fBottom - fTop); } else { positions[i] = fLeft + positions[i] * (fRight - fLeft); } } // this code corrects the values again... fix int nSize = colors.Length; if (positions[0] > 0.0) { ++nSize; } if (positions[colors.Length - 1] < 1) { ++nSize; } Color[] readjcolors = new Color[nSize]; float[] readjpositions = new float[nSize]; if (positions[0] > 0.0) { positions.CopyTo(readjpositions, 1); colors.CopyTo(readjcolors, 1); readjcolors[0] = readjcolors[1]; readjpositions[0] = 0; } else { positions.CopyTo(readjpositions, 0); colors.CopyTo(readjcolors, 0); } if (positions[colors.Length - 1] < 1) { readjcolors[nSize - 1] = readjcolors[nSize - 2]; readjpositions[nSize - 1] = 1; } cb.Colors = readjcolors; cb.Positions = readjpositions; } else { cb.Colors = colors; cb.Positions = positions; } } else { //TODO if (positions.Length == 2 && positions[0] < 1) { positions[1] = 1.0f; } cb.Colors = colors; cb.Positions = positions; } if (colors != null && positions != null) { for (int i = 0; i < positions.Length; i++) { Trace.WriteLine(string.Format("color,position = {0}, {1}", colors[i], positions[i])); } } 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; } Matrix OriginalMatrix = brush.Transform.Clone(); OriginalMatrix.Multiply(GetTransformMatrix(res)); brush.Transform = OriginalMatrix; if (string.Equals(res.GetPropertyValue("color-interpolation"), CssConstants.ValLinearRgb, StringComparison.OrdinalIgnoreCase)) { brush.GammaCorrection = true; } else { brush.GammaCorrection = false; } return(brush); }
private CanvasLinearGradientBrush CreateLinearGradient(CanvasDrawingSession session, Rect area, SvgLinearGradientElement element) { if (this.ResourceCache.ContainsKey(element)) { return((CanvasLinearGradientBrush)this.ResourceCache[element]); } var stops = element.ChildNodes.Cast <SvgStopElement>().Select(s => { var alpha = s.Style.StopOpacity.HasValue ? (byte)(255.0F * s.Style.StopOpacity.Value) : (byte)0xff; var stop = new CanvasGradientStop() { Position = s.Offset, Color = s.Style.StopColor.StopColorType == SvgStopColorType.CurrentColor ? s.Style.Color.ToPlatformColor(alpha) : s.Style.StopColor?.ToPlatformColor(alpha) ?? Color.FromArgb(alpha, 0, 0, 0) }; return(stop); }).ToArray(); var m = element.GradientTransform.Result; var transform = new Matrix3x2 { M11 = (float)m.A, M12 = (float)m.B, M21 = (float)m.C, M22 = (float)m.D, M31 = (float)m.E, M32 = (float)m.F }; float x1, y1, x2, y2; if (element.GradientUnits != SvgUnitType.UserSpaceOnUse) { x1 = this.LengthConverter.ConvertXForOBBU(element.X1, (float)area.X, (float)area.Width); y1 = this.LengthConverter.ConvertYForOBBU(element.Y1, (float)area.Y, (float)area.Height); x2 = this.LengthConverter.ConvertXForOBBU(element.X2, (float)area.X, (float)area.Width); y2 = this.LengthConverter.ConvertYForOBBU(element.Y2, (float)area.Y, (float)area.Height); } else { x1 = this.LengthConverter.ConvertX(element.X1); y1 = this.LengthConverter.ConvertY(element.Y1); x2 = this.LengthConverter.ConvertX(element.X2); y2 = this.LengthConverter.ConvertY(element.Y2); } var spreadMethod = GetSpreadMethod(element.SpreadMethod); var brush = new CanvasLinearGradientBrush(this.ResourceCreator, stops, spreadMethod, CanvasAlphaMode.Straight) { StartPoint = new Vector2 { X = x1, Y = y1 }, EndPoint = new Vector2 { X = x2, Y = y2 }, Transform = transform, }; this.DisposableObjects.Add(brush); this.ResourceCache.Add(element, brush); return(brush); }
private LinearGradientBrush GetLinearGradientBrush(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, new Point(x1, y1), new Point(x2, y2)); SvgSpreadMethod spreadMethod = SvgSpreadMethod.None; if (res.SpreadMethod != null) { spreadMethod = (SvgSpreadMethod)res.SpreadMethod.AnimVal; if (spreadMethod != SvgSpreadMethod.None) { brush.SpreadMethod = WpfConvert.ToSpreadMethod(spreadMethod); } } if (res.GradientUnits != null) { SvgUnitType mappingMode = (SvgUnitType)res.GradientUnits.AnimVal; if (mappingMode == SvgUnitType.ObjectBoundingBox) { brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; } else if (mappingMode == SvgUnitType.UserSpaceOnUse) { brush.MappingMode = BrushMappingMode.Absolute; } } MatrixTransform transform = GetTransformMatrix(res); if (transform != null && !transform.Matrix.IsIdentity) { brush.Transform = transform; } //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; // } // else // { // if (fLeft == fRight) // { // //mode = LinearGradientMode.Vertical; // } // else // { // if (fLeft < fRight) // { // //mode = LinearGradientMode.ForwardDiagonal; // brush.Transform = new RotateTransform(45, 0, 0); // //brush.EndPoint = new Point(x1, y1 + 1); // } // else // { // //mode = LinearGradientMode.BackwardDiagonal; // brush.Transform = new RotateTransform(-45); // } // } // } //} string colorInterpolation = res.GetPropertyValue("color-interpolation"); if (!String.IsNullOrEmpty(colorInterpolation)) { if (colorInterpolation == "linearRGB") { brush.ColorInterpolationMode = ColorInterpolationMode.ScRgbLinearInterpolation; } else { brush.ColorInterpolationMode = ColorInterpolationMode.SRgbLinearInterpolation; } } return(brush); }
public override PageElement VisitLinearGradientElement(SvgLinearGradientElement element) => null;