/
FormattedStringExtensions.cs
129 lines (113 loc) · 3.96 KB
/
FormattedStringExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#nullable enable
using Foundation;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.Controls.Internals;
using Microsoft.Maui.Graphics;
#if !MACOS
using ObjCRuntime;
using UIKit;
#else
using AppKit;
using UIColor = AppKit.NSColor;
using UITextAlignment = AppKit.NSTextAlignment;
#endif
namespace Microsoft.Maui.Controls.Platform
{
public static class FormattedStringExtensions
{
public static NSAttributedString? ToNSAttributedString(this Label label)
=> ToNSAttributedString(
label.FormattedText,
label.RequireFontManager(),
label.LineHeight,
label.HorizontalTextAlignment,
label.ToFont(),
label.TextColor,
label.TextTransform);
public static NSAttributedString ToNSAttributedString(
this FormattedString formattedString,
IFontManager fontManager,
double defaultLineHeight = -1d,
TextAlignment defaultHorizontalAlignment = TextAlignment.Start,
Font? defaultFont = null,
Color? defaultColor = null,
TextTransform defaultTextTransform = TextTransform.Default)
{
if (formattedString == null)
return new NSAttributedString(string.Empty);
var attributed = new NSMutableAttributedString();
for (int i = 0; i < formattedString.Spans.Count; i++)
{
Span span = formattedString.Spans[i];
if (span.Text == null)
continue;
attributed.Append(span.ToNSAttributedString(fontManager, defaultLineHeight, defaultHorizontalAlignment, defaultFont, defaultColor, defaultTextTransform));
}
return attributed;
}
public static NSAttributedString ToNSAttributedString(
this Span span,
IFontManager fontManager,
double defaultLineHeight = -1d,
TextAlignment defaultHorizontalAlignment = TextAlignment.Start,
Font? defaultFont = null,
Color? defaultColor = null,
TextTransform defaultTextTransform = TextTransform.Default)
{
var defaultFontSize = defaultFont?.Size ?? fontManager.DefaultFontSize;
var transform = span.TextTransform != TextTransform.Default ? span.TextTransform : defaultTextTransform;
var text = TextTransformUtilites.GetTransformedText(span.Text, transform);
if (text is null)
return new NSAttributedString(string.Empty);
var style = new NSMutableParagraphStyle();
var lineHeight = span.LineHeight >= 0
? span.LineHeight
: defaultLineHeight;
if (lineHeight >= 0)
{
style.LineHeightMultiple = new nfloat(lineHeight);
}
style.Alignment = defaultHorizontalAlignment switch
{
TextAlignment.Start => UITextAlignment.Left,
TextAlignment.Center => UITextAlignment.Center,
TextAlignment.End => UITextAlignment.Right,
_ => UITextAlignment.Left
};
var font = span.ToFont(defaultFontSize);
if (font.IsDefault && defaultFont.HasValue)
font = defaultFont.Value;
var hasUnderline = false;
var hasStrikethrough = false;
if (span.IsSet(Span.TextDecorationsProperty))
{
var textDecorations = span.TextDecorations;
hasUnderline = (textDecorations & TextDecorations.Underline) != 0;
hasStrikethrough = (textDecorations & TextDecorations.Strikethrough) != 0;
}
var platformFont = font.IsDefault ? null : font.ToUIFont(fontManager);
#if !MACOS
var attrString = new NSAttributedString(
text,
platformFont,
(span.TextColor ?? defaultColor)?.ToPlatform(),
span.BackgroundColor?.ToPlatform(),
underlineStyle: hasUnderline ? NSUnderlineStyle.Single : NSUnderlineStyle.None,
strikethroughStyle: hasStrikethrough ? NSUnderlineStyle.Single : NSUnderlineStyle.None,
paragraphStyle: style,
kerning: (float)span.CharacterSpacing);
#else
var attrString = new NSAttributedString(
text,
platformFont,
(span.TextColor ?? defaultColor)?.ToPlatform(),
span.BackgroundColor?.ToPlatform(),
underlineStyle: hasUnderline ? NSUnderlineStyle.Single : NSUnderlineStyle.None,
strikethroughStyle: hasStrikethrough ? NSUnderlineStyle.Single : NSUnderlineStyle.None,
paragraphStyle: style,
kerningAdjustment: (float)span.CharacterSpacing);
#endif
return attrString;
}
}
}