diff --git a/Pinta.Core/Classes/Document.cs b/Pinta.Core/Classes/Document.cs index 6cd5cb2cae..41e581faee 100644 --- a/Pinta.Core/Classes/Document.cs +++ b/Pinta.Core/Classes/Document.cs @@ -1,21 +1,21 @@ -// +// // Document.cs -// +// // Author: // Jonathan Pobst -// +// // Copyright (c) 2010 Jonathan Pobst -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -76,8 +76,8 @@ public Document ( { // --- Mandatory fields - PreviousSelection = new (this); - Selection = new DocumentSelection (this); + PreviousSelection = new (); + Selection = new DocumentSelection (); Layers = new DocumentLayers (tools, this); Workspace = new DocumentWorkspace (actions, tools, this); @@ -89,7 +89,7 @@ public Document ( this.tools = tools; this.workspace = workspace; - // --- Post-initialization + // --- Post-initialization if (file is not null) { @@ -285,7 +285,7 @@ public ColorBgra GetComputedPixel (PointI position) /// false for the whole selection, true for the part only on our canvas public RectangleI GetSelectedBounds (bool canvasOnly) { - RectangleI bounds = Selection.SelectionPath.GetBounds (); + RectangleI bounds = Selection.GetBounds ().ToInt (); if (canvasOnly) bounds = ClampToImageSize (bounds); diff --git a/Pinta.Core/Classes/DocumentSelection.cs b/Pinta.Core/Classes/DocumentSelection.cs index 8bc085b21e..f577527861 100644 --- a/Pinta.Core/Classes/DocumentSelection.cs +++ b/Pinta.Core/Classes/DocumentSelection.cs @@ -26,7 +26,6 @@ using System; using System.Collections.Generic; -using System.Linq; using Cairo; using ClipperLib; @@ -34,10 +33,8 @@ namespace Pinta.Core; public sealed class DocumentSelection { - private readonly Document owning_document; - internal DocumentSelection (Document owningDocument) + internal DocumentSelection () { - this.owning_document = owningDocument; } private Path? selection_path; @@ -62,7 +59,7 @@ public bool Visible { public Path SelectionPath { get { if (selection_path == null) { - using Context g = new (owning_document.Layers.CurrentUserLayer.Surface); + using Context g = CairoExtensions.CreatePathContext (); selection_path = g.CreatePolygonPath (ConvertToPolygonSet (SelectionPolygons)); } @@ -95,7 +92,7 @@ public void Clip (Context g) /// public DocumentSelection Clone () { - return new (owning_document) { + return new () { SelectionPolygons = [.. SelectionPolygons], Origin = new PointD (Origin.X, Origin.Y), End = new PointD (End.X, End.Y), @@ -126,7 +123,7 @@ public static List> ConvertToPolygons (IReadOnlyList /// A Clipper Polygon collection. /// A Pinta Polygon set. - public static IReadOnlyList> ConvertToPolygonSet (IReadOnlyList> clipperPolygons) + private static IReadOnlyList> ConvertToPolygonSet (IReadOnlyList> clipperPolygons) { var resultingPolygonSet = new PointI[clipperPolygons.Count][]; @@ -174,7 +171,7 @@ public DocumentSelection Transform (Matrix transform) transform.TransformPoint (ref origin); transform.TransformPoint (ref end); - return new (owning_document) { + return new () { SelectionPolygons = newPolygons, Origin = origin, End = end, @@ -330,7 +327,7 @@ public void CreateRectangleSelection (RectangleD r) /// /// The size of the document. /// - public void Invert (Core.Size imageSize) + public void Invert (Size imageSize) { List> resultingPolygons = []; @@ -419,8 +416,8 @@ public RectangleD GetBounds () double maxY = double.MinValue; // Calculate the minimum rectangular bounds that surround the current selection. - foreach (var li in SelectionPolygons) { - foreach (var ip in li) { + foreach (List li in SelectionPolygons) { + foreach (IntPoint ip in li) { minX = Math.Min (minX, ip.X); minY = Math.Min (minY, ip.Y); maxX = Math.Max (maxX, ip.X); diff --git a/Pinta.Core/Extensions/Cairo/CairoExtensions.Core.cs b/Pinta.Core/Extensions/Cairo/CairoExtensions.Core.cs index 352d41c4fc..c5af79cae7 100644 --- a/Pinta.Core/Extensions/Cairo/CairoExtensions.Core.cs +++ b/Pinta.Core/Extensions/Cairo/CairoExtensions.Core.cs @@ -57,12 +57,19 @@ public static ImageSurface Clone (this ImageSurface surf) return newsurf; } - public static Path Clone (this Path path) + /// + /// Placeholder surface used for + /// Another option would be to use a different surface type, like + /// cairo_recording_surface_create(), but an empty image works okay. + /// + private static readonly Lazy empty_surface = new (() => CreateImageSurface (Format.Argb32, 0, 0)); + + /// + /// Creates a Cairo context without a backing image surface, which can only be used for building a Cairo.Path. + /// + public static Context CreatePathContext () { - Document doc = PintaCore.Workspace.ActiveDocument; - using Context g = new (doc.Layers.CurrentUserLayer.Surface); - g.AppendPath (path); - return g.CopyPath (); + return new Context (empty_surface.Value); } /// diff --git a/Pinta.Core/Extensions/Cairo/CairoExtensions.Geometry.cs b/Pinta.Core/Extensions/Cairo/CairoExtensions.Geometry.cs index daf1c9d625..5e9854a554 100644 --- a/Pinta.Core/Extensions/Cairo/CairoExtensions.Geometry.cs +++ b/Pinta.Core/Extensions/Cairo/CairoExtensions.Geometry.cs @@ -85,14 +85,6 @@ public static RectangleD PathExtents (this Context context) y2 - y1); } - public static RectangleI GetBounds (this Path path) - { - Document doc = PintaCore.Workspace.ActiveDocument; - using Context g = new (doc.Layers.CurrentUserLayer.Surface); - g.AppendPath (path); - return g.PathExtents ().ToInt (); - } - public static RectangleI GetBounds (this ImageSurface surf) => new (0, 0, surf.Width, surf.Height); diff --git a/Pinta.Core/Managers/LivePreviewManager.cs b/Pinta.Core/Managers/LivePreviewManager.cs index f1e5f814ce..2916d37e7d 100644 --- a/Pinta.Core/Managers/LivePreviewManager.cs +++ b/Pinta.Core/Managers/LivePreviewManager.cs @@ -82,8 +82,7 @@ public async void Start (BaseEffect effect) workspace.ImageSize.Width, workspace.ImageSize.Height); - Cairo.Path? selectionPath = selection.Visible ? selection.SelectionPath : null; - RenderBounds = (selectionPath != null) ? selectionPath.GetBounds () : LivePreviewSurface.GetBounds (); + RenderBounds = selection.Visible ? selection.GetBounds ().ToInt () : LivePreviewSurface.GetBounds (); RenderBounds = workspace.ClampToImageSize (RenderBounds); const uint UPDATE_MILLISECONDS = 100; diff --git a/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs b/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs index 4a0fa5ebe9..ee7271cfcb 100644 --- a/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs +++ b/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs @@ -316,7 +316,7 @@ private void UpdateInputHistogram () Document doc = workspace.ActiveDocument; ImageSurface surface = doc.Layers.CurrentUserLayer.Surface; - RectangleI rect = doc.Selection.SelectionPath.GetBounds (); + RectangleI rect = doc.Selection.GetBounds ().ToInt (); histogram_input.Histogram.UpdateHistogram (surface, rect); UpdateOutputHistogram (); } diff --git a/Pinta.Tools/Tools/MoveSelectedTool.cs b/Pinta.Tools/Tools/MoveSelectedTool.cs index e2fa8aa121..65a6f7e930 100644 --- a/Pinta.Tools/Tools/MoveSelectedTool.cs +++ b/Pinta.Tools/Tools/MoveSelectedTool.cs @@ -1,21 +1,21 @@ -// +// // MoveSelectedTool.cs -// +// // Author: // Jonathan Pobst -// +// // Copyright (c) 2010 Jonathan Pobst -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -58,7 +58,7 @@ public MoveSelectedTool (IServiceProvider services) : base (services) public override int Priority => 5; protected override RectangleD GetSourceRectangle (Document document) - => document.Selection.SelectionPath.GetBounds ().ToDouble (); + => document.Selection.GetBounds (); protected override void OnStartTransform (Document document) { diff --git a/Pinta.Tools/Tools/MoveSelectionTool.cs b/Pinta.Tools/Tools/MoveSelectionTool.cs index 5f93ca6d20..1cc3f86044 100644 --- a/Pinta.Tools/Tools/MoveSelectionTool.cs +++ b/Pinta.Tools/Tools/MoveSelectionTool.cs @@ -60,7 +60,7 @@ public MoveSelectionTool (IServiceProvider services) : base (services) public override bool IsSelectionTool => true; protected override RectangleD GetSourceRectangle (Document document) - => document.Selection.SelectionPath.GetBounds ().ToDouble (); + => document.Selection.GetBounds (); protected override void OnStartTransform (Document document) { diff --git a/Pinta/MainWindow.cs b/Pinta/MainWindow.cs index 6977254a44..c41ff8d461 100644 --- a/Pinta/MainWindow.cs +++ b/Pinta/MainWindow.cs @@ -630,7 +630,7 @@ private bool HandleDrop (Gtk.DropTarget sender, Gtk.DropTarget.DropSignalArgs ar private void ZoomToSelection_Activated (object sender, EventArgs e) { - PintaCore.Workspace.ActiveWorkspace.ZoomToCanvasRectangle (PintaCore.Workspace.ActiveDocument.Selection.SelectionPath.GetBounds ().ToDouble ()); + PintaCore.Workspace.ActiveWorkspace.ZoomToCanvasRectangle (PintaCore.Workspace.ActiveDocument.Selection.GetBounds ()); } private void ZoomToWindow_Activated (object sender, EventArgs e)