Version 4.148.0
First stable v4 release · Released June 22, 2026 · NuGet · GitHub Release
Supersedes 4.147.0 · Rolls up preview-only work that was never released as stable — those changes are included cumulatively below.
API changes · SkiaSharp API diff · HarfBuzzSharp API diff
Highlights
SkiaSharp 4.148.0 is the first stable v4 release, built on Skia m148. This release rolls up all 4.147.x preview work and lands it as stable. It adds variable fonts with color palette support, animated WebP encoding, and zero-copy stream and shaper APIs. This is a breaking release — review the changes below before upgrading from v3.
Breaking Changes
- SKFont() default typeface is now SKTypeface.Empty, not null — Upstream m132 removed lazy typeface resolution. new SKFont() now eagerly stores SKTypeface.Empty, so MeasureText returns 0 and nothing is drawn. Migration: always construct with an explicit typeface (new SKFont(SKTypeface.Default)) and detect an unset typeface with font.Typeface.IsEmpty instead of a null check. (#3735)
- SKPaint.Typeface returns SKTypeface.Default instead of null — new SKPaint().Typeface is now SKTypeface.Default (non-null). Text drawing still works, but paint.Typeface == null checks no longer fire. Use paint.Typeface.IsEmpty or remove the null guard. (#3736)
- SKTypeface.FromFamilyName returns Default on all platforms for missing families — Android previously returned null for an unknown font family; all platforms now return SKTypeface.Default. For strict null semantics use SKFontManager.Default.MatchFamily(name) which still returns null on no match. (#3737)
- SKStream.Move(long) is obsolete and throws OverflowException for out-of-range offsets — The cast to the underlying 32-bit int is now checked. Out-of-range values throw OverflowException and the overload is marked [Obsolete]. Migration: call Move(int) with a validated in-range value. (#3740)
- GrVkYcbcrConversionInfo lost value-equality; GRVkImageInfo.YcbcrConversionInfo retyped — GrVkYcbcrConversionInfo no longer implements IEquatable
or == / !=. GRVkImageInfo.YcbcrConversionInfo is now typed as GRVkYcbcrConversionInfo. Update any equality comparisons and struct assignments accordingly. (#3741) - GRVkBackendContextNative — five interop fields removed — fMinAPIVersion, fInstanceVersion, fExtensions, fFeatures, and fOwnsInstanceAndDevice were removed from the native Vulkan backend context struct. Delete those assignments and use fVkExtensions in place of fExtensions, fDeviceFeatures / fDeviceFeatures2 in place of fFeatures. (#3741)
- SKNativeObject.IgnorePublicDispose setter removed — The protected setter on SKNativeObject.IgnorePublicDispose is gone; the property is now read-only. Subclasses that assigned this field must be updated.
- SKPaint legacy text/font members promoted to compile errors — All SKPaint text/font properties that were obsoleted in v3 (TextSize, Typeface on paint, etc.) are now compile errors in v4. Migrate to SKFont and pass the font to drawing calls. (#4068, #4114)
Engine
- Skia upgraded from m132 through m148 — The bundled Skia engine spans milestones 132, 133, 147, and 148, bringing upstream bug fixes, performance improvements, and layout improvements across all platforms. — ❤️ @ramezgerges (#3560, #3660, #3702, #4044, #4081, #4125)
API Surface
- Variable font support with color palette API — Variable fonts are now fully supported through axis value APIs. Color font palettes can be enumerated and selected, enabling rich typographic effects without extra libraries. — ❤️ @ramezgerges (#3703, #3742)
- Animated WebP encoding via SKWebpEncoder — SKWebpEncoder now supports multi-frame animated WebP output, filling a long-standing gap between SkiaSharp and the upstream Skia encoder. (#3771)
- Zero-copy stream-to-data conversion with SKStream.GetData() — SKStream.GetData() wraps the underlying buffer as an SKData without copying, enabling efficient conversion from streams to data objects in hot paths. (#3772)
- SKSurface.Draw and SKCanvas.DrawSurface gain SKSamplingOptions overloads — Both drawing methods now accept an SKSamplingOptions parameter for fine-grained control over resampling quality when blitting surfaces. (#3491)
- HarfBuzzSharp HBColor struct and missing API wrappers added — A proper HBColor struct replaces raw uint for hb_color_t, and several missing HarfBuzz API wrappers were added along with naming-convention fixes. (#4000, #4001)
Bug Fixes
- SKPixmap and SKBitmap GetPixelSpan offsets corrected — GetPixelSpan(x, y) previously used Height instead of Width for the x offset and ignored RowBytes for stride. Both are now correct, fixing pixel-access bugs on non-packed bitmaps. (#4128, #4148)
- SKPath finalizer crash when SKPathBuilder is collected first — A race between the SKPath finalizer and an already-collected SKPathBuilder caused native crashes. The object graph is now managed correctly. — ❤️ @ramezgerges (#3796)
- Default typeface resolution moved to the managed layer — The native sk_typeface_ref_default path was replaced by font-manager resolution in managed code, fixing a crash on Android API 36+ and ensuring a non-null default on every platform. — ❤️ @ramezgerges (#3730)
- SKGLView renders correctly after tab switch in MAUI TabBar on Android — The GL surface was not being re-initialized after the view was detached and re-attached during a tab switch, causing a blank canvas. This is now handled correctly. — ❤️ @SimonvBez (#3076)
- WinUI: Projection DLL resolution fixed for .NET 9 consumers — The WinUI3 projection DLL was not found at runtime under .NET 9, causing startup failures. The reference has been corrected. (#4084)
- Native compatibility check moved from ModuleInitializer to SkiaApi constructor — The native-compat gate now runs at first use rather than module load, avoiding spurious failures in environments that load the assembly without invoking SkiaSharp. (#4133)
Lifecycle & Internals
- Singleton instance lifecycle fully reworked — SKObject singleton instances (shared handles that must not be disposed by their wrapper) are now tracked through a proper weak-reference registry, eliminating a class of use-after-free bugs. — ❤️ @ramezgerges (#4080)
Platform
- Linux Bionic (Android NDK sysroot) native assets added — Native binaries for the Linux Bionic ABI are now included, enabling SkiaSharp on environments that use the Android NDK sysroot on Linux. — ❤️ @4Darmygeometry (#3217)
- Tizen x64 and arm64 native builds added — The Tizen platform now ships native builds for both x64 and arm64 architectures. (#3620)
- Apple TFMs corrected: versioned for libraries, unversioned for apps — Apple-platform TFMs are now set to 26.0 for library projects and the unversioned form for app projects, aligning with Apple SDK and .NET conventions. (#3798)
- WASM pre-.NET 8 Emscripten builds dropped — Native WASM builds targeting Emscripten versions before the .NET 8 baseline have been removed, reducing CI surface and aligning with the minimum supported toolchain. (#4022)
Security
- Native dependency refreshes: libexpat, libpng, zlib, freetype, libjpeg-turbo, expat, harfbuzz — All bundled native libraries were updated to their latest releases, addressing known CVEs and bringing upstream security fixes. (#3717, #3718, #3720, #3726, #4012, #4035, #4079)
HarfBuzzSharp 14.2.0
HarfBuzzSharp 14.2.0 ships with this release, adding the HBColor struct for proper color type representation, missing API wrappers, and the underlying harfbuzz library updated to 14.2.0.
Community Contributors ❤️
Thank you to everyone who contributed to this release!
| Contributor | Contributions |
|---|---|
| @ramezgerges | Variable font axis and color palette APIs, singleton lifecycle rework, SKPath finalizer fix, HarfBuzz buffer improvements, and Uno gallery sample updates (#3560, #3666, #3692, #3702, #3703, #3714, #3730, #3758, #3762, #3785, #3790, #3796, #3821, #3867, #4068, #4080) |
| @4Darmygeometry | Linux Bionic native asset support and HarfBuzz color API additions (#3217, #3642) |
| @ebariche | Uno gallery Skottie package fix (#3849) |
| @sasakrsmanovic | API naming convention audit and fixes (#3966) |
| @SimonvBez | SKGLView MAUI TabBar re-render fix on Android (#3076) |
Release Candidate 1 (June 12, 2026)
Release Candidate 1 landed the final Skia m148 upgrade, the singleton lifecycle rework, SKPaint legacy API promotion to errors, pixel-access bug fixes, and the WinUI .NET 9 projection fix. It also completed the variable font and animated WebP work from earlier previews.
Preview 3 (May 24, 2026)
Preview 3 added HarfBuzz 14.2.0, animated WebP encoding, zero-copy SKStream.GetData(), SKSamplingOptions overloads for DrawSurface, HBColor struct, libjpeg-turbo and expat refreshes, and merged the chrome/m147 upstream bug-fix sync.
Preview 2 (May 6, 2026)
Preview 2 delivered animated WebP encoding groundwork, Tizen native builds, Apple TFM corrections, and the SKPath finalizer fix, along with a broad round of CI and infrastructure improvements.
Preview 1 (April 28, 2026)
Preview 1 opened the v4 line: Skia milestones 132 through 147, variable fonts and color palettes, Linux Bionic assets, the managed default-typeface rework, PolySharp for C# 13 on legacy TFMs, and the SKGLView TabBar fix.