|
@@ -1,5 +1,6 @@
|
|
|
using System;
|
|
|
using System.Buffers;
|
|
|
+using System.Collections.Concurrent;
|
|
|
using System.Globalization;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using Avalonia.Media.TextFormatting;
|
|
@@ -13,6 +14,8 @@ namespace Avalonia.Direct2D1.Media
|
|
|
{
|
|
|
internal class TextShaperImpl : ITextShaperImpl
|
|
|
{
|
|
|
+ private static readonly ConcurrentDictionary<int, Language> s_cachedLanguage = new();
|
|
|
+
|
|
|
public ShapedBuffer ShapeText(ReadOnlyMemory<char> text, TextShaperOptions options)
|
|
|
{
|
|
|
var textSpan = text.Span;
|
|
@@ -24,8 +27,8 @@ namespace Avalonia.Direct2D1.Media
|
|
|
using (var buffer = new Buffer())
|
|
|
{
|
|
|
// HarfBuzz needs the surrounding characters to correctly shape the text
|
|
|
- var containingText = GetContainingMemory(text, out var start, out var length);
|
|
|
- buffer.AddUtf16(containingText.Span, start, length);
|
|
|
+ var containingText = GetContainingMemory(text, out var start, out var length).Span;
|
|
|
+ buffer.AddUtf16(containingText, start, length);
|
|
|
|
|
|
MergeBreakPair(buffer);
|
|
|
|
|
@@ -33,7 +36,9 @@ namespace Avalonia.Direct2D1.Media
|
|
|
|
|
|
buffer.Direction = (bidiLevel & 1) == 0 ? Direction.LeftToRight : Direction.RightToLeft;
|
|
|
|
|
|
- buffer.Language = new Language(culture ?? CultureInfo.CurrentCulture);
|
|
|
+ var usedCulture = culture ?? CultureInfo.CurrentCulture;
|
|
|
+
|
|
|
+ buffer.Language = s_cachedLanguage.GetOrAdd(usedCulture.LCID, _ => new Language(usedCulture));
|
|
|
|
|
|
var font = ((GlyphTypefaceImpl)typeface).Font;
|
|
|
|
|
@@ -68,7 +73,7 @@ namespace Avalonia.Direct2D1.Media
|
|
|
|
|
|
var glyphOffset = GetGlyphOffset(glyphPositions, i, textScale);
|
|
|
|
|
|
- if (i < textSpan.Length && textSpan[i] == '\t')
|
|
|
+ if (glyphCluster < containingText.Length && containingText[glyphCluster] == '\t')
|
|
|
{
|
|
|
glyphIndex = typeface.GetGlyph(' ');
|
|
|
|