diff --git a/src/Avalonia.Visuals/ApiCompatBaseline.txt b/src/Avalonia.Visuals/ApiCompatBaseline.txt
index ee4f70e074..ad9a5fd71a 100644
--- a/src/Avalonia.Visuals/ApiCompatBaseline.txt
+++ b/src/Avalonia.Visuals/ApiCompatBaseline.txt
@@ -5,6 +5,8 @@ InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Task
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean, System.Threading.CancellationToken)' is present in the implementation but not in the contract.
MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.PageSlide.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public void Avalonia.Media.GlyphRun..ctor()' does not exist in the implementation but it does exist in the contract.
+MembersMustExist : Member 'public void Avalonia.Media.GlyphRun.GlyphTypeface.set(Avalonia.Media.GlyphTypeface)' does not exist in the implementation but it does exist in the contract.
TypeCannotChangeClassification : Type 'Avalonia.Media.Immutable.ImmutableSolidColorBrush' is a 'class' in the implementation but is a 'struct' in the contract.
MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext)' does not exist in the implementation but it does exist in the contract.
CannotAddAbstractMembers : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' is abstract in the implementation but is missing in the contract.
@@ -77,4 +79,4 @@ InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWr
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmap(System.String)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToHeight(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract.
InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToWidth(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract.
-Total Issues: 78
+Total Issues: 79
diff --git a/src/Avalonia.Visuals/Media/FontFallback.cs b/src/Avalonia.Visuals/Media/FontFallback.cs
index 240604c5c1..8943b57b31 100644
--- a/src/Avalonia.Visuals/Media/FontFallback.cs
+++ b/src/Avalonia.Visuals/Media/FontFallback.cs
@@ -8,7 +8,7 @@
///
/// Get or set the fallback
///
- public FontFamily FontFamily { get; set; }
+ public FontFamily FontFamily { get; set; } = FontFamily.Default;
///
/// Get or set the that is covered by the fallback.
diff --git a/src/Avalonia.Visuals/Media/FontManager.cs b/src/Avalonia.Visuals/Media/FontManager.cs
index 463f020792..72c1c8dcac 100644
--- a/src/Avalonia.Visuals/Media/FontManager.cs
+++ b/src/Avalonia.Visuals/Media/FontManager.cs
@@ -16,7 +16,7 @@ namespace Avalonia.Media
private readonly ConcurrentDictionary _glyphTypefaceCache =
new ConcurrentDictionary();
private readonly FontFamily _defaultFontFamily;
- private readonly IReadOnlyList _fontFallbacks;
+ private readonly IReadOnlyList? _fontFallbacks;
public FontManager(IFontManagerImpl platformImpl)
{
@@ -87,7 +87,7 @@ namespace Avalonia.Media
///
/// The .
///
- public GlyphTypeface? GetOrAddGlyphTypeface(Typeface typeface)
+ public GlyphTypeface GetOrAddGlyphTypeface(Typeface typeface)
{
while (true)
{
@@ -105,7 +105,7 @@ namespace Avalonia.Media
if (typeface.FontFamily == _defaultFontFamily)
{
- return null;
+ throw new InvalidOperationException($"Could not create glyph typeface for: {typeface.FontFamily.Name}.");
}
typeface = new Typeface(_defaultFontFamily, typeface.Style, typeface.Weight);
@@ -126,7 +126,7 @@ namespace Avalonia.Media
///
public bool TryMatchCharacter(int codepoint, FontStyle fontStyle,
FontWeight fontWeight,
- FontFamily fontFamily, CultureInfo culture, out Typeface typeface)
+ FontFamily? fontFamily, CultureInfo? culture, out Typeface typeface)
{
if(_fontFallbacks != null)
{
diff --git a/src/Avalonia.Visuals/Media/FontManagerOptions.cs b/src/Avalonia.Visuals/Media/FontManagerOptions.cs
index 983fd6eb32..54227dce0f 100644
--- a/src/Avalonia.Visuals/Media/FontManagerOptions.cs
+++ b/src/Avalonia.Visuals/Media/FontManagerOptions.cs
@@ -4,8 +4,8 @@ namespace Avalonia.Media
{
public class FontManagerOptions
{
- public string DefaultFamilyName { get; set; }
+ public string? DefaultFamilyName { get; set; }
- public IReadOnlyList FontFallbacks { get; set; }
+ public IReadOnlyList? FontFallbacks { get; set; }
}
}
diff --git a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs
index 52e46110a3..203c8dc221 100644
--- a/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs
+++ b/src/Avalonia.Visuals/Media/Fonts/FontFamilyLoader.cs
@@ -89,7 +89,7 @@ namespace Avalonia.Media.Fonts
{
fileExtension = "." + fontFamilyKey.Source.AbsolutePath.Split('.').LastOrDefault();
- var fileName = fontFamilyKey.Source.LocalPath.Replace(fileExtension, string.Empty).Split('.').LastOrDefault();
+ var fileName = fontFamilyKey.Source.LocalPath.Replace(fileExtension, string.Empty).Split('.').Last();
location = new Uri(fontFamilyKey.Source.AbsoluteUri.Replace("." + fileName + fileExtension, string.Empty), UriKind.RelativeOrAbsolute);
diff --git a/src/Avalonia.Visuals/Media/GlyphRun.cs b/src/Avalonia.Visuals/Media/GlyphRun.cs
index fa9241c2ed..e15a19306a 100644
--- a/src/Avalonia.Visuals/Media/GlyphRun.cs
+++ b/src/Avalonia.Visuals/Media/GlyphRun.cs
@@ -27,14 +27,6 @@ namespace Avalonia.Media
private ReadOnlySlice _glyphClusters;
private ReadOnlySlice _characters;
- ///
- /// Initializes a new instance of the class.
- ///
- public GlyphRun()
- {
-
- }
-
///
/// Initializes a new instance of the class by specifying properties of the class.
///
@@ -56,7 +48,7 @@ namespace Avalonia.Media
ReadOnlySlice glyphClusters = default,
int biDiLevel = 0)
{
- GlyphTypeface = glyphTypeface;
+ _glyphTypeface = glyphTypeface;
FontRenderingEmSize = fontRenderingEmSize;
@@ -74,13 +66,9 @@ namespace Avalonia.Media
}
///
- /// Gets or sets the for the .
+ /// Gets the for the .
///
- public GlyphTypeface GlyphTypeface
- {
- get => _glyphTypeface;
- set => Set(ref _glyphTypeface, value);
- }
+ public GlyphTypeface GlyphTypeface => _glyphTypeface;
///
/// Gets or sets the em size used for rendering the .
diff --git a/src/Avalonia.Visuals/Media/GlyphTypeface.cs b/src/Avalonia.Visuals/Media/GlyphTypeface.cs
index 2be505b9c0..67dfbb84b6 100644
--- a/src/Avalonia.Visuals/Media/GlyphTypeface.cs
+++ b/src/Avalonia.Visuals/Media/GlyphTypeface.cs
@@ -8,8 +8,8 @@ namespace Avalonia.Media
public const int InvisibleGlyph = 3;
public GlyphTypeface(Typeface typeface)
- : this(FontManager.Current?.PlatformImpl.CreateGlyphTypeface(typeface))
- {
+ : this(FontManager.Current.PlatformImpl.CreateGlyphTypeface(typeface))
+ {
}
public GlyphTypeface(IGlyphTypefaceImpl platformImpl)
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
index 3d3e93dd4d..7c6af4eaa7 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextFormatterImpl.cs
@@ -277,7 +277,7 @@ namespace Avalonia.Media.TextFormatting
var textRuns = new List();
- if (previousLineBreak != null)
+ if (previousLineBreak?.RemainingCharacters != null)
{
for (var index = 0; index < previousLineBreak.RemainingCharacters.Count; index++)
{
@@ -317,7 +317,7 @@ namespace Avalonia.Media.TextFormatting
while (textRunEnumerator.MoveNext())
{
- var textRun = textRunEnumerator.Current;
+ var textRun = textRunEnumerator.Current!;
switch (textRun)
{
@@ -398,7 +398,7 @@ namespace Avalonia.Media.TextFormatting
/// The current line break if the line was explicitly broken.
/// The wrapped text line.
private static TextLine PerformTextWrapping(List textRuns, TextRange textRange,
- double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak currentLineBreak)
+ double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak? currentLineBreak)
{
var availableWidth = paragraphWidth;
var currentWidth = 0.0;
@@ -517,7 +517,7 @@ namespace Avalonia.Media.TextFormatting
var lineBreak = remainingCharacters?.Count > 0 ? new TextLineBreak(remainingCharacters) : null;
- if (lineBreak is null && currentLineBreak.TextEndOfLine != null)
+ if (lineBreak is null && currentLineBreak?.TextEndOfLine != null)
{
lineBreak = new TextLineBreak(currentLineBreak.TextEndOfLine);
}
@@ -586,11 +586,11 @@ namespace Avalonia.Media.TextFormatting
{
_textSource = textSource;
_pos = firstTextSourceIndex;
- Current = null!;
+ Current = null;
}
// ReSharper disable once MemberHidesStaticFromOuterClass
- public TextRun Current { get; private set; }
+ public TextRun? Current { get; private set; }
public bool MoveNext()
{
diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
index a53b43935c..b1397518e4 100644
--- a/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
+++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLineImpl.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using Avalonia.Media.TextFormatting.Unicode;
using Avalonia.Platform;
using Avalonia.Utilities;
@@ -479,12 +480,13 @@ namespace Avalonia.Media.TextFormatting
///
internal static ShapedTextCharacters CreateShapedSymbol(TextRun textRun)
{
- var formatterImpl = AvaloniaLocator.Current.GetService();
+ var properties = textRun.Properties;
- var glyphRun = formatterImpl.ShapeText(textRun.Text, textRun.Properties.Typeface, textRun.Properties.FontRenderingEmSize,
- textRun.Properties.CultureInfo);
+ _ = properties ?? throw new InvalidOperationException($"{nameof(TextRun.Properties)} should not be null.");
- return new ShapedTextCharacters(glyphRun, textRun.Properties);
+ var glyphRun = TextShaper.Current.ShapeText(textRun.Text, properties.Typeface, properties.FontRenderingEmSize, properties.CultureInfo);
+
+ return new ShapedTextCharacters(glyphRun, properties);
}
}
}
diff --git a/src/Avalonia.Visuals/Media/Typeface.cs b/src/Avalonia.Visuals/Media/Typeface.cs
index 859cbafafc..8245b63440 100644
--- a/src/Avalonia.Visuals/Media/Typeface.cs
+++ b/src/Avalonia.Visuals/Media/Typeface.cs
@@ -66,7 +66,7 @@ namespace Avalonia.Media
///
/// The glyph typeface.
///
- public GlyphTypeface? GlyphTypeface => FontManager.Current.GetOrAddGlyphTypeface(this);
+ public GlyphTypeface GlyphTypeface => FontManager.Current.GetOrAddGlyphTypeface(this);
public static bool operator !=(Typeface a, Typeface b)
{
diff --git a/src/Avalonia.Visuals/Media/UnicodeRange.cs b/src/Avalonia.Visuals/Media/UnicodeRange.cs
index 743b9fcc07..0077dd64ac 100644
--- a/src/Avalonia.Visuals/Media/UnicodeRange.cs
+++ b/src/Avalonia.Visuals/Media/UnicodeRange.cs
@@ -37,7 +37,7 @@ namespace Avalonia.Media
internal UnicodeRangeSegment Single => _single;
- internal IReadOnlyList Segments => _segments;
+ internal IReadOnlyList? Segments => _segments;
///
/// Determines if given value is inside the range.