Skip to content

Commit 62d83cd

Browse files
committed
refactor custom blur render operation
1 parent 2ffbce0 commit 62d83cd

File tree

1 file changed

+69
-48
lines changed

1 file changed

+69
-48
lines changed

src/client/Launcher/Controls/CustomBlurBehind.cs

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,24 @@ public override void Render(DrawingContext context)
5959
var mat = Material != null
6060
? (ImmutableExperimentalAcrylicMaterial)Material.ToImmutable()
6161
: DefaultAcrylicMaterial;
62-
#pragma warning disable CA2000 // todo: handle this
63-
context.Custom(new BlurBehindRenderOperation(
64-
mat,
65-
new RoundedRect(
66-
new Rect(default, Bounds.Size),
67-
CornerRadius.TopLeft,
68-
CornerRadius.TopRight,
69-
CornerRadius.BottomRight,
70-
CornerRadius.BottomLeft),
71-
BlurRadius));
72-
#pragma warning restore CA2000
62+
63+
var op = new BlurBehindRenderOperation(
64+
mat,
65+
new RoundedRect(
66+
new Rect(default, Bounds.Size),
67+
CornerRadius.TopLeft,
68+
CornerRadius.TopRight,
69+
CornerRadius.BottomRight,
70+
CornerRadius.BottomLeft),
71+
BlurRadius);
72+
73+
context.Custom(op);
74+
75+
op.Dispose();
7376
}
7477

