Пример #1
0
        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);
        }
Пример #2
0
        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);
        }