Browse Source

Introduce a struct enumerator implementation for ReadOnlyList that can be reused

pull/3234/head
Benedikt Schroeder 7 years ago
parent
commit
e704823ced
  1. 48
      src/Avalonia.Base/Utilities/ImmutableReadOnlyListStructEnumerator.cs
  2. 4
      src/Avalonia.Visuals/Media/FontManager.cs
  3. 48
      src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs
  4. 14
      src/Skia/Avalonia.Skia/FontManagerImpl.cs
  5. 3
      tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs

48
src/Avalonia.Base/Utilities/ImmutableReadOnlyListStructEnumerator.cs

@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
namespace Avalonia.Utilities
{
public struct ImmutableReadOnlyListStructEnumerator<T> : IEnumerator, IEnumerator<T>
{
private readonly IReadOnlyList<T> _readOnlyList;
private int _pos;
public ImmutableReadOnlyListStructEnumerator(IReadOnlyList<T> readOnlyList)
{
_readOnlyList = readOnlyList;
_pos = -1;
Current = default;
}
public T Current
{
get;
private set;
}
object IEnumerator.Current => Current;
public void Dispose() { }
public bool MoveNext()
{
if (_pos >= _readOnlyList.Count - 1)
{
return false;
}
Current = _readOnlyList[++_pos];
return true;
}
public void Reset()
{
_pos = -1;
Current = default;
}
}
}

4
src/Avalonia.Visuals/Media/FontManager.cs

@ -70,9 +70,9 @@ namespace Avalonia.Media
}
/// <summary>
/// Get all installed fonts.
/// <param name="checkForUpdates">If <c>true</c> the font collection is updated.</param>
/// Get all installed font family names.
/// </summary>
/// <param name="checkForUpdates">If <c>true</c> the font collection is updated.</param>
public IEnumerable<string> GetInstalledFontFamilyNames(bool checkForUpdates = false) =>
PlatformImpl.GetInstalledFontFamilyNames(checkForUpdates);

48
src/Avalonia.Visuals/Media/Fonts/FamilyNameCollection.cs

@ -6,6 +6,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Avalonia.Utilities;
namespace Avalonia.Media.Fonts
{
@ -57,9 +58,9 @@ namespace Avalonia.Media.Fonts
/// <summary>
/// Returns an enumerator for the name collection.
/// </summary>
public Enumerator GetEnumerator()
public ImmutableReadOnlyListStructEnumerator<string> GetEnumerator()
{
return new Enumerator(this);
return new ImmutableReadOnlyListStructEnumerator<string>(this);
}
IEnumerator<string> IEnumerable<string>.GetEnumerator()
@ -72,49 +73,6 @@ namespace Avalonia.Media.Fonts
return GetEnumerator();
}
public struct Enumerator : IEnumerator, IEnumerator<string>
{
private readonly IReadOnlyList<string> _names;
private int _pos;
public Enumerator(IReadOnlyList<string> names)
{
_names = names;
_pos = -1;
Current = default;
}
public string Current
{
get;
private set;
}
object IEnumerator.Current => Current;
public void Dispose() { }
public bool MoveNext()
{
if (_pos >= _names.Count - 1)
{
return false;
}
Current = _names[++_pos];
return true;
}
public void Reset()
{
_pos = -1;
Current = default;
}
}
/// <summary>
/// Returns a <see cref="string" /> that represents this instance.
/// </summary>

14
src/Skia/Avalonia.Skia/FontManagerImpl.cs

@ -30,7 +30,7 @@ namespace Avalonia.Skia
return _skFontManager.FontFamilies;
}
[ThreadStatic] private static string[] s_languageTagBuffer;
[ThreadStatic] private static string[] t_languageTagBuffer;
public bool TryMatchCharacter(int codepoint, FontWeight fontWeight, FontStyle fontStyle,
FontFamily fontFamily, CultureInfo culture, out FontKey fontKey)
@ -40,20 +40,20 @@ namespace Avalonia.Skia
culture = CultureInfo.CurrentUICulture;
}
if (s_languageTagBuffer == null)
if (t_languageTagBuffer == null)
{
s_languageTagBuffer = new string[2];
t_languageTagBuffer = new string[2];
}
s_languageTagBuffer[0] = culture.TwoLetterISOLanguageName;
s_languageTagBuffer[1] = culture.ThreeLetterISOLanguageName;
t_languageTagBuffer[0] = culture.TwoLetterISOLanguageName;
t_languageTagBuffer[1] = culture.ThreeLetterISOLanguageName;
if (fontFamily != null)
{
foreach (var familyName in fontFamily.FamilyNames)
{
var skTypeface = _skFontManager.MatchCharacter(familyName, (SKFontStyleWeight)fontWeight,
SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle, s_languageTagBuffer, codepoint);
SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle, t_languageTagBuffer, codepoint);
if (skTypeface == null)
{
@ -68,7 +68,7 @@ namespace Avalonia.Skia
else
{
var skTypeface = _skFontManager.MatchCharacter(null, (SKFontStyleWeight)fontWeight,
SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle, s_languageTagBuffer, codepoint);
SKFontStyleWidth.Normal, (SKFontStyleSlant)fontStyle, t_languageTagBuffer, codepoint);
if (skTypeface != null)
{

3
tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.UnitTests;
namespace Avalonia.Visuals.UnitTests.VisualTree
{
@ -57,7 +58,7 @@ namespace Avalonia.Visuals.UnitTests.VisualTree
public IFontManagerImpl CreateFontManager()
{
throw new NotImplementedException();
return new MockFontManagerImpl();
}
public IWriteableBitmapImpl CreateWriteableBitmap(PixelSize size, Vector dpi, PixelFormat? fmt)

Loading…
Cancel
Save