Skip to content

Commit

Permalink
Child Span font attributes inheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
kubaflo committed Nov 28, 2024
1 parent 7c7bf67 commit 1fafb1f
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ void UpdateSearchBarPlaceholder(UITextField textField)
var formatted = (FormattedString)_searchHandler.Placeholder ?? string.Empty;
var targetColor = _searchHandler.PlaceholderColor;
var placeHolderColor = targetColor ?? Microsoft.Maui.Platform.ColorExtensions.PlaceholderColor.ToColor();
textField.AttributedPlaceholder = formatted.ToNSAttributedString(_fontManager, defaultHorizontalAlignment: _searchHandler.HorizontalTextAlignment, defaultColor: placeHolderColor);
textField.AttributedPlaceholder = formatted.ToNSAttributedString(_fontManager, 0, _searchHandler.HorizontalTextAlignment, null, placeHolderColor, TextTransform.Default, TextDecorations.None, FontAttributes.None);

//Center placeholder
//var width = (_uiSearchBar.Frame.Width / 2) - textField.AttributedPlaceholder.Size.Width;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public static SpannableString ToSpannableString(this Label label)
label.ToFont(),
label.TextColor,
label.TextTransform,
label.TextDecorations);
label.TextDecorations,
label.FontAttributes);

// TODO: NET8 this overload must be removed in net8.0 and replaced with the one below
public static SpannableString ToSpannableString(
Expand All @@ -44,7 +45,8 @@ public static SpannableString ToSpannableString(
defaultFont,
defaultColor,
defaultTextTransform,
TextDecorations.None);
TextDecorations.None,
FontAttributes.None);

internal static SpannableString ToSpannableStringNewWay(
this FormattedString formattedString,
Expand All @@ -55,7 +57,8 @@ internal static SpannableString ToSpannableStringNewWay(
Font? defaultFont = null,
Graphics.Color? defaultColor = null,
TextTransform defaultTextTransform = TextTransform.Default,
TextDecorations defaultTextDecorations = TextDecorations.None)
TextDecorations defaultTextDecorations = TextDecorations.None,
FontAttributes defaultFontAttributes = FontAttributes.None)
{
if (formattedString == null)
return new SpannableString(string.Empty);
Expand Down Expand Up @@ -126,6 +129,15 @@ internal static SpannableString ToSpannableStringNewWay(
spannable.SetSpan(new StrikethroughSpan(), start, end, SpanTypes.InclusiveInclusive);
if (textDecorations.HasFlag(TextDecorations.Underline))
spannable.SetSpan(new UnderlineSpan(), start, end, SpanTypes.InclusiveInclusive);

// FontAttributes
var fontAttributes = span.IsSet(Span.FontAttributesProperty)
? span.FontAttributes
: defaultFontAttributes;
if (fontAttributes.HasFlag(FontAttributes.Bold))
spannable.SetSpan(new StyleSpan(TypefaceStyle.Bold), start, end, SpanTypes.InclusiveInclusive);
if (fontAttributes.HasFlag(FontAttributes.Italic))
spannable.SetSpan(new StyleSpan(TypefaceStyle.Italic), start, end, SpanTypes.InclusiveInclusive);
}

return spannable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public static class FormattedStringExtensions
label.HorizontalTextAlignment,
label.ToFont(),
label.TextColor,
label.TextTransform);
label.TextTransform,
label.TextDecorations,
label.FontAttributes);

public static NSAttributedString ToNSAttributedString(
this FormattedString formattedString,
Expand All @@ -38,6 +40,18 @@ public static NSAttributedString ToNSAttributedString(
Font? defaultFont = null,
Color? defaultColor = null,
TextTransform defaultTextTransform = TextTransform.Default)
=> formattedString.ToNSAttributedString(fontManager, defaultLineHeight, defaultHorizontalAlignment, defaultFont, defaultColor, defaultTextTransform);

internal static NSAttributedString ToNSAttributedString(
this FormattedString formattedString,
IFontManager fontManager,
double defaultLineHeight = 0d,
TextAlignment defaultHorizontalAlignment = TextAlignment.Start,
Font? defaultFont = null,
Color? defaultColor = null,
TextTransform defaultTextTransform = TextTransform.Default,
TextDecorations defaultTextDecorations = TextDecorations.None,
FontAttributes defaultFontAttributes = FontAttributes.None)
{
if (formattedString == null)
return new NSAttributedString(string.Empty);
Expand All @@ -50,7 +64,7 @@ public static NSAttributedString ToNSAttributedString(
continue;

attributed.Append(span.ToNSAttributedString(fontManager, defaultLineHeight, defaultHorizontalAlignment,
defaultFont, defaultColor, defaultTextTransform));
defaultFont, defaultColor, defaultTextTransform, defaultTextDecorations, defaultFontAttributes));
}

