Skip to content

Commit 8c77f5f

Browse files
committed
Merge commit '913281dda7d9a65f1ac04aa80ba723af7a2fd699'
2 parents 7e49081 + 913281d commit 8c77f5f

File tree

3 files changed

+87
-7
lines changed

3 files changed

+87
-7
lines changed

LightTextEditorPlus/Demos/AvaloniaDemo/Business/RichTextCases/RichTextCaseProvider.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,16 @@ void Append(string text, double fontSize)
533533
}));
534534
}, "1d0299-使用 rr.导致字符宽度计算错误");
535535

536+
Add(editor =>
537+
{
538+
editor.UseWpfLineSpacingStyle();
539+
editor.AppendRun(new SkiaTextRun("ڸڸ ", editor.StyleRunProperty with
540+
{
541+
FontSize = 20,
542+
FontName = new FontName("Segoe UI"),
543+
}));
544+
}, "a5e370b-包含从右到左的字符时,将出现越界错误");
545+
536546
//Add(editor =>
537547
//{
538548
// editor.UseWpfLineSpacingStyle();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
测试版本: a5e370b84f7fec1617d6ef4142504c8901bf865e
2+
3+
问题描述:
4+
5+
包含从右到左的字符时,将出现越界错误
6+
7+
问题原因: 在 SkiaCharInfoMeasurer 的 SetCharDataInfo 为了处理连写字的时候,取了字符信息,而此时字符排序是逆序,导致越界

LightTextEditorPlus/LightTextEditorPlus.Core/Utils/ReadOnlyCharDataList_/ReadOnlyCharDataListExtension.cs

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
using System.Buffers;
33
using System.Collections.Generic;
44
using System.Diagnostics;
5+
using System.Globalization;
56
using System.Text;
67

78
using LightTextEditorPlus.Core.Document;
9+
using LightTextEditorPlus.Core.Primitive;
810
using LightTextEditorPlus.Core.Primitive.Collections;
911
using LightTextEditorPlus.Core.Utils.TextArrayPools;
1012

@@ -177,30 +179,91 @@ public static TextReadOnlyListSpan<CharData> GetFirstCharSpanContinuous(this Tex
177179
}
178180

179181
var count = 1;
180-
var current = charList[0];
181-
for (int i = 1; i < charList.Count; i++)
182+
183+
if (checker is null)
182184
{
183-
var next = charList[i];
184-
if (checker is null)
185+
var current = charList[0];
186+
var currentStrongDirection = GetStrongFlowDirection(charList[0]);
187+
for (int i = 1; i < charList.Count; i++)
185188
{
189+
var next = charList[i];
186190
if (!current.RunProperty.Equals(next.RunProperty))
187191
{
188192
break;
189193
}
194+
195+
var nextStrongDirection = GetStrongFlowDirection(next);
196+
if (nextStrongDirection.HasValue)
197+
{
198+
if (currentStrongDirection.HasValue && currentStrongDirection.Value != nextStrongDirection.Value)
199+
{
200+
break;
201+
}
202+
203+
currentStrongDirection = nextStrongDirection;
204+
}
205+
206+
count++;
207+
current = next;
190208
}
191-
else
209+
}
210+
else
211+
{
212+
var current = charList[0];
213+
for (int i = 1; i < charList.Count; i++)
192214
{
215+
var next = charList[i];
193216
if (!checker(current, next))
194217
{
195218
break;
196219
}
220+
221+
count++;
222+
current = next;
197223
}
198-
count++;
199-
current = next; // 这步有些多余,但是为了代码的可读性,还是加上了。为什么多余?因此此时 current 必定和 next 相等
200224
}
201225

202226
return charList.Slice(0, count);
203227
}
228+
229+
/// <summary>
230+
/// 获取当前的文本方向
231+
/// </summary>
232+
/// <param name="charData"></param>
233+
/// <returns></returns>
234+
private static FlowDirection? GetStrongFlowDirection(CharData charData)
235+
{
236+
var rune = charData.CharObject.CodePoint.Rune;
237+
UnicodeCategory category = Rune.GetUnicodeCategory(rune);
238+
239+
if (category is not (UnicodeCategory.UppercaseLetter
240+
or UnicodeCategory.LowercaseLetter
241+
or UnicodeCategory.TitlecaseLetter
242+
or UnicodeCategory.ModifierLetter
243+
or UnicodeCategory.OtherLetter))
244+
{
245+
return null;
246+
}
247+
248+
return IsRightToLeftScript(charData.CharObject.CodePoint.Value)
249+
? FlowDirection.RightToLeft
250+
: FlowDirection.LeftToRight;
251+
}
252+
253+
/// <summary>
254+
/// 是否在从右到左范围内
255+
/// </summary>
256+
/// <param name="codePoint"></param>
257+
/// <returns></returns>
258+
private static bool IsRightToLeftScript(int codePoint)
259+
{
260+
return codePoint is
261+
>= 0x0590 and <= 0x08FF // Hebrew, Arabic, Syriac, Thaana 等
262+
or >= 0xFB1D and <= 0xFDFF // Hebrew/Arabic Presentation Forms-A
263+
or >= 0xFE70 and <= 0xFEFF // Arabic Presentation Forms-B
264+
or >= 0x1E900 and <= 0x1E95F // Adlam
265+
or >= 0x1EE00 and <= 0x1EEFF; // Arabic Mathematical Alphabetic Symbols
266+
}
204267
}
205268

206269
/// <summary>

0 commit comments

Comments
 (0)