From ac4b7ac23c4b8e0d4db8b3b609c68b09d4cb5537 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 31 Jul 2026 03:28:30 +1000 Subject: [PATCH] Add IImageBrushSource.GetBitmap(), update build/api suppressions (#21638) * Expose IRef/IImageBrushSource, update build/api suppressions * Hide IRef from image brush source API Internalized `IRef` and removed it from the `IImageBrushSource` public surface by making `Bitmap` internal. Added a `[PrivateApi]` `GetBitmap()` helper returning `IBitmapImpl?` so internal consumers can still access the bitmap without exposing ref-count internals. Updated Skia drawing code to use `GetBitmap()` and refreshed API suppression entries accordingly. --- Directory.Build.props | 2 ++ api/Avalonia.nupkg.xml | 12 ++++++++++++ src/Avalonia.Base/Media/IImageBrush.cs | 12 ++++++++++++ src/Avalonia.Base/Utilities/Ref.cs | 6 +++++- src/Skia/Avalonia.Skia/DrawingContextImpl.cs | 2 +- 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 400198daf9..931a386d31 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -10,6 +10,8 @@ 14.0 $(AvnTreatWarningsAsErrors) true + + $(NoWarn);NU1507 true true true diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml index ce13834a0b..ab26c5e135 100644 --- a/api/Avalonia.nupkg.xml +++ b/api/Avalonia.nupkg.xml @@ -157,6 +157,12 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0006 + P:Avalonia.Media.IImageBrushSource.Bitmap + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0006 M:Avalonia.Controls.Platform.IWin32OptionsTopLevelImpl.SetWindowCornerPreference(Avalonia.Controls.Win32Properties.WindowCornerPreference) @@ -181,6 +187,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0006 + P:Avalonia.Media.IImageBrushSource.Bitmap + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0006 M:Avalonia.Controls.Platform.IWin32OptionsTopLevelImpl.SetWindowCornerPreference(Avalonia.Controls.Win32Properties.WindowCornerPreference) diff --git a/src/Avalonia.Base/Media/IImageBrush.cs b/src/Avalonia.Base/Media/IImageBrush.cs index 439a9401d5..0852f55e8f 100644 --- a/src/Avalonia.Base/Media/IImageBrush.cs +++ b/src/Avalonia.Base/Media/IImageBrush.cs @@ -17,9 +17,21 @@ namespace Avalonia.Media IImageBrushSource? Source { get; } } + /// + /// Provides access to the image source of an . + /// [NotClientImplementable] public interface IImageBrushSource { internal IRef? Bitmap { get; } + + /// + /// Gets the bitmap implementation of the image source. + /// + /// + /// The instance if available; otherwise, null. + /// + [PrivateApi] + IBitmapImpl? GetBitmap() => Bitmap?.Item; } } diff --git a/src/Avalonia.Base/Utilities/Ref.cs b/src/Avalonia.Base/Utilities/Ref.cs index 49a7a42710..499bd1bf02 100644 --- a/src/Avalonia.Base/Utilities/Ref.cs +++ b/src/Avalonia.Base/Utilities/Ref.cs @@ -7,7 +7,11 @@ namespace Avalonia.Utilities /// /// A ref-counted wrapper for a disposable object. /// - /// + /// + /// The type of the item being ref-counted. + /// Must be a reference type to avoid issues with copying value types and must be disposable + /// to ensure the item is cleaned up when the refcount reaches 0. + /// internal interface IRef : IDisposable where T : class { /// diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 8fd2454f33..03fa3d7686 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -1428,7 +1428,7 @@ namespace Avalonia.Skia } else { - tileBrushImage = (tileBrush as IImageBrush)?.Source?.Bitmap?.Item as IDrawableBitmapImpl; + tileBrushImage = (tileBrush as IImageBrush)?.Source?.GetBitmap() as IDrawableBitmapImpl; } if (tileBrush != null && tileBrushImage != null)