Browse Source

All known crashes fixed

flabbet 2 years ago
parent
commit
e4b0323cba
51 changed files with 290 additions and 93 deletions
  1. 1 0
      src/ChunkyImageLib/Chunk.cs
  2. 1 0
      src/ChunkyImageLib/ChunkyImage.cs
  3. 1 0
      src/ChunkyImageLib/ChunkyImageEx.cs
  4. 1 1
      src/ChunkyImageLib/ChunkyImageLib.csproj
  5. 1 0
      src/ChunkyImageLib/CommittedChunkStorage.cs
  6. 1 1
      src/ChunkyImageLib/DataHolders/ColorBounds.cs
  7. 1 0
      src/ChunkyImageLib/IReadOnlyChunkyImage.cs
  8. 1 0
      src/ChunkyImageLib/Operations/BresenhamLineOperation.cs
  9. 1 0
      src/ChunkyImageLib/Operations/DrawingSurfaceLineOperation.cs
  10. 1 0
      src/ChunkyImageLib/Operations/EllipseOperation.cs
  11. 1 0
      src/ChunkyImageLib/Operations/ImageOperation.cs
  12. 1 0
      src/ChunkyImageLib/Operations/PathOperation.cs
  13. 1 0
      src/ChunkyImageLib/Operations/PixelOperation.cs
  14. 1 0
      src/ChunkyImageLib/Operations/PixelsOperation.cs
  15. 2 2
      src/ChunkyImageLib/Operations/ReplaceColorOperation.cs
  16. 7 7
      src/ChunkyImageLib/Shaders/ReplaceColorShader.cs
  17. 3 3
      src/ChunkyImageLib/Shaders/ShaderUtils.cs
  18. 2 1
      src/ChunkyImageLib/Surface.cs
  19. 1 0
      src/PixiEditor.ChangeableDocument/Changes/Drawing/ChangeBrightness_UpdateableChange.cs
  20. 1 0
      src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFillChunkCache.cs
  21. 1 0
      src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs
  22. 1 0
      src/PixiEditor.ChangeableDocument/Changes/Drawing/PasteImage_UpdateableChange.cs
  23. 1 0
      src/PixiEditor.ChangeableDocument/Changes/Drawing/TransformSelectedArea_UpdateableChange.cs
  24. 1 0
      src/PixiEditor.ChangeableDocument/Changes/Root/ResizeImage_Change.cs
  25. 1 0
      src/PixiEditor.ChangeableDocument/Rendering/ChunkRenderer.cs
  26. 1 0
      src/PixiEditor.ChangeableDocument/Rendering/RenderingContext.cs
  27. 3 3
      src/PixiEditor.DrawingApi.Core/Bridge/DrawingBackendApi.cs
  28. 16 0
      src/PixiEditor.DrawingApi.Core/Bridge/NativeObjectsImpl/IPaintImplementation.cs
  29. 1 0
      src/PixiEditor.DrawingApi.Core/Bridge/Operations/ICanvasImplementation.cs
  30. 2 0
      src/PixiEditor.DrawingApi.Core/Bridge/Operations/ISurfaceImplementation.cs
  31. 1 1
      src/PixiEditor.DrawingApi.Core/Surface/Bitmap.cs
  32. 2 2
      src/PixiEditor.DrawingApi.Core/Surface/Canvas.cs
  33. 6 7
      src/PixiEditor.DrawingApi.Core/Surface/DrawingSurface.cs
  34. 1 0
      src/PixiEditor.DrawingApi.Core/Surface/ImageData/ColorSpace.cs
  35. 0 5
      src/PixiEditor.DrawingApi.Core/Surface/ImageData/Image.cs
  36. 2 2
      src/PixiEditor.DrawingApi.Core/Surface/ImageData/ImageInfo.cs
  37. 1 1
      src/PixiEditor.DrawingApi.Core/Surface/NativeObject.cs
  38. 41 8
      src/PixiEditor.DrawingApi.Core/Surface/PaintImpl/Paint.cs
  39. 3 1
      src/PixiEditor.DrawingApi.Core/Surface/PaintImpl/StrokeCap.cs
  40. 4 11
      src/PixiEditor.DrawingApi.Skia/CastUtility.cs
  41. 12 2
      src/PixiEditor.DrawingApi.Skia/ConversionExtensions.cs
  42. 1 1
      src/PixiEditor.DrawingApi.Skia/Implementations/SKObjectImplementation.cs
  43. 17 8
      src/PixiEditor.DrawingApi.Skia/Implementations/SkiaCanvasImplementation.cs
  44. 8 1
      src/PixiEditor.DrawingApi.Skia/Implementations/SkiaColorSpaceImplementation.cs
  45. 95 4
      src/PixiEditor.DrawingApi.Skia/Implementations/SkiaPaintImplementation.cs
  46. 25 16
      src/PixiEditor.DrawingApi.Skia/Implementations/SkiaSurfaceImplementation.cs
  47. 5 5
      src/PixiEditor.DrawingApi.Skia/SkiaDrawingBackend.cs
  48. 1 0
      src/PixiEditor/Models/IO/Importer.cs
  49. 1 0
      src/PixiEditor/Models/Rendering/WriteableBitmapUpdater.cs
  50. 1 0
      src/PixiEditor/PixiEditor.csproj
  51. 5 0
      src/PixiEditor/Views/MainWindow.xaml.cs

