Browse Source

ColorSpace, DrawingSurface improvements and stuff

flabbet 2 years ago
parent
commit
6933f43444

+ 7 - 5
src/ChunkyImageLib/DataHolders/ShapeData.cs

@@ -1,11 +1,13 @@
-using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.ColorsImpl;
+using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.Surface;
 using SkiaSharp;
 using SkiaSharp;
 
 
 namespace ChunkyImageLib.DataHolders;
 namespace ChunkyImageLib.DataHolders;
 
 
 public record struct ShapeData
 public record struct ShapeData
 {
 {
-    public ShapeData(VecD center, VecD size, double rotation, int strokeWidth, SKColor strokeColor, SKColor fillColor, SKBlendMode blendMode = SKBlendMode.SrcOver)
+    public ShapeData(VecD center, VecD size, double rotation, int strokeWidth, Color strokeColor, Color fillColor, BlendMode blendMode = BlendMode.SrcOver)
     {
     {
         StrokeColor = strokeColor;
         StrokeColor = strokeColor;
         FillColor = fillColor;
         FillColor = fillColor;
@@ -15,9 +17,9 @@ public record struct ShapeData
         StrokeWidth = strokeWidth;
         StrokeWidth = strokeWidth;
         BlendMode = blendMode;
         BlendMode = blendMode;
     }
     }
-    public SKColor StrokeColor { get; }
-    public SKColor FillColor { get; }
-    public SKBlendMode BlendMode { get; }
+    public Color StrokeColor { get; }
+    public Color FillColor { get; }
+    public BlendMode BlendMode { get; }
     public VecD Center { get; }
     public VecD Center { get; }
 
 
     /// <summary>Can be negative to show flipping </summary>
     /// <summary>Can be negative to show flipping </summary>

+ 6 - 5
src/ChunkyImageLib/Operations/RectangleOperation.cs

@@ -1,5 +1,6 @@
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.Surface;
 using SkiaSharp;
 using SkiaSharp;
 
 
 namespace ChunkyImageLib.Operations;
 namespace ChunkyImageLib.Operations;
@@ -32,7 +33,7 @@ internal class RectangleOperation : IDrawOperation
         skiaSurf.Canvas.RotateRadians((float)Data.Angle, (float)rect.Center.X, (float)rect.Center.Y);
         skiaSurf.Canvas.RotateRadians((float)Data.Angle, (float)rect.Center.X, (float)rect.Center.Y);
 
 
         // draw fill
         // draw fill
-        if (Data.FillColor.Alpha > 0)
+        if (Data.FillColor.A > 0)
         {
         {
             skiaSurf.Canvas.Save();
             skiaSurf.Canvas.Save();
             skiaSurf.Canvas.ClipRect((SKRect)innerRect);
             skiaSurf.Canvas.ClipRect((SKRect)innerRect);
@@ -42,8 +43,8 @@ internal class RectangleOperation : IDrawOperation
 
 
         // draw stroke
         // draw stroke
         skiaSurf.Canvas.Save();
         skiaSurf.Canvas.Save();
-        skiaSurf.Canvas.ClipRect((SKRect)rect);
-        skiaSurf.Canvas.ClipRect((SKRect)innerRect, SKClipOperation.Difference);
+        skiaSurf.Canvas.ClipRect(rect);
+        skiaSurf.Canvas.ClipRect(innerRect, ClipOperation.Difference);
         skiaSurf.Canvas.DrawColor(Data.StrokeColor, Data.BlendMode);
         skiaSurf.Canvas.DrawColor(Data.StrokeColor, Data.BlendMode);
         skiaSurf.Canvas.Restore();
         skiaSurf.Canvas.Restore();
 
 
@@ -52,9 +53,9 @@ internal class RectangleOperation : IDrawOperation
 
 
     public HashSet<VecI> FindAffectedChunks(VecI imageSize)
     public HashSet<VecI> FindAffectedChunks(VecI imageSize)
     {
     {
-        if (Math.Abs(Data.Size.X) < 1 || Math.Abs(Data.Size.Y) < 1 || (Data.StrokeColor.Alpha == 0 && Data.FillColor.Alpha == 0))
+        if (Math.Abs(Data.Size.X) < 1 || Math.Abs(Data.Size.Y) < 1 || (Data.StrokeColor.A == 0 && Data.FillColor.A == 0))
             return new();
             return new();
-        if (Data.FillColor.Alpha != 0 || Math.Abs(Data.Size.X) == 1 || Math.Abs(Data.Size.Y) == 1)
+        if (Data.FillColor.A != 0 || Math.Abs(Data.Size.X) == 1 || Math.Abs(Data.Size.Y) == 1)
             return OperationHelper.FindChunksTouchingRectangle(Data.Center, Data.Size.Abs(), Data.Angle, ChunkPool.FullChunkSize);
             return OperationHelper.FindChunksTouchingRectangle(Data.Center, Data.Size.Abs(), Data.Angle, ChunkPool.FullChunkSize);
 
 
         var chunks = OperationHelper.FindChunksTouchingRectangle(Data.Center, Data.Size.Abs(), Data.Angle, ChunkPool.FullChunkSize);
         var chunks = OperationHelper.FindChunksTouchingRectangle(Data.Center, Data.Size.Abs(), Data.Angle, ChunkPool.FullChunkSize);

+ 5 - 5
src/ChunkyImageLib/Surface.cs

@@ -54,14 +54,14 @@ public class Surface : IDisposable
         return surface;
         return surface;
     }
     }
 
 
-    public unsafe void DrawBytes(VecI size, byte[] bytes, SKColorType colorType, SKAlphaType alphaType)
+    public unsafe void DrawBytes(VecI size, byte[] bytes, ColorType colorType, AlphaType alphaType)
     {
     {
-        SKImageInfo info = new SKImageInfo(size.X, size.Y, colorType, alphaType);
+        ImageInfo info = new ImageInfo(size.X, size.Y, colorType, alphaType);
 
 
         fixed (void* pointer = bytes)
         fixed (void* pointer = bytes)
         {
         {
-            using SKPixmap map = new(info, new IntPtr(pointer));
-            using SKSurface surface = SKSurface.Create(map);
+            using Pixmap map = new(info, new IntPtr(pointer));
+            using DrawingSurface surface = DrawingSurface.Create(map);
             surface.Draw(DrawingSurface.Canvas, 0, 0, drawingPaint);
             surface.Draw(DrawingSurface.Canvas, 0, 0, drawingPaint);
         }
         }
     }
     }
@@ -126,7 +126,7 @@ public class Surface : IDisposable
 
 
     private DrawingSurface CreateDrawingSurface()
     private DrawingSurface CreateDrawingSurface()
     {
     {
-        var surface = SKSurface.Create(new SKImageInfo(Size.X, Size.Y, SKColorType.RgbaF16, SKAlphaType.Premul, SKColorSpace.CreateSrgb()), PixelBuffer);
+        var surface = DrawingSurface.Create(new ImageInfo(Size.X, Size.Y, ColorType.RgbaF16, AlphaType.Premul, ColorSpace.CreateSrgb()), PixelBuffer);
         if (surface is null)
         if (surface is null)
             throw new InvalidOperationException($"Could not create surface (Size:{Size})");
             throw new InvalidOperationException($"Could not create surface (Size:{Size})");
         return surface;
         return surface;

+ 3 - 1
src/PixiEditor.DrawingApi.Core/Bridge/IDrawingBackend.cs

@@ -6,12 +6,14 @@ namespace PixiEditor.DrawingApi.Core.Bridge
     public interface IDrawingBackend
     public interface IDrawingBackend
     {
     {
         public void Setup();
         public void Setup();
-        public IDrawingBackendColorOperations ColorOperations { get; }
+        public IColorImplementation ColorImplementation { get; }
         public IImageOperations ImageOperations { get; }
         public IImageOperations ImageOperations { get; }
         public ICanvasOperations CanvasOperations { get; }
         public ICanvasOperations CanvasOperations { get; }
         public IPaintImplementation PaintImplementation { get; set; }
         public IPaintImplementation PaintImplementation { get; set; }
         public IVectorPathImplementation PathImplementation { get; set; }
         public IVectorPathImplementation PathImplementation { get; set; }
         public IMatrix3X3Implementation MatrixImplementation { get; set; }
         public IMatrix3X3Implementation MatrixImplementation { get; set; }
         public IPixmapImplementation PixmapImplementation { get; set; }
         public IPixmapImplementation PixmapImplementation { get; set; }
+        public ISurfaceOperations SurfaceOperations { get; set; }
+        public IColorSpaceImplementation ColorSpaceImplementation { get; set; }
     }
     }
 }
 }

+ 10 - 0
src/PixiEditor.DrawingApi.Core/Bridge/NativeObjectsImpl/IColorSpaceImplementation.cs

@@ -0,0 +1,10 @@
+using System;
+using PixiEditor.DrawingApi.Core.Surface.ImageData;
+
+namespace PixiEditor.DrawingApi.Core.Bridge.NativeObjectsImpl;
+
+public interface IColorSpaceImplementation
+{
+    public ColorSpace CreateSrgb();
+    public void Dispose(IntPtr objectPointer);
+}

+ 2 - 1
src/PixiEditor.DrawingApi.Core/Bridge/Operations/ICanvasOperations.cs

@@ -20,7 +20,7 @@ namespace PixiEditor.DrawingApi.Core.Bridge.Operations
         public void DrawPoints(PointMode pointMode, Point[] points, Paint paint);
         public void DrawPoints(PointMode pointMode, Point[] points, Paint paint);
         public void DrawRect(int x, int y, int width, int height, Paint paint);
         public void DrawRect(int x, int y, int width, int height, Paint paint);
         public void ClipPath(VectorPath clipPath, ClipOperation clipOperation, bool antialias);
         public void ClipPath(VectorPath clipPath, ClipOperation clipOperation, bool antialias);
-        public void ClipRect(RectD rect);
+        public void ClipRect(RectD rect, ClipOperation clipOperation);
         public void Clear();
         public void Clear();
         public void Clear(Color color);
         public void Clear(Color color);
         public void DrawLine(VecI from, VecI to, Paint paint);
         public void DrawLine(VecI from, VecI to, Paint paint);
@@ -28,5 +28,6 @@ namespace PixiEditor.DrawingApi.Core.Bridge.Operations
         public void SetMatrix(Matrix3X3 finalMatrix);
         public void SetMatrix(Matrix3X3 finalMatrix);
         public void RestoreToCount(int count);
         public void RestoreToCount(int count);
         public void DrawColor(Color color, BlendMode paintBlendMode);
         public void DrawColor(Color color, BlendMode paintBlendMode);
+        public void RotateRadians(float dataAngle, float centerX, float centerY);
     }
     }
 }
 }

