Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 37 additions & 35 deletions src/Avalonia.Base/Media/FontFamily.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,53 +131,55 @@ private static FrugalStructList<FontSourceIdentifier> GetFontSourceIdentifier(st
{
var result = new FrugalStructList<FontSourceIdentifier>(1);

var segments = name.Split(',');

for (int i = 0; i < segments.Length; i++)
int commaIndex = -1;
do
{
var segment = segments[i];
var innerSegments = segment.Split('#');
// Look for a comma separator to carve out a single segment.
int segmentStart = commaIndex + 1;
commaIndex = name.IndexOf(',', segmentStart);
int segmentEnd = commaIndex == -1
? name.Length
: commaIndex;

var segment = name.AsSpan(segmentStart..segmentEnd).Trim();

FontSourceIdentifier identifier = new FontSourceIdentifier(name, null);
FontSourceIdentifier? identifier = null;

switch (innerSegments.Length)
// Check if there is exactly one '#' (i.e., segment is in the format "path#innerName").
int separatorIndex = segment.IndexOf('#');
if (separatorIndex != -1 && segment[(separatorIndex + 1)..].IndexOf('#') == -1)
{
case 1:
var pathSpan = segment[..separatorIndex].Trim();
var innerName = segment[(separatorIndex + 1)..].Trim();

if (pathSpan.IsEmpty)
{
identifier = new FontSourceIdentifier(innerName.ToString(), null);
}
else
{
string path = pathSpan.ToString();
if (pathSpan.Contains('/') && Uri.TryCreate(path, UriKind.Relative, out var source))
{
identifier = new FontSourceIdentifier(innerSegments[0].Trim(), null);
break;
identifier = new FontSourceIdentifier(innerName.ToString(), source);
}

case 2:
else
{
var path = innerSegments[0].Trim();
var innerName = innerSegments[1].Trim();

if (string.IsNullOrEmpty(path))
{
identifier = new FontSourceIdentifier(innerName, null);
}
else
if (Uri.TryCreate(path, UriKind.Absolute, out source))
{
if (path.Contains('/') && Uri.TryCreate(path, UriKind.Relative, out var source))
{
identifier = new FontSourceIdentifier(innerName, source);
}
else
{
if (Uri.TryCreate(path, UriKind.Absolute, out source))
{
identifier = new FontSourceIdentifier(innerName, source);
}
}
identifier = new FontSourceIdentifier(innerName.ToString(), source);
}

break;
}
}
}

result.Add(identifier);
}
// If we didn't manage to match it to any known format, treat the entire segment as the font name.
identifier ??= new FontSourceIdentifier(
segment.Length == name.Length ? name : segment.ToString(),
null);

result.Add(identifier.Value);
} while (commaIndex != -1);

return result;
}
Expand Down
16 changes: 12 additions & 4 deletions src/Avalonia.Base/Media/TextFormatting/Unicode/BiDi.trie.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@ public static UnicodeTrie Trie
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(Data, 0x00100000, 0x00000000);
}
}

private static ReadOnlySpan<uint> Data => new uint[]
{
// For Debug builds, we store the data in a separate uint[] field to avoid RuntimeFieldInfoStub allocations.
// See also: https://github.com/AvaloniaUI/Avalonia/pull/20175

#if DEBUG
public static ReadOnlySpan<uint> Data => s_data;
private static uint[] s_data =
#else
public static ReadOnlySpan<uint> Data =>
#endif
[
0x0000038D, 0x00000395, 0x0000039D, 0x000003A5, 0x000003BD, 0x000003C5, 0x000003CD, 0x000003D5, 0x000003AD, 0x000003B5, 0x000003AD, 0x000003B5,
0x000003AD, 0x000003B5, 0x000003AD, 0x000003B5, 0x000003AD, 0x000003B5, 0x000003AD, 0x000003B5, 0x000003DB, 0x000003E3, 0x000003EB, 0x000003F3,
0x000003FB, 0x00000403, 0x000003FF, 0x00000407, 0x0000040F, 0x00000417, 0x00000412, 0x0000041A, 0x000003AD, 0x000003B5, 0x000003AD, 0x000003B5,
Expand Down Expand Up @@ -1104,5 +1112,5 @@ public static UnicodeTrie Trie
0x00000000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00000000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000,
0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000, 0x00040000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
};
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static UnicodeTrie Trie
get => new(Data, 0x00110000, 0x00000000);
}

private static ReadOnlySpan<uint> Data => new uint[]
private static readonly uint[] Data = new uint[]
{
0x000003E7, 0x000003EF, 0x000003F7, 0x000003FF, 0x0000041F, 0x00000427, 0x0000042F, 0x00000437, 0x0000043F, 0x00000447, 0x0000044F, 0x00000457,
0x00000417, 0x0000041F, 0x0000045C, 0x00000464, 0x00000417, 0x0000041F, 0x00000468, 0x00000470, 0x00000417, 0x0000041F, 0x00000477, 0x0000047F,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static UnicodeTrie Trie
get => new(Data, 0x000E1000, 0x00000000);
}

private static ReadOnlySpan<uint> Data => new uint[]
private static readonly uint[] Data = new uint[]
{
0x0000035A, 0x00000362, 0x0000036A, 0x00000372, 0x0000038A, 0x00000392, 0x00000362, 0x0000036A, 0x00000362, 0x0000036A, 0x00000362, 0x0000036A,
0x00000362, 0x0000036A, 0x00000362, 0x0000036A, 0x00000362, 0x0000036A, 0x00000362, 0x0000036A, 0x00000362, 0x0000036A, 0x00000362, 0x0000036A,
Expand Down
Loading
Loading