|
|
@ -1149,43 +1149,85 @@ namespace Avalonia.Skia |
|
|
private void ConfigureSceneBrushContentWithPicture(ref PaintWrapper paintWrapper, ISceneBrushContent content, |
|
|
private void ConfigureSceneBrushContentWithPicture(ref PaintWrapper paintWrapper, ISceneBrushContent content, |
|
|
Rect targetRect) |
|
|
Rect targetRect) |
|
|
{ |
|
|
{ |
|
|
var rect = content.Rect; |
|
|
var tileBrush = content.Brush; |
|
|
var contentSize = rect.Size; |
|
|
|
|
|
if (contentSize.Width <= 0 || contentSize.Height <= 0) |
|
|
var contentBounds = content.Rect; |
|
|
|
|
|
|
|
|
|
|
|
if (contentBounds.Size.Width <= 0 || contentBounds.Size.Height <= 0) |
|
|
{ |
|
|
{ |
|
|
paintWrapper.Paint.Color = SKColor.Empty; |
|
|
paintWrapper.Paint.Color = SKColor.Empty; |
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var tileBrush = content.Brush; |
|
|
var brushTransform = Matrix.CreateTranslation(-contentBounds.Position); |
|
|
var transform = rect.TopLeft == default ? Matrix.Identity : Matrix.CreateTranslation(-rect.X, -rect.Y); |
|
|
|
|
|
|
|
|
contentBounds = contentBounds.TransformToAABB(brushTransform); |
|
|
|
|
|
|
|
|
|
|
|
var destinationRect = content.Brush.DestinationRect.ToPixels(targetRect.Size); |
|
|
|
|
|
|
|
|
|
|
|
if (tileBrush.Stretch != Stretch.None) |
|
|
|
|
|
{ |
|
|
|
|
|
//scale content to destination size
|
|
|
|
|
|
var scale = tileBrush.Stretch.CalculateScaling(destinationRect.Size, contentBounds.Size); |
|
|
|
|
|
|
|
|
|
|
|
var scaleTransform = Matrix.CreateScale(scale); |
|
|
|
|
|
|
|
|
|
|
|
contentBounds = contentBounds.TransformToAABB(scaleTransform); |
|
|
|
|
|
|
|
|
|
|
|
brushTransform *= scaleTransform; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var sourceRect = tileBrush.SourceRect.ToPixels(contentBounds); |
|
|
|
|
|
|
|
|
|
|
|
//scale content to source size
|
|
|
|
|
|
if (contentBounds.Size != sourceRect.Size) |
|
|
|
|
|
{ |
|
|
|
|
|
var scale = tileBrush.Stretch.CalculateScaling(sourceRect.Size, contentBounds.Size); |
|
|
|
|
|
|
|
|
|
|
|
var scaleTransform = Matrix.CreateScale(scale); |
|
|
|
|
|
|
|
|
|
|
|
contentBounds = contentBounds.TransformToAABB(scaleTransform); |
|
|
|
|
|
|
|
|
|
|
|
brushTransform *= scaleTransform; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var transform = Matrix.Identity; |
|
|
|
|
|
|
|
|
if (content.Transform is not null) |
|
|
if (content.Transform is not null) |
|
|
{ |
|
|
{ |
|
|
var transformOrigin = content.TransformOrigin.ToPixels(targetRect); |
|
|
var transformOrigin = content.TransformOrigin.ToPixels(targetRect); |
|
|
var offset = Matrix.CreateTranslation(transformOrigin); |
|
|
var offset = Matrix.CreateTranslation(transformOrigin); |
|
|
|
|
|
transform = -offset * content.Transform.Value * offset; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
transform *= -offset * content.Transform.Value * offset; |
|
|
if (content.Brush.TileMode == TileMode.None) |
|
|
|
|
|
{ |
|
|
|
|
|
brushTransform *= transform; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (tileBrush.Stretch == Stretch.None && transform == Matrix.Identity) |
|
|
|
|
|
{ |
|
|
|
|
|
//align content
|
|
|
|
|
|
var alignmentOffset = TileBrushCalculator.CalculateTranslate(tileBrush.AlignmentX, tileBrush.AlignmentY, |
|
|
|
|
|
contentBounds, destinationRect, Vector.One); |
|
|
|
|
|
|
|
|
|
|
|
brushTransform *= Matrix.CreateTranslation(alignmentOffset); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var calc = new TileBrushCalculator(tileBrush, contentSize, targetRect.Size); |
|
|
|
|
|
transform *= calc.IntermediateTransform; |
|
|
|
|
|
|
|
|
|
|
|
using var pictureTarget = new PictureRenderTarget(_gpu, _grContext, _intermediateSurfaceDpi); |
|
|
using var pictureTarget = new PictureRenderTarget(_gpu, _grContext, _intermediateSurfaceDpi); |
|
|
using (var ctx = pictureTarget.CreateDrawingContext(calc.IntermediateSize)) |
|
|
using (var ctx = pictureTarget.CreateDrawingContext(destinationRect.Size)) |
|
|
{ |
|
|
{ |
|
|
ctx.PushClip(calc.IntermediateClip); |
|
|
|
|
|
ctx.PushRenderOptions(RenderOptions); |
|
|
ctx.PushRenderOptions(RenderOptions); |
|
|
content.Render(ctx, transform); |
|
|
content.Render(ctx, brushTransform); |
|
|
ctx.PopRenderOptions(); |
|
|
ctx.PopRenderOptions(); |
|
|
ctx.PopClip(); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
using var picture = pictureTarget.GetPicture(); |
|
|
using var picture = pictureTarget.GetPicture(); |
|
|
|
|
|
|
|
|
var paintTransform = |
|
|
var paintTransform = |
|
|
tileBrush.TileMode != TileMode.None |
|
|
tileBrush.TileMode != TileMode.None |
|
|
? SKMatrix.CreateTranslation(-(float)calc.DestinationRect.X, -(float)calc.DestinationRect.Y) |
|
|
? SKMatrix.CreateTranslation(-(float)destinationRect.X, -(float)destinationRect.Y) |
|
|
: SKMatrix.CreateIdentity(); |
|
|
: SKMatrix.CreateIdentity(); |
|
|
|
|
|
|
|
|
SKShaderTileMode tileX = |
|
|
SKShaderTileMode tileX = |
|
|
@ -1204,11 +1246,16 @@ namespace Avalonia.Skia |
|
|
|
|
|
|
|
|
paintTransform = SKMatrix.Concat(paintTransform, |
|
|
paintTransform = SKMatrix.Concat(paintTransform, |
|
|
SKMatrix.CreateScale((float)(96.0 / _intermediateSurfaceDpi.X), (float)(96.0 / _intermediateSurfaceDpi.Y))); |
|
|
SKMatrix.CreateScale((float)(96.0 / _intermediateSurfaceDpi.X), (float)(96.0 / _intermediateSurfaceDpi.Y))); |
|
|
|
|
|
|
|
|
if (tileBrush.DestinationRect.Unit == RelativeUnit.Relative) |
|
|
if (tileBrush.DestinationRect.Unit == RelativeUnit.Relative) |
|
|
paintTransform = |
|
|
paintTransform = |
|
|
paintTransform.PreConcat(SKMatrix.CreateTranslation((float)targetRect.X, (float)targetRect.Y)); |
|
|
paintTransform.PreConcat(SKMatrix.CreateTranslation((float)targetRect.X, (float)targetRect.Y)); |
|
|
|
|
|
|
|
|
|
|
|
if (tileBrush.TileMode != TileMode.None) |
|
|
|
|
|
{ |
|
|
|
|
|
paintTransform = paintTransform.PreConcat(transform.ToSKMatrix()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
using (var shader = picture.ToShader(tileX, tileY, paintTransform, |
|
|
using (var shader = picture.ToShader(tileX, tileY, paintTransform, |
|
|
new SKRect(0, 0, picture.CullRect.Width, picture.CullRect.Height))) |
|
|
new SKRect(0, 0, picture.CullRect.Width, picture.CullRect.Height))) |
|
|
{ |
|
|
{ |
|
|
|