+ 3 - 1
src/PixiEditor.DrawingApi.Core/Bridge/Operations/IDrawingBackendColorOperations.cs → src/PixiEditor.DrawingApi.Core/Bridge/Operations/IColorImplementation.cs

@@ -1,10 +1,12 @@
 using PixiEditor.DrawingApi.Core.ColorsImpl;
 using PixiEditor.DrawingApi.Core.ColorsImpl;
+using PixiEditor.DrawingApi.Core.Surface.ImageData;
 
 
 namespace PixiEditor.DrawingApi.Core.Bridge.Operations
 namespace PixiEditor.DrawingApi.Core.Bridge.Operations
 {
 {
-    public interface IDrawingBackendColorOperations
+    public interface IColorImplementation
     {
     {
         public ColorF ColorToColorF(uint colorValue);
         public ColorF ColorToColorF(uint colorValue);
         public Color ColorFToColor(ColorF color);
         public Color ColorFToColor(ColorF color);
+        public ColorType GetPlatformColorType();
     }
     }
 }
 }

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

@@ -8,6 +8,6 @@ namespace PixiEditor.DrawingApi.Core.Bridge.Operations
         public Image Snapshot(DrawingSurface drawingSurface);
         public Image Snapshot(DrawingSurface drawingSurface);
         public void DisposeImage(Image image);
         public void DisposeImage(Image image);
         public Image FromEncodedData(string path);
         public Image FromEncodedData(string path);
