private static TextureFilter RenderBrushToTextureFilter(LinearGradientBrush brush, Point uvMin, Point uvMax) { // 0-255 spread for each color pass int size = (brush.GradientStops.Count - 1) * 256; if (brush.MappingMode == BrushMappingMode.Absolute) { // Convert to relative Matrix scale = GetConversionToRelative(uvMin, uvMax); brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; brush.StartPoint *= scale; brush.EndPoint *= scale; } BilinearTextureFilter filter = new BilinearTextureFilter(RenderBrushToImageData(brush, size, size)); filter.HasErrorEstimation = false; return(filter); }
private static TextureFilter RenderBrushToTextureFilter(RadialGradientBrush brush, Point uvMin, Point uvMax) { if (brush.MappingMode == BrushMappingMode.Absolute) { // Convert to relative Matrix scale = GetConversionToRelative(uvMin, uvMax); brush.MappingMode = BrushMappingMode.RelativeToBoundingBox; brush.Center *= scale; brush.GradientOrigin *= scale; brush.RadiusX *= scale.M11; brush.RadiusY *= scale.M22; } #if HIGH_RES // How close is the GradientOrigin to the edge of the ellipse defined by Center and RadiusX/Y ? // The gradient has the least room to interpolate between o and c+r. // We need to draw the gradient large enough to allow 256 color values for the shortest segment. // // ,,-----,, // ,' ', // / \ c == Center // ; ; o == GradientOrigin // | c | c+r == Center + RadiusX/Y // ; o ; // \ / // ", ," // ''-----'' // // c------o----c+r x is the thin area between the GradientOrigin and the edge of the ellipse // x 512 * r/x is how we scale that area into an acceptable rendering space // // o--1--2---3-c+r But we must also note that x may be subdivided by GradientStops... // x1 x2 x3 x4 512 * r/xn is the actual scale we want (xn is the shortest GradientStop segment) // double x = brush.RadiusX - Math.Abs(brush.Center.X - brush.GradientOrigin.X); double y = brush.RadiusY - Math.Abs(brush.Center.Y - brush.GradientOrigin.Y); x = Math.Max(x, 0); y = Math.Max(y, 0); SortedList <int, double> list = new SortedList <int, double>(); foreach (GradientStop stop in brush.GradientStops) { list.Add(list.Count, stop.Offset); } double shortest = 1.0; for (int n = 1; n < list.Count; n++) { double offset = Math.Abs(list.Values[n] - list.Values[n - 1]); // We can't do anything with 0, so skip it if it shows up. if (MathEx.NotCloseEnough(offset, 0)) { shortest = Math.Min(shortest, offset); } } double w = 512 * brush.RadiusX / (x * shortest); double h = 512 * brush.RadiusY / (y * shortest); #endif double w = brush.GradientStops.Count * 256 * 2; double h = w; BilinearTextureFilter filter = new BilinearTextureFilter(RenderBrushToImageData(brush, (int)w, (int)h)); filter.HasErrorEstimation = false; return(filter); }