Skip to content

Commit

Permalink
Use TextHighlighter to implement background color for Span (#5025)
Browse files Browse the repository at this point in the history
  • Loading branch information
cshung committed Mar 3, 2022
1 parent b844082 commit a840828
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/Compatibility/Core/src/Windows/LabelRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ void UpdateTextPlainText(TextBlock textBlock)
{
var span = formatted.Spans[i];

var run = span.ToRun(fontManager);
var run = span.ToRunAndColorsTuple(fontManager).Item1;
heights.Add(Control.FindDefaultLineHeight(run));
textBlock.Inlines.Add(run);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.Controls.Internals;
Expand All @@ -20,19 +21,38 @@ public static void UpdateInlines(this TextBlock textBlock, FormattedString forma
// Have to implement a measure here, otherwise inline.ContentStart and ContentEnd will be null, when used in RecalculatePositions
textBlock.Measure(new global::Windows.Foundation.Size(double.MaxValue, double.MaxValue));

var runs = formattedString.ToRuns(defaultLineHeight, defaultHorizontalAlignment, defaultFont, defaultColor, defaultTextTransform);
var runAndColorTuples = formattedString.ToRunAndColorsTuples(defaultLineHeight, defaultHorizontalAlignment, defaultFont, defaultColor, defaultTextTransform);

var heights = new List<double>();
foreach (var run in runs)
int currentTextIndex = 0;
foreach (var runAndColorTuple in runAndColorTuples)
{
Run run = runAndColorTuple.Item1;
Color textColor = runAndColorTuple.Item2;
Color background = runAndColorTuple.Item3;
heights.Add(textBlock.FindDefaultLineHeight(run));
textBlock.Inlines.Add(run);
int length = run.Text.Length;
if (background != null || textColor != null)
{
TextHighlighter textHighlighter = new TextHighlighter { Ranges = { new TextRange(currentTextIndex, length) } };
if (background != null)
{
textHighlighter.Background = background.ToPlatform();
}
if (textColor != null)
{
textHighlighter.Foreground = textColor.ToPlatform();
}
textBlock.TextHighlighters.Add(textHighlighter);
}
currentTextIndex += length;
}
}

public static IEnumerable<Run> ToRuns(this FormattedString formattedString, double defaultLineHeight = 0d, TextAlignment defaultHorizontalAlignment = TextAlignment.Start, Font? defaultFont = null, Color? defaultColor = null, TextTransform defaultTextTransform = TextTransform.Default, IFontManager? fontManager = null)
public static IEnumerable<Tuple<Run, Color, Color>> ToRunAndColorsTuples(this FormattedString formattedString, double defaultLineHeight = 0d, TextAlignment defaultHorizontalAlignment = TextAlignment.Start, Font? defaultFont = null, Color? defaultColor = null, TextTransform defaultTextTransform = TextTransform.Default, IFontManager? fontManager = null)
{
var runs = new List<Run>();
var runs = new List<Tuple<Run, Color, Color>>();

if (formattedString != null && formattedString.Spans != null)
{
Expand All @@ -41,27 +61,21 @@ public static IEnumerable<Run> ToRuns(this FormattedString formattedString, doub
for (var i = 0; i < formattedString.Spans.Count; i++)
{
var span = formattedString.Spans[i];
var run = span.ToRun(fontManager, defaultFont, defaultColor, defaultTextTransform);
var run = span.ToRunAndColorsTuple(fontManager, defaultFont, defaultColor, defaultTextTransform);
runs.Add(run);
}
}

return runs;
}

public static Run ToRun(this Span span, IFontManager fontManager, Font? defaultFont = null, Color? defaultColor = null, TextTransform defaultTextTransform = TextTransform.Default)
public static Tuple<Run, Color, Color> ToRunAndColorsTuple(this Span span, IFontManager fontManager, Font? defaultFont = null, Color? defaultColor = null, TextTransform defaultTextTransform = TextTransform.Default)
{
var transform = span.TextTransform != TextTransform.Default ? span.TextTransform : defaultTextTransform;

var text = TextTransformUtilites.GetTransformedText(span.Text, transform);

var run = new Run { Text = text ?? string.Empty };

var fgcolor = span.TextColor ?? defaultColor;
if (fgcolor is not null)
run.Foreground = fgcolor.ToPlatform();

// NOTE: Background is not supported in Run
var run = new Run { Text = text ?? string.Empty };

var font = span.ToFont();
if (font.IsDefault && defaultFont.HasValue)
Expand All @@ -77,7 +91,7 @@ public static Run ToRun(this Span span, IFontManager fontManager, Font? defaultF

run.CharacterSpacing = span.CharacterSpacing.ToEm();

return run;
return Tuple.Create(run, span.TextColor, span.BackgroundColor);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public async Task NativeFormattedStringContainsSpan()
result = spannable.ToString();
#elif WINDOWS
var runs = formattedString.ToRuns(fontManager: fontManager);
var tuples = formattedString.ToRunAndColorsTuples(fontManager: fontManager);
foreach (var r in runs)
result += r.Text;
foreach (var t in tuples)
result += t.Item1.Text;
#endif
return result;
});
Expand Down

0 comments on commit a840828

Please sign in to comment.