-        public Pixmap PeekPixels(DrawingSurface drawingSurface);
+        public void GetColorShifts(ref int platformColorAlphaShift, ref int platformColorRedShift, ref int platformColorGreenShift, ref int platformColorBlueShift);
     }
     }
 }
 }

+ 13 - 0
src/PixiEditor.DrawingApi.Core/Bridge/Operations/ISurfaceOperations.cs

@@ -0,0 +1,13 @@
+using System;
+using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.ImageData;
+
+namespace PixiEditor.DrawingApi.Core.Bridge.Operations;
+
+public interface ISurfaceOperations
+{
+    public Pixmap PeekPixels(DrawingSurface drawingSurface);
+    public DrawingSurface Create(ImageInfo imageInfo, IntPtr pixels, int rowBytes);
+    public bool ReadPixels(DrawingSurface drawingSurface, ImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY);
+    public void Draw(DrawingSurface drawingSurface, Canvas surfaceToDraw, int x, int y, Paint drawingPaint);
+}

+ 2 - 2
src/PixiEditor.DrawingApi.Core/ColorsImpl/ColorF.cs

@@ -337,7 +337,7 @@ namespace PixiEditor.DrawingApi.Core.ColorsImpl
         /// <returns>The new <see cref="T:DrawingApiCore.ColorF" /> instance.</returns>
         /// <returns>The new <see cref="T:DrawingApiCore.ColorF" /> instance.</returns>
         public static implicit operator ColorF(Color color)
         public static implicit operator ColorF(Color color)
         {
         {
-            return DrawingBackendApi.Current.ColorOperations.ColorToColorF((uint)color);
+            return DrawingBackendApi.Current.ColorImplementation.ColorToColorF((uint)color);
         }
         }
 
 
         /// <param name="color">The color to convert.</param>
         /// <param name="color">The color to convert.</param>
