示例#1
0
        YamlObject FromOpacityGradientStop(OpacityGradientStop value)
        {
            var result = new YamlMap
            {
                { nameof(value.Opacity), Scalar(value.Opacity) },
                { nameof(value.Offset), Scalar(value.Offset) },
            };

            return(result);
        }
示例#2
0
        static YamlObject FromOpacityGradientStop(OpacityGradientStop value)
        {
            var result = new YamlMap
            {
                { "OpacityPercent", value.OpacityPercent },
                { "Offset", value.Offset },
            };

            return(result);
        }
示例#3
0
        /// <summary>
        /// Converts a list of <see cref="GradientStop"/>s into an equivalent list of
        /// <see cref="ColorGradientStop"/> of the same length, but with the opacity from any
        /// <see cref="OpacityGradientStop"/>s multiplied into the alpha channel of the
        /// <see cref="ColorGradientStop"/>s.
        /// The color and opacity values are calculated by interpolating from the surrounding stops.
        /// The result is ordered by offset.
        /// </summary>
        /// <returns>A list of <see cref="ColorGradientStop"/>s ordered by offset.</returns>
        public static IEnumerable <ColorGradientStop> Optimize(IEnumerable <GradientStop> stops)
        {
            // Order the stops. This is necessary because we will be searching forward in offset to find
            // the next stop of a particular type to use for interpolating colors and opacities.
            // If a color stop is at the same offset as an opacity stop, put the color stop first.
            var orderedStops = stops.OrderBy(s => s.Offset).ThenBy(s => s.Kind == GradientStop.GradientStopKind.Color ? 0 : 1).ToArray();

            OpacityGradientStop previousOpacityStop = null;
            OpacityGradientStop nextOpacityStop     = null;
            ColorGradientStop   previousColorStop   = null;
            ColorGradientStop   nextColorStop       = null;
            var foundLastColorStop   = false;
            var foundLastOpacityStop = false;

            // Convert GradientStops into ColorGradientStops by interpolating the color or opacity values from
            // the surrounding GradientStops.
            for (var i = 0; i < orderedStops.Length; i++)
            {
                var currentStop = orderedStops[i];

                // The stop is either an OpacityGradientStop or a ColorGradientStop. Convert to a ColorGradientStop
                // by interpolating the color or opacity as necessary.
                Color   color;
                Opacity opacity;

                if (currentStop.Kind == GradientStop.GradientStopKind.Color)
                {
                    // The stop is a ColorGradientStop. Get the color value directly from the stop,
                    // and interpolate the opacity value from the surrounding OpacityGradientStops.
                    var currentColorStop = previousColorStop = (ColorGradientStop)currentStop;
                    color = currentColorStop.Color;

                    // Invalidate nextColorStop to force a search for the next color stop.
                    nextColorStop = null;

                    // If there's an opacity stop at the same offset, it will be the next stop in the list.
                    if (i + 1 < orderedStops.Length &&
                        orderedStops[i + 1].Offset == currentStop.Offset &&
                        orderedStops[i + 1].Kind == GradientStop.GradientStopKind.Opacity)
                    {
                        opacity = ((OpacityGradientStop)orderedStops[i + 1]).Opacity;
                    }
                    else
                    {
                        // Find the next opacity stop, if there is one.
                        if (nextOpacityStop is null && !foundLastOpacityStop)
                        {
                            nextOpacityStop = (OpacityGradientStop)FindNextStopOfKind(
                                orderedStops,
                                i + 1,
                                GradientStop.GradientStopKind.Opacity);
                            if (nextOpacityStop is null)
                            {
                                // Indicate that we should not search again.
                                foundLastOpacityStop = true;
                            }
                        }

                        // Interpolate the opacity value from the surrounding stops.
                        if (previousOpacityStop is null)
                        {
                            // There is no previous opacity stop. Use the next opacity
                            // stop if there is one, or Opaque if there are no opacity stops.
                            opacity = nextOpacityStop?.Opacity ?? Opacity.Opaque;
                        }
                        else
                        {
                            // If there's a following opacity stop, interpolate between previous
                            // and next, otherwise continue using the previous opacity.
                            opacity = nextOpacityStop is null
                                ? previousOpacityStop.Opacity
                                : InterpolateOpacity(previousOpacityStop, nextOpacityStop, currentStop.Offset);
                        }
                    }
                }
                else
                {
                    // The stop is an OpacityGradientStop. Get the opacity value directly from the stop,
                    // and interpolate the color value from the surrounding ColorStops.
                    var currentOpacityStop = previousOpacityStop = (OpacityGradientStop)currentStop;
                    opacity = previousOpacityStop.Opacity;

                    // Invalidate nextOpacityStop to force a search for the next opacity stop.
                    nextOpacityStop = null;

                    // If there's a color stop at the same offset, it will be the previous stop in the list.
                    if (i > 0 &&
                        orderedStops[i - 1].Offset == currentStop.Offset &&
                        orderedStops[i - 1].Kind == GradientStop.GradientStopKind.Color)
                    {
                        color = ((ColorGradientStop)orderedStops[i - 1]).Color;
                    }
                    else
                    {
                        // Find the next color stop, if there is one.
                        if (nextColorStop is null && !foundLastColorStop)
                        {
                            nextColorStop = (ColorGradientStop)FindNextStopOfKind(
                                orderedStops,
                                i + 1,
                                GradientStop.GradientStopKind.Color);
                            if (nextColorStop is null)
                            {
                                // Indicate that we should not search again.
                                foundLastColorStop = true;
                            }
                        }

                        // Interpolate the color value from the surrounding stops.
                        if (previousColorStop is null)
                        {
                            // There is no previous color. Use the next color, or black if there are no
                            // colors. There should always be at least one color, so black is arbitrary.
                            color = nextColorStop?.Color ?? Color.Black;
                        }
                        else
                        {
                            // If there's a following color stop, interpolate between previous
                            // and next, otherwise continue using the previous color.
                            color = nextColorStop is null
                                ? previousColorStop.Color
                                : InterpolateColor(previousColorStop, nextColorStop, currentStop.Offset);
                        }
                    }
                }

                yield return(new ColorGradientStop(currentStop.Offset, color * opacity));
            }
        }