Skip to content

Commit ee43e10

Browse files
committed
Fix Android arrange coordinate conversion
1 parent 1a4f263 commit ee43e10

File tree

8 files changed

+96
-15
lines changed

8 files changed

+96
-15
lines changed
30.8 KB
Loading
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
x:Class="Maui.Controls.Sample.Issues.Issue17884">
5+
<Label Text="CHAT MISSING_WORD"
6+
TextColor="Black"
7+
AutomationId="StubLabel"
8+
x:Name="StubLabel"
9+
FontSize="16"
10+
FontFamily="MontserratBold"
11+
Shadow="{Shadow Offset='0,1', Radius=1, Brush=Aqua}"
12+
MaxLines="1"
13+
LineBreakMode="NoWrap"
14+
VerticalOptions="Center"
15+
HorizontalOptions="Center">
16+
<Label.GestureRecognizers>
17+
<TapGestureRecognizer Tapped="OnStubLabelTapped"/>
18+
</Label.GestureRecognizers>
19+
</Label>
20+
</ContentPage>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+

2+
namespace Maui.Controls.Sample.Issues
3+
{
4+
[Issue(IssueTracker.Github, 17884, "[Android] Entire words omitted & letters truncated from Label display", PlatformAffected.Android)]
5+
public partial class Issue17884 : ContentPage
6+
{
7+
public Issue17884()
8+
{
9+
InitializeComponent();
10+
}
11+
12+
private void OnStubLabelTapped(object sender, EventArgs e)
13+
{
14+
++StubLabel.FontSize;
15+
}
16+
}
17+
}

src/Controls/tests/TestCases.HostApp/MauiProgram.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public static MauiApp CreateMauiApp()
2121
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
2222
fonts.AddFont("FontAwesome.ttf", "FA");
2323
fonts.AddFont("ionicons.ttf", "Ion");
24+
fonts.AddFont("Montserrat-Bold.otf", "MontserratBold");
2425
})
2526
.RenderingPerformanceAddMappers()
2627
.Issue21109AddMappers()
Binary file not shown.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#if ANDROID
2+
using NUnit.Framework;
3+
using UITest.Appium;
4+
using UITest.Core;
5+
6+
namespace Microsoft.Maui.TestCases.Tests.Issues
7+
{
8+
public class Issue17884 : _IssuesUITest
9+
{
10+
public Issue17884(TestDevice device)
11+
: base(device)
12+
{ }
13+
14+
public override string Issue => "[Android] Entire words omitted & letters truncated from Label display";
15+
16+
[Test]
17+
[Category(UITestCategories.Visual)]
18+
public void VerifyTextIsNotMissing()
19+
{
20+
App.WaitForElement("StubLabel");
21+
VerifyScreenshot();
22+
}
23+
}
24+
}
25+
#endif

src/Core/src/Handlers/ViewHandlerExtensions.Android.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ internal static void PlatformArrangeHandler(this IViewHandler viewHandler, Rect
102102
{
103103
var platformView = viewHandler.ToPlatform();
104104

105-
var Context = viewHandler.MauiContext?.Context;
106-
var MauiContext = viewHandler.MauiContext;
105+
var context = viewHandler.MauiContext?.Context;
106+
var mauiContext = viewHandler.MauiContext;
107107

108-
if (platformView == null || MauiContext == null || Context == null)
108+
if (platformView == null || mauiContext == null || context == null)
109109
{
110110
return;
111111
}
@@ -116,10 +116,7 @@ internal static void PlatformArrangeHandler(this IViewHandler viewHandler, Rect
116116
return;
117117
}
118118

119-
var left = Context.ToPixels(frame.Left);
120-
var top = Context.ToPixels(frame.Top);
121-
var bottom = Context.ToPixels(frame.Bottom);
122-
var right = Context.ToPixels(frame.Right);
119+
var (left, top, right, bottom) = context.ToPixels(frame);
123120

124121
var viewParent = platformView.Parent;
125122
if (viewParent?.LayoutDirection == LayoutDirection.Rtl && viewParent is View parentView)
@@ -130,7 +127,7 @@ internal static void PlatformArrangeHandler(this IViewHandler viewHandler, Rect
130127
right = left + width;
131128
}
132129

133-
platformView.Layout((int)left, (int)top, (int)right, (int)bottom);
130+
platformView.Layout(left, top, right, bottom);
134131

135132
viewHandler.Invoke(nameof(IView.Frame), frame);
136133
}

src/Core/src/Platform/Android/ContextExtensions.cs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,36 @@ public static float ToPixels(this Context? self, double dp)
104104
return (float)Math.Ceiling(dp * s_displayDensity);
105105
}
106106

107+
/// <summary>
108+
/// Converts dp to pixels, rounding to the nearest whole pixel.
109+
/// </summary>
110+
/// <remarks>
111+
/// This is especially useful when converting coordinates to the nearest pixel.
112+
/// Do not use this method when setting sizes, as it may lead to visual truncation of the content
113+
/// when rounding down.
114+
/// </remarks>
115+
internal static float ToPixelsRound(this Context? self, double dp)
116+
{
117+
EnsureMetrics(self);
118+
119+
return (float)Math.Round(dp * s_displayDensity, MidpointRounding.AwayFromZero);
120+
}
121+
107122
public static (int left, int top, int right, int bottom) ToPixels(this Context context, Graphics.Rect rectangle)
108123
{
109-
return
110-
(
111-
(int)context.ToPixels(rectangle.Left),
112-
(int)context.ToPixels(rectangle.Top),
113-
(int)context.ToPixels(rectangle.Right),
114-
(int)context.ToPixels(rectangle.Bottom)
115-
);
124+
// Use `ToPixels` to get enough pixels to display the whole content
125+
var width = (int)context.ToPixels(rectangle.Width);
126+
var height = (int)context.ToPixels(rectangle.Height);
127+
// Use `ToPixelsRound` to position the content on the nearest pixel
128+
var left = (int)context.ToPixelsRound(rectangle.Left);
129+
var top = (int)context.ToPixelsRound(rectangle.Top);
130+
131+
// Compute the right and bottom edges based on platform-specific sizes
132+
// Do NOT compute them based on the rectangle's right and bottom as it may lead to visual truncation
133+
var right = left + width;
134+
var bottom = top + height;
135+
136+
return (left, top, right, bottom);
116137
}
117138

118139
public static Thickness ToPixels(this Context context, Thickness thickness)

0 commit comments

Comments
 (0)