@@ -346,7 +346,7 @@ namespace PixiEditor.DrawingApi.Core.ColorsImpl
         /// <remarks>As a result of converting a floating-point color to an integer color, some data loss will occur.</remarks>
         /// <remarks>As a result of converting a floating-point color to an integer color, some data loss will occur.</remarks>
         public static explicit operator Color(ColorF color)
         public static explicit operator Color(ColorF color)
         {
         {
-            return DrawingBackendApi.Current.ColorOperations.ColorFToColor(color);
+            return DrawingBackendApi.Current.ColorImplementation.ColorFToColor(color);
         }
         }
 
 
         /// <param name="obj">The object to compare with the current object.</param>
         /// <param name="obj">The object to compare with the current object.</param>

+ 11 - 0
src/PixiEditor.DrawingApi.Core/Numerics/RectI.cs

@@ -344,4 +344,15 @@ public struct RectI : IEquatable<RectI>
     {
     {
         return $"{{X: {X}, Y: {Y}, W: {Width}, H: {Height}}}";
         return $"{{X: {X}, Y: {Y}, W: {Width}, H: {Height}}}";
     }
     }
+
+    public static RectI Create(int width, int height)
+    {
+        return new RectI()
+        {
+            Left = 0,
+            Right = width,
+            Top = 0,
+            Bottom = height
+        };
+    }
 }
 }

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

@@ -96,9 +96,9 @@ namespace PixiEditor.DrawingApi.Core.Surface
             DrawingBackendApi.Current.CanvasOperations.ClipPath(clipPath, clipOperation, antialias);
             DrawingBackendApi.Current.CanvasOperations.ClipPath(clipPath, clipOperation, antialias);
         }
         }
 
 
-        public void ClipRect(RectD rect)
+        public void ClipRect(RectD rect, ClipOperation clipOperation = ClipOperation.Intersect)
         {
         {
-            DrawingBackendApi.Current.CanvasOperations.ClipRect(rect);
+            DrawingBackendApi.Current.CanvasOperations.ClipRect(rect, clipOperation);
         }
         }
 
 
         public void Clear()
         public void Clear()
@@ -135,5 +135,10 @@ namespace PixiEditor.DrawingApi.Core.Surface
         {
         {
             DrawingBackendApi.Current.CanvasOperations.DrawColor(color, paintBlendMode);
             DrawingBackendApi.Current.CanvasOperations.DrawColor(color, paintBlendMode);
         }
         }
+
+        public void RotateRadians(float dataAngle, float centerX, float centerY)
+        {
+            DrawingBackendApi.Current.CanvasOperations.RotateRadians(dataAngle, centerX, centerY);
+        }
     }
     }
 }
 }

+ 27 - 4
src/PixiEditor.DrawingApi.Core/Surface/DrawingSurface.cs

