Skip to content

Commit

Permalink
Fix Android arrange coordinate conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
albyrock87 committed Jan 16, 2025
1 parent 1a4f263 commit ee43e10
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 15 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue17884.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue17884">
<Label Text="CHAT MISSING_WORD"
TextColor="Black"
AutomationId="StubLabel"
x:Name="StubLabel"
FontSize="16"
FontFamily="MontserratBold"
Shadow="{Shadow Offset='0,1', Radius=1, Brush=Aqua}"
MaxLines="1"
LineBreakMode="NoWrap"
VerticalOptions="Center"
HorizontalOptions="Center">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="OnStubLabelTapped"/>
</Label.GestureRecognizers>
</Label>
</ContentPage>
17 changes: 17 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue17884.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 17884, "[Android] Entire words omitted & letters truncated from Label display", PlatformAffected.Android)]
public partial class Issue17884 : ContentPage
{
public Issue17884()
{
InitializeComponent();
}

private void OnStubLabelTapped(object sender, EventArgs e)
{
++StubLabel.FontSize;
}
}
}
1 change: 1 addition & 0 deletions src/Controls/tests/TestCases.HostApp/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public static MauiApp CreateMauiApp()
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("FontAwesome.ttf", "FA");
fonts.AddFont("ionicons.ttf", "Ion");
fonts.AddFont("Montserrat-Bold.otf", "MontserratBold");
})
.RenderingPerformanceAddMappers()
.Issue21109AddMappers()
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#if ANDROID
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues
{
public class Issue17884 : _IssuesUITest
{
public Issue17884(TestDevice device)
: base(device)
{ }

public override string Issue => "[Android] Entire words omitted & letters truncated from Label display";

[Test]
[Category(UITestCategories.Visual)]
public void VerifyTextIsNotMissing()
{
App.WaitForElement("StubLabel");
VerifyScreenshot();
}
}
}
#endif
13 changes: 5 additions & 8 deletions src/Core/src/Handlers/ViewHandlerExtensions.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ internal static void PlatformArrangeHandler(this IViewHandler viewHandler, Rect
{
var platformView = viewHandler.ToPlatform();

var Context = viewHandler.MauiContext?.Context;
var MauiContext = viewHandler.MauiContext;
var context = viewHandler.MauiContext?.Context;
var mauiContext = viewHandler.MauiContext;

if (platformView == null || MauiContext == null || Context == null)
if (platformView == null || mauiContext == null || context == null)
{
return;
}
Expand All @@ -116,10 +116,7 @@ internal static void PlatformArrangeHandler(this IViewHandler viewHandler, Rect
return;
}

var left = Context.ToPixels(frame.Left);
var top = Context.ToPixels(frame.Top);
var bottom = Context.ToPixels(frame.Bottom);
var right = Context.ToPixels(frame.Right);
var (left, top, right, bottom) = context.ToPixels(frame);

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

platformView.Layout((int)left, (int)top, (int)right, (int)bottom);
platformView.Layout(left, top, right, bottom);

viewHandler.Invoke(nameof(IView.Frame), frame);
}
Expand Down
35 changes: 28 additions & 7 deletions src/Core/src/Platform/Android/ContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,36 @@ public static float ToPixels(this Context? self, double dp)
return (float)Math.Ceiling(dp * s_displayDensity);
}

/// <summary>
/// Converts dp to pixels, rounding to the nearest whole pixel.
/// </summary>
/// <remarks>
/// This is especially useful when converting coordinates to the nearest pixel.
/// Do not use this method when setting sizes, as it may lead to visual truncation of the content
/// when rounding down.
/// </remarks>
internal static float ToPixelsRound(this Context? self, double dp)
{
EnsureMetrics(self);

return (float)Math.Round(dp * s_displayDensity, MidpointRounding.AwayFromZero);
}

public static (int left, int top, int right, int bottom) ToPixels(this Context context, Graphics.Rect rectangle)
{
return
(
(int)context.ToPixels(rectangle.Left),
(int)context.ToPixels(rectangle.Top),
(int)context.ToPixels(rectangle.Right),
(int)context.ToPixels(rectangle.Bottom)
);
// Use `ToPixels` to get enough pixels to display the whole content
var width = (int)context.ToPixels(rectangle.Width);
var height = (int)context.ToPixels(rectangle.Height);
// Use `ToPixelsRound` to position the content on the nearest pixel
var left = (int)context.ToPixelsRound(rectangle.Left);
var top = (int)context.ToPixelsRound(rectangle.Top);

// Compute the right and bottom edges based on platform-specific sizes
// Do NOT compute them based on the rectangle's right and bottom as it may lead to visual truncation
var right = left + width;
var bottom = top + height;

return (left, top, right, bottom);
}

public static Thickness ToPixels(this Context context, Thickness thickness)
Expand Down

0 comments on commit ee43e10

Please sign in to comment.