Skip to content

Commit

Permalink
feat: Added CompositionGradientBrush implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
VitezslavImrysek committed Jul 30, 2021
1 parent 61628e1 commit 38db8d6
Show file tree
Hide file tree
Showing 17 changed files with 690 additions and 222 deletions.
89 changes: 15 additions & 74 deletions src/Uno.UI/UI/Xaml/Controls/Border/BorderLayerRenderer.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,45 +117,19 @@ private static IDisposable InnerCreateLayer(UIElement owner, LayoutState state)
var backgroundShape = compositor.CreateSpriteShape();
var outerShape = compositor.CreateSpriteShape();

Brush.AssignAndObserveBrush(borderBrush, color => borderShape.FillBrush = compositor.CreateColorBrush(color))
.DisposeWith(disposables);

if (background is GradientBrush gradientBackground)
{
//var fillMask = new CAShapeLayer()
//{
// Path = path,
// Frame = area,
// // We only use the fill color to create the mask area
// FillColor = _Color.White.CGColor,
//};
//// We reduce the adjustedArea again so that the gradient is inside the border (like in Windows)
//adjustedArea = adjustedArea.Shrink((float)adjustedStrokeThicknessOffset);

//CreateGradientBrushLayers(area, adjustedArea, parent, sublayers, ref insertionIndex, gradientBackground, fillMask);
}
else if (background is SolidColorBrush scbBackground)
{
Brush.AssignAndObserveBrush(scbBackground, color => backgroundShape.FillBrush = compositor.CreateColorBrush(color))
// Border brush
Brush.AssignAndObserveBrush(borderBrush, compositor, brush => borderShape.FillBrush = brush)
.DisposeWith(disposables);
}
else if (background is ImageBrush imgBackground)

// Background brush
if (background is ImageBrush imgBackground)
{
adjustedArea = CreateImageLayer(compositor, disposables, borderThickness, adjustedArea, backgroundShape, adjustedArea, imgBackground);
}
else if (background is AcrylicBrush acrylicBrush)
{
Brush.AssignAndObserveBrush(acrylicBrush, color => backgroundShape.FillBrush = compositor.CreateColorBrush(color))
.DisposeWith(disposables);
}
else if (background is XamlCompositionBrushBase unsupportedCompositionBrush)
{
Brush.AssignAndObserveBrush(unsupportedCompositionBrush, color => backgroundShape.FillBrush = compositor.CreateColorBrush(color))
.DisposeWith(disposables);
}
else
{
backgroundShape.FillBrush = null;
Brush.AssignAndObserveBrush(background, compositor, brush => backgroundShape.FillBrush = brush)
.DisposeWith(disposables);
}

var borderPath = GetRoundedRect(cornerRadius, innerCornerRadius, area, adjustedArea);
Expand Down Expand Up @@ -190,55 +164,21 @@ private static IDisposable InnerCreateLayer(UIElement owner, LayoutState state)

var backgroundArea = area;

if (background is GradientBrush gradientBackground)
{
var fullArea = new Rect(
area.X + borderThickness.Left,
area.Y + borderThickness.Top,
area.Width - borderThickness.Left - borderThickness.Right,
area.Height - borderThickness.Top - borderThickness.Bottom);

var insideArea = new Rect(default, fullArea.Size);
// var insertionIndex = 0;

// CreateGradientBrushLayers(fullArea, insideArea, parent, sublayers, ref insertionIndex, gradientBackground, fillMask: null);
}
else if (background is SolidColorBrush scbBackground)
{
Brush.AssignAndObserveBrush(scbBackground, c => backgroundShape.FillBrush = compositor.CreateColorBrush(c))
.DisposeWith(disposables);

// This is required because changing the CornerRadius changes the background drawing
// implementation and we don't want a rectangular background behind a rounded background.
Disposable.Create(() => backgroundShape.FillBrush = null)
.DisposeWith(disposables);
}
else if (background is ImageBrush imgBackground)
// Background brush
if (background is ImageBrush imgBackground)
{
backgroundArea = CreateImageLayer(compositor, disposables, borderThickness, adjustedArea, backgroundShape, backgroundArea, imgBackground);
}
else if (background is AcrylicBrush acrylicBrush)
{
Brush.AssignAndObserveBrush(acrylicBrush, c => backgroundShape.FillBrush = compositor.CreateColorBrush(c))
.DisposeWith(disposables);

Disposable.Create(() => backgroundShape.FillBrush = null)
.DisposeWith(disposables);
}
else if (background is XamlCompositionBrushBase unsupportedCompositionBrush)
else
{
Brush.AssignAndObserveBrush(unsupportedCompositionBrush, c => backgroundShape.FillBrush = compositor.CreateColorBrush(c))
Brush.AssignAndObserveBrush(background, compositor, brush => backgroundShape.FillBrush = brush)
.DisposeWith(disposables);

// This is required because changing the CornerRadius changes the background drawing
// implementation and we don't want a rectangular background behind a rounded background.
Disposable.Create(() => backgroundShape.FillBrush = null)
.DisposeWith(disposables);
}
else
{
backgroundShape.FillBrush = null;
}

var geometrySource = new SkiaGeometrySource2D();
var geometry = geometrySource.Geometry;
Expand All @@ -251,13 +191,14 @@ private static IDisposable InnerCreateLayer(UIElement owner, LayoutState state)

if (borderThickness != Thickness.Empty)
{
Action<Action<CompositionSpriteShape, SkiaSharp.SKPath>> createLayer = builder =>
Action<Action<CompositionSpriteShape, SKPath>> createLayer = builder =>
{
var spriteShape = compositor.CreateSpriteShape();
var geometry = new SkiaGeometrySource2D();

Brush.AssignAndObserveBrush(borderBrush, c => spriteShape.StrokeBrush = compositor.CreateColorBrush(c))
.DisposeWith(disposables);
// Border brush
Brush.AssignAndObserveBrush(borderBrush, compositor, brush => spriteShape.StrokeBrush = brush)
.DisposeWith(disposables);

builder(spriteShape, geometry.Geometry);
spriteShape.Geometry = compositor.CreatePathGeometry(new CompositionPath(geometry));
Expand Down
Loading

0 comments on commit 38db8d6

Please sign in to comment.