@@ -4,13 +4,27 @@ using PixiEditor.DrawingApi.Core.Surface.ImageData;
 
 
 namespace PixiEditor.DrawingApi.Core.Surface
 namespace PixiEditor.DrawingApi.Core.Surface
 {
 {
-    public class DrawingSurface
+    public class DrawingSurface : NativeObject
     {
     {
         public float Width { get; set; }
         public float Width { get; set; }
         public float Height { get; set; }
         public float Height { get; set; }
         
         
         public DrawingSurfaceProperties Properties { get; private set; }
         public DrawingSurfaceProperties Properties { get; private set; }
         public Canvas Canvas { get; private set; }
         public Canvas Canvas { get; private set; }
+        
+        internal DrawingSurface(IntPtr objPtr) : base(objPtr)
+        {
+        }
+        
+        public DrawingSurface Create(Pixmap imageInfo)
+        {
+            return DrawingBackendApi.Current.SurfaceOperations.Create(ObjectPointer, imageInfo);
+        }
+        
+        public void Draw(Canvas drawingSurfaceCanvas, int x, int y, Paint drawingPaint)
+        {
+            DrawingBackendApi.Current.SurfaceOperations.Draw(this, drawingSurfaceCanvas, x, y, drawingPaint);
+        }
 
 
         public Image Snapshot()
         public Image Snapshot()
         {
         {
@@ -19,12 +33,21 @@ namespace PixiEditor.DrawingApi.Core.Surface
 
 
         public Pixmap PeekPixels()
         public Pixmap PeekPixels()
         {
         {
-            return DrawingBackendApi.Current.ImageOperations.PeekPixels(this);
+            return DrawingBackendApi.Current.SurfaceOperations.PeekPixels(this);
+        }
+        
+        public bool ReadPixels(ImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY)
+        {
+            return DrawingBackendApi.Current.SurfaceOperations.ReadPixels(this, dstInfo, dstPixels, dstRowBytes, srcX, srcY);
+        }
+
+        public static DrawingSurface Create(ImageInfo imageInfo, IntPtr pixels, int rowBytes)
+        {
+            return DrawingBackendApi.Current.SurfaceOperations.Create(imageInfo, pixels, rowBytes);
         }
         }
 
 
-        public static DrawingSurface Create(ImageInfo imageInfo, IntPtr arr, int chunkSize)
+        public override void Dispose()
         {
         {
-            
         }
         }
     }
     }
 }
 }

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

@@ -1,8 +1,21 @@
-using SkiaSharp;
+using System;
+using PixiEditor.DrawingApi.Core.Bridge;
 
 
 namespace PixiEditor.DrawingApi.Core.Surface.ImageData;
 namespace PixiEditor.DrawingApi.Core.Surface.ImageData;
 
 
-public class ColorSpace
+public class ColorSpace : NativeObject
 {
 {
+    internal ColorSpace(IntPtr objPtr) : base(objPtr)
+    {
+    }
     
     
+    public static ColorSpace CreateSrgb()
+    {
+        return DrawingBackendApi.Current.ColorSpaceImplementation.CreateSrgb();
+    }
+
+    public override void Dispose()
+    {
+        DrawingBackendApi.Current.ColorSpaceImplementation.Dispose(ObjectPointer);
+    }
 }
 }

+ 53 - 0
src/PixiEditor.DrawingApi.Core/Surface/ImageData/ColorTypeExtensions.cs

@@ -0,0 +1,53 @@
+using System;
+
+namespace PixiEditor.DrawingApi.Core.Surface.ImageData;
+
+public static class ColorTypeExtensions
+{
+    public static int GetBytesPerPixel(this ColorType colorType)
+        {
+          switch (colorType)
+          {
+            case ColorType.Unknown:
+              return 0;
+            case ColorType.Alpha8:
+              return 1;
+            case ColorType.Rgb565:
+              return 2;
+            case ColorType.Argb4444:
+              return 2;
+            case ColorType.Rgba8888:
+              return 4;
+            case ColorType.Rgb888x:
+              return 4;
+            case ColorType.Bgra8888:
+              return 4;
+            case ColorType.Rgba1010102:
+              return 4;
+            case ColorType.Rgb101010x:
+              return 4;
+            case ColorType.Gray8:
+              return 1;
+            case ColorType.RgbaF16:
+              return 8;
+            case ColorType.RgbaF16Clamped:
+              return 8;
+            case ColorType.RgbaF32:
+              return 16;
+            case ColorType.Rg88:
+              return 2;
+            case ColorType.AlphaF16:
+              return 2;
+            case ColorType.RgF16:
+              return 4;
+            case ColorType.Alpha16:
+              return 2;
+            case ColorType.Rg1616:
+              return 4;
+            case ColorType.Rgba16161616:
+              return 8;
+            default:
+              throw new ArgumentOutOfRangeException(nameof (colorType));
+          }
+        }
+}

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

@@ -1,4 +1,5 @@
-using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.Bridge;
+using PixiEditor.DrawingApi.Core.Numerics;
 using HashCode = System.HashCode;
 using HashCode = System.HashCode;
 
 
 namespace PixiEditor.DrawingApi.Core.Surface.ImageData;
 namespace PixiEditor.DrawingApi.Core.Surface.ImageData;
@@ -10,7 +11,7 @@ public struct ImageInfo : System.IEquatable<ImageInfo>
     
     
     /// <summary>The current 32-bit color for the current platform.</summary>
     /// <summary>The current 32-bit color for the current platform.</summary>
     /// <remarks>On Windows, it is typically <see cref="ColorType.Bgra8888" />, and on Unix-based systems (macOS, Linux) it is typically <see cref="ColorType.Rgba8888" />.</remarks>
     /// <remarks>On Windows, it is typically <see cref="ColorType.Bgra8888" />, and on Unix-based systems (macOS, Linux) it is typically <see cref="ColorType.Rgba8888" />.</remarks>
-    public static readonly ColorType PlatformColorType = SkiaApi.sk_colortype_get_default_8888().FromNative();
+    public static readonly ColorType PlatformColorType = DrawingBackendApi.Current.ColorImplementation.GetPlatformColorType();
     
     
     /// <summary>The number of bits to shift left for the alpha color component.</summary>
     /// <summary>The number of bits to shift left for the alpha color component.</summary>
     public static readonly int PlatformColorAlphaShift;
     public static readonly int PlatformColorAlphaShift;
@@ -26,11 +27,7 @@ public struct ImageInfo : System.IEquatable<ImageInfo>
 
 
     static unsafe ImageInfo()
     static unsafe ImageInfo()
     {
     {
-      fixed (int* a = &ImageInfo.PlatformColorAlphaShift)
-        fixed (int* r = &ImageInfo.PlatformColorRedShift)
-          fixed (int* g = &ImageInfo.PlatformColorGreenShift)
-            fixed (int* b = &ImageInfo.PlatformColorBlueShift)
-              SkiaApi.sk_color_get_bit_shift(a, r, g, b);
+      DrawingBackendApi.Current.ImageOperations.GetColorShifts(ref PlatformColorAlphaShift, ref PlatformColorRedShift, ref PlatformColorGreenShift, ref PlatformColorBlueShift);
     }
     }
 
 
     /// <summary>Gets or sets the width.</summary>
     /// <summary>Gets or sets the width.</summary>
@@ -59,7 +56,7 @@ public struct ImageInfo : System.IEquatable<ImageInfo>
       this.Height = height;
       this.Height = height;
       this.ColorType = ImageInfo.PlatformColorType;
       this.ColorType = ImageInfo.PlatformColorType;
       this.AlphaType = AlphaType.Premul;
       this.AlphaType = AlphaType.Premul;
-      this.ColorSpace = (ColorSpace) null;
+      this.ColorSpace = (ColorSpace)null;
     }
     }
 
 
     public ImageInfo(int width, int height, ColorType colorType)
     public ImageInfo(int width, int height, ColorType colorType)
