Skip to content

Commit c229dc4

Browse files
committed
fix(text): avoid per-inline surrogate mutation
1 parent 772a80b commit c229dc4

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

src/Uno.UI/UI/Xaml/Documents/UnicodeText.skia.cs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ internal unsafe UnicodeText(
138138

139139
foreach (var inline in inlines)
140140
{
141-
var inlineText = SanitizeText(inline.GetText());
141+
var inlineText = inline.GetText();
142142
if (string.IsNullOrEmpty(inlineText))
143143
{
144144
continue;
@@ -151,12 +151,36 @@ internal unsafe UnicodeText(
151151

152152
var currentFontDetails = inline.FontInfo;
153153
int currentScript = 0;
154-
for (var i = 0; i < inlineText.Length; i += char.IsSurrogate(inlineText, i) ? 2 : 1)
154+
for (var i = 0; i < inlineText.Length;)
155155
{
156156
FontDetails newFontDetails;
157-
var codepoint = char.ConvertToUtf32(inlineText, i);
157+
int codepoint;
158+
int codepointLength;
159+
if (char.IsHighSurrogate(inlineText[i]))
160+
{
161+
if (i + 1 < inlineText.Length && char.IsLowSurrogate(inlineText[i + 1]))
162+
{
163+
codepoint = char.ConvertToUtf32(inlineText, i);
164+
codepointLength = 2;
165+
}
166+
else
167+
{
168+
codepoint = '\uFFFD';
169+
codepointLength = 1;
170+
}
171+
}
172+
else if (char.IsLowSurrogate(inlineText[i]))
173+
{
174+
codepoint = '\uFFFD';
175+
codepointLength = 1;
176+
}
177+
else
178+
{
179+
codepoint = inlineText[i];
180+
codepointLength = 1;
181+
}
158182

159-
var newScript = ICU.GetMethod<ICU.uscript_getScript>()(char.ConvertToUtf32(inlineText, i), out var errorCode);
183+
var newScript = ICU.GetMethod<ICU.uscript_getScript>()(codepoint, out var errorCode);
160184
ICU.CheckErrorCode<ICU.uscript_getScript>(errorCode);
161185

162186
if (newScript != currentScript)
@@ -185,6 +209,8 @@ internal unsafe UnicodeText(
185209
}
186210
currentFontDetails = newFontDetails;
187211
}
212+
213+
i += codepointLength;
188214
}
189215

190216
scriptBreaks.Add(inlineStart + inlineText.Length);

0 commit comments

Comments
 (0)