private static GradientStop GetStartStop(float offset, List <GradientStop> stops) { for (int i = stops.Count - 1; i >= 0; i--) { GradientStop stop = stops[i]; if (offset >= stop.Offset) { return(stop); } } if (stops.Count != 0) { return(stops[0]); } return(null); }
/// <summary> /// Generates the linear gradient texture content /// </summary> /// <param name="lineStart">The line start.</param> /// <param name="lineEnd">The line end.</param> /// <param name="borderThickness">The border thickness.</param> /// <param name="sortedStops">The sorted stops.</param> /// <param name="spread">The spread.</param> /// <param name="isBorder">if set to <c>true</c> [is border].</param> public override void GenerateLinearGradient(PointF lineStart, PointF lineEnd, Thickness borderThickness, List <GradientStop> sortedStops, GradientSpreadMethod spread, bool isBorder) { Color[] data = new Color[Width * Height]; Color startColor = Color.TransparentBlack; Color endColor = Color.TransparentBlack; PointF point = new PointF(); float length = GetLength(lineStart, lineEnd); int index = 0; for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { point.Y = y; point.X = x; if ((borderThickness.Top > point.Y || borderThickness.Bottom >= Height - point.Y) || (borderThickness.Left > point.X || borderThickness.Right >= Width - point.X) || !isBorder) { PointF projectPoint = ProjectToLine(lineStart, lineEnd, point, Width); float finalOffset = GetLength(projectPoint, lineStart) / length; switch (spread) { case GradientSpreadMethod.Pad: if (projectPoint.X <= lineStart.X && projectPoint.Y <= lineStart.Y) { finalOffset = 0; } if (projectPoint.X >= lineEnd.X && projectPoint.Y >= lineEnd.Y) { finalOffset = 1; } break; case GradientSpreadMethod.Reflect: if (projectPoint.X <= lineStart.X && projectPoint.Y <= lineStart.Y || projectPoint.X >= lineEnd.X && projectPoint.Y >= lineEnd.Y) { if (finalOffset > 1) { finalOffset = ((float)Math.Ceiling(finalOffset) - finalOffset); } } break; case GradientSpreadMethod.Repeat: if (projectPoint.X <= lineStart.X && projectPoint.Y <= lineStart.Y) { if (finalOffset > 0) { finalOffset = ((float)Math.Ceiling(finalOffset) - finalOffset); } } if (projectPoint.X >= lineEnd.X && projectPoint.Y >= lineEnd.Y) { if (finalOffset > 1) { finalOffset = (finalOffset - (float)Math.Floor(finalOffset)); } } break; default: Debug.Assert(false); break; } GradientStop startStop = GetStartStop(finalOffset, sortedStops); startColor = startStop != null ? new Color { PackedValue = startStop.Color.PackedValue } : Color.TransparentBlack; GradientStop endStop = GetEndStop(finalOffset, sortedStops, spread); endColor = endStop != null ? new Color { PackedValue = endStop.Color.PackedValue } : Color.TransparentBlack; if (endStop != null && startStop != null) { finalOffset = (finalOffset - startStop.Offset) * (1f / (endStop.Offset - startStop.Offset)); } if (float.IsInfinity(finalOffset)) { finalOffset = 0; } if (float.IsNaN(finalOffset)) { finalOffset = 1; } Color finalColor = Color.Lerp(startColor, endColor, finalOffset); data[index] = finalColor; } else { data[index] = Color.TransparentBlack; } index++; } } texture.SetData <Color>(data); }