Browse Source

Merge remote-tracking branch 'origin/adirh3/mica-backdrop-brush' into adirh3/mica-backdrop-brush

pull/6574/head
Adir 5 years ago
parent
commit
118d1f6adf
  1. 22
      src/Avalonia.Controls/Primitives/Popup.cs
  2. 4
      src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml
  3. 47
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  4. 4
      src/Skia/Avalonia.Skia/FormattedTextImpl.cs
  5. 4
      src/Windows/Avalonia.Direct2D1/Media/AvaloniaTextRenderer.cs
  6. 32
      src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
  7. 7
      src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs
  8. 11
      src/Windows/Avalonia.Direct2D1/Media/RadialGradientBrushImpl.cs
  9. 3
      tests/Avalonia.RenderTests/Media/ConicGradientBrushTests.cs
  10. 12
      tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs
  11. 3
      tests/Avalonia.RenderTests/Media/RadialGradientBrushTests.cs

22
src/Avalonia.Controls/Primitives/Popup.cs

@ -145,7 +145,9 @@ namespace Avalonia.Controls.Primitives
{ {
IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false); IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false);
ChildProperty.Changed.AddClassHandler<Popup>((x, e) => x.ChildChanged(e)); ChildProperty.Changed.AddClassHandler<Popup>((x, e) => x.ChildChanged(e));
IsOpenProperty.Changed.AddClassHandler<Popup>((x, e) => x.IsOpenChanged((AvaloniaPropertyChangedEventArgs<bool>)e)); IsOpenProperty.Changed.AddClassHandler<Popup>((x, e) => x.IsOpenChanged((AvaloniaPropertyChangedEventArgs<bool>)e));
VerticalOffsetProperty.Changed.AddClassHandler<Popup>((x, _) => x.HandlePositionChange());
HorizontalOffsetProperty.Changed.AddClassHandler<Popup>((x, _) => x.HandlePositionChange());
} }
/// <summary> /// <summary>
@ -519,6 +521,24 @@ namespace Avalonia.Controls.Primitives
base.OnDetachedFromLogicalTree(e); base.OnDetachedFromLogicalTree(e);
Close(); Close();
} }
private void HandlePositionChange()
{
if (_openState != null)
{
var placementTarget = PlacementTarget ?? this.FindLogicalAncestorOfType<IControl>();
if (placementTarget == null)
return;
_openState.PopupHost.ConfigurePosition(
placementTarget,
PlacementMode,
new Point(HorizontalOffset, VerticalOffset),
PlacementAnchor,
PlacementGravity,
PlacementConstraintAdjustment,
PlacementRect);
}
}
private static IDisposable SubscribeToEventHandler<T, TEventHandler>(T target, TEventHandler handler, Action<T, TEventHandler> subscribe, Action<T, TEventHandler> unsubscribe) private static IDisposable SubscribeToEventHandler<T, TEventHandler>(T target, TEventHandler handler, Action<T, TEventHandler> subscribe, Action<T, TEventHandler> unsubscribe)
{ {

4
src/Avalonia.Themes.Fluent/Controls/MenuItem.xaml

@ -75,8 +75,6 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ContentPresenter Name="PART_IconPresenter" <ContentPresenter Name="PART_IconPresenter"
Content="{TemplateBinding Icon}" Content="{TemplateBinding Icon}"
Width="16"
Height="16"
Margin="{DynamicResource MenuIconPresenterMargin}" Margin="{DynamicResource MenuIconPresenterMargin}"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" /> VerticalAlignment="Center" />
@ -199,6 +197,8 @@
</Style> </Style>
<Style Selector="MenuItem /template/ ContentPresenter#PART_IconPresenter"> <Style Selector="MenuItem /template/ ContentPresenter#PART_IconPresenter">
<Setter Property="Width" Value="16" />
<Setter Property="Height" Value="16" />
<Setter Property="IsVisible" Value="False" /> <Setter Property="IsVisible" Value="False" />
</Style> </Style>
<Style Selector="MenuItem:icon /template/ ContentPresenter#PART_IconPresenter"> <Style Selector="MenuItem:icon /template/ ContentPresenter#PART_IconPresenter">

47
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -164,7 +164,7 @@ namespace Avalonia.Skia
/// <inheritdoc /> /// <inheritdoc />
public void DrawLine(IPen pen, Point p1, Point p2) public void DrawLine(IPen pen, Point p1, Point p2)
{ {
using (var paint = CreatePaint(_strokePaint, pen, new Rect(p1, p2).Normalize())) using (var paint = CreatePaint(_strokePaint, pen, new Size(Math.Abs(p2.X - p1.X), Math.Abs(p2.Y - p1.Y))))
{ {
if (paint.Paint is object) if (paint.Paint is object)
{ {
@ -177,10 +177,10 @@ namespace Avalonia.Skia
public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry)
{ {
var impl = (GeometryImpl) geometry; var impl = (GeometryImpl) geometry;
var rect = geometry.Bounds; var size = geometry.Bounds.Size;
using (var fill = brush != null ? CreatePaint(_fillPaint, brush, rect) : default(PaintWrapper)) using (var fill = brush != null ? CreatePaint(_fillPaint, brush, size) : default(PaintWrapper))
using (var stroke = pen?.Brush != null ? CreatePaint(_strokePaint, pen, rect) : default(PaintWrapper)) using (var stroke = pen?.Brush != null ? CreatePaint(_strokePaint, pen, size) : default(PaintWrapper))
{ {
if (fill.Paint != null) if (fill.Paint != null)
{ {
@ -354,7 +354,7 @@ namespace Avalonia.Skia
if (brush != null) if (brush != null)
{ {
using (var paint = CreatePaint(_fillPaint, brush, rect.Rect)) using (var paint = CreatePaint(_fillPaint, brush, rect.Rect.Size))
{ {
if (isRounded) if (isRounded)
{ {
@ -397,7 +397,7 @@ namespace Avalonia.Skia
if (pen?.Brush != null) if (pen?.Brush != null)
{ {
using (var paint = CreatePaint(_strokePaint, pen, rect.Rect)) using (var paint = CreatePaint(_strokePaint, pen, rect.Rect.Size))
{ {
if (paint.Paint is object) if (paint.Paint is object)
{ {
@ -417,7 +417,7 @@ namespace Avalonia.Skia
/// <inheritdoc /> /// <inheritdoc />
public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text) public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text)
{ {
using (var paint = CreatePaint(_fillPaint, foreground, text.Bounds)) using (var paint = CreatePaint(_fillPaint, foreground, text.Bounds.Size))
{ {
var textImpl = (FormattedTextImpl) text; var textImpl = (FormattedTextImpl) text;
textImpl.Draw(this, Canvas, origin.ToSKPoint(), paint, _canTextUseLcdRendering); textImpl.Draw(this, Canvas, origin.ToSKPoint(), paint, _canTextUseLcdRendering);
@ -427,7 +427,7 @@ namespace Avalonia.Skia
/// <inheritdoc /> /// <inheritdoc />
public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun) public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{ {
using (var paintWrapper = CreatePaint(_fillPaint, foreground, new Rect(glyphRun.Size))) using (var paintWrapper = CreatePaint(_fillPaint, foreground, glyphRun.Size))
{ {
var glyphRunImpl = (GlyphRunImpl)glyphRun.GlyphRunImpl; var glyphRunImpl = (GlyphRunImpl)glyphRun.GlyphRunImpl;
@ -537,7 +537,7 @@ namespace Avalonia.Skia
var paint = new SKPaint(); var paint = new SKPaint();
Canvas.SaveLayer(paint); Canvas.SaveLayer(paint);
_maskStack.Push(CreatePaint(paint, mask, bounds, true)); _maskStack.Push(CreatePaint(paint, mask, bounds.Size, true));
} }
/// <inheritdoc /> /// <inheritdoc />
@ -593,19 +593,18 @@ namespace Avalonia.Skia
/// <param name="paintWrapper">Paint wrapper.</param> /// <param name="paintWrapper">Paint wrapper.</param>
/// <param name="targetRect">Target bound rect.</param> /// <param name="targetRect">Target bound rect.</param>
/// <param name="gradientBrush">Gradient brush.</param> /// <param name="gradientBrush">Gradient brush.</param>
private void ConfigureGradientBrush(ref PaintWrapper paintWrapper, Rect targetRect, IGradientBrush gradientBrush) private void ConfigureGradientBrush(ref PaintWrapper paintWrapper, Size targetSize, IGradientBrush gradientBrush)
{ {
var tileMode = gradientBrush.SpreadMethod.ToSKShaderTileMode(); var tileMode = gradientBrush.SpreadMethod.ToSKShaderTileMode();
var stopColors = gradientBrush.GradientStops.Select(s => s.Color.ToSKColor()).ToArray(); var stopColors = gradientBrush.GradientStops.Select(s => s.Color.ToSKColor()).ToArray();
var stopOffsets = gradientBrush.GradientStops.Select(s => (float)s.Offset).ToArray(); var stopOffsets = gradientBrush.GradientStops.Select(s => (float)s.Offset).ToArray();
var position = targetRect.Position.ToSKPoint();
switch (gradientBrush) switch (gradientBrush)
{ {
case ILinearGradientBrush linearGradient: case ILinearGradientBrush linearGradient:
{ {
var start = position + linearGradient.StartPoint.ToPixels(targetRect.Size).ToSKPoint(); var start = linearGradient.StartPoint.ToPixels(targetSize).ToSKPoint();
var end = position + linearGradient.EndPoint.ToPixels(targetRect.Size).ToSKPoint(); var end = linearGradient.EndPoint.ToPixels(targetSize).ToSKPoint();
// would be nice to cache these shaders possibly? // would be nice to cache these shaders possibly?
using (var shader = using (var shader =
@ -618,10 +617,10 @@ namespace Avalonia.Skia
} }
case IRadialGradientBrush radialGradient: case IRadialGradientBrush radialGradient:
{ {
var center = position + radialGradient.Center.ToPixels(targetRect.Size).ToSKPoint(); var center = radialGradient.Center.ToPixels(targetSize).ToSKPoint();
var radius = (float)(radialGradient.Radius * targetRect.Width); var radius = (float)(radialGradient.Radius * targetSize.Width);
var origin = position + radialGradient.GradientOrigin.ToPixels(targetRect.Size).ToSKPoint(); var origin = radialGradient.GradientOrigin.ToPixels(targetSize).ToSKPoint();
if (origin.Equals(center)) if (origin.Equals(center))
{ {
@ -666,7 +665,7 @@ namespace Avalonia.Skia
} }
case IConicGradientBrush conicGradient: case IConicGradientBrush conicGradient:
{ {
var center = position + conicGradient.Center.ToPixels(targetRect.Size).ToSKPoint(); var center = conicGradient.Center.ToPixels(targetSize).ToSKPoint();
// Skia's default is that angle 0 is from the right hand side of the center point // Skia's default is that angle 0 is from the right hand side of the center point
// but we are matching CSS where the vertical point above the center is 0. // but we are matching CSS where the vertical point above the center is 0.
@ -868,10 +867,10 @@ namespace Avalonia.Skia
/// </summary> /// </summary>
/// <param name="paint">The paint to wrap.</param> /// <param name="paint">The paint to wrap.</param>
/// <param name="brush">Source brush.</param> /// <param name="brush">Source brush.</param>
/// <param name="targetRect">Target rect.</param> /// <param name="targetSize">Target size.</param>
/// <param name="disposePaint">Optional dispose of the supplied paint.</param> /// <param name="disposePaint">Optional dispose of the supplied paint.</param>
/// <returns>Paint wrapper for given brush.</returns> /// <returns>Paint wrapper for given brush.</returns>
internal PaintWrapper CreatePaint(SKPaint paint, IBrush brush, Rect targetRect, bool disposePaint = false) internal PaintWrapper CreatePaint(SKPaint paint, IBrush brush, Size targetSize, bool disposePaint = false)
{ {
var paintWrapper = new PaintWrapper(paint, disposePaint); var paintWrapper = new PaintWrapper(paint, disposePaint);
@ -890,7 +889,7 @@ namespace Avalonia.Skia
if (brush is IGradientBrush gradient) if (brush is IGradientBrush gradient)
{ {
ConfigureGradientBrush(ref paintWrapper, targetRect, gradient); ConfigureGradientBrush(ref paintWrapper, targetSize, gradient);
return paintWrapper; return paintWrapper;
} }
@ -910,7 +909,7 @@ namespace Avalonia.Skia
if (tileBrush != null && tileBrushImage != null) if (tileBrush != null && tileBrushImage != null)
{ {
ConfigureTileBrush(ref paintWrapper, targetRect.Size, tileBrush, tileBrushImage); ConfigureTileBrush(ref paintWrapper, targetSize, tileBrush, tileBrushImage);
} }
else else
{ {
@ -925,10 +924,10 @@ namespace Avalonia.Skia
/// </summary> /// </summary>
/// <param name="paint">The paint to wrap.</param> /// <param name="paint">The paint to wrap.</param>
/// <param name="pen">Source pen.</param> /// <param name="pen">Source pen.</param>
/// <param name="targetRect">Target rect.</param> /// <param name="targetSize">Target size.</param>
/// <param name="disposePaint">Optional dispose of the supplied paint.</param> /// <param name="disposePaint">Optional dispose of the supplied paint.</param>
/// <returns></returns> /// <returns></returns>
private PaintWrapper CreatePaint(SKPaint paint, IPen pen, Rect targetRect, bool disposePaint = false) private PaintWrapper CreatePaint(SKPaint paint, IPen pen, Size targetSize, bool disposePaint = false)
{ {
// In Skia 0 thickness means - use hairline rendering // In Skia 0 thickness means - use hairline rendering
// and for us it means - there is nothing rendered. // and for us it means - there is nothing rendered.
@ -937,7 +936,7 @@ namespace Avalonia.Skia
return default; return default;
} }
var rv = CreatePaint(paint, pen.Brush, targetRect, disposePaint); var rv = CreatePaint(paint, pen.Brush, targetSize, disposePaint);
paint.IsStroke = true; paint.IsStroke = true;
paint.StrokeWidth = (float) pen.Thickness; paint.StrokeWidth = (float) pen.Thickness;

4
src/Skia/Avalonia.Skia/FormattedTextImpl.cs

@ -278,9 +278,9 @@ namespace Avalonia.Skia
if (fb != null) if (fb != null)
{ {
//TODO: figure out how to get the brush rect //TODO: figure out how to get the brush size
currentWrapper = context.CreatePaint(new SKPaint { IsAntialias = true }, fb, currentWrapper = context.CreatePaint(new SKPaint { IsAntialias = true }, fb,
default); new Size());
} }
else else
{ {

4
src/Windows/Avalonia.Direct2D1/Media/AvaloniaTextRenderer.cs

@ -34,10 +34,10 @@ namespace Avalonia.Direct2D1.Media
{ {
var wrapper = clientDrawingEffect as BrushWrapper; var wrapper = clientDrawingEffect as BrushWrapper;
// TODO: Work out how to get the rect below rather than passing default. // TODO: Work out how to get the size below rather than passing new Size().
var brush = (wrapper == null) ? var brush = (wrapper == null) ?
_foreground : _foreground :
_context.CreateBrush(wrapper.Brush, default).PlatformBrush; _context.CreateBrush(wrapper.Brush, new Size()).PlatformBrush;
_renderTarget.DrawGlyphRun( _renderTarget.DrawGlyphRun(
new RawVector2 { X = baselineOriginX, Y = baselineOriginY }, new RawVector2 { X = baselineOriginX, Y = baselineOriginY },

32
src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs

@ -192,7 +192,7 @@ namespace Avalonia.Direct2D1.Media
{ {
using (var d2dSource = ((BitmapImpl)source.Item).GetDirect2DBitmap(_deviceContext)) using (var d2dSource = ((BitmapImpl)source.Item).GetDirect2DBitmap(_deviceContext))
using (var sourceBrush = new BitmapBrush(_deviceContext, d2dSource.Value)) using (var sourceBrush = new BitmapBrush(_deviceContext, d2dSource.Value))
using (var d2dOpacityMask = CreateBrush(opacityMask, opacityMaskRect)) using (var d2dOpacityMask = CreateBrush(opacityMask, opacityMaskRect.Size))
using (var geometry = new SharpDX.Direct2D1.RectangleGeometry(Direct2D1Platform.Direct2D1Factory, destRect.ToDirect2D())) using (var geometry = new SharpDX.Direct2D1.RectangleGeometry(Direct2D1Platform.Direct2D1Factory, destRect.ToDirect2D()))
{ {
if (d2dOpacityMask.PlatformBrush != null) if (d2dOpacityMask.PlatformBrush != null)
@ -217,7 +217,9 @@ namespace Avalonia.Direct2D1.Media
{ {
if (pen != null) if (pen != null)
{ {
using (var d2dBrush = CreateBrush(pen.Brush, new Rect(p1, p2).Normalize())) var size = new Rect(p1, p2).Size;
using (var d2dBrush = CreateBrush(pen.Brush, size))
using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext)) using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext))
{ {
if (d2dBrush.PlatformBrush != null) if (d2dBrush.PlatformBrush != null)
@ -243,7 +245,7 @@ namespace Avalonia.Direct2D1.Media
{ {
if (brush != null) if (brush != null)
{ {
using (var d2dBrush = CreateBrush(brush, geometry.Bounds)) using (var d2dBrush = CreateBrush(brush, geometry.Bounds.Size))
{ {
if (d2dBrush.PlatformBrush != null) if (d2dBrush.PlatformBrush != null)
{ {
@ -255,7 +257,7 @@ namespace Avalonia.Direct2D1.Media
if (pen != null) if (pen != null)
{ {
using (var d2dBrush = CreateBrush(pen.Brush, geometry.GetRenderBounds(pen))) using (var d2dBrush = CreateBrush(pen.Brush, geometry.GetRenderBounds(pen).Size))
using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext)) using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext))
{ {
if (d2dBrush.PlatformBrush != null) if (d2dBrush.PlatformBrush != null)
@ -280,7 +282,7 @@ namespace Avalonia.Direct2D1.Media
if (brush != null) if (brush != null)
{ {
using (var b = CreateBrush(brush, rect)) using (var b = CreateBrush(brush, rect.Size))
{ {
if (b.PlatformBrush != null) if (b.PlatformBrush != null)
{ {
@ -309,7 +311,7 @@ namespace Avalonia.Direct2D1.Media
if (pen?.Brush != null) if (pen?.Brush != null)
{ {
using (var wrapper = CreateBrush(pen.Brush, rect)) using (var wrapper = CreateBrush(pen.Brush, rect.Size))
using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext)) using (var d2dStroke = pen.ToDirect2DStrokeStyle(_deviceContext))
{ {
if (wrapper.PlatformBrush != null) if (wrapper.PlatformBrush != null)
@ -347,7 +349,7 @@ namespace Avalonia.Direct2D1.Media
{ {
var impl = (FormattedTextImpl)text; var impl = (FormattedTextImpl)text;
using (var brush = CreateBrush(foreground, impl.Bounds)) using (var brush = CreateBrush(foreground, impl.Bounds.Size))
using (var renderer = new AvaloniaTextRenderer(this, _deviceContext, brush.PlatformBrush)) using (var renderer = new AvaloniaTextRenderer(this, _deviceContext, brush.PlatformBrush))
{ {
if (brush.PlatformBrush != null) if (brush.PlatformBrush != null)
@ -365,7 +367,7 @@ namespace Avalonia.Direct2D1.Media
/// <param name="glyphRun">The glyph run.</param> /// <param name="glyphRun">The glyph run.</param>
public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun) public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun)
{ {
using (var brush = CreateBrush(foreground, new Rect(glyphRun.Size))) using (var brush = CreateBrush(foreground, glyphRun.Size))
{ {
var glyphRunImpl = (GlyphRunImpl)glyphRun.GlyphRunImpl; var glyphRunImpl = (GlyphRunImpl)glyphRun.GlyphRunImpl;
@ -456,9 +458,9 @@ namespace Avalonia.Direct2D1.Media
/// Creates a Direct2D brush wrapper for a Avalonia brush. /// Creates a Direct2D brush wrapper for a Avalonia brush.
/// </summary> /// </summary>
/// <param name="brush">The avalonia brush.</param> /// <param name="brush">The avalonia brush.</param>
/// <param name="destinationRect">The brush's target area.</param> /// <param name="destinationSize">The size of the brush's target area.</param>
/// <returns>The Direct2D brush wrapper.</returns> /// <returns>The Direct2D brush wrapper.</returns>
public BrushImpl CreateBrush(IBrush brush, Rect destinationRect) public BrushImpl CreateBrush(IBrush brush, Size destinationSize)
{ {
var solidColorBrush = brush as ISolidColorBrush; var solidColorBrush = brush as ISolidColorBrush;
var linearGradientBrush = brush as ILinearGradientBrush; var linearGradientBrush = brush as ILinearGradientBrush;
@ -473,11 +475,11 @@ namespace Avalonia.Direct2D1.Media
} }
else if (linearGradientBrush != null) else if (linearGradientBrush != null)
{ {
return new LinearGradientBrushImpl(linearGradientBrush, _deviceContext, destinationRect); return new LinearGradientBrushImpl(linearGradientBrush, _deviceContext, destinationSize);
} }
else if (radialGradientBrush != null) else if (radialGradientBrush != null)
{ {
return new RadialGradientBrushImpl(radialGradientBrush, _deviceContext, destinationRect); return new RadialGradientBrushImpl(radialGradientBrush, _deviceContext, destinationSize);
} }
else if (conicGradientBrush != null) else if (conicGradientBrush != null)
{ {
@ -490,7 +492,7 @@ namespace Avalonia.Direct2D1.Media
imageBrush, imageBrush,
_deviceContext, _deviceContext,
(BitmapImpl)imageBrush.Source.PlatformImpl.Item, (BitmapImpl)imageBrush.Source.PlatformImpl.Item,
destinationRect.Size); destinationSize);
} }
else if (visualBrush != null) else if (visualBrush != null)
{ {
@ -521,7 +523,7 @@ namespace Avalonia.Direct2D1.Media
visualBrush, visualBrush,
_deviceContext, _deviceContext,
new D2DBitmapImpl(intermediate.Bitmap), new D2DBitmapImpl(intermediate.Bitmap),
destinationRect.Size); destinationSize);
} }
} }
} }
@ -573,7 +575,7 @@ namespace Avalonia.Direct2D1.Media
ContentBounds = PrimitiveExtensions.RectangleInfinite, ContentBounds = PrimitiveExtensions.RectangleInfinite,
MaskTransform = PrimitiveExtensions.Matrix3x2Identity, MaskTransform = PrimitiveExtensions.Matrix3x2Identity,
Opacity = 1, Opacity = 1,
OpacityBrush = CreateBrush(mask, bounds).PlatformBrush OpacityBrush = CreateBrush(mask, bounds.Size).PlatformBrush
}; };
var layer = _layerPool.Count != 0 ? _layerPool.Pop() : new Layer(_deviceContext); var layer = _layerPool.Count != 0 ? _layerPool.Pop() : new Layer(_deviceContext);
_deviceContext.PushLayer(ref parameters, layer); _deviceContext.PushLayer(ref parameters, layer);

7
src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs

@ -8,7 +8,7 @@ namespace Avalonia.Direct2D1.Media
public LinearGradientBrushImpl( public LinearGradientBrushImpl(
ILinearGradientBrush brush, ILinearGradientBrush brush,
SharpDX.Direct2D1.RenderTarget target, SharpDX.Direct2D1.RenderTarget target,
Rect destinationRect) Size destinationSize)
{ {
if (brush.GradientStops.Count == 0) if (brush.GradientStops.Count == 0)
{ {
@ -21,9 +21,8 @@ namespace Avalonia.Direct2D1.Media
Position = (float)s.Offset Position = (float)s.Offset
}).ToArray(); }).ToArray();
var position = destinationRect.Position; var startPoint = brush.StartPoint.ToPixels(destinationSize);
var startPoint = position + brush.StartPoint.ToPixels(destinationRect.Size); var endPoint = brush.EndPoint.ToPixels(destinationSize);
var endPoint = position + brush.EndPoint.ToPixels(destinationRect.Size);
using (var stops = new SharpDX.Direct2D1.GradientStopCollection( using (var stops = new SharpDX.Direct2D1.GradientStopCollection(
target, target,

11
src/Windows/Avalonia.Direct2D1/Media/RadialGradientBrushImpl.cs

@ -8,7 +8,7 @@ namespace Avalonia.Direct2D1.Media
public RadialGradientBrushImpl( public RadialGradientBrushImpl(
IRadialGradientBrush brush, IRadialGradientBrush brush,
SharpDX.Direct2D1.RenderTarget target, SharpDX.Direct2D1.RenderTarget target,
Rect destinationRect) Size destinationSize)
{ {
if (brush.GradientStops.Count == 0) if (brush.GradientStops.Count == 0)
{ {
@ -21,13 +21,12 @@ namespace Avalonia.Direct2D1.Media
Position = (float)s.Offset Position = (float)s.Offset
}).ToArray(); }).ToArray();
var position = destinationRect.Position; var centerPoint = brush.Center.ToPixels(destinationSize);
var centerPoint = position + brush.Center.ToPixels(destinationRect.Size); var gradientOrigin = brush.GradientOrigin.ToPixels(destinationSize) - centerPoint;
var gradientOrigin = position + brush.GradientOrigin.ToPixels(destinationRect.Size) - centerPoint;
// Note: Direct2D supports RadiusX and RadiusY but Cairo backend supports only Radius property // Note: Direct2D supports RadiusX and RadiusY but Cairo backend supports only Radius property
var radiusX = brush.Radius * destinationRect.Width; var radiusX = brush.Radius * destinationSize.Width;
var radiusY = brush.Radius * destinationRect.Height; var radiusY = brush.Radius * destinationSize.Height;
using (var stops = new SharpDX.Direct2D1.GradientStopCollection( using (var stops = new SharpDX.Direct2D1.GradientStopCollection(
target, target,

3
tests/Avalonia.RenderTests/Media/ConicGradientBrushTests.cs

@ -200,7 +200,8 @@ namespace Avalonia.Direct2D1.RenderTests.Media
Child = new DrawnControl(c => Child = new DrawnControl(c =>
{ {
c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100)); c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100));
c.DrawRectangle(brush, null, new Rect(100, 100, 100, 100)); using (c.PushPreTransform(Matrix.CreateTranslation(100, 100)))
c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100));
}), }),
}; };

12
tests/Avalonia.RenderTests/Media/LinearGradientBrushTests.cs

@ -81,10 +81,10 @@ namespace Avalonia.Direct2D1.RenderTests.Media
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative), StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative), EndPoint = new RelativePoint(1, 1, RelativeUnit.Relative),
GradientStops = GradientStops =
{ {
new GradientStop { Color = Colors.Red, Offset = 0 }, new GradientStop { Color = Colors.Red, Offset = 0 },
new GradientStop { Color = Colors.Blue, Offset = 1 } new GradientStop { Color = Colors.Blue, Offset = 1 }
} }
}; };
Decorator target = new Decorator Decorator target = new Decorator
@ -94,7 +94,9 @@ namespace Avalonia.Direct2D1.RenderTests.Media
Child = new DrawnControl(c => Child = new DrawnControl(c =>
{ {
c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100)); c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100));
c.DrawRectangle(brush, null, new Rect(100, 100, 100, 100));
using (c.PushPreTransform(Matrix.CreateTranslation(100, 100)))
c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100));
}), }),
}; };

3
tests/Avalonia.RenderTests/Media/RadialGradientBrushTests.cs

@ -185,7 +185,8 @@ namespace Avalonia.Direct2D1.RenderTests.Media
Child = new DrawnControl(c => Child = new DrawnControl(c =>
{ {
c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100)); c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100));
c.DrawRectangle(brush, null, new Rect(100, 100, 100, 100)); using (c.PushPreTransform(Matrix.CreateTranslation(100, 100)))
c.DrawRectangle(brush, null, new Rect(0, 0, 100, 100));
}), }),
}; };

Loading…
Cancel
Save