return attributed;
Expand All @@ -64,6 +78,19 @@ public static NSAttributedString ToNSAttributedString(
Font? defaultFont = null,
Color? defaultColor = null,
TextTransform defaultTextTransform = TextTransform.Default)
=> span.ToNSAttributedString(fontManager, defaultLineHeight, defaultHorizontalAlignment, defaultFont, defaultColor, defaultTextTransform);


internal static NSAttributedString ToNSAttributedString(
this Span span,
IFontManager fontManager,
double defaultLineHeight = 0d, // TODO: NET8 should be -1, but too late to change for NET8
TextAlignment defaultHorizontalAlignment = TextAlignment.Start,
Font? defaultFont = null,
Color? defaultColor = null,
TextTransform defaultTextTransform = TextTransform.Default,
TextDecorations defaultTextDecorations = TextDecorations.None,
FontAttributes defaultFontAttributes = FontAttributes.None)
{
var defaultFontSize = defaultFont?.Size ?? fontManager.DefaultFontSize;

Expand Down Expand Up @@ -103,6 +130,27 @@ public static NSAttributedString ToNSAttributedString(
hasUnderline = (textDecorations & TextDecorations.Underline) != 0;
hasStrikethrough = (textDecorations & TextDecorations.Strikethrough) != 0;
}
else if (defaultTextDecorations != TextDecorations.None)
{
hasUnderline = (defaultTextDecorations & TextDecorations.Underline) != 0;
hasStrikethrough = (defaultTextDecorations & TextDecorations.Strikethrough) != 0;
}

if (span.IsSet(Span.FontAttributesProperty))
{
var fontAttributes = span.FontAttributes;
if (fontAttributes.HasFlag(FontAttributes.Bold))
font = font.WithWeight(FontWeight.Bold);
if (fontAttributes.HasFlag(FontAttributes.Italic))
font = font.WithSlant(FontSlant.Italic);
}
else if(defaultFontAttributes != FontAttributes.None)
{
if (defaultFontAttributes.HasFlag(FontAttributes.Bold))
font = font.WithWeight(FontWeight.Bold);
if (defaultFontAttributes.HasFlag(FontAttributes.Italic))
font = font.WithSlant(FontSlant.Italic);
}

var platformFont = font.IsDefault ? null : font.ToUIFont(fontManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public async Task NativeFormattedStringContainsSpan()
{
var result = string.Empty;
#if __IOS__
var attributed = formattedString.ToNSAttributedString(fontManager);
var attributed = formattedString.ToNSAttributedString(fontManager, 0, TextAlignment.Start, null, null, TextTransform.None, TextDecorations.None, FontAttributes.None);
attributed.EnumerateAttributes(new Foundation.NSRange(0, attributed.Length),
Foundation.NSAttributedStringEnumeration.None, new Foundation.NSAttributedRangeCallback((Foundation.NSDictionary dict, Foundation.NSRange range, ref bool flag) =>
Expand Down
35 changes: 35 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue21034.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?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.Issue21034">
<Label TextColor="Blue"
AutomationId="Label"
Margin="30"
VerticalOptions="Center"
TextDecorations="Underline"
FontAttributes="Bold">
<Label.FormattedText>
<FormattedString>
<Span Text="Bold, underlined, blue"/>
<Span Text=" "
TextDecorations="None"/>
<Span Text="Green, italic"
TextColor="Green"
TextDecorations="None"
FontAttributes="Italic"/>
<Span Text=" "
TextDecorations="None"/>
<Span FontAttributes="Bold"
TextColor="Red"
TextDecorations="Strikethrough"
Text="Red, bold, strikethrough"/>
<Span Text=" "
TextDecorations="None"/>
<Span TextColor="Black"
FontFamily="FA"
Text="&#xf133;"/>
</FormattedString>
</Label.FormattedText>
</Label>
</ContentPage>
12 changes: 12 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue21034.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Maui.Controls.Sample.Issues
{

[Issue(IssueTracker.Github, 21034, "Child Span does not inherit TextColor or FontAttributes from parent Label", PlatformAffected.Android | PlatformAffected.iOS)]
public partial class Issue21034 : ContentPage
{
public Issue21034()
{
InitializeComponent();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

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

public override string Issue => "Child Span does not inherit TextColor or FontAttributes from parent Label";

[Test]
[Category(UITestCategories.Label)]
public void SpanShouldInheritLabelsProperties()
{
App.WaitForElement("Label");
VerifyScreenshot();
}
}
}

0 comments on commit 1fafb1f

Please sign in to comment.