Skip to content

Commit 1f58600

Browse files
committed
Fix GraphicsView scaling after canvas.ResetState on Android (#31183)
1 parent e2f570f commit 1f58600

6 files changed

Lines changed: 92 additions & 7 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
namespace Maui.Controls.Sample.Issues;
2+
3+
[Issue(IssueTracker.Github, 31182, "GraphicsView draws at half size after canvas.ResetState()", PlatformAffected.Android)]
4+
public class Issue31182 : TestContentPage
5+
{
6+
protected override void Init()
7+
{
8+
var someView = new SomeView
9+
{
10+
WidthRequest = 200,
11+
HeightRequest = 200
12+
};
13+
14+
var label = new Label
15+
{
16+
Text = "Invalidated",
17+
AutomationId = "label",
18+
IsVisible = true
19+
};
20+
21+
someView.Loaded += (s, e) =>
22+
{
23+
Dispatcher.DispatchDelayed(TimeSpan.FromMilliseconds(100), () =>
24+
{
25+
MainThread.BeginInvokeOnMainThread(() =>
26+
{
27+
someView.Invalidate();
28+
label.IsVisible = true;
29+
});
30+
});
31+
};
32+
33+
Content = new VerticalStackLayout
34+
{
35+
WidthRequest = 200,
36+
HeightRequest = 200,
37+
Background = Colors.Red,
38+
Children =
39+
{
40+
someView,
41+
label
42+
}
43+
};
44+
}
45+
46+
class SomeView : GraphicsView, IDrawable
47+
{
48+
public SomeView() { Drawable = this; }
49+
50+
public void Draw(ICanvas canvas, RectF dirtyRect)
51+
{
52+
canvas.ResetState();
53+
canvas.FillColor = Colors.Yellow;
54+
canvas.FillRectangle(dirtyRect);
55+
}
56+
}
57+
}
4.07 KB
Loading
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using NUnit.Framework;
2+
using UITest.Appium;
3+
using UITest.Core;
4+
5+
namespace Microsoft.Maui.TestCases.Tests.Issues;
6+
7+
public class Issue31182 : _IssuesUITest
8+
{
9+
public Issue31182(TestDevice testDevice) : base(testDevice) { }
10+
11+
public override string Issue => "GraphicsView draws at half size after canvas.ResetState()";
12+
13+
[Test]
14+
[Category(UITestCategories.GraphicsView)]
15+
public void GraphicsViewShouldDrawAtFullSize()
16+
{
17+
App.WaitForElement("label");
18+
VerifyScreenshot();
19+
}
20+
}
9.42 KB
Loading

src/Graphics/src/Graphics/Platforms/Android/PlatformGraphicsView.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ public PlatformGraphicsView(Context context, IAttributeSet attrs, IDrawable draw
1919
{
2020
_scale = Resources.DisplayMetrics.Density;
2121
_canvas = new PlatformCanvas(context);
22-
_scalingCanvas = new ScalingCanvas(_canvas);
22+
_scalingCanvas = new ScalingCanvas(_canvas, _scale);
2323
Drawable = drawable;
2424
}
2525

2626
public PlatformGraphicsView(Context context, IDrawable drawable = null) : base(context)
2727
{
2828
_scale = Resources.DisplayMetrics.Density;
2929
_canvas = new PlatformCanvas(context);
30-
_scalingCanvas = new ScalingCanvas(_canvas);
30+
_scalingCanvas = new ScalingCanvas(_canvas, _scale);
3131
Drawable = drawable;
3232
}
3333

@@ -67,7 +67,6 @@ public override void Draw(Canvas androidCanvas)
6767
}
6868

6969
_scalingCanvas.ResetState();
70-
_scalingCanvas.Scale(_scale, _scale);
7170
//Since we are using a scaling canvas, we need to scale the rectangle
7271
dirtyRect.Height /= _scale;
7372
dirtyRect.Width /= _scale;

src/Graphics/src/Graphics/ScalingCanvas.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public class ScalingCanvas : ICanvas, IBlurrableCanvas
1717
private readonly Stack<float> _scaleYStack = new Stack<float>();
1818
private float _scaleX = 1f;
1919
private float _scaleY = 1f;
20+
private float _initialScaleX = 1f;
21+
private float _initialScaleY = 1f;
2022

2123
/// <summary>
2224
/// Initializes a new instance of the <see cref="ScalingCanvas"/> class.
@@ -29,6 +31,12 @@ public ScalingCanvas(ICanvas wrapped)
2931
_blurrableCanvas = _canvas as IBlurrableCanvas;
3032
}
3133

34+
internal ScalingCanvas(ICanvas wrapped, float scale) : this(wrapped)
35+
{
36+
_initialScaleX = scale;
37+
_initialScaleY = scale;
38+
}
39+
3240
/// <inheritdoc/>
3341
public float DisplayScale
3442
{
@@ -271,8 +279,9 @@ public void ResetState()
271279
_canvas.ResetState();
272280
_scaleXStack.Clear();
273281
_scaleYStack.Clear();
274-
_scaleX = 1;
275-
_scaleY = 1;
282+
_scaleX = _initialScaleX;
283+
_scaleY = _initialScaleY;
284+
_canvas.Scale(_scaleX, _scaleY);
276285
}
277286

278287
public bool RestoreState()
@@ -285,8 +294,8 @@ public bool RestoreState()
285294
}
286295
else
287296
{
288-
_scaleX = 1;
289-
_scaleY = 1;
297+
_scaleX = _initialScaleX;
298+
_scaleY = _initialScaleY;
290299
}
291300

292301
return restored;

0 commit comments

Comments
 (0)