Skip to content

Commit

Permalink
Add the rest of the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mattleibow committed Feb 9, 2024
1 parent 724c65c commit e0aef33
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 18 deletions.
46 changes: 34 additions & 12 deletions binding/SkiaSharp.Resources/ResourceProvider.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.IO;

namespace SkiaSharp.Resources
{
public unsafe class ResourceProvider : SKObject, ISKSkipObjectRegistration
public abstract unsafe class ResourceProvider : SKObject, ISKSkipObjectRegistration
{
internal ResourceProvider (IntPtr handle, bool owns)
: base (handle, owns)
Expand All @@ -18,26 +17,49 @@ protected override void DisposeNative ()

public SKData? Load (string resourcePath, string resourceName) =>
SKData.GetObject (ResourcesApi.skresources_resource_provider_load (Handle, resourcePath, resourceName));
}

public class CachingResourceProvider : ResourceProvider
{
public CachingResourceProvider (ResourceProvider resourceProvider)
: base (Create (resourceProvider), true)
{
}

public static ResourceProvider CreateCaching (ResourceProvider resourceProvider)
public static IntPtr Create (ResourceProvider resourceProvider)
{
_ = resourceProvider ?? throw new ArgumentNullException (nameof (resourceProvider));
return GetObject (ResourcesApi.skresources_caching_resource_provider_proxy_make (resourceProvider.Handle))!;
return ResourcesApi.skresources_caching_resource_provider_proxy_make (resourceProvider.Handle);
}
}

public class DataUriResourceProvider : ResourceProvider
{
public DataUriResourceProvider (bool preDecode = false)
: this (null, preDecode)
{
}

public DataUriResourceProvider (ResourceProvider? fallbackProvider, bool preDecode = false)
: base (Create (fallbackProvider, preDecode), true)
{
}

public static ResourceProvider CreateDataUri (ResourceProvider fallbackProvider, bool preDecode = false)
private static IntPtr Create (ResourceProvider? fallbackProvider, bool preDecode = false) =>
ResourcesApi.skresources_data_uri_resource_provider_proxy_make (fallbackProvider?.Handle ?? IntPtr.Zero, preDecode);
}

public class FileResourceProvider : ResourceProvider
{
public FileResourceProvider (string baseDirectory, bool preDecode = false)
: base (Create (baseDirectory, preDecode), true)
{
_ = fallbackProvider ?? throw new ArgumentNullException (nameof (fallbackProvider));
return GetObject (ResourcesApi.skresources_data_uri_resource_provider_proxy_make (fallbackProvider.Handle, preDecode))!;
}

public static ResourceProvider CreateFile (string baseDirectory, bool preDecode = false)
private static IntPtr Create (string baseDirectory, bool preDecode)
{
using var baseDir = new SKString(baseDirectory ?? throw new ArgumentNullException (nameof (baseDirectory)));
return GetObject (ResourcesApi.skresources_file_resource_provider_make (baseDir.Handle, preDecode))!;
return ResourcesApi.skresources_file_resource_provider_make (baseDir.Handle, preDecode);
}

internal static ResourceProvider? GetObject (IntPtr handle) =>
handle == IntPtr.Zero ? null : new ResourceProvider (handle, true);
}
}
6 changes: 6 additions & 0 deletions binding/SkiaSharp.Skottie/Animation.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.IO;
using SkiaSharp.Resources;
using SkiaSharp.SceneGraph;

namespace SkiaSharp.Skottie
Expand All @@ -20,6 +21,11 @@ void ISKNonVirtualReferenceCounted.UnreferenceNative ()
protected override void DisposeNative ()
=> SkottieApi.skottie_animation_delete (Handle);

// AnimationBuilder

public static AnimationBuilder CreateBuilder (AnimationBuilderFlags flags = AnimationBuilderFlags.None) =>
new AnimationBuilder (flags);

// Parse

public static Animation? Parse (string json) =>
Expand Down
82 changes: 82 additions & 0 deletions binding/SkiaSharp.Skottie/AnimationBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.IO;
using SkiaSharp.Resources;