@@ -97,7 +94,7 @@ public struct ImageInfo : System.IEquatable<ImageInfo>
     /// <summary>Gets the number of bytes used per pixel.</summary>
     /// <summary>Gets the number of bytes used per pixel.</summary>
     /// <value />
     /// <value />
     /// <remarks>This is calculated from the <see cref="ImageInfo.ColorType" />. If the color type is <see cref="ColorType.Unknown" />, then the value will be 0.</remarks>
     /// <remarks>This is calculated from the <see cref="ImageInfo.ColorType" />. If the color type is <see cref="ColorType.Unknown" />, then the value will be 0.</remarks>
-    public readonly int BytesPerPixel => this.ColorType.GetBytesPerPixel();
+    public readonly int BytesPerPixel => ColorType.GetBytesPerPixel();
 
 
     /// <summary>Gets the number of bits used per pixel.</summary>
     /// <summary>Gets the number of bits used per pixel.</summary>
     /// <value />
     /// <value />
@@ -141,7 +138,7 @@ public struct ImageInfo : System.IEquatable<ImageInfo>
     public readonly RectI Rect => RectI.Create(this.Width, this.Height);
     public readonly RectI Rect => RectI.Create(this.Width, this.Height);
 
 
 
 
-    public readonly ImageInfo WithSize(VecI size) => this.WithSize(size.Width, size.Height);
+    public readonly ImageInfo WithSize(VecI size) => this.WithSize(size.X, size.Y);
 
 
     /// <param name="width">The width.</param>
     /// <param name="width">The width.</param>
     /// <param name="height">The height.</param>
     /// <param name="height">The height.</param>

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