78+
// Render operation implementation
79+
7580
private sealed class BlurBehindRenderOperation : ICustomDrawOperation
7681
{
7782
private readonly ImmutableExperimentalAcrylicMaterial _material;
@@ -87,26 +92,6 @@ public BlurBehindRenderOperation(ImmutableExperimentalAcrylicMaterial material,
8792
_blurRadius = blurRadius;
8893
}
8994

90-
public bool HitTest(Point p)
91-
{
92-
return _bounds.ContainsExclusive(p);
93-
}
94-
95-
private static SKColorFilter CreateAlphaColorFilter(double opacity)
96-
{
97-
if (opacity > 1)
98-
opacity = 1;
99-
var c = new byte[256];
100-
var a = new byte[256];
101-
for (var i = 0; i < 256; i++)
102-
{
103-
c[i] = (byte)i;
104-
a[i] = (byte)(i * opacity);
105-
}
106-
107-
return SKColorFilter.CreateTable(a, c, c, c);
108-
}
109-
11095
public void Render(ImmediateDrawingContext context)
11196
{
11297
var feature = context.TryGetFeature<ISkiaSharpApiLeaseFeature>();
@@ -128,10 +113,9 @@ public void Render(ImmediateDrawingContext context)
128113
SKShaderTileMode.Clamp,
129114
currentInvertedTransform);
130115

131-
using var skrrect = new SKRoundRect(new SKRect(0, 0, (float)_bounds.Rect.Width, (float)_bounds.Rect.Height));
132-
skrrect.SetRectRadii(skrrect.Rect, [new SKPoint((float)_bounds.RadiiTopLeft.X, (float)_bounds.RadiiTopLeft.Y), new SKPoint((float)_bounds.RadiiTopRight.X, (float)_bounds.RadiiTopRight.Y), new SKPoint((float)_bounds.RadiiBottomRight.X, (float)_bounds.RadiiBottomRight.Y), new SKPoint((float)_bounds.RadiiBottomLeft.X, (float)_bounds.RadiiBottomLeft.Y)]);
116+
using var skrrect = CreateSKRoundRect(_bounds);
133117

134-
// todo: fix this (it's for designer only)
118+
// todo: fix this (it's for the designer only)
135119
if (skia.GrContext == null)
136120
{
137121
using var designerFilter = SKImageFilter.CreateBlur(_blurRadius, _blurRadius, SKShaderTileMode.Clamp);
@@ -172,23 +156,10 @@ public void Render(ImmediateDrawingContext context)
172156
using var acrylliPaint = new SKPaint();
173157
acrylliPaint.IsAntialias = true;
174158

175-
const double noiseOpacity = 0.0225;
176-
177159
var tintColor = _material.TintColor;
178160
var tint = new SKColor(tintColor.R, tintColor.G, tintColor.B, tintColor.A);
179161

180-
if (_acrylicNoiseShader == null)
181-
{
182-
using var stream = typeof(SkiaPlatform).Assembly.GetManifestResourceStream("Avalonia.Skia.Assets.NoiseAsset_256X256_PNG.png");
183-
using var bitmap = SKBitmap.Decode(stream);
184-
#pragma warning disable CA2000 // Elimina gli oggetti prima che siano esterni all'ambito
185-
_acrylicNoiseShader = SKShader.CreateBitmap(
186-
bitmap,
187-
SKShaderTileMode.Repeat,
188-
SKShaderTileMode.Repeat)
189-
.WithColorFilter(CreateAlphaColorFilter(noiseOpacity));
190-
#pragma warning restore CA2000 // Elimina gli oggetti prima che siano esterni all'ambito
191-
}
162+
EnsureAcrylicNoiseShader();
192163

193164
using var backdrop = SKShader.CreateColor(new SKColor(_material.MaterialColor.R, _material.MaterialColor.G, _material.MaterialColor.B, _material.MaterialColor.A));
194165
using var tintShader = SKShader.CreateColor(tint);
@@ -199,6 +170,56 @@ public void Render(ImmediateDrawingContext context)
199170
skia.SkCanvas.DrawRoundRect(skrrect, acrylliPaint);
200171
}
201172

173+
[SuppressMessage("", "CA2000")]
174+
private static void EnsureAcrylicNoiseShader()
175+
{
176+
if (_acrylicNoiseShader != null)
177+
return;
178+
179+
const double noiseOpacity = 0.0225;
180+
181+
using var stream = typeof(SkiaPlatform).Assembly.GetManifestResourceStream("Avalonia.Skia.Assets.NoiseAsset_256X256_PNG.png");
182+
using var bitmap = SKBitmap.Decode(stream);
183+
184+
_acrylicNoiseShader = SKShader.CreateBitmap(
185+
bitmap,
186+
SKShaderTileMode.Repeat,
187+
SKShaderTileMode.Repeat)
188+
.WithColorFilter(CreateAlphaColorFilter(noiseOpacity));
189+
}
190+
191+
private static SKRoundRect CreateSKRoundRect(RoundedRect bounds)
192+
{
193+
var skrrect = new SKRoundRect(new SKRect(0, 0, (float)bounds.Rect.Width, (float)bounds.Rect.Height));
194+
skrrect.SetRectRadii(skrrect.Rect, [
195+
new SKPoint((float)bounds.RadiiTopLeft.X, (float)bounds.RadiiTopLeft.Y),
196+
new SKPoint((float)bounds.RadiiTopRight.X, (float)bounds.RadiiTopRight.Y),
197+
new SKPoint((float)bounds.RadiiBottomRight.X, (float)bounds.RadiiBottomRight.Y),
198+
new SKPoint((float)bounds.RadiiBottomLeft.X, (float)bounds.RadiiBottomLeft.Y)]);
199+
200+
return skrrect;
201+
}
202+
203+
private static SKColorFilter CreateAlphaColorFilter(double opacity)
204+
{
205+
if (opacity > 1)
206+
opacity = 1;
207+
var c = new byte[256];
208+
var a = new byte[256];
209+
for (var i = 0; i < 256; i++)
210+
{
211+
c[i] = (byte)i;
212+
a[i] = (byte)(i * opacity);
213+
}
214+
215+
return SKColorFilter.CreateTable(a, c, c, c);
216+
}
217+
218+
public bool HitTest(Point p)
219+
{
220+
return _bounds.ContainsExclusive(p);
221+
}
222+
202223
public bool Equals(ICustomDrawOperation? other)
203224
{
204225
return other is BlurBehindRenderOperation op && op._bounds == _bounds && op._material.Equals(_material);

0 commit comments

Comments
 (0)