|
@@ -14,6 +14,7 @@ using ChunkyImageLib;
|
|
using ChunkyImageLib.DataHolders;
|
|
using ChunkyImageLib.DataHolders;
|
|
using PixiEditor.AvaloniaUI.Helpers;
|
|
using PixiEditor.AvaloniaUI.Helpers;
|
|
using PixiEditor.AvaloniaUI.Helpers.Converters;
|
|
using PixiEditor.AvaloniaUI.Helpers.Converters;
|
|
|
|
+using PixiEditor.AvaloniaUI.Models.DocumentModels;
|
|
using PixiEditor.AvaloniaUI.ViewModels.Document;
|
|
using PixiEditor.AvaloniaUI.ViewModels.Document;
|
|
using PixiEditor.AvaloniaUI.Views.Overlays;
|
|
using PixiEditor.AvaloniaUI.Views.Overlays;
|
|
using PixiEditor.AvaloniaUI.Views.Overlays.Pointers;
|
|
using PixiEditor.AvaloniaUI.Views.Overlays.Pointers;
|
|
@@ -50,6 +51,9 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
|
|
public static readonly StyledProperty<Cursor> DefaultCursorProperty = AvaloniaProperty.Register<Scene, Cursor>(
|
|
public static readonly StyledProperty<Cursor> DefaultCursorProperty = AvaloniaProperty.Register<Scene, Cursor>(
|
|
nameof(DefaultCursor));
|
|
nameof(DefaultCursor));
|
|
|
|
|
|
|
|
+ public static readonly StyledProperty<ViewportColorChannels> ChannelsProperty = AvaloniaProperty.Register<Scene, ViewportColorChannels>(
|
|
|
|
+ nameof(Channels));
|
|
|
|
+
|
|
public Cursor DefaultCursor
|
|
public Cursor DefaultCursor
|
|
{
|
|
{
|
|
get => GetValue(DefaultCursorProperty);
|
|
get => GetValue(DefaultCursorProperty);
|
|
@@ -86,6 +90,12 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
|
|
set => SetValue(SurfaceProperty, value);
|
|
set => SetValue(SurfaceProperty, value);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public ViewportColorChannels Channels
|
|
|
|
+ {
|
|
|
|
+ get => GetValue(ChannelsProperty);
|
|
|
|
+ set => SetValue(ChannelsProperty, value);
|
|
|
|
+ }
|
|
|
|
+
|
|
private Bitmap? checkerBitmap;
|
|
private Bitmap? checkerBitmap;
|
|
|
|
|
|
private Overlay? capturedOverlay;
|
|
private Overlay? capturedOverlay;
|
|
@@ -104,6 +114,12 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
|
|
CheckerImagePathProperty.Changed.AddClassHandler<Scene>(CheckerImagePathChanged);
|
|
CheckerImagePathProperty.Changed.AddClassHandler<Scene>(CheckerImagePathChanged);
|
|
AllOverlaysProperty.Changed.AddClassHandler<Scene>(ActiveOverlaysChanged);
|
|
AllOverlaysProperty.Changed.AddClassHandler<Scene>(ActiveOverlaysChanged);
|
|
DefaultCursorProperty.Changed.AddClassHandler<Scene>(DefaultCursorChanged);
|
|
DefaultCursorProperty.Changed.AddClassHandler<Scene>(DefaultCursorChanged);
|
|
|
|
+ ChannelsProperty.Changed.AddClassHandler<Scene>(ChannelsChanged);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static void ChannelsChanged(Scene scene, AvaloniaPropertyChangedEventArgs args)
|
|
|
|
+ {
|
|
|
|
+ scene.InvalidateVisual();
|
|
}
|
|
}
|
|
|
|
|
|
public Scene()
|
|
public Scene()
|
|
@@ -130,7 +146,8 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
|
|
using var operation = new DrawSceneOperation(Surface, Document, CanvasPos, Scale * resolutionScale, angle, FlipX, FlipY,
|
|
using var operation = new DrawSceneOperation(Surface, Document, CanvasPos, Scale * resolutionScale, angle, FlipX, FlipY,
|
|
dirtyRect,
|
|
dirtyRect,
|
|
Bounds,
|
|
Bounds,
|
|
- sceneOpacity);
|
|
|
|
|
|
+ sceneOpacity,
|
|
|
|
+ Channels.GetColorMatrix());
|
|
|
|
|
|
var matrix = CalculateTransformMatrix();
|
|
var matrix = CalculateTransformMatrix();
|
|
context.PushTransform(matrix);
|
|
context.PushTransform(matrix);
|
|
@@ -454,13 +471,14 @@ internal class DrawSceneOperation : SkiaDrawOperation
|
|
public bool FlipX { get; set; }
|
|
public bool FlipX { get; set; }
|
|
public bool FlipY { get; set; }
|
|
public bool FlipY { get; set; }
|
|
public Rect ViewportBounds { get; }
|
|
public Rect ViewportBounds { get; }
|
|
|
|
+ public ColorMatrix ColorMatrix { get; }
|
|
|
|
|
|
public RectI SurfaceRectToRender { get; }
|
|
public RectI SurfaceRectToRender { get; }
|
|
|
|
|
|
private SKPaint _paint = new SKPaint();
|
|
private SKPaint _paint = new SKPaint();
|
|
|
|
|
|
public DrawSceneOperation(Surface surface, DocumentViewModel document, VecD contentPosition, double scale,
|
|
public DrawSceneOperation(Surface surface, DocumentViewModel document, VecD contentPosition, double scale,
|
|
- double angle, bool flipX, bool flipY, Rect dirtyBounds, Rect viewportBounds, double opacity) : base(dirtyBounds)
|
|
|
|
|
|
+ double angle, bool flipX, bool flipY, Rect dirtyBounds, Rect viewportBounds, double opacity, ColorMatrix colorMatrix) : base(dirtyBounds)
|
|
{
|
|
{
|
|
Surface = surface;
|
|
Surface = surface;
|
|
Document = document;
|
|
Document = document;
|
|
@@ -469,6 +487,7 @@ internal class DrawSceneOperation : SkiaDrawOperation
|
|
Angle = angle;
|
|
Angle = angle;
|
|
FlipX = flipX;
|
|
FlipX = flipX;
|
|
FlipY = flipY;
|
|
FlipY = flipY;
|
|
|
|
+ ColorMatrix = colorMatrix;
|
|
ViewportBounds = viewportBounds;
|
|
ViewportBounds = viewportBounds;
|
|
_paint.Color = _paint.Color.WithAlpha((byte)(opacity * 255));
|
|
_paint.Color = _paint.Color.WithAlpha((byte)(opacity * 255));
|
|
SurfaceRectToRender = FindRectToRender((float)scale);
|
|
SurfaceRectToRender = FindRectToRender((float)scale);
|
|
@@ -489,6 +508,11 @@ internal class DrawSceneOperation : SkiaDrawOperation
|
|
}
|
|
}
|
|
|
|
|
|
using Image snapshot = Surface.DrawingSurface.Snapshot(SurfaceRectToRender);
|
|
using Image snapshot = Surface.DrawingSurface.Snapshot(SurfaceRectToRender);
|
|
|
|
+
|
|
|
|
+ var matrixValues = new float[ColorMatrix.Width * ColorMatrix.Height];
|
|
|
|
+ ColorMatrix.TryGetMembers(matrixValues);
|
|
|
|
+
|
|
|
|
+ _paint.ColorFilter = SKColorFilter.CreateColorMatrix(matrixValues);
|
|
canvas.DrawImage((SKImage)snapshot.Native, SurfaceRectToRender.X, SurfaceRectToRender.Y, _paint);
|
|
canvas.DrawImage((SKImage)snapshot.Native, SurfaceRectToRender.X, SurfaceRectToRender.Y, _paint);
|
|
|
|
|
|
canvas.Restore();
|
|
canvas.Restore();
|