namespace SkiaSharp.Skottie
{
public sealed unsafe class AnimationBuilder : SKObject, ISKSkipObjectRegistration
{
internal AnimationBuilder (AnimationBuilderFlags flags)
: this (SkottieApi.skottie_animation_builder_new (flags), true)
{
}

internal AnimationBuilder (IntPtr handle, bool owns)
: base (handle, owns)
{
}

public AnimationBuilder SetFontManager (SKFontManager fontManager)
{
_ = fontManager ?? throw new ArgumentNullException (nameof (fontManager));
SkottieApi.skottie_animation_builder_set_font_manager (Handle, fontManager.Handle);
return this;
}

public AnimationBuilder SetResourceProvider (ResourceProvider resourceProvider)
{
_ = resourceProvider ?? throw new ArgumentNullException (nameof (resourceProvider));
SkottieApi.skottie_animation_builder_set_resource_provider (Handle, resourceProvider.Handle);
return this;
}

public AnimationBuilderStats Stats
{
get
{
AnimationBuilderStats stats;
SkottieApi.skottie_animation_builder_get_stats (Handle, &stats);
return stats;
}
}

public Animation? Build (Stream stream)
{
_ = stream ?? throw new ArgumentNullException (nameof (stream));

using var data = SKData.Create (stream);
return Build (data);
}

public Animation? Build (SKStream stream)
{
_ = stream ?? throw new ArgumentNullException (nameof (stream));

using var data = SKData.Create (stream);
return Build (data);
}

public Animation? Build (SKData data)
{
_ = data ?? throw new ArgumentNullException (nameof (data));

var preamble = Utils.GetPreambleSize (data);
var span = data.AsSpan ().Slice (preamble);

fixed (byte* ptr = span) {
return Animation.GetObject (SkottieApi.skottie_animation_builder_make_from_data (Handle, ptr, (IntPtr)span.Length));
}
}

public Animation? Build (string path)
{
_ = path ?? throw new ArgumentNullException (nameof (path));

using var data = SKData.Create (path);
return Build (data);
}

protected override void DisposeNative ()
=> SkottieApi.skottie_animation_builder_delete (Handle);
}
}
21 changes: 21 additions & 0 deletions binding/SkiaSharp.Skottie/AnimationBuilderStats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

using System;

namespace SkiaSharp.Skottie
{
public partial struct AnimationBuilderStats
{
public readonly TimeSpan TotalLoadTime =>
TimeSpan.FromMilliseconds (fTotalLoadTimeMS);

public readonly TimeSpan JsonParseTime =>
TimeSpan.FromMilliseconds (fJsonParseTimeMS);

public readonly TimeSpan SceneParseTime =>
TimeSpan.FromMilliseconds (fSceneParseTimeMS);

public readonly int JsonSize => (int)fJsonSize;

public readonly int AnimatorCount => (int)fAnimatorCount;
}
}
1 change: 1 addition & 0 deletions tests/Content/images/lottie-base64_dotnet-bot.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tests/Content/images/lottie-base64_women-thinking.json

Large diffs are not rendered by default.

24 changes: 20 additions & 4 deletions tests/Tests/Resources/ResourceProviderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public void FileResourceProviderCanReadFiles()
var fullPath = Path.Combine(PathToImages, "baboon.png");
var expectedData = SKData.Create(fullPath);

using var rp = ResourceProvider.CreateFile(PathToImages);
using var rp = new FileResourceProvider(PathToImages);

using var data = rp.Load("baboon.png");

Expand All @@ -26,13 +26,29 @@ public void ProxyProviderCanReadFiles()
var fullPath = Path.Combine(PathToImages, "baboon.png");
var expectedData = SKData.Create(fullPath);

using var files = ResourceProvider.CreateFile(PathToImages);
using var datauri = ResourceProvider.CreateDataUri(files);
using var caching = ResourceProvider.CreateCaching(datauri);
using var files = new FileResourceProvider(PathToImages);
using var datauri = new DataUriResourceProvider(files);
using var caching = new CachingResourceProvider(datauri);

using var data = caching.Load("baboon.png");

Assert.Equal(expectedData.ToArray(), data.ToArray());
}

[SkippableFact]
public void CanCreateDefaultDataUri()
{
using var datauri = new DataUriResourceProvider();

Assert.NotNull(datauri);
}

[SkippableFact]
public void CanCreateNullDataUri()
{
using var datauri = new DataUriResourceProvider(null);

Assert.NotNull(datauri);
}
}
}
98 changes: 98 additions & 0 deletions tests/Tests/Skottie/AnimationBuilderTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using System.IO;
using SkiaSharp.Resources;
using SkiaSharp.SceneGraph;
using SkiaSharp.Skottie;
using Xunit;