+ 1 - 0
src/ChunkyImageLib/Chunk.cs

@@ -1,6 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib;
 

+ 1 - 0
src/ChunkyImageLib/ChunkyImage.cs

@@ -6,6 +6,7 @@ using OneOf.Types;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 
 [assembly: InternalsVisibleTo("ChunkyImageLibTest")]

+ 1 - 0
src/ChunkyImageLib/ChunkyImageEx.cs

@@ -2,6 +2,7 @@
 using ChunkyImageLib.Operations;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib;
 public static class IReadOnlyChunkyImageEx

+ 1 - 1
src/ChunkyImageLib/ChunkyImageLib.csproj

@@ -9,7 +9,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="ComputeSharp.Core" Version="2.0.0-alpha.27" />
+    <PackageReference Include="ComputeSharp.Core" Version="2.0.0-alpha.28" />
     <PackageReference Include="ComputeSharp.Dynamic" Version="2.0.0-alpha.28" />
     <PackageReference Include="OneOf" Version="3.0.216" />
   </ItemGroup>

+ 1 - 0
src/ChunkyImageLib/CommittedChunkStorage.cs

@@ -1,6 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib;
 

+ 1 - 1
src/ChunkyImageLib/DataHolders/ColorBounds.cs

@@ -58,7 +58,7 @@ public struct ColorBounds
     }
     
     [ShaderMethod]
