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.