namespace SkiaSharp.Tests
{
public class AnimationBuilderTest : SKTest
{
public static TheoryData<string> DefaultLottieFiles =>
AnimationTest.DefaultLottieFiles;

public static TheoryData<string> Base64Files =>
new TheoryData<string>
{
"lottie-base64_dotnet-bot.json",
"lottie-base64_women-thinking.json",
};

[SkippableTheory]
[MemberData(nameof(DefaultLottieFiles))]
public void DefaultBuilderIsTheSameAsDefaultCreate(string filename)
{
var path = Path.Combine(PathToImages, filename);
using var data = SKData.Create(path);
var directAnimation = Animation.Create(data);

var builderAnimation = Animation.CreateBuilder().Build(data);
Assert.NotNull(builderAnimation);
Assert.NotEqual(IntPtr.Zero, builderAnimation.Handle);

Assert.Equal(directAnimation.Duration, builderAnimation.Duration);
Assert.Equal(directAnimation.Fps, builderAnimation.Fps);
Assert.Equal(directAnimation.InPoint, builderAnimation.InPoint);
Assert.Equal(directAnimation.OutPoint, builderAnimation.OutPoint);
Assert.Equal(directAnimation.Version, builderAnimation.Version);
Assert.Equal(directAnimation.Size, builderAnimation.Size);
}

[SkippableTheory]
[MemberData(nameof(DefaultLottieFiles))]
public void DefaultBuilderHasStats(string filename)
{
var path = Path.Combine(PathToImages, filename);
using var data = SKData.Create(path);

var builder = Animation.CreateBuilder();
var animation = builder.Build(data);
Assert.NotNull(animation);

var stats = builder.Stats;
Assert.True(stats.SceneParseTime > TimeSpan.Zero);
Assert.True(stats.JsonParseTime > TimeSpan.Zero);
Assert.True(stats.TotalLoadTime > TimeSpan.Zero);
Assert.True(stats.JsonSize > 0);
Assert.True(stats.AnimatorCount > 0);
}

[SkippableTheory]
[MemberData(nameof(Base64Files))]
public void CanLoadBase64Images(string filename)
{
var path = Path.Combine(PathToImages, filename);
using var data = SKData.Create(path);

var animation = Animation
.CreateBuilder()
.SetResourceProvider(new DataUriResourceProvider())
.Build(data);

Assert.NotNull(animation);
Assert.True(animation.Duration > TimeSpan.Zero);
}

[SkippableTheory]
[MemberData(nameof(Base64Files))]
public void CanRenderWithBase64(string filename)
{
var animation = Animation
.CreateBuilder()
.SetResourceProvider(new DataUriResourceProvider())
.Build(Path.Combine(PathToImages, filename));

using var bmp = new SKBitmap((int)animation.Size.Width, (int)animation.Size.Height);
bmp.Erase(SKColors.Red);
var beforePixels = bmp.Pixels;

using var canvas = new SKCanvas(bmp);
animation.Seek(0.1);
animation.Render(canvas, bmp.Info.Rect);
var afterPixels = bmp.Pixels;

Assert.NotEqual(beforePixels, afterPixels);
}
}
}
41 changes: 39 additions & 2 deletions tests/Tests/Skottie/AnimationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,12 @@ public void When_Default_Create_From_File(string filename)
Assert.NotEqual(IntPtr.Zero, animation.Handle);
}

private Animation BuildDefaultAnimation()
private Animation BuildDefaultAnimation() =>
BuildAnimation("LottieLogo1.json");

private Animation BuildAnimation(string filename)
{
var path = Path.Combine(PathToImages, "LottieLogo1.json");
var path = Path.Combine(PathToImages, filename);
var result = Animation.TryCreate(path, out var animation);

Assert.True(result);
Expand Down Expand Up @@ -307,5 +310,39 @@ public void When_Size()

Assert.Equal(new SKSize(375, 667), animation.Size);
}

[SkippableFact]
public void Can_Render()
{
var animation = BuildDefaultAnimation();

using var bmp = new SKBitmap((int)animation.Size.Width, (int)animation.Size.Height);
bmp.Erase(SKColors.Red);
var beforePixels = bmp.Pixels;

using var canvas = new SKCanvas(bmp);
animation.Seek(0.1);
animation.Render(canvas, bmp.Info.Rect);
var afterPixels = bmp.Pixels;

Assert.NotEqual(beforePixels, afterPixels);
}

[SkippableFact]
public void Can_Not_Render_With_Base64()
{
var animation = BuildAnimation("lottie-base64_dotnet-bot.json");

using var bmp = new SKBitmap((int)animation.Size.Width, (int)animation.Size.Height);
bmp.Erase(SKColors.Red);
var beforePixels = bmp.Pixels;

using var canvas = new SKCanvas(bmp);
animation.Seek(0.1);
animation.Render(canvas, bmp.Info.Rect);
var afterPixels = bmp.Pixels;

Assert.Equal(beforePixels, afterPixels);
}
}
}

0 comments on commit e0aef33

Please sign in to comment.