@@ -1,6 +1,5 @@
 using System;
 using System;
 using PixiEditor.DrawingApi.Core.Bridge;
 using PixiEditor.DrawingApi.Core.Bridge;
-using SkiaSharp;
 
 
 namespace PixiEditor.DrawingApi.Core.Surface;
 namespace PixiEditor.DrawingApi.Core.Surface;
 
 
@@ -10,6 +9,9 @@ public class Pixmap : NativeObject
     {
     {
     }
     }
 
 
+    public int Width { get; set; }
+    public int Height { get; set; }
+
     public override void Dispose()
     public override void Dispose()
     {
     {
         DrawingBackendApi.Current.PixmapImplementation.Dispose(ObjectPointer);
         DrawingBackendApi.Current.PixmapImplementation.Dispose(ObjectPointer);

+ 3 - 2
src/PixiEditor/Helpers/SurfaceHelpers.cs

@@ -4,6 +4,7 @@ using System.Windows.Media.Imaging;
 using ChunkyImageLib;
 using ChunkyImageLib;
 using ChunkyImageLib.DataHolders;
 using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.DrawingApi.Core.Surface.ImageData;
 using SkiaSharp;
 using SkiaSharp;
 
 
 namespace PixiEditor.Helpers;
 namespace PixiEditor.Helpers;
@@ -38,11 +39,11 @@ public static class SurfaceHelpers
         return result;
         return result;
     }
     }
 
 
-    private static unsafe byte[] ToByteArray(Surface surface, SKColorType colorType = SKColorType.Bgra8888, SKAlphaType alphaType = SKAlphaType.Premul)
+    private static unsafe byte[] ToByteArray(Surface surface, ColorType colorType = ColorType.Bgra8888, AlphaType alphaType = AlphaType.Premul)
     {
     {
         int width = surface.Size.X;
         int width = surface.Size.X;
         int height = surface.Size.Y;
         int height = surface.Size.Y;
-        var imageInfo = new SKImageInfo(width, height, colorType, alphaType, SKColorSpace.CreateSrgb());
+        var imageInfo = new ImageInfo(width, height, colorType, alphaType, ColorSpace.CreateSrgb());
 
 
         byte[] buffer = new byte[width * height * imageInfo.BytesPerPixel];
         byte[] buffer = new byte[width * height * imageInfo.BytesPerPixel];
         fixed (void* pointer = buffer)
         fixed (void* pointer = buffer)

+ 4 - 3
src/PixiEditor/ViewModels/SubViewModels/Document/DocumentViewModel.cs

@@ -11,6 +11,7 @@ using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.ChangeableDocument.Rendering;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.ImageData;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 using PixiEditor.DrawingApi.Core.Surface.Vector;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Controllers;
@@ -118,7 +119,7 @@ internal class DocumentViewModel : NotifyableObject
         {
         {
             if (ReferenceLayer is null)
             if (ReferenceLayer is null)
                 return Matrix.Identity;
                 return Matrix.Identity;
-            SKMatrix skiaMatrix = OperationHelper.CreateMatrixFromPoints(ReferenceLayer.Shape, ReferenceLayer.Image.Size);
+            Matrix3X3 skiaMatrix = OperationHelper.CreateMatrixFromPoints(ReferenceLayer.Shape, ReferenceLayer.Image.Size);
             return new Matrix(skiaMatrix.ScaleX, skiaMatrix.SkewY, skiaMatrix.SkewX, skiaMatrix.ScaleY, skiaMatrix.TransX, skiaMatrix.TransY);
             return new Matrix(skiaMatrix.ScaleX, skiaMatrix.SkewY, skiaMatrix.SkewX, skiaMatrix.ScaleY, skiaMatrix.TransX, skiaMatrix.TransY);
         }
         }
     }
     }
