Skip to content

Commit

Permalink
Add and remove the compatibility APIs (#2789)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattleibow committed Apr 8, 2024
1 parent a290ccf commit 647403d
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 25 deletions.
4 changes: 4 additions & 0 deletions binding/SkiaSharp/SKCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,10 @@ public void ResetMatrix ()
public void SetMatrix (in SKMatrix matrix) =>
SetMatrix ((SKMatrix44)matrix);

[Obsolete("Use SetMatrix(in SKMatrix) instead.", true)]
public void SetMatrix (SKMatrix matrix) =>
SetMatrix (in matrix);

public void SetMatrix (in SKMatrix44 matrix)
{
fixed (SKMatrix44* ptr = &matrix) {
Expand Down
36 changes: 36 additions & 0 deletions binding/SkiaSharp/SKImageFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ protected override void Dispose (bool disposing) =>

// CreateMatrix

[Obsolete("Use SetMatrix(in SKMatrix) instead.", true)]
public static SKImageFilter CreateMatrix (SKMatrix matrix) =>
CreateMatrix (in matrix);

[Obsolete("Use SetMatrix(in SKMatrix, SKSamplingOptions, SKImageFilter) instead.", true)]
public static SKImageFilter CreateMatrix (SKMatrix matrix, SKFilterQuality quality, SKImageFilter? input) =>
CreateMatrix (in matrix, quality.ToSamplingOptions (), input);

public static SKImageFilter CreateMatrix (in SKMatrix matrix) =>
CreateMatrix (matrix, SKSamplingOptions.Default, null);

Expand All @@ -29,6 +37,14 @@ public static SKImageFilter CreateMatrix (in SKMatrix matrix, SKSamplingOptions

// CreateAlphaThreshold

[Obsolete("Use CreateAlphaThreshold(SKRegion, float, float, SKImageFilter) instead.", true)]
public static SKImageFilter CreateAlphaThreshold(SKRectI region, float innerThreshold, float outerThreshold, SKImageFilter? input)
{
var reg = new SKRegion ();
reg.SetRect (region);
return CreateAlphaThreshold (reg, innerThreshold, outerThreshold, input);
}

public static SKImageFilter CreateAlphaThreshold (SKRegion region, float innerThreshold, float outerThreshold) =>
CreateAlphaThreshold (region, innerThreshold, outerThreshold, null);

Expand Down Expand Up @@ -376,6 +392,10 @@ public static SKImageFilter CreateImage (SKImage image, SKRect src, SKRect dst,
return GetObject (SkiaApi.sk_imagefilter_new_image (image.Handle, &src, &dst, &sampling));
}

[Obsolete("Use CreateImage(SKImage, SKRect, SKRect, SKSamplingOptions) instead.", true)]
public static SKImageFilter CreateImage (SKImage image, SKRect src, SKRect dst, SKFilterQuality filterQuality) =>
CreateImage (image, src, dst, filterQuality.ToSamplingOptions ());

// CreateMagnifier

public static SKImageFilter CreateMagnifier (SKRect lensBounds, float zoomAmount, float inset, SKSamplingOptions sampling) =>
Expand All @@ -390,6 +410,22 @@ public static SKImageFilter CreateMagnifier (SKRect lensBounds, float zoomAmount
private static SKImageFilter CreateMagnifier (SKRect lensBounds, float zoomAmount, float inset, SKSamplingOptions sampling, SKImageFilter? input, SKRect* cropRect) =>
GetObject (SkiaApi.sk_imagefilter_new_magnifier (&lensBounds, zoomAmount, inset, &sampling, input?.Handle ?? IntPtr.Zero, cropRect));

// CreatePaint

[Obsolete("Use CreateShader(SKShader) instead.", true)]
public static SKImageFilter CreatePaint (SKPaint paint)
{
_ = paint ?? throw new ArgumentNullException (nameof (paint));
return CreateShader(paint.Shader, paint.IsDither, null);
}

[Obsolete("Use CreateShader(SKShader, bool, SKRect) instead.", true)]
public static SKImageFilter CreatePaint (SKPaint paint, SKRect cropRect)
{
_ = paint ?? throw new ArgumentNullException (nameof (paint));
return CreateShader(paint.Shader, paint.IsDither, &cropRect);
}

// CreateShader

public static SKImageFilter CreateShader (SKShader? shader) =>
Expand Down
15 changes: 13 additions & 2 deletions binding/SkiaSharp/SKPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,11 @@ public bool Contains (float x, float y) =>
public void Offset (SKPoint offset) =>
Offset (offset.X, offset.Y);

public void Offset (float dx, float dy) =>
Transform (SKMatrix.CreateTranslation (dx, dy));
public void Offset (float dx, float dy)
{
var matrix = SKMatrix.CreateTranslation (dx, dy);
Transform (in matrix);
}

public void MoveTo (SKPoint point) =>
SkiaApi.sk_path_move_to (Handle, point.X, point.Y);
Expand Down Expand Up @@ -340,6 +343,14 @@ public void Transform (in SKMatrix matrix, SKPath destination)
SkiaApi.sk_path_transform_to_dest (Handle, m, destination.Handle);
}

[Obsolete("Use Transform(in SKMatrix) instead.", true)]
public void Transform (SKMatrix matrix) =>
Transform (in matrix);

[Obsolete("Use Transform(in SKMatrix matrix, SKPath destination) instead.", true)]
public void Transform (SKMatrix matrix, SKPath destination) =>
Transform (in matrix, destination);

public void AddPath (SKPath other, float dx, float dy, SKPathAddMode mode = SKPathAddMode.Append)
{
if (other == null)
Expand Down
1 change: 1 addition & 0 deletions binding/SkiaSharp/SkiaSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<AssemblyName>SkiaSharp</AssemblyName>
<PackagingGroup>SkiaSharp</PackagingGroup>
<Nullable>enable</Nullable>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('net4'))">
<DefineConstants>$(DefineConstants);USE_DELEGATES</DefineConstants>
Expand Down
91 changes: 73 additions & 18 deletions changelogs/SkiaSharp/3.0.0/SkiaSharp.humanreadable.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
# API diff: SkiaSharp.dll

## SkiaSharp.dll

> Assembly Version Changed: 3.0.0.0 vs 2.88.0.0
### Major Changes
# SkiaSharp 3.x Changes

The diff below contains all the changes that are in addition to the removal of obsolete types and members. The 3.x release is a major upgrade and many of the obsolete types and members needed to go away.

#### Platform Reduction
**Contents**

SkiaSharp supports many platforms, however in 3.x we reduce the platforms to just the more modern ones:
* [Improvements](#improvements)
There are many new APIs and improvements to exisitng features.
* [Breaking Changes](#breaking-changes)
In order to update to the latest skia builds and to keep the library maintainable, we unfortunately had to make some hard choices and remove some old APIs.
* [Platform Reduction](#platform-reduction)
In order to move forward, we had to reduce our supported platforms. However, all the modern and supported .NET platforms are still there.
* [ABI Breaking Changes](#abi-breaking-changes)
Unfortunately several APIs had to be dropped. This could be that the new skia engine does not support a feature or it was not working previously.
* [Removed `[Obsolete]` Types and Members](#removed-obsolete-types-and-members)
Several obsolete APIs were removed as they have been marked for removal for several years now. In most cases, there are already alternatives that you can use instead.
* [Analysis and Tooling](#analysis-and-tooling)
Because some breaking changes are hard to detect and since SkiaSharp is so widely used, we have put together some tooling to help you detect those breaking APIs before you even update.
* [Newly Obsoleted Types and Members](#newly-obsoleted-types-and-members)
The new version of skia does things a bit differently in some places, so some existing APIs are no longer relevant or there are better APIs to use.
* [API diff: SkiaSharp.dll](#api-diff-skiasharpdll)
This is a more readable diff of SkiaSharp as the full diff is really long and has many changes that are not really relevant.

* .NET Standard 2.0+
* .NET Framework 4.6.2+
* .NET 7+ (All the platforms: Android, iOS, Mac Catalyst, macOS, Tizen, tvOS, Windows)

#### Improvements
## Improvements

There are some small improvements in the initial release of 3.x, and many more will be added with later builds.

Expand All @@ -30,9 +36,19 @@ There are some small improvements in the initial release of 3.x, and many more w
* CPU is NOT accelerated and may be very slow.
* `SKMatrix44` is now a high-performance struct that can be used on any `SKCanvas`.

#### Breaking Changes
## Breaking Changes

With the major update from 2x to 3x, some APIs were broken to make maintainance easier as well as to simplify things for consumers.
With the major update from 2.x to 3.x, some APIs were broken to make maintainance easier as well as to simplify things for consumers.

### Platform Reduction

SkiaSharp supports many platforms, however in 3.x we reduce the platforms to just the more modern ones:

* .NET Standard 2.0+
* .NET Framework 4.6.2+
* .NET 7+ (All the platforms: Android, iOS, Mac Catalyst, macOS, Tizen, tvOS, Windows)

### ABI Breaking Changes

Below is a list of notable breaking changes.

Expand All @@ -45,7 +61,7 @@ Below is a list of notable breaking changes.
* `SK3dView` was removed because it was expensive to use
The new `SKMatrix44` can do all the same things as well as just using `System.Numerics.Matrix4x4` and related `System.Numerics` types.

##### Removed [Obsolete] Types and Members
### Removed `[Obsolete]` Types and Members

Many types and members were obsoleted at trhe start of the 2.x version (and some before).
The 3.x release will be removing all the members that were previously marked `[Obsolete]`.
Expand All @@ -63,9 +79,44 @@ Some of the notable removals are:
* `SKMask` - All types and members relating to `SKMask` have been removed.
* `SKXmlWriter` - All types and members relating to `SKXmlWriter` and `SKXmlStreamWriter` have been removed.

#### Obsoleted Types and Members
### Analysis and Tooling

If you are upgrading to SkiaSharp 3.x, you may be interested in using the [`api-tools` .NET CLI tool](https://nuget.org/packages/api-tools) to help identify any usages of removed types.

There is [full documentation available](https://github.com/mattleibow/Mono.ApiTools.NuGetDiff/blob/5c14bf43a6a587c2fd2878c7884ff1db6a9beca1/docs/api-tools.md#compat-command), but the `api-tools` CLI tool can be used to find all usages of missing types and members:

```sh
dotnet api-tools compat Svg.Skia/Svg.Skia.dll SkiaSharp/v3/SkiaSharp.dll
```

This will produce an output similar to:

```xml
<?xml version="1.0" encoding="utf-8"?>
<assemblies>
<assembly>
<types>
<type fullname="SkiaSharp.SKImageFilter/CropRect" />
<type fullname="SkiaSharp.SKCropRectFlags" />
</types>
<members>
<member fullname="System.Void SkiaSharp.SKImageFilter/CropRect::.ctor(SkiaSharp.SKRect,SkiaSharp.SKCropRectFlags)" />
<member fullname="SkiaSharp.SKImageFilter SkiaSharp.SKImageFilter::CreateMerge(SkiaSharp.SKImageFilter[],SkiaSharp.SKImageFilter/CropRect)" />
<member fullname="SkiaSharp.SKImageFilter SkiaSharp.SKImageFilter::CreatePaint(SkiaSharp.SKPaint,SkiaSharp.SKImageFilter/CropRect)" />
<!-- several other items -->
<member fullname="System.Void SkiaSharp.SKPath::Transform(SkiaSharp.SKMatrix)" />
<member fullname="System.Void SkiaSharp.SKCanvas::SetMatrix(SkiaSharp.SKMatrix)" />
</members>
</assembly>
</assemblies>
```

This output indicates that there are several usages of missing types and members. However, in many cases, there are overloads or alternate APIs that can be used that are present in both 2.x and 3.x versions of SkiaSharp.


## Newly Obsoleted Types and Members

With the major update from 2x to 3x, several APIs are no longer the recommeneded way to do something. There might be a better or cleaner way of doing something. For all of these types and members, they will be marked `[Obsolete]` and removed in the next major release.
With the major update from 2.x to 3.x, several APIs are no longer the recommeneded way to do something. There might be a better or cleaner way of doing something. For all of these types and members, they will be marked `[Obsolete]` and removed in the next major release.

Some of the notable obsolete items are:

Expand All @@ -74,6 +125,10 @@ Some of the notable obsolete items are:
* `SKFont` & `SKPaint` - All the "font-related" members on `SKPaint` have been marked obsolete and now exist on `SKFont`.
In previous skia versions, the `SKPaint` functionality was split into 2 objects: `SKPaint` and `SKFont`. SkiaSharp tried to maintain 100% backwards compatibility by re-merginf the types. However, this is getting hard to maintain. As a result, `SKFont` is now the correct replacement to work with typefaces and character styles. All APIs tha accepted just a `SKPaint` now also have an overload that accepts `SKFont` and `SKTextAlign`.

## API diff: SkiaSharp.dll

> Assembly Version Changed: 3.0.0.0 vs 2.88.0.0
### Namespace SkiaSharp

#### Type Changed: SkiaSharp.GRGlFramebufferInfo
Expand Down
4 changes: 4 additions & 0 deletions source/SkiaSharp.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,13 @@
</PropertyGroup>

<PropertyGroup>
<!-- Setup debug symbols -->
<DebugType>portable</DebugType>
<DebugSymbols>true</DebugSymbols>
<!-- We have a lot of unsafe code -->
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<!-- We don't use the build output so don't do extra work -->
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
</PropertyGroup>

<PropertyGroup Condition=" '$(TF_BUILD)' == 'true' or '$(GITHUB_ACTIONS)' == 'true' or '$(CI)' == 'true' ">
Expand Down
18 changes: 18 additions & 0 deletions source/SkiaSharp.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ internal partial class VersionConstants {
</ItemGroup>
</Target>

<!--
===================================================================================================================
_RemoveObsoleteItemsFromReferenceAssembly
Remove all the [Obsolete(error: true)] symbols from the reference assembly.
===================================================================================================================
-->
<ItemGroup Condition="'$(ProduceReferenceAssembly)' == 'true'">
<PackageReference Include="Mono.ApiTools.MSBuildTasks" Version="0.3.0" PrivateAssets="all" />
</ItemGroup>
<Target Name="_RemoveObsoleteItemsFromReferenceAssembly"
AfterTargets="CoreCompile"
Condition="'$(ProduceReferenceAssembly)' == 'true'">
<RemoveObsoleteSymbols Assembly="@(IntermediateRefAssembly)" />
</Target>

<!--
===================================================================================================================
_SignAssembly
Expand All @@ -157,6 +173,7 @@ internal partial class VersionConstants {
AfterTargets="$(_SignAssemblyAfterTargets)"
Condition=" $(IsWindows) and '$(SignAssembly)' == 'true' and '$(TargetPath)' != '' and '$(BuildingInsideVisualStudio)' != 'true' ">
<Exec Command="&quot;$(_SnExePath)&quot; -q -R @(IntermediateAssembly -> '&quot;%(Identity)&quot;') &quot;$(AssemblyOriginatorKeyFile)&quot;" />
<Exec Command="&quot;$(_SnExePath)&quot; -q -R @(IntermediateRefAssembly -> '&quot;%(Identity)&quot;') &quot;$(AssemblyOriginatorKeyFile)&quot;" Condition="'$(ProduceReferenceAssembly)' == 'true'" />
</Target>

<!--
Expand All @@ -175,6 +192,7 @@ internal partial class VersionConstants {
AfterTargets="$(_SignAssemblyVerifyAfterTargets)"
Condition=" $(IsWindows) and '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' and '$(BuildingInsideVisualStudio)' != 'true' ">
<Exec Command="&quot;$(_SnExePath)&quot; -vf &quot;$(TargetPath)&quot;" StandardOutputImportance="Normal" />
<Exec Command="&quot;$(_SnExePath)&quot; -vf &quot;$(TargetRefPath)&quot;" StandardOutputImportance="Normal" Condition="'$(ProduceReferenceAssembly)' == 'true'" />
</Target>

<!--
Expand Down
67 changes: 62 additions & 5 deletions source/SkiaSharp.NuGet.targets
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,14 @@ $(PackageNotes)</PackageDescription>
<None Include="@(PackageFile)" Link="%(PackagePath)" Pack="True" />
</ItemGroup>

<!-- Generate the README -->
<Target Name="_IncludeAdditionalPackageFiles"
<!--
===================================================================================================================
_GeneratePackageReadmeFile
Generate the package README file.
===================================================================================================================
-->
<Target Name="_GeneratePackageReadmeFile"
BeforeTargets="_GetPackageFiles"
Condition="'$(PackageDescription)' != ''">
<WriteLinesToFile File="$(IntermediateOutputPath)$(PackageReadmeFile)" Lines="$(PackageDescription)" Overwrite="True" />
Expand All @@ -34,23 +40,74 @@ $(PackageNotes)</PackageDescription>
</ItemGroup>
</Target>

<!-- Add the xml docs -->
<!--
===================================================================================================================
_IncludeAdditionalTfmSpecificPackageFilesPrepare
Create all the properties needed to add additional files.
===================================================================================================================
-->
<Target Name="_IncludeAdditionalTfmSpecificPackageFilesPrepare">
<GetNuGetShortFolderName
TargetFrameworkMoniker="$(TargetFrameworkMoniker)"
TargetPlatformMoniker="$(TargetPlatformMoniker)">
<Output TaskParameter="NuGetShortFolderName" PropertyName="NuGetShortFolderName" />
</GetNuGetShortFolderName>
</Target>

<!--
===================================================================================================================
IncludeMDocTfmSpecificPackageFiles
Include the XML docs in the package.
===================================================================================================================
-->
<Target Name="IncludeMDocTfmSpecificPackageFiles">
<ItemGroup>
<TfmSpecificPackageFile Include="$(MDocOutputPath)" PackagePath="lib\$(NuGetShortFolderName)\$(MDocOutputName)"
Exclude="@(DocumentationProjectOutputGroupOutput)" Condition="Exists('$(MDocOutputPath)')" />
</ItemGroup>
</Target>

<!--
===================================================================================================================
IncludeReferenceAssemblyTfmSpecificPackageFiles
Include the reference assembly in the package.
===================================================================================================================
-->
<Target Name="IncludeReferenceAssemblyTfmSpecificPackageFiles">
<ItemGroup>
<TfmSpecificPackageFile Include="$(TargetRefPath)" PackagePath="ref\$(NuGetShortFolderName)\$(TargetFileName)"
Condition="Exists('$(TargetRefPath)')" />
</ItemGroup>
</Target>

<!--
===================================================================================================================
_IncludeAdditionalTfmSpecificPackageFiles
Include all the additional files in the package.
===================================================================================================================
-->
<PropertyGroup>
<_IncludeAdditionalTfmSpecificPackageFilesDependsOn>
_IncludeAdditionalTfmSpecificPackageFilesPrepare;
IncludeMDocTfmSpecificPackageFiles;
IncludeReferenceAssemblyTfmSpecificPackageFiles;
IncludeAdditionalTfmSpecificPackageFiles;
</_IncludeAdditionalTfmSpecificPackageFilesDependsOn>
</PropertyGroup>
<Target Name="_IncludeAdditionalTfmSpecificPackageFiles"
DependsOnTargets="_IncludeAdditionalTfmSpecificPackageFilesPrepare;IncludeAdditionalTfmSpecificPackageFiles" />
DependsOnTargets="$(_IncludeAdditionalTfmSpecificPackageFilesDependsOn)" />

<!--
===================================================================================================================
_IncludeAdditionalVersionInfo
<!-- Set the package version properties -->
Set the package version properties.
===================================================================================================================
-->
<Target Name="_IncludeAdditionalVersionInfo">
<PropertyGroup>
<PackageVersion>$(Version)</PackageVersion>
Expand Down

0 comments on commit 647403d

Please sign in to comment.