diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml
index 16bb0e1583..cf44429ab7 100644
--- a/api/Avalonia.nupkg.xml
+++ b/api/Avalonia.nupkg.xml
@@ -703,6 +703,12 @@
baseline/Avalonia/lib/net10.0/Avalonia.Base.dll
current/Avalonia/lib/net10.0/Avalonia.Base.dll
+
+ CP0006
+ M:Avalonia.Media.Fonts.IFontCollection.TryCreateSyntheticGlyphTypeface(Avalonia.Media.IGlyphTypeface,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,Avalonia.Media.IGlyphTypeface@)
+ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll
+ current/Avalonia/lib/net10.0/Avalonia.Base.dll
+
CP0006
M:Avalonia.Media.Fonts.IFontCollection.TryGetFamilyTypefaces(System.String,System.Collections.Generic.IReadOnlyList{Avalonia.Media.Typeface}@)
@@ -721,6 +727,12 @@
baseline/Avalonia/lib/net10.0/Avalonia.Base.dll
current/Avalonia/lib/net10.0/Avalonia.Base.dll
+
+ CP0006
+ M:Avalonia.Media.Fonts.IFontCollection.TryGetNearestMatch(System.String,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,Avalonia.Media.IGlyphTypeface@)
+ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll
+ current/Avalonia/lib/net10.0/Avalonia.Base.dll
+
CP0006
M:Avalonia.Media.IGlyphTypeface.GetGlyphAdvance(System.UInt16)
@@ -961,6 +973,12 @@
baseline/Avalonia/lib/net8.0/Avalonia.Base.dll
current/Avalonia/lib/net8.0/Avalonia.Base.dll
+
+ CP0006
+ M:Avalonia.Media.Fonts.IFontCollection.TryCreateSyntheticGlyphTypeface(Avalonia.Media.IGlyphTypeface,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,Avalonia.Media.IGlyphTypeface@)
+ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll
+ current/Avalonia/lib/net8.0/Avalonia.Base.dll
+
CP0006
M:Avalonia.Media.Fonts.IFontCollection.TryGetFamilyTypefaces(System.String,System.Collections.Generic.IReadOnlyList{Avalonia.Media.Typeface}@)
@@ -979,6 +997,12 @@
baseline/Avalonia/lib/net8.0/Avalonia.Base.dll
current/Avalonia/lib/net8.0/Avalonia.Base.dll
+
+ CP0006
+ M:Avalonia.Media.Fonts.IFontCollection.TryGetNearestMatch(System.String,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,Avalonia.Media.IGlyphTypeface@)
+ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll
+ current/Avalonia/lib/net8.0/Avalonia.Base.dll
+
CP0006
M:Avalonia.Media.IGlyphTypeface.GetGlyphAdvance(System.UInt16)
diff --git a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
index addd6d1dbd..a94ec5e262 100644
--- a/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
+++ b/samples/RenderDemo/Pages/GlyphRunPage.xaml.cs
@@ -22,7 +22,7 @@ namespace RenderDemo.Pages
public class GlyphRunControl : Control
{
- private GlyphTypeface _glyphTypeface = Typeface.Default.GlyphTypeface;
+ private IGlyphTypeface _glyphTypeface = Typeface.Default.GlyphTypeface;
private readonly Random _rand = new Random();
private ushort[] _glyphIndices = new ushort[1];
private char[] _characters = new char[1];
@@ -81,7 +81,7 @@ namespace RenderDemo.Pages
public class GlyphRunGeometryControl : Control
{
- private GlyphTypeface _glyphTypeface = Typeface.Default.GlyphTypeface;
+ private IGlyphTypeface _glyphTypeface = Typeface.Default.GlyphTypeface;
private readonly Random _rand = new Random();
private ushort[] _glyphIndices = new ushort[1];
private char[] _characters = new char[1];
diff --git a/samples/TextTestApp/MainWindow.axaml.cs b/samples/TextTestApp/MainWindow.axaml.cs
index f32a5b707e..493bc3e9d4 100644
--- a/samples/TextTestApp/MainWindow.axaml.cs
+++ b/samples/TextTestApp/MainWindow.axaml.cs
@@ -223,12 +223,12 @@ namespace TextTestApp
}
}
- private IImage CreateGlyphDrawing(GlyphTypeface glyphTypeface, double emSize, GlyphInfo info)
+ private IImage CreateGlyphDrawing(IGlyphTypeface glyphTypeface, double emSize, GlyphInfo info)
{
return new DrawingImage { Drawing = new GeometryDrawing { Brush = Brushes.Black, Geometry = GetGlyphOutline(glyphTypeface, emSize, info) } };
}
- private Geometry GetGlyphOutline(GlyphTypeface typeface, double emSize, GlyphInfo info)
+ private Geometry GetGlyphOutline(IGlyphTypeface typeface, double emSize, GlyphInfo info)
{
// substitute for GlyphTypeface.GetGlyphOutline
return new GlyphRun(typeface, emSize, new[] { '\0' }, [info]).BuildGeometry();
diff --git a/src/Avalonia.Base/Media/FontManager.cs b/src/Avalonia.Base/Media/FontManager.cs
index 0c9f1c870a..075e674ece 100644
--- a/src/Avalonia.Base/Media/FontManager.cs
+++ b/src/Avalonia.Base/Media/FontManager.cs
@@ -98,7 +98,7 @@ namespace Avalonia.Media
///
/// True, if the could create the glyph typeface, False otherwise.
///
- public bool TryGetGlyphTypeface(Typeface typeface, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ public bool TryGetGlyphTypeface(Typeface typeface, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
glyphTypeface = null;
@@ -187,7 +187,7 @@ namespace Avalonia.Media
}
}
- private bool TryGetGlyphTypefaceByKeyAndName(Typeface typeface, FontFamilyKey key, string familyName, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ private bool TryGetGlyphTypefaceByKeyAndName(Typeface typeface, FontFamilyKey key, string familyName, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
var source = key.Source.EnsureAbsolute(key.BaseUri);
diff --git a/src/Avalonia.Base/Media/Fonts/FontCollectionBase.cs b/src/Avalonia.Base/Media/Fonts/FontCollectionBase.cs
index 4dd5e91dfa..72608a5133 100644
--- a/src/Avalonia.Base/Media/Fonts/FontCollectionBase.cs
+++ b/src/Avalonia.Base/Media/Fonts/FontCollectionBase.cs
@@ -15,7 +15,7 @@ namespace Avalonia.Media.Fonts
Comparer.Create((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
// Make this internal for testing purposes
- internal readonly ConcurrentDictionary> _glyphTypefaceCache = new();
+ internal readonly ConcurrentDictionary> _glyphTypefaceCache = new();
private readonly object _fontFamiliesLock = new();
private volatile FontFamily[] _fontFamilies = Array.Empty();
@@ -87,11 +87,11 @@ namespace Avalonia.Media.Fonts
}
public virtual bool TryCreateSyntheticGlyphTypeface(
- GlyphTypeface glyphTypeface,
+ IGlyphTypeface glyphTypeface,
FontStyle style,
FontWeight weight,
FontStretch stretch,
- [NotNullWhen(true)] out GlyphTypeface? syntheticGlyphTypeface)
+ [NotNullWhen(true)] out IGlyphTypeface? syntheticGlyphTypeface)
{
syntheticGlyphTypeface = null;
@@ -154,7 +154,7 @@ namespace Avalonia.Media.Fonts
public IEnumerator GetEnumerator() => ((IEnumerable)_fontFamilies).GetEnumerator();
public virtual bool TryGetGlyphTypeface(string familyName, FontStyle style, FontWeight weight,
- FontStretch stretch, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
var typeface = new Typeface(familyName, style, weight, stretch).Normalize(out familyName);
@@ -189,7 +189,7 @@ namespace Avalonia.Media.Fonts
return false;
}
- public bool TryGetNearestMatch(string familyName, FontStyle style, FontWeight weight, FontStretch stretch, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ public bool TryGetNearestMatch(string familyName, FontStyle style, FontWeight weight, FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
if (!_glyphTypefaceCache.TryGetValue(familyName, out var glyphTypefaces))
{
@@ -206,15 +206,15 @@ namespace Avalonia.Media.Fonts
///
/// Attempts to add the specified to the font collection.
///
- /// This method checks the and, if applicable,
- /// the typographic family name and other family names provided by the interface.
+ /// This method checks the and, if applicable,
+ /// the typographic family name and other family names provided by the interface.
/// If any of these names can be associated with the glyph typeface, the typeface is added to the collection.
/// The method ensures that duplicate entries are not added.
/// The glyph typeface to add. Must not be and must have a non-empty .
/// if the glyph typeface was successfully added to the collection; otherwise, .
- public bool TryAddGlyphTypeface(GlyphTypeface glyphTypeface)
+ public bool TryAddGlyphTypeface(IGlyphTypeface glyphTypeface)
{
if (glyphTypeface == null || string.IsNullOrEmpty(glyphTypeface.FamilyName))
{
@@ -263,7 +263,7 @@ namespace Avalonia.Media.Fonts
/// succeeds; otherwise, .
/// if the glyph typeface was successfully created and added; otherwise, .
- public bool TryAddGlyphTypeface(Stream stream, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ public bool TryAddGlyphTypeface(Stream stream, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
glyphTypeface = null;
@@ -272,7 +272,7 @@ namespace Avalonia.Media.Fonts
return false;
}
- glyphTypeface = new GlyphTypeface(platformTypeface, FontSimulations.None);
+ glyphTypeface = new GlyphTypeface(platformTypeface);
return TryAddGlyphTypeface(glyphTypeface);
}
@@ -313,7 +313,7 @@ namespace Avalonia.Media.Fonts
continue;
}
- var glyphTypeface = new GlyphTypeface(platformTypeface, FontSimulations.None);
+ var glyphTypeface = new GlyphTypeface(platformTypeface);
var key = glyphTypeface.ToFontCollectionKey();
@@ -348,7 +348,7 @@ namespace Avalonia.Media.Fonts
if (_fontManagerImpl.TryCreateGlyphTypeface(stream, FontSimulations.None, out var platformTypeface))
{
- var glyphTypeface = new GlyphTypeface(platformTypeface, FontSimulations.None);
+ var glyphTypeface = new GlyphTypeface(platformTypeface);
if (TryAddGlyphTypeface(glyphTypeface))
{
@@ -372,7 +372,7 @@ namespace Avalonia.Media.Fonts
if (_fontManagerImpl.TryCreateGlyphTypeface(stream, FontSimulations.None, out var platformTypeface))
{
- var glyphTypeface = new GlyphTypeface(platformTypeface, FontSimulations.None);
+ var glyphTypeface = new GlyphTypeface(platformTypeface);
if (TryAddGlyphTypeface(glyphTypeface))
{
@@ -452,7 +452,7 @@ namespace Avalonia.Media.Fonts
/// When this method returns, contains the matching if a match is found; otherwise,
/// .
/// if a matching glyph typeface is found; otherwise, .
- protected bool TryGetGlyphTypeface(string familyName, FontCollectionKey key, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ protected bool TryGetGlyphTypeface(string familyName, FontCollectionKey key, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
glyphTypeface = null;
@@ -558,7 +558,8 @@ namespace Avalonia.Media.Fonts
/// provided collection of glyph typefaces.
///
/// This method attempts to find the best match for the specified font key by considering
- /// various fallback strategies, such as normalizing the font style, stretch, and weight. If no suitable match is found, the method will return the first available non-null from the
+ /// various fallback strategies, such as normalizing the font style, stretch, and weight.
+ /// If no suitable match is found, the method will return the first available non-null from the
/// collection, if any.
/// A collection of glyph typefaces, indexed by .
/// The representing the desired font attributes.
@@ -566,7 +567,8 @@ namespace Avalonia.Media.Fonts
/// key, if a match is found; otherwise, .
/// if a matching is found; otherwise, .
- protected bool TryGetNearestMatch(IDictionary glyphTypefaces, FontCollectionKey key, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ protected bool TryGetNearestMatch(IDictionary glyphTypefaces,
+ FontCollectionKey key, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
if (glyphTypefaces.TryGetValue(key, out glyphTypeface) && glyphTypeface != null)
{
@@ -631,7 +633,7 @@ namespace Avalonia.Media.Fonts
/// The glyph typeface to add to the cache. Can be null.
/// if the glyph typeface was successfully added to the cache; otherwise, .
- protected bool TryAddGlyphTypeface(string familyName, FontCollectionKey key, GlyphTypeface? glyphTypeface)
+ protected bool TryAddGlyphTypeface(string familyName, FontCollectionKey key, IGlyphTypeface? glyphTypeface)
{
if (string.IsNullOrEmpty(familyName))
{
@@ -655,7 +657,7 @@ namespace Avalonia.Media.Fonts
}
// Family doesn't exist yet. Create a new dictionary instance and try to install it.
- var newDict = new ConcurrentDictionary();
+ var newDict = new ConcurrentDictionary();
// GetOrAdd will return the instance that ended up in the dictionary. If it's our
// newDict instance then we won the race to add the family and should publish it.
@@ -697,9 +699,9 @@ namespace Avalonia.Media.Fonts
/// null.
/// true if a suitable fallback glyph typeface is found; otherwise, false.
private static bool TryFindStretchFallback(
- IDictionary glyphTypefaces,
+ IDictionary glyphTypefaces,
FontCollectionKey key,
- [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
glyphTypeface = null;
@@ -744,9 +746,9 @@ namespace Avalonia.Media.Fonts
/// null.
/// true if a fallback glyph typeface matching the requested weight is found; otherwise, false.
private static bool TryFindWeightFallback(
- IDictionary glyphTypefaces,
+ IDictionary glyphTypefaces,
FontCollectionKey key,
- [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
glyphTypeface = null;
var weight = (int)key.Weight;
diff --git a/src/Avalonia.Base/Media/Fonts/IFontCollection.cs b/src/Avalonia.Base/Media/Fonts/IFontCollection.cs
index b074dd5ce4..0bed5eadd3 100644
--- a/src/Avalonia.Base/Media/Fonts/IFontCollection.cs
+++ b/src/Avalonia.Base/Media/Fonts/IFontCollection.cs
@@ -5,6 +5,12 @@ using System.Globalization;
namespace Avalonia.Media.Fonts
{
+ ///
+ /// Represents a collection of font families and provides methods for querying and managing font typefaces
+ /// within the collection.
+ ///
+ /// Implementations of this interface allow applications to retrieve font families, match
+ /// characters to typefaces, and obtain glyph typefaces based on specific font properties.
public interface IFontCollection : IReadOnlyList, IDisposable
{
///
@@ -22,7 +28,7 @@ namespace Avalonia.Media.Fonts
/// The glyph typeface.
/// Returns true if a glyph typface can be found; otherwise, false
bool TryGetGlyphTypeface(string familyName, FontStyle style, FontWeight weight,
- FontStretch stretch, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface);
+ FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface);
///
/// Tries to match a specified character to a that supports specified font properties.
@@ -59,7 +65,8 @@ namespace Avalonia.Media.Fonts
/// The font stretch.
///
/// Returns true if a synthetic glyph typface can be created; otherwise, false
- bool TryCreateSyntheticGlyphTypeface(GlyphTypeface glyphTypeface, FontStyle style, FontWeight weight, FontStretch stretch, [NotNullWhen(true)] out GlyphTypeface? syntheticGlyphTypeface);
+ bool TryCreateSyntheticGlyphTypeface(IGlyphTypeface glyphTypeface, FontStyle style, FontWeight weight, FontStretch stretch,
+ [NotNullWhen(true)] out IGlyphTypeface? syntheticGlyphTypeface);
///
/// Attempts to retrieve the glyph typeface that most closely matches the specified font family name, style,
@@ -74,9 +81,10 @@ namespace Avalonia.Media.Fonts
/// The desired font style.
/// The desired font weight.
/// The desired font stretch.
- /// When this method returns, contains the that most closely matches the specified
+ /// When this method returns, contains the that most closely matches the specified
/// parameters, if a match is found; otherwise, . This parameter is passed uninitialized.
/// if a matching glyph typeface is found; otherwise, .
- bool TryGetNearestMatch(string familyName, FontStyle style, FontWeight weight, FontStretch stretch, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface);
+ bool TryGetNearestMatch(string familyName, FontStyle style, FontWeight weight, FontStretch stretch,
+ [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface);
}
}
diff --git a/src/Avalonia.Base/Media/Fonts/SystemFontCollection.cs b/src/Avalonia.Base/Media/Fonts/SystemFontCollection.cs
index 4f86cbad88..3b8929cdb5 100644
--- a/src/Avalonia.Base/Media/Fonts/SystemFontCollection.cs
+++ b/src/Avalonia.Base/Media/Fonts/SystemFontCollection.cs
@@ -26,7 +26,7 @@ namespace Avalonia.Media.Fonts
public override Uri Key => FontManager.SystemFontsKey;
public override bool TryGetGlyphTypeface(string familyName, FontStyle style, FontWeight weight,
- FontStretch stretch, [NotNullWhen(true)] out GlyphTypeface? glyphTypeface)
+ FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface)
{
var typeface = new Typeface(familyName, style, weight, stretch).Normalize(out familyName);
@@ -86,13 +86,34 @@ namespace Avalonia.Media.Fonts
if (_platformImpl.TryMatchCharacter(codepoint, style, weight, stretch, familyName, culture, out var platformTypeface))
{
- var glyphTypeface = new GlyphTypeface(platformTypeface);
-
+ // Construct the resulting Typeface
match = new Typeface(platformTypeface.FamilyName, platformTypeface.Style, platformTypeface.Weight,
platformTypeface.Stretch);
- // Add to cache if not already present
- return TryAddGlyphTypeface(glyphTypeface);
+ // Compute the key for cache lookup this can be different from the requested key
+ var key = match.ToFontCollectionKey();
+
+ // Check cache first: if an entry exists and is non-null, match succeeded and we can return true.
+ if (_glyphTypefaceCache.TryGetValue(platformTypeface.FamilyName, out var glyphTypefaces) && glyphTypefaces.TryGetValue(key, out var existing))
+ {
+ return existing != null;
+ }
+
+ // Not in cache yet: create glyph typeface and try to add it.
+ var glyphTypeface = new GlyphTypeface(platformTypeface);
+
+ if (TryAddGlyphTypeface(platformTypeface.FamilyName, key, glyphTypeface))
+ {
+ return true;
+ }
+
+ // TryAddGlyphTypeface failed: another thread may have added an entry. Re-check the cache.
+ if (_glyphTypefaceCache.TryGetValue(platformTypeface.FamilyName, out glyphTypefaces) && glyphTypefaces.TryGetValue(key, out existing))
+ {
+ return existing != null;
+ }
+
+ return false;
}
return false;
diff --git a/src/Avalonia.Base/Media/GlyphRun.cs b/src/Avalonia.Base/Media/GlyphRun.cs
index a54ea7363b..8742fb0807 100644
--- a/src/Avalonia.Base/Media/GlyphRun.cs
+++ b/src/Avalonia.Base/Media/GlyphRun.cs
@@ -39,7 +39,7 @@ namespace Avalonia.Media
/// The baseline origin of the run.
/// The bidi level.
public GlyphRun(
- GlyphTypeface glyphTypeface,
+ IGlyphTypeface glyphTypeface,
double fontRenderingEmSize,
ReadOnlyMemory characters,
IReadOnlyList glyphIndices,
@@ -61,7 +61,7 @@ namespace Avalonia.Media
/// The baseline origin of the run.
/// The bidi level.
public GlyphRun(
- GlyphTypeface glyphTypeface,
+ IGlyphTypeface glyphTypeface,
double fontRenderingEmSize,
ReadOnlyMemory characters,
IReadOnlyList glyphInfos,
@@ -90,7 +90,7 @@ namespace Avalonia.Media
}
private static IReadOnlyList CreateGlyphInfos(IReadOnlyList glyphIndices,
- double fontRenderingEmSize, GlyphTypeface glyphTypeface)
+ double fontRenderingEmSize, IGlyphTypeface glyphTypeface)
{
var glyphIndexSpan = ListToSpan(glyphIndices);
@@ -142,7 +142,7 @@ namespace Avalonia.Media
///
/// Gets the for the .
///
- public GlyphTypeface GlyphTypeface { get; }
+ public IGlyphTypeface GlyphTypeface { get; }
///
/// Gets or sets the em size used for rendering the .
diff --git a/src/Avalonia.Base/Media/IPlatformTypeface.cs b/src/Avalonia.Base/Media/IPlatformTypeface.cs
index 4365354adc..21c95412f4 100644
--- a/src/Avalonia.Base/Media/IPlatformTypeface.cs
+++ b/src/Avalonia.Base/Media/IPlatformTypeface.cs
@@ -31,6 +31,11 @@ namespace Avalonia.Media
///
FontStretch Stretch { get; }
+ ///
+ /// Gets the algorithmic style simulations applied to object.
+ ///
+ FontSimulations FontSimulations { get; }
+
///
/// Returns the font file stream represented by the .
///
diff --git a/src/Avalonia.Base/Media/TextFormatting/ShapedBuffer.cs b/src/Avalonia.Base/Media/TextFormatting/ShapedBuffer.cs
index 71640fac08..5ab7770192 100644
--- a/src/Avalonia.Base/Media/TextFormatting/ShapedBuffer.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/ShapedBuffer.cs
@@ -13,7 +13,7 @@ namespace Avalonia.Media.TextFormatting
private GlyphInfo[]? _rentedBuffer;
private ArraySlice _glyphInfos;
- public ShapedBuffer(ReadOnlyMemory text, int bufferLength, GlyphTypeface glyphTypeface, double fontRenderingEmSize, sbyte bidiLevel)
+ public ShapedBuffer(ReadOnlyMemory text, int bufferLength, IGlyphTypeface glyphTypeface, double fontRenderingEmSize, sbyte bidiLevel)
{
Text = text;
_rentedBuffer = ArrayPool.Shared.Rent(bufferLength);
@@ -23,7 +23,7 @@ namespace Avalonia.Media.TextFormatting
BidiLevel = bidiLevel;
}
- internal ShapedBuffer(ReadOnlyMemory text, ArraySlice glyphInfos, GlyphTypeface glyphTypeface, double fontRenderingEmSize, sbyte bidiLevel)
+ internal ShapedBuffer(ReadOnlyMemory text, ArraySlice glyphInfos, IGlyphTypeface glyphTypeface, double fontRenderingEmSize, sbyte bidiLevel)
{
Text = text;
_glyphInfos = glyphInfos;
@@ -40,7 +40,7 @@ namespace Avalonia.Media.TextFormatting
///
/// The buffer's glyph typeface.
///
- public GlyphTypeface GlyphTypeface { get; }
+ public IGlyphTypeface GlyphTypeface { get; }
///
/// The buffers font rendering em size.
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs b/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs
index cd8b0a3175..b5bd1f4da5 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs
@@ -167,8 +167,8 @@ namespace Avalonia.Media.TextFormatting
///
internal static bool TryGetShapeableLength(
ReadOnlySpan text,
- GlyphTypeface glyphTypeface,
- GlyphTypeface? defaultGlyphTypeface,
+ IGlyphTypeface glyphTypeface,
+ IGlyphTypeface? defaultGlyphTypeface,
out int length)
{
length = 0;
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextMetrics.cs b/src/Avalonia.Base/Media/TextFormatting/TextMetrics.cs
index c0412d1efc..db59f92661 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextMetrics.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextMetrics.cs
@@ -5,7 +5,7 @@
///
public readonly record struct TextMetrics
{
- public TextMetrics(GlyphTypeface glyphTypeface, double fontRenderingEmSize)
+ public TextMetrics(IGlyphTypeface glyphTypeface, double fontRenderingEmSize)
{
var fontMetrics = glyphTypeface.Metrics;
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextRunProperties.cs b/src/Avalonia.Base/Media/TextFormatting/TextRunProperties.cs
index cf2f74ee4d..11db49aaf1 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextRunProperties.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextRunProperties.cs
@@ -12,7 +12,7 @@ namespace Avalonia.Media.TextFormatting
///
public abstract class TextRunProperties : IEquatable
{
- private GlyphTypeface? _cachedGlyphTypeFace;
+ private IGlyphTypeface? _cachedGlyphTypeFace;
///
/// Run typeface
@@ -54,7 +54,7 @@ namespace Avalonia.Media.TextFormatting
///
public virtual BaselineAlignment BaselineAlignment => BaselineAlignment.Baseline;
- internal GlyphTypeface CachedGlyphTypeface
+ internal IGlyphTypeface CachedGlyphTypeface
=> _cachedGlyphTypeFace ??= Typeface.GlyphTypeface;
public bool Equals(TextRunProperties? other)
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextShaperOptions.cs b/src/Avalonia.Base/Media/TextFormatting/TextShaperOptions.cs
index 9ae20a3eaa..48dbaedad4 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextShaperOptions.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextShaperOptions.cs
@@ -10,7 +10,7 @@ namespace Avalonia.Media.TextFormatting
{
// TODO12: Remove in 12.0.0 and make fontFeatures parameter in main ctor optional
public TextShaperOptions(
- GlyphTypeface typeface,
+ IGlyphTypeface typeface,
double fontRenderingEmSize = 12,
sbyte bidiLevel = 0,
CultureInfo? culture = null,
@@ -22,7 +22,7 @@ namespace Avalonia.Media.TextFormatting
// TODO12:Change signature in 12.0.0
public TextShaperOptions(
- GlyphTypeface typeface,
+ IGlyphTypeface typeface,
IReadOnlyList? fontFeatures,
double fontRenderingEmSize = 12,
sbyte bidiLevel = 0,
@@ -42,7 +42,7 @@ namespace Avalonia.Media.TextFormatting
///
/// Get the typeface.
///
- public GlyphTypeface GlyphTypeface { get; }
+ public IGlyphTypeface GlyphTypeface { get; }
///
/// Get the font rendering em size.
///
diff --git a/src/Avalonia.Base/Media/Typeface.cs b/src/Avalonia.Base/Media/Typeface.cs
index 1adcac5b75..c9ad271568 100644
--- a/src/Avalonia.Base/Media/Typeface.cs
+++ b/src/Avalonia.Base/Media/Typeface.cs
@@ -83,7 +83,7 @@ namespace Avalonia.Media
///
/// The glyph typeface.
///
- public GlyphTypeface GlyphTypeface
+ public IGlyphTypeface GlyphTypeface
{
get
{
diff --git a/src/Avalonia.Base/Rendering/Composition/Server/DiagnosticTextRenderer.cs b/src/Avalonia.Base/Rendering/Composition/Server/DiagnosticTextRenderer.cs
index 2c2e3e886b..087bce5a14 100644
--- a/src/Avalonia.Base/Rendering/Composition/Server/DiagnosticTextRenderer.cs
+++ b/src/Avalonia.Base/Rendering/Composition/Server/DiagnosticTextRenderer.cs
@@ -29,7 +29,7 @@ namespace Avalonia.Rendering.Composition.Server
return maxHeight;
}
- public DiagnosticTextRenderer(GlyphTypeface glyphTypeface, double fontRenderingEmSize)
+ public DiagnosticTextRenderer(IGlyphTypeface glyphTypeface, double fontRenderingEmSize)
{
var chars = new char[LastChar - FirstChar + 1];
for (var c = FirstChar; c <= LastChar; c++)
diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs
index a015beff81..7dd73b1556 100644
--- a/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs
+++ b/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs
@@ -76,7 +76,7 @@ namespace Avalonia.Headless
{
_fontMemory = UnmanagedFontMemory.LoadFromStream(stream);
- var dummy = new GlyphTypeface(this, FontSimulations.None);
+ var dummy = new GlyphTypeface(this);
FamilyName = familyName;
Weight = dummy.Weight;
@@ -92,6 +92,8 @@ namespace Avalonia.Headless
public FontStretch Stretch { get; }
+ public FontSimulations FontSimulations => FontSimulations.None;
+
public void Dispose()
{
_fontMemory.Dispose();
diff --git a/tests/Avalonia.Base.UnitTests/Media/GlyphTypefaceTests.cs b/tests/Avalonia.Base.UnitTests/Media/GlyphTypefaceTests.cs
index b8f697517b..28f7280b3a 100644
--- a/tests/Avalonia.Base.UnitTests/Media/GlyphTypefaceTests.cs
+++ b/tests/Avalonia.Base.UnitTests/Media/GlyphTypefaceTests.cs
@@ -90,6 +90,8 @@ namespace Avalonia.Base.UnitTests.Media
public string FamilyName { get; }
+ public FontSimulations FontSimulations => FontSimulations.None;
+
public void Dispose()
{
_fontMemory.Dispose();
diff --git a/tests/Avalonia.Skia.UnitTests/Media/EmbeddedFontCollectionTests.cs b/tests/Avalonia.Skia.UnitTests/Media/EmbeddedFontCollectionTests.cs
index 87a2b867d2..a927fd8024 100644
--- a/tests/Avalonia.Skia.UnitTests/Media/EmbeddedFontCollectionTests.cs
+++ b/tests/Avalonia.Skia.UnitTests/Media/EmbeddedFontCollectionTests.cs
@@ -139,14 +139,14 @@ namespace Avalonia.Skia.UnitTests.Media
_createSyntheticTypefaces = createSyntheticTypefaces;
}
- public IDictionary> GlyphTypefaceCache => _glyphTypefaceCache;
+ public IDictionary> GlyphTypefaceCache => _glyphTypefaceCache;
public override bool TryCreateSyntheticGlyphTypeface(
- GlyphTypeface glyphTypeface,
+ IGlyphTypeface glyphTypeface,
FontStyle style,
FontWeight weight,
FontStretch stretch,
- [NotNullWhen(true)] out GlyphTypeface? syntheticGlyphTypeface)
+ [NotNullWhen(true)] out IGlyphTypeface? syntheticGlyphTypeface)
{
if (!_createSyntheticTypefaces)
{
diff --git a/tests/Avalonia.Skia.UnitTests/Media/FontCollectionTests.cs b/tests/Avalonia.Skia.UnitTests/Media/FontCollectionTests.cs
index 494fa4462d..7a97435a7c 100644
--- a/tests/Avalonia.Skia.UnitTests/Media/FontCollectionTests.cs
+++ b/tests/Avalonia.Skia.UnitTests/Media/FontCollectionTests.cs
@@ -45,7 +45,7 @@ namespace Avalonia.Skia.UnitTests.Media
{
}
- public IDictionary> GlyphTypefaceCache => _glyphTypefaceCache;
+ public IDictionary> GlyphTypefaceCache => _glyphTypefaceCache;
}
[Fact]
@@ -126,11 +126,11 @@ namespace Avalonia.Skia.UnitTests.Media
}
public override bool TryCreateSyntheticGlyphTypeface(
- GlyphTypeface glyphTypeface,
+ IGlyphTypeface glyphTypeface,
FontStyle style,
FontWeight weight,
FontStretch stretch,
- [NotNullWhen(true)] out GlyphTypeface? syntheticGlyphTypeface)
+ [NotNullWhen(true)] out IGlyphTypeface? syntheticGlyphTypeface)
{
syntheticGlyphTypeface = null;
diff --git a/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs b/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs
index bc375ed8e3..bf50870eb4 100644
--- a/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs
+++ b/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs
@@ -313,13 +313,18 @@ namespace Avalonia.Skia.UnitTests.Media
new Uri(s_fontUri, UriKind.Absolute)));
Assert.True(FontManager.Current.TryGetGlyphTypeface(new Typeface("Noto Mono", FontStyle.Italic, FontWeight.Bold),
- out var glyphTypeface));
+ out var italicBoldTypeface));
- Assert.Equal("Noto Mono", glyphTypeface.FamilyName);
+ Assert.Equal("Noto Mono", italicBoldTypeface.FamilyName);
- Assert.Equal(FontWeight.Bold, glyphTypeface.Weight);
+ Assert.True(italicBoldTypeface.PlatformTypeface.FontSimulations.HasFlag(FontSimulations.Bold));
- Assert.Equal(FontStyle.Italic, glyphTypeface.Style);
+ Assert.True(italicBoldTypeface.PlatformTypeface.FontSimulations.HasFlag(FontSimulations.Oblique));
+
+ Assert.True(FontManager.Current.TryGetGlyphTypeface(new Typeface("Noto Mono", FontStyle.Normal, FontWeight.Normal),
+ out var regularTypeface));
+
+ Assert.NotEqual(((SkiaTypeface)regularTypeface.PlatformTypeface).SKTypeface, ((SkiaTypeface)italicBoldTypeface.PlatformTypeface).SKTypeface);
}
}
}