@@ -170,14 +171,14 @@ internal class DocumentViewModel : NotifyableObject
         foreach (KeyValuePair<ChunkResolution, WriteableBitmap> bitmap in Bitmaps)
         foreach (KeyValuePair<ChunkResolution, WriteableBitmap> bitmap in Bitmaps)
         {
         {
             DrawingSurface? surface = DrawingSurface.Create(
             DrawingSurface? surface = DrawingSurface.Create(
-                new SKImageInfo(bitmap.Value.PixelWidth, bitmap.Value.PixelHeight, SKColorType.Bgra8888, SKAlphaType.Premul, SKColorSpace.CreateSrgb()),
+                new ImageInfo(bitmap.Value.PixelWidth, bitmap.Value.PixelHeight, ColorType.Bgra8888, AlphaType.Premul, ColorSpace.CreateSrgb()),
                 bitmap.Value.BackBuffer, bitmap.Value.BackBufferStride);
                 bitmap.Value.BackBuffer, bitmap.Value.BackBufferStride);
             Surfaces[bitmap.Key] = surface;
             Surfaces[bitmap.Key] = surface;
         }
         }
 
 
         VecI previewSize = StructureMemberViewModel.CalculatePreviewSize(SizeBindable);
         VecI previewSize = StructureMemberViewModel.CalculatePreviewSize(SizeBindable);
         PreviewBitmap = new WriteableBitmap(previewSize.X, previewSize.Y, 96, 96, PixelFormats.Pbgra32, null);
         PreviewBitmap = new WriteableBitmap(previewSize.X, previewSize.Y, 96, 96, PixelFormats.Pbgra32, null);
-        PreviewSurface = DrawingSurface.Create(new SKImageInfo(previewSize.X, previewSize.Y, SKColorType.Bgra8888), PreviewBitmap.BackBuffer, PreviewBitmap.BackBufferStride);
+        PreviewSurface = DrawingSurface.Create(new ImageInfo(previewSize.X, previewSize.Y, ColorType.Bgra8888), PreviewBitmap.BackBuffer, PreviewBitmap.BackBufferStride);
     }
     }
 
 
     public static DocumentViewModel Build(Action<DocumentViewModelBuilder> builder)
     public static DocumentViewModel Build(Action<DocumentViewModelBuilder> builder)

+ 2 - 2
src/PixiEditor/ViewModels/SubViewModels/Document/StructureMemberViewModel.cs

@@ -1,9 +1,9 @@
 using System.ComponentModel;
 using System.ComponentModel;
 using System.Windows.Media;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
-using ChunkyImageLib.DataHolders;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surface;
 using PixiEditor.DrawingApi.Core.Surface;
+using PixiEditor.DrawingApi.Core.Surface.ImageData;
 using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.DocumentModels;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
 using BlendMode = PixiEditor.ChangeableDocument.Enums.BlendMode;
 using BlendMode = PixiEditor.ChangeableDocument.Enums.BlendMode;
@@ -165,6 +165,6 @@ internal abstract class StructureMemberViewModel : INotifyPropertyChanged
         this.guidValue = guidValue;
         this.guidValue = guidValue;
         VecI previewSize = CalculatePreviewSize(doc.SizeBindable);
         VecI previewSize = CalculatePreviewSize(doc.SizeBindable);
         PreviewBitmap = new WriteableBitmap(previewSize.X, previewSize.Y, 96, 96, PixelFormats.Pbgra32, null);
         PreviewBitmap = new WriteableBitmap(previewSize.X, previewSize.Y, 96, 96, PixelFormats.Pbgra32, null);
-        PreviewSurface = DrawingSurface.Create(new SKImageInfo(previewSize.X, previewSize.Y, SKColorType.Bgra8888), PreviewBitmap.BackBuffer, PreviewBitmap.BackBufferStride);
+        PreviewSurface = DrawingSurface.Create(new ImageInfo(previewSize.X, previewSize.Y, ColorType.Bgra8888), PreviewBitmap.BackBuffer, PreviewBitmap.BackBufferStride);
     }
     }
 }
 }