-    public readonly bool IsWithinBounds(float4 color)
+    public readonly bool IsWithinBounds(Float4 color)
     {
         float r = color.R;
         float g = color.G;

+ 1 - 0
src/ChunkyImageLib/IReadOnlyChunkyImage.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib;
 

+ 1 - 0
src/ChunkyImageLib/Operations/BresenhamLineOperation.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib.Operations;
 internal class BresenhamLineOperation : IDrawOperation

+ 1 - 0
src/ChunkyImageLib/Operations/DrawingSurfaceLineOperation.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib.Operations;
 internal class DrawingSurfaceLineOperation : IDrawOperation

+ 1 - 0
src/ChunkyImageLib/Operations/EllipseOperation.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 
 namespace ChunkyImageLib.Operations;

+ 1 - 0
src/ChunkyImageLib/Operations/ImageOperation.cs

@@ -1,6 +1,7 @@
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib.Operations;
 

+ 1 - 0
src/ChunkyImageLib/Operations/PathOperation.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 
 namespace ChunkyImageLib.Operations;

+ 1 - 0
src/ChunkyImageLib/Operations/PixelOperation.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib.Operations;
 

+ 1 - 0
src/ChunkyImageLib/Operations/PixelsOperation.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib.Operations;
 

+ 2 - 2
src/ChunkyImageLib/Operations/ReplaceColorOperation.cs

@@ -32,9 +32,9 @@ internal class ReplaceColorOperation : IDrawOperation
 
     private static void ReplaceColor(HlslColorBounds oldColorBounds, Color newColor, Chunk chunk)
     {
-        Span<UInt2> span = chunk.Surface.DrawingSurface.PeekPixels().GetPixelSpan<uint2>();
+        Span<UInt2> span = chunk.Surface.DrawingSurface.PeekPixels().GetPixelSpan<UInt2>();
         using var texture = GraphicsDevice.GetDefault()
-            .AllocateReadWriteTexture2D<uint2>(chunk.PixelSize.X, chunk.PixelSize.Y);
+            .AllocateReadWriteTexture2D<UInt2>(chunk.PixelSize.X, chunk.PixelSize.Y);
 
         texture.CopyFrom(span);
 

+ 7 - 7
src/ChunkyImageLib/Shaders/ReplaceColorShader.cs

@@ -1,17 +1,17 @@
-using ChunkyImageLib.DataHolders;
-using ComputeSharp;
+using ComputeSharp;
 
 namespace ChunkyImageLib.Shaders;
 
 [AutoConstructor]
-public readonly partial struct ReplaceColorShader : IComputeShader
+internal readonly partial struct ReplaceColorShader : IComputeShader
 {
-    public readonly ReadWriteTexture2D<uint2> texture;
+    public readonly ReadWriteTexture2D<UInt2> texture;
     public readonly HlslColorBounds colorBounds;
     public readonly UInt2 newColor;
+    
     public void Execute()
     {
-        uint2 rgba = texture[ThreadIds.XY];
+        UInt2 rgba = texture[ThreadIds.XY];
         Float4 rgbaFloat = ShaderUtils.UnpackPixel(rgba);
         
         if(IsWithinBounds(rgbaFloat))
@@ -20,7 +20,7 @@ public readonly partial struct ReplaceColorShader : IComputeShader
         }
     }
 
-    private bool IsWithinBounds(float4 color)
+    private bool IsWithinBounds(Float4 color)
     {
         float r = color.R;
         float g = color.G;
@@ -47,7 +47,7 @@ public readonly struct HlslColorBounds
     public readonly float UpperB;
     public readonly float UpperA;
 
-    public HlslColorBounds(float4 color)
+    public HlslColorBounds(Float4 color)
     {
         static (float lower, float upper) FindInclusiveBoundaryPremul(float channel, float alpha)
         {

+ 3 - 3
src/ChunkyImageLib/Shaders/ShaderUtils.cs

@@ -5,9 +5,9 @@ namespace ChunkyImageLib.Shaders;
 
 public static class ShaderUtils
 {
-    public static float4 UnpackPixel(uint2 packedPixel)
+    public static Float4 UnpackPixel(UInt2 packedPixel)
     {
-        return new float4(
+        return new Float4(
             Hlsl.Float16ToFloat32(packedPixel.X),
             Hlsl.Float16ToFloat32(packedPixel.X >> 16),
             Hlsl.Float16ToFloat32(packedPixel.Y),
@@ -15,7 +15,7 @@ public static class ShaderUtils
         );
     }
 
-    public static uint2 PackPixel(Color color)
+    public static UInt2 PackPixel(Color color)
     {
         uint convR = (BitConverter.HalfToUInt16Bits((Half)(color.R / 255f)));
         uint convG = (BitConverter.HalfToUInt16Bits((Half)(color.G / 255f)));

+ 2 - 1
src/ChunkyImageLib/Surface.cs

@@ -4,6 +4,7 @@ using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace ChunkyImageLib;
 
@@ -123,7 +124,7 @@ public class Surface : IDisposable
 
     private DrawingSurface CreateDrawingSurface()
     {
-        var surface = DrawingSurface.Create(new ImageInfo(Size.X, Size.Y, ColorType.RgbaF16, AlphaType.Premul, ColorSpace.CreateSrgb()), PixelBuffer);
+        var surface = PixiEditor.DrawingApi.Core.Surface.DrawingSurface.Create(new ImageInfo(Size.X, Size.Y, ColorType.RgbaF16, AlphaType.Premul, ColorSpace.CreateSrgb()), PixelBuffer);
         if (surface is null)
             throw new InvalidOperationException($"Could not create surface (Size:{Size})");
         return surface;

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changes/Drawing/ChangeBrightness_UpdateableChange.cs

@@ -1,6 +1,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changes/Drawing/FloodFill/FloodFillChunkCache.cs

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing.FloodFill;
 

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changes/Drawing/LineBasedPen_UpdateableChange.cs

@@ -1,6 +1,7 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 internal class LineBasedPen_UpdateableChange : UpdateableChange

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changes/Drawing/PasteImage_UpdateableChange.cs

@@ -1,5 +1,6 @@
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;
 internal class PasteImage_UpdateableChange : UpdateableChange

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changes/Drawing/TransformSelectedArea_UpdateableChange.cs

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.Changes.Selection;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 
 namespace PixiEditor.ChangeableDocument.Changes.Drawing;

+ 1 - 0
src/PixiEditor.ChangeableDocument/Changes/Root/ResizeImage_Change.cs

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using BlendMode = PixiEditor.DrawingApi.Core.Surface.BlendMode;
 
 namespace PixiEditor.ChangeableDocument.Changes.Root;

+ 1 - 0
src/PixiEditor.ChangeableDocument/Rendering/ChunkRenderer.cs

@@ -2,6 +2,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.ChangeableDocument.Rendering;
 

+ 1 - 0
src/PixiEditor.ChangeableDocument/Rendering/RenderingContext.cs

@@ -1,6 +1,7 @@
 using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using BlendMode = PixiEditor.ChangeableDocument.Enums.BlendMode;
 using DrawingApiBlendMode = PixiEditor.DrawingApi.Core.Surface.BlendMode;
 

+ 3 - 3
src/PixiEditor.DrawingApi.Core/Bridge/DrawingBackendApi.cs

@@ -3,7 +3,7 @@ using PixiEditor.DrawingApi.Core.Exceptions;
 
 namespace PixiEditor.DrawingApi.Core.Bridge
 {
-    public class DrawingBackendApi
+    public static class DrawingBackendApi
     {
         private static IDrawingBackend _current;
 
@@ -18,9 +18,9 @@ namespace PixiEditor.DrawingApi.Core.Bridge
             }
         }
         
-        public void SetupBackend(IDrawingBackend backend)
+        public static void SetupBackend(IDrawingBackend backend)
         {
-            if (Current != null)
+            if (_current != null)
             {
                 throw new InitializationDuplicateException("Drawing backend was already initialized.");
             }

+ 16 - 0
src/PixiEditor.DrawingApi.Core/Bridge/NativeObjectsImpl/IPaintImplementation.cs

@@ -1,5 +1,7 @@
 using System;
+using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.DrawingApi.Core.Bridge.NativeObjectsImpl
 {
@@ -8,5 +10,19 @@ namespace PixiEditor.DrawingApi.Core.Bridge.NativeObjectsImpl
         public IntPtr CreatePaint();
         public void Dispose(IntPtr paintObjPointer);
         public Paint Clone(IntPtr paintObjPointer);
+        public Color GetColor(Paint paint);
+        public void SetColor(Paint paint, Color value);
+        public BlendMode GetBlendMode(Paint paint);
+        public void SetBlendMode(Paint paint, BlendMode value);
+        public FilterQuality GetFilterQuality(Paint paint);
+        public void SetFilterQuality(Paint paint, FilterQuality value);
+        public bool GetIsAntiAliased(Paint paint);
+        public void SetIsAntiAliased(Paint paint, bool value);
+        public PaintStyle GetStyle(Paint paint);
+        public void SetStyle(Paint paint, PaintStyle value);
+        public StrokeCap GetStrokeCap(Paint paint);
+        public void SetStrokeCap(Paint paint, StrokeCap value);
+        public float GetStrokeWidth(Paint paint);
+        public void SetStrokeWidth(Paint paint, float value);
     }
 }

+ 1 - 0
src/PixiEditor.DrawingApi.Core/Bridge/Operations/ICanvasImplementation.cs

@@ -3,6 +3,7 @@ using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 
 namespace PixiEditor.DrawingApi.Core.Bridge.Operations

+ 2 - 0
src/PixiEditor.DrawingApi.Core/Bridge/Operations/ISurfaceImplementation.cs

@@ -1,6 +1,7 @@
 using System;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.DrawingApi.Core.Bridge.Operations;
 
@@ -13,4 +14,5 @@ public interface ISurfaceImplementation
     public DrawingSurface Create(ImageInfo imageInfo, IntPtr pixelBuffer);
     public DrawingSurface Create(Pixmap pixmap);
     public DrawingSurface Create(ImageInfo imageInfo);
+    public void Dispose(DrawingSurface drawingSurface);
 }

+ 1 - 1
src/PixiEditor.DrawingApi.Core/Surface/Bitmap.cs

@@ -8,7 +8,7 @@ public class Bitmap : NativeObject
     public Bitmap(IntPtr objPtr) : base(objPtr)
     {
     }
-
+    
     public override void Dispose()
     {
         DrawingBackendApi.Current.BitmapImplementation.Dispose(ObjectPointer);

+ 2 - 2
src/PixiEditor.DrawingApi.Core/Surface/Canvas.cs

@@ -3,14 +3,14 @@ using PixiEditor.DrawingApi.Core.Bridge;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 
 namespace PixiEditor.DrawingApi.Core.Surface
 {
     public class Canvas : NativeObject
     {
-        
-        internal Canvas(IntPtr objPtr) : base(objPtr)
+        public Canvas(IntPtr objPtr) : base(objPtr)
         {
         }
         

+ 6 - 7
src/PixiEditor.DrawingApi.Core/Surface/DrawingSurface.cs

@@ -1,19 +1,17 @@
 using System;
 using PixiEditor.DrawingApi.Core.Bridge;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 
 namespace PixiEditor.DrawingApi.Core.Surface
 {
     public class DrawingSurface : NativeObject
     {
-        public float Width { get; set; }
-        public float Height { get; set; }
-        
-        public DrawingSurfaceProperties Properties { get; private set; }
         public Canvas Canvas { get; private set; }
         
-        public DrawingSurface(IntPtr objPtr) : base(objPtr)
+        public DrawingSurface(IntPtr objPtr, Canvas canvas) : base(objPtr)
         {
+            Canvas = canvas;
         }
         
         public static DrawingSurface Create(Pixmap imageInfo)
@@ -41,7 +39,7 @@ namespace PixiEditor.DrawingApi.Core.Surface
             return DrawingBackendApi.Current.SurfaceImplementation.ReadPixels(this, dstInfo, dstPixels, dstRowBytes, srcX, srcY);
         }
         
-        public DrawingSurface Create(ImageInfo imageInfo)
+        public static DrawingSurface Create(ImageInfo imageInfo)
         {
             return DrawingBackendApi.Current.SurfaceImplementation.Create(imageInfo);
         }
@@ -51,13 +49,14 @@ namespace PixiEditor.DrawingApi.Core.Surface
             return DrawingBackendApi.Current.SurfaceImplementation.Create(imageInfo, pixels, rowBytes);
         }
         
-        public DrawingSurface Create(ImageInfo imageInfo, IntPtr pixelBuffer)
+        public static DrawingSurface Create(ImageInfo imageInfo, IntPtr pixelBuffer)
         {
             return DrawingBackendApi.Current.SurfaceImplementation.Create(imageInfo, pixelBuffer);
         }
 
         public override void Dispose()
         {
+            DrawingBackendApi.Current.SurfaceImplementation.Dispose(this);
         }
     }
 }

+ 1 - 0
src/PixiEditor.DrawingApi.Core/Surface/ImageData/ColorSpace.cs

@@ -7,6 +7,7 @@ public class ColorSpace : NativeObject
 {
     public ColorSpace(IntPtr objPtr) : base(objPtr)
     {
+        
     }
     
     public static ColorSpace CreateSrgb()

+ 0 - 5
src/PixiEditor.DrawingApi.Core/Surface/ImageData/Image.cs

@@ -20,11 +20,6 @@ namespace PixiEditor.DrawingApi.Core.Surface.ImageData
         public Image(IntPtr objPtr) : base(objPtr)
         {
         }
-        
-        ~Image()
-        {
-            Dispose();
-        }
 
         public override void Dispose()
         {

+ 2 - 2
src/PixiEditor.DrawingApi.Core/Surface/ImageData/ImageInfo.cs

@@ -48,7 +48,7 @@ public struct ImageInfo : System.IEquatable<ImageInfo>
 
     /// <summary>Gets or sets the color space.</summary>
     /// <value />
-    public ColorSpace ColorSpace { get; set; }
+    public ColorSpace? ColorSpace { get; set; }
 
     public ImageInfo(int width, int height)
     {
@@ -56,7 +56,7 @@ public struct ImageInfo : System.IEquatable<ImageInfo>
       this.Height = height;
       this.ColorType = ImageInfo.PlatformColorType;
       this.AlphaType = AlphaType.Premul;
-      this.ColorSpace = (ColorSpace)null;
+      this.ColorSpace = null;
     }
 
     public ImageInfo(int width, int height, ColorType colorType)

+ 1 - 1
src/PixiEditor.DrawingApi.Core/Surface/NativeObject.cs

@@ -6,7 +6,7 @@ public abstract class NativeObject : IDisposable
 {
     public IntPtr ObjectPointer { get; protected set; }
     public abstract void Dispose();
-    
+
     internal NativeObject(IntPtr objPtr)
     {
         ObjectPointer = objPtr;

+ 41 - 8
src/PixiEditor.DrawingApi.Core/Surface/PaintImpl/Paint.cs

@@ -2,22 +2,55 @@
 using PixiEditor.DrawingApi.Core.Bridge;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 
-namespace PixiEditor.DrawingApi.Core.Surface
+namespace PixiEditor.DrawingApi.Core.Surface.PaintImpl
 {
     /// <summary>
     ///     Class used to define surface paint, which is a collection of paint operations.
     /// </summary>
     public class Paint : NativeObject
     {
-        public Color Color { get; set; }
-        public BlendMode BlendMode { get; set; } = BlendMode.Src;
-        public FilterQuality FilterQuality { get; set; } = FilterQuality.None;
-        public bool IsAntiAliased { get; set; } = false;
-        public PaintStyle Style { get; set; }
-        public StrokeCap StrokeCap { get; set; }
-        public float StrokeWidth { get; set; }
+        public Color Color
+        {
+            get => DrawingBackendApi.Current.PaintImplementation.GetColor(this);
+            set => DrawingBackendApi.Current.PaintImplementation.SetColor(this, value);
+        }
+
+        public BlendMode BlendMode
+        {
+            get => DrawingBackendApi.Current.PaintImplementation.GetBlendMode(this);
+            set => DrawingBackendApi.Current.PaintImplementation.SetBlendMode(this, value);
+        }
         
+        public FilterQuality FilterQuality 
+        {
+            get => DrawingBackendApi.Current.PaintImplementation.GetFilterQuality(this);
+            set => DrawingBackendApi.Current.PaintImplementation.SetFilterQuality(this, value);
+        }
+        
+        public bool IsAntiAliased 
+        {
+            get => DrawingBackendApi.Current.PaintImplementation.GetIsAntiAliased(this);
+            set => DrawingBackendApi.Current.PaintImplementation.SetIsAntiAliased(this, value);
+        }
         
+        public PaintStyle Style 
+        {
+            get => DrawingBackendApi.Current.PaintImplementation.GetStyle(this);
+            set => DrawingBackendApi.Current.PaintImplementation.SetStyle(this, value);
+        }
+        
+        public StrokeCap StrokeCap 
+        {
+            get => DrawingBackendApi.Current.PaintImplementation.GetStrokeCap(this);
+            set => DrawingBackendApi.Current.PaintImplementation.SetStrokeCap(this, value);
+        }
+        
+        public float StrokeWidth 
+        {
+            get => DrawingBackendApi.Current.PaintImplementation.GetStrokeWidth(this);
+            set => DrawingBackendApi.Current.PaintImplementation.SetStrokeWidth(this, value);
+        }
+
         public Paint(IntPtr objPtr) : base(objPtr)
         {
         }

+ 3 - 1
src/PixiEditor.DrawingApi.Core/Surface/PaintImpl/StrokeCap.cs

@@ -1,4 +1,6 @@
-namespace PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
+
+namespace PixiEditor.DrawingApi.Core.Surface;
 
 /// <summary>Various options for <see cref="Paint.StrokeCap" />.</summary>
 /// <remarks>This is the treatment that is applied to the beginning and end of each non-closed contour (e.g. lines).</remarks>

+ 4 - 11
src/PixiEditor.DrawingApi.Skia/CastUtility.cs

@@ -1,22 +1,15 @@
 using System;
+using System.Reflection.Emit;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 
 namespace PixiEditor.DrawingApi.Skia
 {
     public static class CastUtility
     {
-        public static unsafe T2[] UnsafeArrayCast<T1, T2>(T1[] source) where T2 : unmanaged
+        public static T2[] UnsafeArrayCast<T1, T2>(T1[] source) where T1 : struct where T2 : struct
         {
-            unsafe
-            {
-                T2[] target = new T2[source.Length];
-                fixed (void* p = target)
-                {
-                    Unsafe.Copy(p, ref source);
-                }
-                
-                return target;
-            }
+            return MemoryMarshal.Cast<T1, T2>(source).ToArray();
         }
     }
 }

+ 12 - 2
src/PixiEditor.DrawingApi.Skia/ConversionExtensions.cs

@@ -50,11 +50,21 @@ namespace PixiEditor.DrawingApi.Skia
         {
             return new SKImageInfo(info.Width, info.Height, (SKColorType)info.ColorType, (SKAlphaType)info.AlphaType);
         }
+        
+        public static Color ToBackendColor(this SKColor color)
+        {
+            return new Color(color.Red, color.Green, color.Blue, color.Alpha);
+        }
 
         public static ImageInfo ToImageInfo(this SKImageInfo info, SkiaColorSpaceImplementation colorSpaceImpl)
         {
-            ColorSpace cs = new ColorSpace(info.ColorSpace.Handle);
-            colorSpaceImpl.ManagedInstances[info.ColorSpace.Handle] = info.ColorSpace;
+            ColorSpace? cs = null;
+            if (info.ColorSpace != null)
+            {
+                cs = new ColorSpace(info.ColorSpace.Handle);
+                colorSpaceImpl.ManagedInstances[info.ColorSpace.Handle] = info.ColorSpace;
+            }
+
             return new ImageInfo(info.Width, info.Height,
                 (ColorType)info.ColorType,
                 (AlphaType)info.AlphaType,

+ 1 - 1
src/PixiEditor.DrawingApi.Skia/Implementations/SKObjectImplementation.cs

@@ -6,7 +6,7 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
 {
     public abstract class SkObjectImplementation<T> where T : SKObject
     {
-        internal Dictionary<IntPtr, T> ManagedInstances = new Dictionary<IntPtr, T>();
+        internal readonly Dictionary<IntPtr, T> ManagedInstances = new Dictionary<IntPtr, T>();
         
         public virtual void DisposeObject(IntPtr objPtr)
         {

+ 17 - 8
src/PixiEditor.DrawingApi.Skia/Implementations/SkiaCanvasImplementation.cs

@@ -4,6 +4,7 @@ using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 using SkiaSharp;
 
@@ -12,7 +13,7 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
     public sealed class SkiaCanvasImplementation : SkObjectImplementation<SKCanvas>, ICanvasImplementation
     {
         private readonly SkObjectImplementation<SKPaint> _paintImpl;
-        private readonly SkObjectImplementation<SKSurface> _surfaceImpl;
+        private SkObjectImplementation<SKSurface> _surfaceImpl;
         private readonly SkObjectImplementation<SKImage> _imageImpl;
         private readonly SkObjectImplementation<SKBitmap> _bitmapImpl;
         private readonly SkObjectImplementation<SKPath> _pathImpl;
@@ -26,6 +27,11 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
             _pathImpl = pathImpl;
         }
         
+        public void SetSurfaceImpl(SkiaSurfaceImplementation surfaceImpl)
+        {
+            _surfaceImpl = surfaceImpl;
+        }
+        
         public void DrawPixel(IntPtr objectPointer, int posX, int posY, Paint drawingPaint)
         {
             ManagedInstances[objectPointer].DrawPoint(
@@ -100,37 +106,40 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
 
         public void ClipPath(IntPtr objPtr, VectorPath clipPath, ClipOperation clipOperation, bool antialias)
         {
-            throw new NotImplementedException();
+            SKCanvas canvas = ManagedInstances[objPtr];
+            canvas.ClipPath(_pathImpl[clipPath.ObjectPointer], (SKClipOperation)clipOperation, antialias);
         }
 
         public void ClipRect(IntPtr objPtr, RectD rect, ClipOperation clipOperation)
         {
-            throw new NotImplementedException();
+            SKCanvas canvas = ManagedInstances[objPtr];
+            canvas.ClipRect(rect.ToSKRect(), (SKClipOperation)clipOperation);
         }
 
         public void Clear(IntPtr objPtr)
         {
-            throw new NotImplementedException();
+            ManagedInstances[objPtr].Clear();
         }
 
         public void Clear(IntPtr objPtr, Color color)
         {
-            throw new NotImplementedException();
+            ManagedInstances[objPtr].Clear(color.ToSKColor());
         }
 
         public void DrawLine(IntPtr objPtr, VecI from, VecI to, Paint paint)
         {
-            throw new NotImplementedException();
+            ManagedInstances[objPtr].DrawLine(from.X, from.Y, to.X, to.Y, _paintImpl[paint.ObjectPointer]);
         }
 
         public void Flush(IntPtr objPtr)
         {
-            throw new NotImplementedException();
+            ManagedInstances[objPtr].Flush();
         }
 
         public void SetMatrix(IntPtr objPtr, Matrix3X3 finalMatrix)
         {
-            throw new NotImplementedException();
+            SKCanvas canvas = ManagedInstances[objPtr];
+            canvas.SetMatrix(finalMatrix.ToSkMatrix());
         }
 
         public void RestoreToCount(IntPtr objPtr, int count)

+ 8 - 1
src/PixiEditor.DrawingApi.Skia/Implementations/SkiaColorSpaceImplementation.cs

@@ -7,6 +7,13 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
 {
     public class SkiaColorSpaceImplementation : SkObjectImplementation<SKColorSpace>, IColorSpaceImplementation
     {
+        private readonly IntPtr _srgbPointer;
+        
+        public SkiaColorSpaceImplementation()
+        {
+            _srgbPointer = SKColorSpace.CreateSrgb().Handle;
+        }
+        
         public ColorSpace CreateSrgb()
         {
             SKColorSpace skColorSpace = SKColorSpace.CreateSrgb();
@@ -16,8 +23,8 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
 
         public void Dispose(IntPtr objectPointer)
         {
+            if (objectPointer == _srgbPointer) return;
             ManagedInstances[objectPointer].Dispose();
-            
             ManagedInstances.Remove(objectPointer);
         }
     }

+ 95 - 4
src/PixiEditor.DrawingApi.Skia/Implementations/SkiaPaintImplementation.cs

@@ -1,7 +1,8 @@
 using System;
-using System.Collections.Generic;
 using PixiEditor.DrawingApi.Core.Bridge.NativeObjectsImpl;
+using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using SkiaSharp;
 
 namespace PixiEditor.DrawingApi.Skia.Implementations
@@ -10,13 +11,18 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
     {
         public IntPtr CreatePaint()
         {
-            SKPaint paint = new SKPaint();
-            ManagedInstances[paint.Handle] = paint;
-            return paint.Handle;
+            SKPaint skPaint = new SKPaint();
+            skPaint.IsAntialias = false;
+            skPaint.BlendMode = SKBlendMode.Src;
+            skPaint.FilterQuality = SKFilterQuality.None;
+            
+            ManagedInstances[skPaint.Handle] = skPaint;
+            return skPaint.Handle;
         }
 
         public void Dispose(IntPtr paintObjPointer)
         {
+            if (!ManagedInstances.ContainsKey(paintObjPointer)) return;
             SKPaint paint = ManagedInstances[paintObjPointer];
             paint.Dispose();
             ManagedInstances.Remove(paintObjPointer);
@@ -25,7 +31,92 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
         public Paint Clone(IntPtr paintObjPointer)
         {
             SKPaint clone = ManagedInstances[paintObjPointer].Clone();
+            ManagedInstances[clone.Handle] = clone;
             return new Paint(clone.Handle);
         }
+
+        public Color GetColor(Paint paint)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            return skPaint.Color.ToBackendColor();
+        }
+
+        public void SetColor(Paint paint, Color value)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            skPaint.Color = value.ToSKColor();
+        }
+
+        public BlendMode GetBlendMode(Paint paint)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            return (BlendMode)skPaint.BlendMode;
+        }
+
+        public void SetBlendMode(Paint paint, BlendMode value)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            skPaint.BlendMode = (SKBlendMode)value;
+        }
+
+        public FilterQuality GetFilterQuality(Paint paint)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            return (FilterQuality)skPaint.FilterQuality;
+        }
+
+        public void SetFilterQuality(Paint paint, FilterQuality value)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            skPaint.FilterQuality = (SKFilterQuality)value;
+        }
+
+        public bool GetIsAntiAliased(Paint paint)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            return skPaint.IsAntialias;
+        }
+
+        public void SetIsAntiAliased(Paint paint, bool value)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            skPaint.IsAntialias = value;
+        }
+
+        public PaintStyle GetStyle(Paint paint)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            return (PaintStyle)skPaint.Style;
+        }
+
+        public void SetStyle(Paint paint, PaintStyle value)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            skPaint.Style = (SKPaintStyle)value;
+        }
+
+        public StrokeCap GetStrokeCap(Paint paint)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            return (StrokeCap)skPaint.StrokeCap;
+        }
+
+        public void SetStrokeCap(Paint paint, StrokeCap value)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            skPaint.StrokeCap = (SKStrokeCap)value;
+        }
+
+        public float GetStrokeWidth(Paint paint)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            return skPaint.StrokeWidth;
+        }
+
+        public void SetStrokeWidth(Paint paint, float value)
+        {
+            SKPaint skPaint = ManagedInstances[paint.ObjectPointer];
+            skPaint.StrokeWidth = value;
+        }
     }
 }

+ 25 - 16
src/PixiEditor.DrawingApi.Skia/Implementations/SkiaSurfaceImplementation.cs

@@ -2,6 +2,7 @@
 using PixiEditor.DrawingApi.Core.Bridge.Operations;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using SkiaSharp;
 
 namespace PixiEditor.DrawingApi.Skia.Implementations
@@ -11,7 +12,7 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
         private readonly SkiaPixmapImplementation _pixmapImplementation;
         private readonly SkiaCanvasImplementation _canvasImplementation;
         private readonly SkiaPaintImplementation _paintImplementation;
-        
+
         public SkiaSurfaceImplementation(SkiaPixmapImplementation pixmapImplementation, SkiaCanvasImplementation canvasImplementation, SkiaPaintImplementation paintImplementation)
         {
             _pixmapImplementation = pixmapImplementation;
@@ -25,14 +26,6 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
             return _pixmapImplementation.CreateFrom(pixmap);
         }
 
-        public DrawingSurface Create(ImageInfo imageInfo, IntPtr pixels, int rowBytes)
-        {
-            SKSurface skSurface = SKSurface.Create(imageInfo.ToSkImageInfo(), pixels, rowBytes);
-            DrawingSurface surface = new DrawingSurface(skSurface.Handle);
-            ManagedInstances[skSurface.Handle] = skSurface;
-            return surface;
-        }
-
         public bool ReadPixels(DrawingSurface drawingSurface, ImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX,
             int srcY)
         {
@@ -46,28 +39,44 @@ namespace PixiEditor.DrawingApi.Skia.Implementations
             SKPaint paint = _paintImplementation[drawingPaint.ObjectPointer];
             ManagedInstances[drawingSurface.ObjectPointer].Draw(canvas, x, y, paint);
         }
+        
+        public DrawingSurface Create(ImageInfo imageInfo, IntPtr pixels, int rowBytes)
+        {
+            SKSurface skSurface = SKSurface.Create(imageInfo.ToSkImageInfo(), pixels, rowBytes);
+            return CreateDrawingSurface(skSurface);
+        }
 
         public DrawingSurface Create(ImageInfo imageInfo, IntPtr pixelBuffer)
         {
             SKSurface skSurface = SKSurface.Create(imageInfo.ToSkImageInfo(), pixelBuffer);
-            DrawingSurface surface = new DrawingSurface(skSurface.Handle);
-            ManagedInstances[skSurface.Handle] = skSurface;
-            return surface;
+            return CreateDrawingSurface(skSurface);
         }
 
         public DrawingSurface Create(Pixmap pixmap)
         {
             SKPixmap skPixmap = _pixmapImplementation[pixmap.ObjectPointer];
             SKSurface skSurface = SKSurface.Create(skPixmap);
-            DrawingSurface surface = new DrawingSurface(skSurface.Handle);
-            ManagedInstances[skSurface.Handle] = skSurface;
-            return surface;
+            return CreateDrawingSurface(skSurface);
         }
 
         public DrawingSurface Create(ImageInfo imageInfo)
         {
             SKSurface skSurface = SKSurface.Create(imageInfo.ToSkImageInfo());
-            DrawingSurface surface = new DrawingSurface(skSurface.Handle);
+            return CreateDrawingSurface(skSurface);
+        }
+
+        public void Dispose(DrawingSurface drawingSurface)
+        {
+            ManagedInstances[drawingSurface.ObjectPointer].Dispose();
+            ManagedInstances.Remove(drawingSurface.ObjectPointer);
+        }
+
+        private DrawingSurface CreateDrawingSurface(SKSurface skSurface)
+        {
+            _canvasImplementation.ManagedInstances[skSurface.Canvas.Handle] = skSurface.Canvas;
+            Canvas canvas = new Canvas(skSurface.Canvas.Handle);
+
+            DrawingSurface surface = new DrawingSurface(skSurface.Handle, canvas);
             ManagedInstances[skSurface.Handle] = skSurface;
             return surface;
         }

+ 5 - 5
src/PixiEditor.DrawingApi.Skia/SkiaDrawingBackend.cs

@@ -45,12 +45,12 @@ namespace PixiEditor.DrawingApi.Skia
             
             SkiaBitmapImplementation bitmapImpl = new SkiaBitmapImplementation();
             BitmapImplementation = bitmapImpl;
-
-            SkiaSurfaceImplementation surfaceImpl = null;
-
-            SkiaCanvasImplementation canvasImpl = new SkiaCanvasImplementation(paintImpl, surfaceImpl, imgImpl, bitmapImpl, pathImpl);
             
-            surfaceImpl = new SkiaSurfaceImplementation(pixmapImpl, canvasImpl, paintImpl);
+            SkiaCanvasImplementation canvasImpl = new SkiaCanvasImplementation(paintImpl, null, imgImpl, bitmapImpl, pathImpl);
+            
+            var surfaceImpl = new SkiaSurfaceImplementation(pixmapImpl, canvasImpl, paintImpl);
+
+            canvasImpl.SetSurfaceImpl(surfaceImpl);
 
             CanvasImplementation = canvasImpl;
 

+ 1 - 0
src/PixiEditor/Models/IO/Importer.cs

@@ -7,6 +7,7 @@ using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface.ImageData;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.Exceptions;
 using PixiEditor.Helpers;
 using PixiEditor.Models.DataHolders;

+ 1 - 0
src/PixiEditor/Models/Rendering/WriteableBitmapUpdater.cs

@@ -5,6 +5,7 @@ using PixiEditor.ChangeableDocument.Changeables.Interfaces;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.PaintImpl;
 using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.Rendering.RenderInfos;
 using PixiEditor.ViewModels.SubViewModels.Document;

+ 1 - 0
src/PixiEditor/PixiEditor.csproj

@@ -334,6 +334,7 @@
 	</ItemGroup>
 	<ItemGroup>
 		<ProjectReference Include="..\PixiEditor.ChangeableDocument\PixiEditor.ChangeableDocument.csproj" />
+		<ProjectReference Include="..\PixiEditor.DrawingApi.Skia\PixiEditor.DrawingApi.Skia.csproj" />
 		<ProjectReference Include="..\PixiEditor.UpdateModule\PixiEditor.UpdateModule.csproj" />
 		<ProjectReference Include="..\PixiEditor.Zoombox\PixiEditor.Zoombox.csproj" />
 	</ItemGroup>

+ 5 - 0
src/PixiEditor/Views/MainWindow.xaml.cs

@@ -4,6 +4,8 @@ using System.Windows.Input;
 using System.Windows.Interop;
 using System.Windows.Media.Imaging;
 using Microsoft.Extensions.DependencyInjection;
+using PixiEditor.DrawingApi.Core.Bridge;
+using PixiEditor.DrawingApi.Skia;
 using PixiEditor.Models.IO;
 using PixiEditor.Models.UserPreferences;
 using PixiEditor.ViewModels.SubViewModels.Document;
@@ -32,6 +34,9 @@ internal partial class MainWindow : Window
             .AddPixiEditor()
             .BuildServiceProvider();
 
+        SkiaDrawingBackend skiaDrawingBackend = new SkiaDrawingBackend();
+        DrawingBackendApi.SetupBackend(skiaDrawingBackend);
+
         preferences = services.GetRequiredService<IPreferences>();
         DataContext = services.GetRequiredService<ViewModelMain>();
         DataContext.Setup(services);