public RadialGradientImageSourceEffectProcessor() { Name = "Radial Gradient"; m_radialGradient = new RadialGradient(new Point(0.5, 0.5), new EllipseRadius(0.5, 0.5)); m_radialGradient.Stops = new[] { new GradientStop{Offset=0.0, Color=Colors.Red}, new GradientStop{Offset=0.5, Color=Colors.Green}, new GradientStop{Offset=1.0, Color=Colors.Cyan} }; m_gradientImageSource = new GradientImageSource(new Size(800,500), m_radialGradient); SetupEffectCategory(m_gradientImageSource); m_propertyDescriptions = new Dictionary<string, PropertyDescription>(); m_propertyDescriptions.Add("CenterX", new PropertyDescription(0, 1.0, 0.5)); m_propertyDescriptions.Add("CenterY", new PropertyDescription(0, 1.0, 0.5)); m_propertyDescriptions.Add("RadiuxX", new PropertyDescription(0, 1.0, 0.5)); m_propertyDescriptions.Add("RadiuxY", new PropertyDescription(0, 1.0, 0.5)); AddEditors(); m_centerX = 0.5; m_centerY = 0.5; m_radiusX = 0.5; m_radiusY = 0.5; }
/// <summary> /// Provides a configured LinearGradient that can be used in combination with a GradientImageSource to provide a mask for the LensBlurEffect. /// It will expect the LensBlur will be blurred with 1 kernel when the double is different from None. /// </summary> /// <param name="ellipse">The band that represents the focus area in the image. Pixels within this band won't be blurred. /// Areas outside of the area will be progressively more blurred as the distance from the focus band increases.</param> /// <param name="strength">Strength of the blur.</param> /// <returns>A LinearGradient that can be used in combination with a GradientImageSource to be used by LensBlur.</returns> public static RadialGradient GenerateGradient(FocusEllipse ellipse, KernelGenerator kernelGenerator) { if (kernelGenerator.GetKernelBands().Count == 0) { return null; } EllipseRadius maxBlurRadius = null; if ((ellipse.Radius.X < minDiffBetweenStops) && (ellipse.Radius.Y < minDiffBetweenStops)) { maxBlurRadius = new EllipseRadius(minDiffBetweenStops, minDiffBetweenStops); } else { double factor = 0.9; bool widthGtHight = ellipse.Radius.X > ellipse.Radius.Y; if (widthGtHight) { maxBlurRadius = new EllipseRadius(factor, factor * ellipse.Radius.Y / ellipse.Radius.X); } else { maxBlurRadius = new EllipseRadius(factor * ellipse.Radius.X / ellipse.Radius.Y, factor); } } var gradient = new RadialGradient(ellipse.Center, maxBlurRadius); SetGradientStops(gradient, ellipse, maxBlurRadius, kernelGenerator); return gradient; }
public LightEffect() { var globalCurve = new Curve(CurveInterpolation.Linear, new[] { new Point(0, 0), new Point(41, 59), new Point(112, 146), new Point(189, 211), new Point(255, 255) }); var redCurve = new Curve(CurveInterpolation.Linear, new[] { new Point(18, 0), new Point(126, 116), new Point(255, 228), }); Curve.Compose(redCurve, globalCurve, redCurve); var greenCurve = globalCurve; var blueCurve = new Curve(CurveInterpolation.Linear, new[] { new Point(0, 44), new Point(113, 138), new Point(230, 255), }); Curve.Compose(blueCurve, globalCurve, blueCurve); var gradient = new RadialGradient { EllipseRadius = new EllipseRadius(1.5, 0), CenterPoint = new Point(0.5, 0.5), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(0, 0, 0, 0)}, new GradientStop {Offset = 1, Color = Color.FromArgb(255, 255, 255, 255)} } }; var overlayFactory = new OverlayFactory( "ms-appx:///images/Filters_Landscape_Overlay_Light.jpg", "ms-appx:///images/Filters_Portrait_Overlay_Light.jpg", "ms-appx:///images/Filters_Square_Overlay_Light.jpg"); LayerList = new LayerList() { new AdjustmentLayer(LayerStyle.Normal(0.2), new CurvesEffect(redCurve, greenCurve, blueCurve)), new Layer(LayerStyle.Softlight(0.3), context => new ColorImageSource(context.BackgroundLayer.ImageSize, Color.FromArgb(255, 200, 200, 200))), new Layer(LayerStyle.Softlight(0.7), context => new GradientImageSource(context.BackgroundLayer.ImageSize, gradient)), new Layer(LayerStyle.Screen(), context => overlayFactory.CreateAsync(context.BackgroundLayer.ImageSize)) }; }
protected override void DrawBackground(Context context, Gdk.Rectangle region) { LayoutRoundedRectangle(context, region); context.Clip(); context.SetSourceColor(CairoExtensions.ParseColor("D3E6FF")); context.Paint(); context.Save(); context.Translate(region.X + region.Width / 2.0, region.Y + region.Height); using (var rg = new RadialGradient(0, 0, 0, 0, 0, region.Height * 1.2)) { var color = CairoExtensions.ParseColor("E5F0FF"); rg.AddColorStop(0, color); color.A = 0; rg.AddColorStop(1, color); context.Scale(region.Width / (double)region.Height, 1.0); context.SetSource(rg); context.Paint(); } context.Restore(); LayoutRoundedRectangle(context, region, -3, -3, 2); context.SetSourceRGBA(1, 1, 1, 0.4); context.LineWidth = 1; context.StrokePreserve(); context.Clip(); int boxSize = 11; int x = region.Left + (region.Width % boxSize) / 2; for (; x < region.Right; x += boxSize) { context.MoveTo(x + 0.5, region.Top); context.LineTo(x + 0.5, region.Bottom); } int y = region.Top + (region.Height % boxSize) / 2; y += boxSize / 2; for (; y < region.Bottom; y += boxSize) { context.MoveTo(region.Left, y + 0.5); context.LineTo(region.Right, y + 0.5); } context.SetSourceRGBA(1, 1, 1, 0.2); context.Stroke(); context.ResetClip(); }
public OvalShadow(int shadowRadius, int circleDiameter, CircleProgressBar progressBar) : base() { mProgressBar = progressBar; mShadowPaint = new Paint(); mShadowRadius = shadowRadius; mCircleDiameter = circleDiameter; mRadialGradient = new RadialGradient(mCircleDiameter / 2, mCircleDiameter / 2, mShadowRadius, new int[] { FILL_SHADOW_COLOR, Color.Transparent }, null, Shader.TileMode.Clamp); mShadowPaint.SetShader(mRadialGradient); }
private void CreateAndSetShader(Canvas canvas, PointF center, int oldWidth, int radius) { var colorWith0Alpha = _config.Color; colorWith0Alpha.A = 0; var shader = new RadialGradient(center.X, center.Y, radius, CalculateColors(canvas), CalculateStops(canvas, radius, oldWidth), Shader.TileMode.Clamp); _paint.SetShader(shader); }
public static ColorBase GetColor(Brush brush, double opacity, Rect bounds, double angle = 0) { var solidBrush = brush as SolidColorBrush; if (solidBrush != null) { return GetRgbColor(solidBrush.Color, opacity); } var linerBrush = brush as LinearGradientBrush; if (linerBrush != null) { var startPoint = new Point(bounds.X + linerBrush.StartPoint.X * bounds.Width, bounds.Y + linerBrush.StartPoint.Y * bounds.Height); var endPoint = new Point(bounds.X + linerBrush.EndPoint.X * bounds.Width, bounds.Y + linerBrush.EndPoint.Y * bounds.Height); LinearGradient gradient = new LinearGradient(startPoint, endPoint); foreach (var stop in linerBrush.GradientStops) { gradient.GradientStops.Add(new Telerik.Windows.Documents.Fixed.Model.ColorSpaces.GradientStop(GetRgbColor(stop.Color, opacity), stop.Offset)); } gradient.Position.RotateAt(angle, bounds.Center().X, bounds.Center().Y); return gradient; } var radialBrush = brush as RadialGradientBrush; if (radialBrush != null) { var startPoint = new Point(bounds.X + radialBrush.GradientOrigin.X * bounds.Width, bounds.Y + radialBrush.GradientOrigin.Y * bounds.Height); var endPoint = new Point(bounds.X + radialBrush.Center.X * bounds.Width, bounds.Y + radialBrush.Center.Y * bounds.Height); var radiusX = radialBrush.RadiusX * bounds.Width; var radiusY = radialBrush.RadiusY * bounds.Height; Point scale = new Point(1, 1); if (radiusX > radiusY) scale.X = radiusX / radiusY; else if (radiusY > radiusX) scale.Y = radiusY / radiusX; RadialGradient gradient = new RadialGradient(startPoint, endPoint, 0, Math.Min(radiusX, radiusY)); for (int i = 0; i < radialBrush.GradientStops.Count; i++) { var stop = radialBrush.GradientStops[i]; var color = GetRgbColor(stop.Color, opacity); gradient.GradientStops.Add(new Telerik.Windows.Documents.Fixed.Model.ColorSpaces.GradientStop(color, stop.Offset)); } gradient.Position.ScaleAt(scale.X, scale.Y, bounds.Center().X, bounds.Center().Y); gradient.Position.RotateAt(angle, bounds.Center().X, bounds.Center().Y); return gradient; } return RgbColors.Black; }
public OvalShadow(CircleImageView circleImageView, int shadowRadius, int circleDiameter) : base() { _circleImageView = circleImageView; mShadowPaint = new Paint(); _circleImageView.mShadowRadius = shadowRadius; mCircleDiameter = circleDiameter; mRadialGradient = new RadialGradient(mCircleDiameter / 2, mCircleDiameter / 2, _circleImageView.mShadowRadius, new int[] { FILL_SHADOW_COLOR, Color.Transparent.ToArgb() }, null, Shader.TileMode.Clamp); mShadowPaint.SetShader(mRadialGradient); }
public OvalShadow(CircleImageView circleImageView, int shadowRadius, int circleDiameter) : base() { _circleImageView = circleImageView; _shadowPaint = new Paint(); _circleImageView._shadowRadius = shadowRadius; _circleDiameter = circleDiameter; var radialGradient = new RadialGradient(_circleDiameter / 2, _circleDiameter / 2, _circleImageView._shadowRadius, new int[] { FillShadowColor, Color.Transparent.ToArgb() }, null, Shader.TileMode.Clamp); _shadowPaint.SetShader(radialGradient); }
public void RadialGradientSmall() { InitBlank(); var g = new RadialGradient(5, 5, 5, 30, 30, 15); g.AddColorStop(0, Colors.Red); g.AddColorStop(0.5, Colors.Green); g.AddColorStop(1, Colors.Blue); context.Rectangle(5, 5, 40, 40); context.Pattern = g; context.Fill(); CheckImage("RadialGradientSmall.png"); }
protected virtual void DrawBackground(Cairo.Context context, Gdk.Rectangle region) { LayoutRoundedRectangle(context, region); context.ClipPreserve(); using (LinearGradient lg = new LinearGradient(region.X, region.Y, region.X, region.Y + region.Height)) { lg.AddColorStop(0, Styles.StatusBarFill1Color); lg.AddColorStop(1, Styles.StatusBarFill4Color); context.SetSource(lg); context.FillPreserve(); } context.Save(); double midX = region.X + region.Width / 2.0; double midY = region.Y + region.Height; context.Translate(midX, midY); using (RadialGradient rg = new RadialGradient(0, 0, 0, 0, 0, region.Height * 1.2)) { rg.AddColorStop(0, Styles.StatusBarFill1Color); rg.AddColorStop(1, Styles.WithAlpha(Styles.StatusBarFill1Color, 0)); context.Scale(region.Width / (double)region.Height, 1.0); context.SetSource(rg); context.Fill(); } context.Restore(); using (LinearGradient lg = new LinearGradient(0, region.Y, 0, region.Y + region.Height)) { lg.AddColorStop(0, Styles.StatusBarShadowColor1); lg.AddColorStop(1, Styles.WithAlpha(Styles.StatusBarShadowColor1, Styles.StatusBarShadowColor1.A * 0.2)); LayoutRoundedRectangle(context, region, 0, -1); context.LineWidth = 1; context.SetSource(lg); context.Stroke(); } using (LinearGradient lg = new LinearGradient(0, region.Y, 0, region.Y + region.Height)) { lg.AddColorStop(0, Styles.StatusBarShadowColor2); lg.AddColorStop(1, Styles.WithAlpha(Styles.StatusBarShadowColor2, Styles.StatusBarShadowColor2.A * 0.2)); LayoutRoundedRectangle(context, region, 0, -2); context.LineWidth = 1; context.SetSource(lg); context.Stroke(); } context.ResetClip(); }
public IRadialGradient Construct(RadialGradientBuilder builder) { var radialGradient = new RadialGradient { Center = builder.Center, Shape = builder.Shape, Stretch = builder.Stretch, Radius = builder.Radius, IsRepeating = builder.IsRepeating, Stops = new GradientElements <GradientStop>(builder.Stops.Cast <GradientStop>()) }; return(radialGradient); }
private Pattern CreateMask() { double max = Math.Max(blur.Bounds.Width, blur.Bounds.Height) * .25; double scale = blur.Bounds.Width / (double)info.Bounds.Width; RadialGradient circle; circle = new RadialGradient(center.X * scale, center.Y * scale, radius * max * .7, center.X * scale, center.Y * scale, radius * max + max * .2); circle.AddColorStop(0, new Cairo.Color(0.0, 0.0, 0.0, 0.0)); circle.AddColorStop(1.0, new Cairo.Color(1.0, 1.0, 1.0, 1.0)); return(circle); }
private static void SetGradientStops(RadialGradient gradient, FocusEllipse ellipse, EllipseRadius maxBlurRadius, KernelGenerator kernelGenerator) { var stops = new List <GradientStop>(); double firstStopOffset; if (maxBlurRadius.X > minDiffBetweenStops) { firstStopOffset = ellipse.Radius.X / maxBlurRadius.X; //Add the focus area at the center of the ellipse. stops.Add(new GradientStop() { Color = Color.FromArgb(255, 0, 0, 0), Offset = 0 }); stops.Add(new GradientStop() { Color = Color.FromArgb(255, 0, 0, 0), Offset = firstStopOffset }); } else { firstStopOffset = minDiffBetweenStops; } double sumOfBandWidths = kernelGenerator.GetKernelBands().Select(band => band.Width).Sum(); var currentStopOffset = firstStopOffset + minDiffBetweenStops; var kernelBands = kernelGenerator.GetKernelBands(); byte kernelIndex = 0; foreach (var band in kernelBands) { kernelIndex++; stops.Add(new GradientStop() { Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset }); currentStopOffset = currentStopOffset + (band.Width / sumOfBandWidths) * (1 - firstStopOffset) * FocusToBlurTransitionWidth; } stops.Add(new GradientStop() { Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset }); var validStops = EnsureMinDiffBetweenPoints(stops); gradient.Stops = validStops.ToArray(); }
private string GetPosition(RadialGradient gradient) { var center = gradient.Center; var posX = FlagsHelper.IsSet(gradient.Flags, RadialGradientFlags.XProportional) ? $"{center.X * 100}%" : $"{center.X}px"; var posY = FlagsHelper.IsSet(gradient.Flags, RadialGradientFlags.YProportional) ? $"{center.Y * 100}%" : $"{center.Y}px"; return($"at {posX} {posY}"); }
private void AddBall(float x, float y) { var rnd = new Random(); var shapeHolder = CreateBall(x, y); var red = 100 + rnd.Next(155); var green = 100 + rnd.Next(155); var blue = 100 + rnd.Next(155); var color = new Color(red, green, blue); var darkColor = new Color(red / 4, green / 4, blue); var paint = shapeHolder.Shape.Paint; var gradient = new RadialGradient(37.5f, 12.5f, 50f, color, darkColor, Shader.TileMode.Clamp); paint.SetShader(gradient); balls.Add(shapeHolder); }
public void ParseCss_RadialGradients_CorrectlyParsed(string css, RadialGradient expected) { // Arrange var parser = new CssGradientParser(); // Act var gradients = parser.ParseCss(css); // Assert using (new AssertionScope()) { gradients.Should().HaveCount(1); gradients[0].Should().BeEquivalentTo(expected, options => options.IgnoringCyclicReferences()); } }
public LandscapeBackgroundDoF() { Name = "LandscapeBackgroundDoF"; var radialGradient = new RadialGradient(new Point(0.5, 0.3), new EllipseRadius(0.2, 0.4)) { Stops = new [] { new GradientStop() {Color = foreground, Offset = 0}, new GradientStop() {Color = foreground, Offset = 0.5}, new GradientStop() {Color = background, Offset = 0.51}, new GradientStop() {Color = background, Offset = 0.9} } }; m_scribbles = new GradientImageSource(new Size(500, 500), radialGradient); //Editors.Add(new EnumEditorViewModel<LandscapeBackgroundDoF, DepthOfFieldQuality>("Quality", this, (effect) => //{ // if (effect.m_effectEffect == null) return DepthOfFieldQuality.Preview; // return effect.m_effectEffect.Quality; //}, (effect, value) => //{ // if (effect.m_effectEffect == null) // return; // effect.m_effectEffect.Quality = value; //})); Editors.Add(new RangeEditorViewModelEx<LandscapeBackgroundDoF>("Strength above horizon", 0, 1.0, this, (effect) => { if (effect.m_effectEffect == null) return 1.0; return effect.m_effectEffect.StrengthAboveHorizon; }, (effect, value) => { if (effect.m_effectEffect == null) return; effect.m_effectEffect.StrengthAboveHorizon = value; })); Editors.Add(new RangeEditorViewModelEx<LandscapeBackgroundDoF>("Strength below horizon", 0, 1.0, this, (effect) => { if (effect.m_effectEffect == null) return 1.0; return effect.m_effectEffect.StrengthBelowHorizon; }, (effect, value) => { if (effect.m_effectEffect == null) return; effect.m_effectEffect.StrengthBelowHorizon = value; })); }
public void SaveRestoreRadialGradient() { // Pattern is saved InitBlank(); var g = new RadialGradient(20, 20, 5, 30, 30, 30); g.AddColorStop(0, Colors.Red); g.AddColorStop(0.5, Colors.Green); g.AddColorStop(1, Colors.Blue); context.Save(); context.Pattern = g; context.Restore(); context.Rectangle(5, 5, 40, 40); context.Fill(); CheckImage("SaveRestoreRadialGradient.png"); }
//--------------------------------------------------------------------- private static void Demo02() { Action <Surface> draw = surface => { using (var c = new Context(surface)) { c.Scale(500, 500); Gradient radpat = new RadialGradient(0.25, 0.25, 0.1, 0.5, 0.5, 0.5); radpat.AddColorStop(0, new Color(1.0, 0.8, 0.8)); radpat.AddColorStop(1, new Color(0.9, 0.0, 0.0)); for (int i = 1; i < 10; i++) { for (int j = 1; j < 10; j++) { c.Rectangle(i / 10d - 0.04, j / 10d - 0.04, 0.08, 0.08); } } c.Source = radpat; c.Fill(); Gradient linpat = new LinearGradient(0.25, 0.35, 0.75, 0.65); linpat.AddColorStop(0.00, new Color(1, 1, 1, 0)); linpat.AddColorStop(0.25, new Color(0, 1, 0, 0.5)); linpat.AddColorStop(0.50, new Color(1, 1, 1, 0)); linpat.AddColorStop(0.75, new Color(0, 0, 1, 0.5)); linpat.AddColorStop(1.00, new Color(1, 1, 1, 0)); c.Rectangle(0, 0, 1, 1); c.Source = linpat; c.Fill(); } }; using (Surface surface = new ImageSurface(Format.Argb32, 500, 500)) { draw(surface); surface.WriteToPng("demo02.png"); } using (Surface surface = new PdfSurface("demo02.pdf", 500, 500)) draw(surface); using (Surface surface = new SvgSurface("demo02.svg", 500, 500)) draw(surface); }
protected internal override Shader GetShader(Rect destinationRect) { var center = Center; var radiusX = RadiusX; var radiusY = RadiusY; float radius; if (MappingMode == BrushMappingMode.RelativeToBoundingBox) { var size = destinationRect.Size; center = new Point(center.X * size.Width, Center.Y * size.Height); radius = (float)(radiusX * size.Width + radiusY * size.Height) / 2.0f; // We take the avg } else { center = center.LogicalToPhysicalPixels(); radius = ViewHelper.LogicalToPhysicalPixels((radiusX + radiusY) / 2.0d); // We take the avg } // Android requires a radius and two or more stop points. if (radius <= 0 || GradientStops.Count < 2) { return(null); } var colors = GradientStops.SelectToArray(s => ((Android.Graphics.Color)GetColorWithOpacity(s.Color)).ToArgb()); var locations = GradientStops.SelectToArray(s => (float)s.Offset); var width = destinationRect.Width; var height = destinationRect.Height; var transform = RelativeTransform?.ToNativeMatrix(size: new Windows.Foundation.Size(width, height)); var shader = new RadialGradient( (float)center.X, (float)center.Y, radius, colors, locations, Shader.TileMode.Clamp); return(shader); }
private static XElementBuilder BuildRadialGradient(RadialGradient gradient) { return(XElementBuilder.WithName("radialGradient").Add( //TODO: incorporate, fx, fy to affect the focal point( intriguing ) new XAttribute("cx", "50%"), new XAttribute("cy", "50%")) .Add( new XElement("stop", new XAttribute("stop-color", SvgColor(gradient.CenterColor)), new XAttribute("stop-opacity", SvgOpacity(gradient.CenterColor)), new XAttribute("offset", "0%") ), new XElement("stop", new XAttribute("stop-color", SvgColor(gradient.EdgeColor)), new XAttribute("stop-opacity", SvgOpacity(gradient.EdgeColor)), new XAttribute("offset", "100%") ))); }
//--------------------------------------------------------------------- private static void Gradient() { Action <Surface> draw = surface => { using (var c = new Context(surface)) { Gradient pat = new LinearGradient(0.0, 0.0, 0.0, 256.0); pat.AddColorStopRgba(1, 0, 0, 0, 1); pat.AddColorStopRgba(0, 1, 1, 1, 1); c.Rectangle(0, 0, 256, 256); c.SetSource(pat); c.Fill(); pat.Dispose(); pat = new RadialGradient(115.2, 102.4, 25.6, 102.4, 102.4, 128.0); pat.AddColorStopRgba(0, 1, 1, 1, 1); pat.AddColorStopRgba(1, 0, 0, 0, 1); c.SetSource(pat); c.Arc(128.0, 128.0, 76.8, 0, 2 * Math.PI); c.Fill(); pat.Dispose(); } }; using (Surface surface = new ImageSurface(Format.Argb32, 500, 500)) { draw(surface); surface.WriteToPng("gradient.png"); } using (Surface surface = new PdfSurface("gradient.pdf", 500, 500)) { draw(surface); surface.WriteToPng("gradient1.png"); } using (Surface surface = new SvgSurface("gradient.svg", 500, 500)) { draw(surface); surface.WriteToPng("gradient2.png"); } }
private void LoadMapValues() { heightMap = Noise.GenerateNoise(mapValues.width, mapValues.height, mapValues.seed, mapValues.offsetX, mapValues.offsetY, mapValues.scale, mapValues.octaves, mapValues.persistance, mapValues.lacunarity); Vector2 center = new Vector2(mapValues.width * 0.5f, mapValues.height * 0.5f); gradientMap = RadialGradient.GenerateGradient(mapValues.width, mapValues.height, mapValues.gradientThreshold, center, mapValues.gradientIntensityPoint, mapValues.gradientIntensity); for (int x = 0; x < mapValues.width; ++x) { for (int y = 0; y < mapValues.height; ++y) { float xPos = x; float yPos = y; tilemapPositionValues.Add(new Vector2(xPos, yPos), Mathf.Clamp01(heightMap[x, y] + gradientMap[x, y])); } } }
Fill GetRadialCircleFill() { //Create a radial gradient paint with // + Center point and Focal point is at the center of viewing region // + Radius X = Radius Y RadialGradient paint = new RadialGradient(); paint.CenterX = w / 2; paint.CenterY = h / 2; paint.FocusX = w / 2; paint.FocusY = h / 2; paint.Radius = Math.Min(w, h) / 3; paint.Style = gradientStyle; paint.Ramp = GetColorRamp(); //create fill and return result Fill result = new Fill(paint); return(result); }
public void gradient(Context cr, int width, int height) { Normalize(cr, width, height); LinearGradient lg = new LinearGradient(0.0, 0.0, 0.0, 1.0); lg.AddColorStop(1, new Color(0, 0, 0, 1)); lg.AddColorStop(0, new Color(1, 1, 1, 1)); cr.Rectangle(0, 0, 1, 1); cr.Source = lg; cr.Fill(); RadialGradient rg = new RadialGradient(0.45, 0.4, 0.1, 0.4, 0.4, 0.5); rg.AddColorStop(0, new Color(1, 1, 1, 1)); rg.AddColorStop(1, new Color(0, 0, 0, 1)); cr.Source = rg; cr.Arc(0.5, 0.5, 0.3, 0, 2 * Math.PI); cr.Fill(); }
void DrawLed(int index, Context cr) { PointD led = new PointD(); led.X = imageX + CurrentDefinition.Leds[index].X / scale; led.Y = imageY + CurrentDefinition.Leds[index].Y / scale; double glowRadius = LedSize * 2 / scale; RadialGradient gradient = new RadialGradient(led.X, led.Y, 0, led.X, led.Y, glowRadius); gradient.AddColorStop(0, new Cairo.Color(ColorBuffer[index].Red, ColorBuffer[index].Green, ColorBuffer[index].Blue, ColorBuffer[index].Alpha)); gradient.AddColorStop(0.15, new Cairo.Color(ColorBuffer[index].Red, ColorBuffer[index].Green, ColorBuffer[index].Blue, ColorBuffer[index].Alpha)); gradient.AddColorStop(1, new Cairo.Color(ColorBuffer[index].Red, ColorBuffer[index].Green, ColorBuffer[index].Blue, 0)); cr.Save(); cr.Rectangle(led.X - glowRadius, led.Y - glowRadius, glowRadius * 2, glowRadius * 2); cr.Clip(); cr.SetSource(gradient); cr.Mask(gradient); cr.Restore(); gradient.Dispose(); }
public override void ApplyBrushToContext(GraphicsContext g) { using (ImageSurface surface = ((ImageSurface)g.GetTarget())) { double actualWidth = surface.Width; double actualHeight = surface.Height; double maximumRadius = actualWidth > actualHeight ? actualWidth : actualHeight; using (RadialGradient lg = new RadialGradient(CX0 * actualWidth, CY0 * actualHeight, Radius0 * maximumRadius, CX1 * actualWidth, CY1 * actualHeight, Radius1 * maximumRadius)) { if (GradientStops != null) { foreach (GradientStop gs in GradientStops) { lg.AddColorStop(gs.Offset, gs.Color); } } g.SetSource(lg); } } }
private Texture2D GenerateTexture() { Texture2D mask = new Texture2D(texWidth, texHeight); Vector2 center = new Vector2(texWidth * 0.5f, texHeight * 0.5f); float[,] gradient = RadialGradient.GenerateGradient(texWidth, texHeight, mapValues.gradientThreshold, center, mapValues.gradientIntensityPoint, mapValues.gradientIntensity); for (int y = 0; y < texWidth; ++y) { for (int x = 0; x < texHeight; ++x) { Color color = new Color(gradient[x, y], gradient[x, y], gradient[x, y], 1); mask.SetPixel(x, y, color); } } mask.Apply(); return(mask); }
private void GenerateMap() { heightMap = Noise.GenerateNoise(mapValues.width, mapValues.height, mapValues.seed, heightMapValues.offsetX, heightMapValues.offsetY, mapValues.scale, heightMapValues.octaves, heightMapValues.persistance, heightMapValues.lacunarity); Vector2 center = new Vector2(mapValues.width * 0.5f, mapValues.height * 0.5f); float[,] gradientMap = RadialGradient.GenerateGradient(mapValues.width, mapValues.height, gradientMapValues.gradientThreshold, center, gradientMapValues.gradientIntensityPoint, gradientMapValues.gradientIntensity); for (int x = 0; x < mapValues.width; ++x) { for (int y = 0; y < mapValues.height; ++y) { BiomePreset biome = GetBiome(Mathf.Clamp01(heightMap[x, y] + gradientMap[x, y])); tilemap.SetTile(new Vector3Int(x, y, 0), biome.PickRandomTile()); //tilemap.SetTile(new Vector3Int(x, y, 0), SpawnFoliage(biome)); } } }
public void Parse_ValidGradientCss_ExpectedGradientReturned(string css, RadialGradient expectedGradient) { // Arrange var reader = new CssReader(css); var builder = new GradientBuilder(); var definition = new RadialGradientDefinition(); // Act definition.Parse(reader, builder); // Assert var result = builder.Build(); using (new AssertionScope()) { result.Should().HaveCount(1); var gradient = result[0] as RadialGradient; gradient.Should().NotBeNull(); gradient.Should().BeEquivalentTo(expectedGradient); } }
public void DrawEllipse(Ellipse ellipse, float ringWidth, int slices = 64) { float innerRadiusRatio = 1 - (ringWidth / ellipse.RadiusX); float[] offsets; var solidColor = Color as SolidColor; if (solidColor != null) { Color = RadialGradient.New(Color.Name, new[] { new GradientStop(SharpDX.Mathematics.Color.Transparent, 0), new GradientStop(solidColor.Color, innerRadiusRatio), new GradientStop(solidColor.Color, 1) }); } EllipseColorShader shader = ChooseEllipseOutlineShader(innerRadiusRatio, Color, out offsets); Color4[] colors = shader(ellipse, Color, offsets.Length * slices, slices); int[] indices; Vector3[] vertices = EllipseMesh.CreateRingMesh(ellipse, offsets, slices, Transform, out indices); var vertexArray = new VertexPositionColor[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { vertexArray[i] = new VertexPositionColor() { Position = vertices[i], Color = colors[i] } } ; shapes.Add(new ShapeMeshDescription() { Vertices = vertexArray, Indices = indices }); }
Fill GetRadialFocalFill() { //Create a radial gradient paint with // + Center point is at the center of viewing region // + Different radius X, radius Y // + Focal point is near the top-left of viewing region RadialGradient paint = new RadialGradient(); paint.CenterX = w / 2; paint.CenterY = h / 2; paint.FocusX = w / 4; paint.FocusY = h / 2.5; paint.RadiusX = w / 3; paint.RadiusY = h / 3; paint.Style = gradientStyle; paint.Ramp = GetColorRamp(); //create fill and return result Fill result = new Fill(paint); return(result); }
protected override void OnBoundsChange(Rect bounds) { base.OnBoundsChange(bounds); mRect.Set(margin, margin, bounds.Width() - margin, bounds.Height() - margin); if (useGradientOverlay) { var colors = new int[] { 0, 0, 0x7f000000 }; var pos = new float[] { 0.0f, 0.7f, 1.0f }; RadialGradient vignette = new RadialGradient(mRect.CenterX(), mRect.CenterY() * 1.0f / 0.7f, mRect.CenterX() * 1.3f, colors, pos, Shader.TileMode.Clamp); Matrix oval = new Matrix(); oval.SetScale(1.0f, 0.7f); vignette.SetLocalMatrix(oval); paint.SetShader(new ComposeShader(bitmapShader, vignette, PorterDuff.Mode.SrcOver)); } }
public UGRadialGradientBrush(IUGContext context, Vector2 center, float radius, IEnumerable <UGGradientStop> gradientStops, UGEdgeBehavior edgeBehavior) { Center = center; Radius = radius; EdgeBehavior = edgeBehavior; Stops = gradientStops.ToArray(); if (Stops.Length < 2) { throw new ArgumentException(nameof(gradientStops)); } var colors = gradientStops.Select(s => s.Color.ColorAsInt).ToArray(); var offsets = gradientStops.Select(s => s.Offset).ToArray(); _native = new RadialGradient( Center.X, Center.Y, Radius, colors, offsets, edgeBehavior.ToAGShaderTileMode()); }
private static void SetGradientStops(RadialGradient gradient, FocusEllipse ellipse, EllipseRadius maxBlurRadius, KernelGenerator kernelGenerator) { var stops = new List<GradientStop>(); double firstStopOffset; if (maxBlurRadius.X > minDiffBetweenStops) { firstStopOffset = ellipse.Radius.X / maxBlurRadius.X; //Add the focus area at the center of the ellipse. stops.Add(new GradientStop() { Color = Color.FromArgb(255, 0, 0, 0), Offset = 0 }); stops.Add(new GradientStop() { Color = Color.FromArgb(255, 0, 0, 0), Offset = firstStopOffset }); } else { firstStopOffset = minDiffBetweenStops; } double sumOfBandWidths = kernelGenerator.GetKernelBands().Select(band => band.Width).Sum(); var currentStopOffset = firstStopOffset + minDiffBetweenStops; var kernelBands = kernelGenerator.GetKernelBands(); byte kernelIndex = 0; foreach (var band in kernelBands) { kernelIndex++; stops.Add(new GradientStop() { Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset }); currentStopOffset = currentStopOffset + (band.Width / sumOfBandWidths) * (1 - firstStopOffset) * FocusToBlurTransitionWidth; } stops.Add(new GradientStop() { Color = Color.FromArgb(255, kernelIndex, kernelIndex, kernelIndex), Offset = currentStopOffset }); var validStops = EnsureMinDiffBetweenPoints(stops); gradient.Stops = validStops.ToArray(); }
public static Task<List<IImageProcessor>> CreateEffects() { // This seems to take 150-200 ms minimum, so better do it on the thread pool. return Task.Run(async () => { var imageProcessors = new List<IImageProcessor>(); EffectProcessor effectViewModel = null; var source = await PreloadedImages.Man; imageProcessors.Add(new EffectProcessor("Antique", new AntiqueEffect())); imageProcessors.Add(new EffectProcessor("Auto Enhance", new AutoEnhanceEffect())); imageProcessors.Add(new EffectProcessor("Auto Levels", new AutoLevelsEffect())); imageProcessors.Add(new BlendEffectProcessor()); imageProcessors.Add(new EffectProcessor("Blur", new BlurEffect())); imageProcessors.Add(new EffectProcessor("Brightness Effect", new BrightnessEffect())); imageProcessors.Add(new EffectProcessor("Cartoon", new CartoonEffect())); imageProcessors.Add(new EffectProcessor("ChromaKey", new ChromaKeyEffect())); imageProcessors.Add(new EffectProcessor("ColorAdjust", new ColorAdjustEffect())); imageProcessors.Add(new EffectProcessor("ColorBoost", new ColorBoostEffect(1.0))); imageProcessors.Add(new EffectProcessor("Colorization", new ColorizationEffect())); imageProcessors.Add(new EffectProcessor("Color Swap", new ColorSwapEffect(Windows.UI.Color.FromArgb(255, 255, 0, 0), Windows.UI.Color.FromArgb(255, 0, 255, 0), 0.8, false, true))); imageProcessors.Add(new EffectProcessor("Contrast", new ContrastEffect(0.5))); imageProcessors.Add(new CropEffectProcessor()); imageProcessors.Add(new CurveProcessor()); imageProcessors.Add(new EffectProcessor("Despeckle", new DespeckleEffect(DespeckleLevel.Low))); imageProcessors.Add(new EffectProcessor("Emboss", new EmbossEffect(0.5))); imageProcessors.Add(new EffectProcessor("Exposure", new ExposureEffect(ExposureMode.Natural, 0.5))); imageProcessors.Add(new EffectProcessor("Flip", new FlipEffect(FlipMode.Both))); imageProcessors.Add(new EffectProcessor("Fog", new FogEffect())); imageProcessors.Add(new EffectProcessor("Foundation", new FoundationEffect())); imageProcessors.Add(new EffectProcessor("GaussianNoise", new GaussianNoiseEffect(1.0))); var gradient = new RadialGradient(new Point(0.5, 0.5), new EllipseRadius(0.5, 0.5)); gradient.Stops = new[] { new GradientStop{Offset=0.0, Color=Colors.Red}, new GradientStop{Offset=1.0, Color=Colors.Cyan} }; var gradientImageSource = new GradientImageSource(new Size(800, 500), gradient); imageProcessors.Add(new EffectProcessor("Grayscale", new GrayscaleEffect())); imageProcessors.Add(new EffectProcessor("Grayscale Negative", new GrayscaleNegativeEffect())); imageProcessors.Add(new HSLProcessor()); imageProcessors.Add(new EffectProcessor("HdrEffect", new HdrEffect())); imageProcessors.Add(new EffectProcessor("HueSaturationEffect", new HueSaturationEffect())); effectViewModel = new EffectProcessor("Levels", new LevelsEffect(), true, true); { RangeEditorViewModelEx<LevelsEffect> blackEditor = null; RangeEditorViewModelEx<LevelsEffect> grayEditor = null; RangeEditorViewModelEx<LevelsEffect> whiteEditor = null; blackEditor = new RangeEditorViewModelEx<LevelsEffect>( "Black", 0.0, 1.0, effectViewModel, effect => effect.Black, (effect, value) => { effect.Black = value; if (grayEditor.Value < value) grayEditor.Value = value; if (whiteEditor.Value < value) whiteEditor.Value = value; }); grayEditor = new RangeEditorViewModelEx<LevelsEffect>( "Gray", 0.0, 1.0, effectViewModel, effect => effect.Gray, (effect, value) => { effect.Gray = value; if (blackEditor.Value > value) blackEditor.Value = value; if (whiteEditor.Value < value) whiteEditor.Value = value; }); whiteEditor = new RangeEditorViewModelEx<LevelsEffect>( "White", 0.0, 1.0, effectViewModel, effect => effect.White, (effect, value) => { effect.White = value; if (blackEditor.Value > value) blackEditor.Value = value; if (grayEditor.Value > value) grayEditor.Value = value; }); effectViewModel.Editors.Add(blackEditor); effectViewModel.Editors.Add(grayEditor); effectViewModel.Editors.Add(whiteEditor); } imageProcessors.Add(effectViewModel); imageProcessors.Add(new LinearGradientImageSourceEffectProcessor()); imageProcessors.Add(new EffectProcessor("Local Boost Automatic", new LocalBoostAutomaticEffect(8))); imageProcessors.Add(new EffectProcessor("LocalBoost", new LocalBoostEffect())); imageProcessors.Add(new EffectProcessor("Lomo", new LomoEffect())); imageProcessors.Add(new EffectProcessor("Magic Pen", new MagicPenEffect())); imageProcessors.Add(new EffectProcessor("Milky", new MilkyEffect())); imageProcessors.Add(new EffectProcessor("Mirror", new MirrorEffect())); imageProcessors.Add(new EffectProcessor("Mono Color", new MonoColorEffect(Windows.UI.Color.FromArgb(255, 255, 0, 0), 0.8))); imageProcessors.Add(new EffectProcessor("Moonlight", new MoonlightEffect(21))); imageProcessors.Add(new EffectProcessor("Negative", new NegativeEffect())); imageProcessors.Add(new EffectProcessor("Noise", new NoiseEffect(NoiseLevel.Maximum))); imageProcessors.Add(new EffectProcessor("Oily", new OilyEffect(OilBrushSize.Medium))); imageProcessors.Add(new EffectProcessor("Paint", new PaintEffect(4))); imageProcessors.Add(new EffectProcessor("Posterize", new PosterizeEffect(10))); imageProcessors.Add(new RadialGradientImageSourceEffectProcessor()); imageProcessors.Add(new ReframingEffectProcessor()); imageProcessors.Add(new EffectProcessor("Rotation", new RotationEffect())); imageProcessors.Add(new RgbLevelsEffectProcessor()); imageProcessors.Add(new RgbMixerEffectProcessor()); imageProcessors.Add(new SaturationLightnessProcessor()); imageProcessors.Add(new EffectProcessor("Sharpness", new SharpnessEffect(0.2))); imageProcessors.Add(new EffectProcessor("Sepia", new SepiaEffect())); imageProcessors.Add(new EffectProcessor("Sketch", new Lumia.Imaging.Artistic.SketchEffect(SketchMode.Color))); imageProcessors.Add(new EffectProcessor("Solarize", new SolarizeEffect(0.8))); imageProcessors.Add(new SplitToneEffectProcessor()); imageProcessors.Add(new SpotlightEffectProcessor()); imageProcessors.Add(new EffectProcessor("Stamp", new StampEffect(5, 200.0 / 255.0))); imageProcessors.Add(new EffectProcessor("Temperature and Tint", new TemperatureAndTintEffect(50.0 / 255.0, 50.0 / 255.0))); imageProcessors.Add(new EffectProcessor("Vibrance", new VibranceEffect())); imageProcessors.Add(new EffectProcessor("Vignetting", new VignettingEffect(0.8, Windows.UI.Color.FromArgb(255, 255, 0, 0)))); imageProcessors.Add(new EffectProcessor("Watercolor", new WatercolorEffect(0.8, 0.8))); imageProcessors.Add(new EffectProcessor("Warping", new WarpingEffect(WarpMode.Twister, 0.8))); imageProcessors.Add(new EffectProcessor("White Balance", new WhiteBalanceEffect(WhitePointCalculationMode.Maximum, Color.FromArgb(1,219,213,199)))); imageProcessors.Add(new EffectProcessor("Whiteboard Enhancement", new WhiteboardEnhancementEffect(WhiteboardEnhancementMode.Hard), canRenderAtPreviewSize: false)); //GlamMe effects imageProcessors.Add(new BWEffect()); imageProcessors.Add(new ElegantEffect()); imageProcessors.Add(new RetroEffect()); imageProcessors.Add(new VintageEffect()); imageProcessors.Add(new MintEffect()); imageProcessors.Add(new OldPosterEffect()); imageProcessors.Add(new LensBlureSampleEffect()); imageProcessors.Add(new GlamMeLomoEffect()); imageProcessors.Add(new FreshEffect()); imageProcessors.Add(new LightEffect()); // Creative Studio Effects imageProcessors.Add(new BWloEffect()); imageProcessors.Add(new IndoorEffect()); imageProcessors.Add(new SunsetEffect()); imageProcessors.Add(new BWHiEffect()); imageProcessors.Add(new BWCopperEffect()); imageProcessors.Add(new LoSatWarmEffect()); // imageProcessors.Add(new BlockTiltDoF()); // imageProcessors.Add(new EllipseTiltDoF()); // imageProcessors.Add(new LandscapeBackgroundDoF()); // imageProcessors.Add(new LensBlurProcessor()); // Special command editor return imageProcessors; }); }
private void Initialize() { _cameraPreviewImageSource = new CameraPreviewImageSource(_photoCaptureDevice); if (_blendImageUri != null) { _blendImageProvider = new StreamImageSource((System.Windows.Application.GetResourceStream(_blendImageUri).Stream)); } else { var colorStops = new GradientStop[] { new GradientStop { Color = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00), Offset = 0.0 }, new GradientStop { Color = Color.FromArgb(0xFF, 0x00, 0xFF, 0x00), Offset = 0.7 }, new GradientStop { Color = Color.FromArgb(0xFF, 0x00, 0x00, 0xFF), Offset = 1.0 } }; var gradient = new RadialGradient(new Point(0, 0), new EllipseRadius(1, 0), colorStops); var size = new Size(640, 480); _blendImageProvider = new GradientImageSource(size, gradient); } var nameFormat = "{0}/" + EffectCount + " - {1}"; switch (_effectIndex) { case 0: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_None); } break; case 1: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Normal); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Normal, GlobalAlpha); } break; case 2: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Multiply); _blendEffect = new BlendEffect(_cameraPreviewImageSource, _blendImageProvider, BlendFunction.Multiply, GlobalAlpha); } break; case 3: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Add); _blendEffect = new BlendEffect(_cameraPreviewImageSource, _blendImageProvider, BlendFunction.Add, GlobalAlpha); } break; case 4: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Color); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Color, GlobalAlpha); } break; case 5: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Colorburn); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Colorburn, GlobalAlpha); } break; case 6: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Colordodge); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Colordodge, GlobalAlpha); } break; case 7: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Overlay); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Overlay, GlobalAlpha); } break; case 8: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Softlight); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Softlight, GlobalAlpha); } break; case 9: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Screen); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Screen, GlobalAlpha); } break; case 10: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Hardlight); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Hardlight, GlobalAlpha); } break; case 11: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Darken); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Darken, GlobalAlpha); } break; case 12: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Lighten); _blendEffect = new BlendEffect(_cameraPreviewImageSource, _blendImageProvider, BlendFunction.Lighten, GlobalAlpha); } break; case 13: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Hue); _blendEffect = new BlendEffect(_cameraPreviewImageSource, _blendImageProvider, BlendFunction.Hue, GlobalAlpha); } break; case 14: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Exclusion); _blendEffect = new BlendEffect(_cameraPreviewImageSource, _blendImageProvider, BlendFunction.Exclusion, GlobalAlpha); } break; case 15: { EffectName = String.Format(nameFormat, _effectIndex + 1, AppResources.Filter_Blend_Difference); _blendEffect = new BlendEffect(_cameraPreviewImageSource,_blendImageProvider, BlendFunction.Difference, GlobalAlpha); } break; } if (_blendEffect != null) { _blendEffect.TargetArea = _targetArea; _blendEffect.TargetAreaRotation = _targetAreaRotation; } }
public VioletEffect() { var globalCurve = new Curve { Points = new[] { new Point(0,0), new Point(41, 59), new Point(112, 146), new Point(189, 211), new Point(255, 255), } }; var redCurve = new Curve { Points = new[] { new Point(0, 0), new Point(255, 255) } }; var greenCurve = new Curve { Points = new[] { new Point(0, 0), new Point(255, 255) } }; var blueCurve = new Curve { Points = new[] { new Point(0, 0), new Point(57, 53), new Point(166, 160), new Point(255, 255) } }; Curve.Compose(redCurve, globalCurve, redCurve); Curve.Compose(greenCurve, globalCurve, greenCurve); Curve.Compose(blueCurve, globalCurve, blueCurve); var gradient = new RadialGradient { CenterPoint = new Point(0.5, 0.5), EllipseRadius = new EllipseRadius(1.0, 0), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(255, 156, 62, 68)}, new GradientStop {Offset = 1.0, Color = Color.FromArgb(255, 95, 1, 75)}, } }; LayerList = new LayerList() { new AdjustmentLayer(LayerStyle.Normal(), new CurvesEffect(redCurve, greenCurve, blueCurve)), new AdjustmentLayer(LayerStyle.Normal(), new ContrastEffect(0.5)), // .AdjustmentLayer(LayerStyle.Normal(), new ExposureEffect(ExposureMode.Natural, -0.2)), new AdjustmentLayer(LayerStyle.Normal(), new VibranceEffect() { Level = 0.3 }), new Layer(LayerStyle.Screen(), context => new GradientImageSource(context.BackgroundLayer.ImageSize, gradient)) }; }
public RetroEffect() { var globalCurve = new Curve { Points = new[] { new Point(0, 0), new Point(41, 59), new Point(112, 146), new Point(189, 211), new Point(255, 255) } }; var redCurve = new Curve(CurveInterpolation.NaturalCubicSpline, new[] { new Point(0, 0), new Point(75, 61), new Point(255, 255) }); Curve.Compose(redCurve, globalCurve, redCurve); var greenCurve = new Curve(CurveInterpolation.NaturalCubicSpline, new[] { new Point(0, 0), new Point(59, 34), new Point(182, 199), new Point(255, 255) }); Curve.Compose(greenCurve, globalCurve, greenCurve); var blueCurve = new Curve(CurveInterpolation.NaturalCubicSpline, new[] { new Point(0, 91), new Point(128, 128), new Point(255, 185) }); Curve.Compose(blueCurve, globalCurve, blueCurve); var yellowPurpleGradient = new LinearGradient { StartPoint = new Point(0.0, 0.5), EndPoint = new Point(1.0, 0.5), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(255, 255, 255, 0)}, new GradientStop {Offset = 0.5, Color = Color.FromArgb(255, 148, 106, 77)}, new GradientStop {Offset = 1.0, Color = Color.FromArgb(255, 72, 3, 131)} } }; var redTransparentGradient = new LinearGradient { StartPoint = new Point(0.0, 0.5), EndPoint = new Point(1.0, 0.5), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(255, 255, 0, 0)}, new GradientStop {Offset = 1.0, Color = Color.FromArgb(0, 255, 0, 0)} } }; var spotGradient = new RadialGradient { CenterPoint = new Point(0.5, 0.3), EllipseRadius = new EllipseRadius(0, 0.2), Stops = new[] { new GradientStop {Offset = 0.0, Color = Color.FromArgb(255, 255, 255, 255)}, new GradientStop {Offset = 1.0, Color = Color.FromArgb(0, 255, 255, 255)} } }; var vignetteGradient = new RadialGradient { CenterPoint = new Point(0.5, 0.5), EllipseRadius = new EllipseRadius(1.0, 0), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(255, 255, 255, 255)}, new GradientStop {Offset = 0.9, Color = Color.FromArgb(255, 0, 0, 0)} } }; LayerList = new LayerList() { new AdjustmentLayer(LayerStyle.Normal(), new CurvesEffect(redCurve, greenCurve, blueCurve)), new Layer(LayerStyle.Softlight(0.3), context => new GradientImageSource(context.BackgroundLayer.ImageSize, yellowPurpleGradient)), new Layer(LayerStyle.Screen(0.75, targetArea: new Rect(0, 0, 0.4, 1.0)), context => new GradientImageSource(new Size(context.BackgroundLayer.ImageSize.Width * 0.4, context.BackgroundLayer.ImageSize.Height), redTransparentGradient)), new Layer(LayerStyle.Softlight(), context => new GradientImageSource(context.BackgroundLayer.ImageSize, spotGradient)), new Layer(LayerStyle.Softlight(0.6), context => new GradientImageSource(context.BackgroundLayer.ImageSize, vignetteGradient)) }; }
/// <summary> /// Filling using radial gradient for circle gradient only /// </summary> /// <param name="radial">radial</param> /// <param name="rows">rows</param> /// <param name="startRowIndex">start y index</param> /// <param name="endRowIndex">end y index</param> void FillingEllipseFocalEvenOdd(RadialGradient radial, uint opacity, RowData[] rows, int startRowIndex, int endRowIndex) { // now not need to check null or not uint[] builtColors = radial.GetLinearColors(opacity); #region private variable for filling int currentCoverage, scLastCoverage, scLastX = 0; int tempCover = 0; int currentArea = 0; int lastXPosition = 0; int startXPosition = 0; byte calculatedCoverage = 0; double centerX = radial.CenterX; double centerY = radial.CenterY; // in this case radius x = radius y double radius = radial.RadiusX; double radiusYForX = radial.RadiusY / radial.RadiusX; // this is precompute value so that (* ColorIndexScale / radius) now just ( * preComputeRadiusLookup ) double preComputeRadiusLookup = ColorIndexScale / radius; CellData currentCellData = null; uint colorData = 0; double dx = 0, dy = 0; double dySquared = 0; // saving dy * dy // focus is changed to relative from the center double absoluteFocusX = radial.FocusX; double absoluteFocusY = radial.FocusY; double focusX = radial.FocusX - centerX; double focusY = radial.FocusY - centerY; focusY = focusY / radiusYForX; // note that dx,dy need to move center /* * dx = (currentXPosition - absoluteFocusX); * dy = (startRowIndex - absoluteFocusY); * currentColorIndexValue = (int) ( ( ( (dx * focusX) + (dy * focusY) + Math.Sqrt ( Math.Abs ( radius * radius * (dx * dx + dy * dy) - (dx * focusY - dy * focusX) * (dx * focusY - dy * focusX) ) ) ) * (radius / ((radius * radius) - ((focusX * focusX )+ (focusY * focusY)))) ) * 256 /radius ); */ //note that ( radius / (( radius * radius) - ((focusX * focusX) + (focusY * focusY))) is const // so that need to pre compute double preComputeMultiply = radius / ((radius * radius) - ((focusX * focusX) + (focusY * focusY))); #region modify when pre compute for multiply is zero if (preComputeMultiply == 0) { if (focusX != 0) { if (focusX < 0) { focusX += GradientAdjustment; } else { focusX -= GradientAdjustment; } } if (focusY != 0) { if (focusY < 0) { focusY += GradientAdjustment; } else { focusY -= GradientAdjustment; } } preComputeMultiply = radius / ((radius * radius) - ((focusX * focusX) + (focusY * focusY))); } #endregion double preComputeMultiplyIncludeLookup = preComputeRadiusLookup * preComputeMultiply; // saving dy * focusY double dyFocusY = 0; double dyFocusX = 0; double dxFocusYIncrement = 0; // saving dx * focusY - dyFocusX double radiusSquared = radius * radius; int currentColorIndexValue = 0; //int currentXPosition = 0; uint dst, dstRB, dstG; #endregion #region FILLING if (radial.Ramp.NoBlendingColor) { // when no need to blending, when draw a horizontal line // do not need check the back color, alway setup if (radial.Style != GradientStyle.Pad) { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; #region cumpute value for row //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY); dy = ((startRowIndex - centerY) / radiusYForX) - focusY; dySquared = dy * dy; dyFocusX = dy * focusX; dyFocusY = dy * focusY; #endregion if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region prepare for row color index calculation // get current color index value //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex; //currentXPosition = scLastX + 1; dx = (scLastX + 1 - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion if (scLastCoverage >= 255) { while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); //currentColorIndexValue = // (int) // ( // ( // ( // (dx * focusX) + (dy * focusY) // + Math.Sqrt // ( // Math.Abs // ( // radius * radius // * (dx * dx + dy * dy) // - (dx * focusY - dy * focusX) // * (dx * focusY - dy * focusX) // ) // ) // ) * (radius / // ((radius * radius) - ((focusX * focusX) + (focusY * focusY)))) // ) * 256 / radius // ); // change for color index calculation dx++; dxFocusYIncrement += focusY; #endregion BufferData[startXPosition] = builtColors[currentColorIndexValue & ColorIndexDoubleMask]; startXPosition++; } } else { calculatedCoverage = (byte)scLastCoverage; while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); // change for color index calculation dx++; dxFocusYIncrement += focusY; #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask]; //calculatedCoverage = (byte)((colorData >> 24)); //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { // blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); } startXPosition++; } } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region calculate color index //currentXPosition = currentCellData.X; //currentColorIndexValue = // (int)(Math.Sqrt(dyFocusY + // (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #region prepare for row color index calculation // get current color index value dx = (currentCellData.X - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); #endregion #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex]; //calculatedCoverage = (byte)(colorData >> 24); #region blend pixel //tempCover = (int)((tempCover * calculatedCoverage) >> 8); if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } else { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; #region cumpute value for row //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY); dy = ((startRowIndex - centerY) / radiusYForX) - focusY; dySquared = dy * dy; dyFocusX = dy * focusX; dyFocusY = dy * focusY; #endregion if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region prepare for row color index calculation // get current color index value dx = (scLastX + 1 - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion if (scLastCoverage >= 255) { while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); // change for color index calculation dx++; dxFocusYIncrement += focusY; #endregion BufferData[startXPosition] = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; startXPosition++; } } else { calculatedCoverage = (byte)(scLastCoverage); while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); // change for color index calculation dx++; dxFocusYIncrement += focusY; #endregion colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; //calculatedCoverage = (byte)((colorData >> 24)); //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { // blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); } startXPosition++; } } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region calculate color index #region prepare for row color index calculation // get current color index value dx = (currentCellData.X - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); #endregion #endregion colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; //calculatedCoverage = (byte)(colorData >> 24); #region blend pixel //tempCover = (int)((tempCover * calculatedCoverage) >> 8); if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } } else { // when no need to blending, when draw a horizontal line // do not need check the back color, alway setup if (radial.Style != GradientStyle.Pad) { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; #region cumpute value for row //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY); dy = ((startRowIndex - centerY) / radiusYForX) - focusY; dySquared = dy * dy; dyFocusX = dy * focusX; dyFocusY = dy * focusY; #endregion if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region prepare for row color index calculation // get current color index value dx = (scLastX + 1 - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); // change for color index calculation dx++; dxFocusYIncrement += focusY; #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask]; calculatedCoverage = (byte)((colorData >> 24)); calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { // blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); } startXPosition++; } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region prepare for row color index calculation // get current color index value dx = (currentCellData.X - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex]; calculatedCoverage = (byte)(colorData >> 24); #region blend pixel tempCover = (int)((tempCover * calculatedCoverage) >> 8); //if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } else { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; #region cumpute value for row //dyFocusY = (startRowIndex - centerY) * (startRowIndex - centerY); dy = ((startRowIndex - centerY) / radiusYForX) - focusY; dySquared = dy * dy; dyFocusX = dy * focusX; dyFocusY = dy * focusY; #endregion if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region prepare for row color index calculation // get current color index value dx = (scLastX + 1 - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); // change for color index calculation dx++; dxFocusYIncrement += focusY; #endregion colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; calculatedCoverage = (byte)((colorData >> 24)); calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { // blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); } startXPosition++; } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region prepare for row color index calculation // get current color index value dx = (currentCellData.X - absoluteFocusX); dxFocusYIncrement = (dx * focusY - dyFocusX); #endregion #region calculate color index currentColorIndexValue = (int) ((((dx * focusX) + dyFocusY + Math.Sqrt(Math.Abs( radiusSquared * (dx * dx + dySquared) - dxFocusYIncrement * dxFocusYIncrement)) ) * preComputeMultiplyIncludeLookup) ); #endregion colorData = builtColors[currentColorIndexValue < 0 ? 0 : currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; calculatedCoverage = (byte)(colorData >> 24); #region blend pixel tempCover = (int)((tempCover * calculatedCoverage) >> 8); //if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here dst = BufferData[startXPosition]; dstRB = dst & 0x00FF00FF; dstG = (dst >> 8) & 0xFF; BufferData[startXPosition] = (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } } #endregion }
/// <summary> /// Filling using radial gradient for circle gradient only /// </summary> /// <param name="radial">radial</param> /// <param name="rows">rows</param> /// <param name="startRowIndex">start y index</param> /// <param name="endRowIndex">end y index</param> /// <param name="gammaLutRed">gamma look up table for red</param> /// <param name="gammaLutGreen">gamma look up table for green</param> /// <param name="gammaLutBlue">gamma look up table for blue</param> void FillingRadialEvenOdd(RadialGradient radial, uint opacity, RowData[] rows, int startRowIndex, int endRowIndex, byte[] gammaLutRed, byte[] gammaLutGreen, byte[] gammaLutBlue) { // now not need to check null or not uint[] builtColors = radial.GetLinearColors(opacity); #region private variable for filling int currentCoverage, scLastCoverage, scLastX = 0; int tempCover = 0; int currentArea = 0; int lastXPosition = 0; int startXPosition = 0; byte calculatedCoverage = 0; double centerX = radial.CenterX; double centerY = radial.CenterY; // in this case radius x = radius y double radius = radial.RadiusX; // saving precompute value for rows /* Normal calculation to get the color index * currentColorIndexValue = (int)(Math.Sqrt( (startRowIndex - centerY) * (startRowIndex - centerY) + (currentXPosition - centerX) * (currentXPosition - centerX)) * ColorIndexScale / radius ); * but * preComputeForRow= (startRowIndex - centerY) * (startRowIndex - centerY) * so that * currentColorIndexValue = * (int)(Math.Sqrt( (preComputeForRow) + (currentXPosition - centerX) * (currentXPosition - centerX)) * ColorIndexScale / radius ); */ double preComputeForRow = 0; // this is precompute value so that (* ColorIndexScale / radius) now just ( * preComputeRadiusLookup ) double preComputeRadiusLookup = ColorIndexScale / radius; CellData currentCellData = null; uint colorData = 0; //uint colorG = 0; //uint colorRB = 0; int currentColorIndexValue = 0; int currentXPosition = 0; uint dst, dstRB, dstG; #endregion #region FILLING if (radial.Ramp.NoBlendingColor) { // when no need to blending, when draw a horizontal line // do not need check the back color, alway setup if (radial.Style != GradientStyle.Pad) { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY); if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; // get current color index value //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex; currentXPosition = scLastX + 1; if (scLastCoverage >= 255) { while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int)(Math.Sqrt( preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion BufferData[startXPosition] = builtColors[currentColorIndexValue & ColorIndexDoubleMask]; startXPosition++; currentXPosition++; } } else { calculatedCoverage = (byte)scLastCoverage; while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int)(Math.Sqrt( preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask]; //calculatedCoverage = (byte)((colorData >> 24)); //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion } startXPosition++; currentXPosition++; } } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region calculate color index currentXPosition = currentCellData.X; currentColorIndexValue = (int)(Math.Sqrt(preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex]; //calculatedCoverage = (byte)(colorData >> 24); #region blend pixel //tempCover = (int)((tempCover * calculatedCoverage) >> 8); if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here //dst = BufferData[startXPosition]; //dstRB = dst & 0x00FF00FF; //dstG = (dst >> 8) & 0xFF; //BufferData[startXPosition] = // (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) // | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) // | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion } #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } else { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY); if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; // get current color index value //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex; currentXPosition = scLastX + 1; if (scLastCoverage >= 255) { while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int)(Math.Sqrt( preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion BufferData[startXPosition] = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; startXPosition++; currentXPosition++; } } else { calculatedCoverage = (byte)(scLastCoverage); while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int)(Math.Sqrt( preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; //calculatedCoverage = (byte)((colorData >> 24)); //calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { //// blend here //dst = BufferData[startXPosition]; //dstRB = dst & 0x00FF00FF; //dstG = (dst >> 8) & 0xFF; //BufferData[startXPosition] = // (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) // | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) // | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion } startXPosition++; currentXPosition++; } } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region calculate color index currentXPosition = currentCellData.X; currentColorIndexValue = (int)(Math.Sqrt(preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue];//fixedColor[currentCellData.X - CurrentStartXIndex]; //calculatedCoverage = (byte)(colorData >> 24); #region blend pixel //tempCover = (int)((tempCover * calculatedCoverage) >> 8); if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here //dst = BufferData[startXPosition]; //dstRB = dst & 0x00FF00FF; //dstG = (dst >> 8) & 0xFF; //BufferData[startXPosition] = // (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) // | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) // | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion } #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } } else { // when no need to blending, when draw a horizontal line // do not need check the back color, alway setup if (radial.Style != GradientStyle.Pad) { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY); if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; // get current color index value //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex; currentXPosition = scLastX + 1; while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int)(Math.Sqrt( preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask]; calculatedCoverage = (byte)((colorData >> 24)); calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion } startXPosition++; currentXPosition++; } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region calculate color index currentXPosition = currentCellData.X; currentColorIndexValue = (int)(Math.Sqrt(preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue & ColorIndexDoubleMask];//fixedColor[currentCellData.X - CurrentStartXIndex]; calculatedCoverage = (byte)(colorData >> 24); #region blend pixel tempCover = (int)((tempCover * calculatedCoverage) >> 8); //if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here //dst = BufferData[startXPosition]; //dstRB = dst & 0x00FF00FF; //dstG = (dst >> 8) & 0xFF; //BufferData[startXPosition] = // (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) // | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) // | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } else { #region filling without blend for horizontal lines startRowIndex--; while (++startRowIndex <= endRowIndex) { currentCoverage = scLastCoverage = scLastX = 0; preComputeForRow = (startRowIndex - centerY) * (startRowIndex - centerY); if (rows[startRowIndex] != null) { // get first cell in current row currentCellData = rows[startRowIndex].First; if (currentCellData != null) { #region fill current row do { currentArea = currentCellData.Area; #region blend horizontal line if ((currentCellData.X > scLastX + 1) && (scLastCoverage != 0)) { // fast bit absolute scLastCoverage = (scLastCoverage ^ (scLastCoverage >> 31)) - (scLastCoverage >> 31); #region even odd change scLastCoverage &= 511; if (scLastCoverage >= 256) { scLastCoverage = 512 - scLastCoverage - 1; } #endregion if (scLastCoverage != 0) { #region BLEND HORIZONTAL LINE // calculate start and end position startXPosition = BufferStartOffset + startRowIndex * BufferStride + scLastX + 1; lastXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; // get current color index value //currentColorIndexValue = scLastX + 1 - CurrentStartXIndex; currentXPosition = scLastX + 1; while (startXPosition < lastXPosition) { #region calculate color index currentColorIndexValue = (int)(Math.Sqrt( preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue]; calculatedCoverage = (byte)((colorData >> 24)); calculatedCoverage = (byte)((scLastCoverage * calculatedCoverage) >> 8); if (calculatedCoverage >= 254) { BufferData[startXPosition] = colorData; } else { //// blend here //dst = BufferData[startXPosition]; //dstRB = dst & 0x00FF00FF; //dstG = (dst >> 8) & 0xFF; //BufferData[startXPosition] = // (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) // | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) // | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion } startXPosition++; currentXPosition++; } #endregion } } #endregion currentCoverage += currentCellData.Coverage; #region blend the current cell // fast absolute tempCover = ((currentCoverage << 9) - currentArea) >> 9; if (tempCover != 0) { // fast bit absolute tempCover = (tempCover ^ (tempCover >> 31)) - (tempCover >> 31); #region even odd change tempCover &= 511; if (tempCover >= 256) { tempCover = 512 - tempCover - 1; } #endregion // get current color data #region calculate color index currentXPosition = currentCellData.X; currentColorIndexValue = (int)(Math.Sqrt(preComputeForRow + (currentXPosition - centerX) * (currentXPosition - centerX)) * preComputeRadiusLookup); #endregion colorData = builtColors[currentColorIndexValue > 254 ? 255 : currentColorIndexValue];//fixedColor[currentCellData.X - CurrentStartXIndex]; calculatedCoverage = (byte)(colorData >> 24); #region blend pixel tempCover = (int)((tempCover * calculatedCoverage) >> 8); //if (tempCover > 255) tempCover = 255; calculatedCoverage = (byte)tempCover; startXPosition = BufferStartOffset + startRowIndex * BufferStride + currentCellData.X; #region blend here //dst = BufferData[startXPosition]; //dstRB = dst & 0x00FF00FF; //dstG = (dst >> 8) & 0xFF; //BufferData[startXPosition] = // (uint)(AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) // | (uint)((((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) << 8) & 0x0000FF00) // | (uint)(((((((colorData & 0x00FF00FF)) - dstRB) * calculatedCoverage) >> 8) + dstRB) & 0x00FF00FF); #region gamma apply dst = BufferData[startXPosition]; dstG = (dst >> 8) & 0xFF; dstRB = ((((((colorData & 0x00FF00FF)) - (dst & 0x00FF00FF)) * calculatedCoverage) >> 8) + (dst & 0x00FF00FF)); BufferData[startXPosition] = (uint)((AlphaCache[(((dst >> 24) & 0xFF) << 8) + calculatedCoverage]) | (((uint)gammaLutGreen[(((((((colorData & 0x00FF00) >> 8) - dstG) * calculatedCoverage) >> 8) + dstG) & 0xFF)] << 8)) | ((uint)gammaLutRed[(dstRB & 0x00FF0000) >> 16] << 16) | (gammaLutBlue[(dstRB & 0x00FF)])) ; #endregion #endregion #endregion } #endregion scLastCoverage = currentCoverage; scLastX = currentCellData.X; // move to next cell currentCellData = currentCellData.Next; } while (currentCellData != null); #endregion } } } #endregion } } #endregion }
public GlamMeLomoEffect() { var globalCurve = new Curve(CurveInterpolation.NaturalCubicSpline, new[] { new Point(0, 0), new Point(41, 59), new Point(112, 146), new Point(189, 211), new Point(255, 255) }); var redCurve = new Curve(CurveInterpolation.NaturalCubicSpline, new[] { new Point(0, 0), new Point(101, 45), new Point(191, 193), new Point(255, 255) }); Curve.Compose(redCurve, globalCurve, redCurve); var greenCurve = new Curve(CurveInterpolation.NaturalCubicSpline, new[] { new Point(0, 0), new Point(78, 61), new Point(187, 199), new Point(255, 255) }); Curve.Compose(greenCurve, globalCurve, greenCurve); var blueCurve = new Curve(CurveInterpolation.NaturalCubicSpline, new[] { new Point(0, 0), new Point(56, 71), new Point(204, 181), new Point(255, 255) }); Curve.Compose(blueCurve, globalCurve, blueCurve); var linearGradient = new LinearGradient { StartPoint = new Point(0.0, 0.5), EndPoint = new Point(1.0, 0.5), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(255, 135, 135, 135) }, new GradientStop {Offset = 1.0, Color = Color.FromArgb(255, 193, 193, 193) } } }; var vignetteGradient = new RadialGradient { CenterPoint = new Point(0.5, 0.5), EllipseRadius = new EllipseRadius(2.0, 0), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(0, 255, 255, 255)}, new GradientStop {Offset = 0.9, Color = Color.FromArgb(255, 0, 0, 0)} } }; var vignette2Gradient = new RadialGradient { CenterPoint = new Point(0.5, 0.5), EllipseRadius = new EllipseRadius(1.0, 0), Stops = new[] { new GradientStop {Offset = 0, Color = Color.FromArgb(0, 0, 0, 0)}, new GradientStop {Offset = 0.5, Color = Color.FromArgb(0, 0, 0, 0)}, new GradientStop {Offset = 1.0, Color = Color.FromArgb(255, 0, 0, 0)} } }; LayerList = new LayerList() { new AdjustmentLayer(LayerStyle.Normal(), new CurvesEffect(redCurve, greenCurve, blueCurve)), new Layer(LayerStyle.Overlay(), context => new GradientImageSource(context.BackgroundLayer.ImageSize, linearGradient)), new Layer(LayerStyle.Softlight(0.4), context => new GradientImageSource(context.BackgroundLayer.ImageSize, vignetteGradient)), new Layer(LayerStyle.Darken(0.5), context => new GradientImageSource(context.BackgroundLayer.ImageSize, vignette2Gradient)) }; }