Skip to content

Commit 772db8e

Browse files
committed
Refactor DocumentSelection
- Remove the reference to the owning document. This was only used for creating a Cairo.Context for building the selection path, but this doesn't actually need access to the document's active layer. Instead, a new utility method provides a context which can be used solely for building paths - Use `DocumentSelection.Bounds()` to get the selection bounds, rather than going through the Cairo.Path. This also makes the GetBounds() extension method unused, eliminating some references to the global PintaCore - Remove unused Path.Clone() extension method
1 parent a09ac91 commit 772db8e

File tree

9 files changed

+41
-46
lines changed

9 files changed

+41
-46
lines changed

Pinta.Core/Classes/Document.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
//
1+
//
22
// Document.cs
3-
//
3+
//
44
// Author:
55
// Jonathan Pobst <[email protected]>
6-
//
6+
//
77
// Copyright (c) 2010 Jonathan Pobst
8-
//
8+
//
99
// Permission is hereby granted, free of charge, to any person obtaining a copy
1010
// of this software and associated documentation files (the "Software"), to deal
1111
// in the Software without restriction, including without limitation the rights
1212
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1313
// copies of the Software, and to permit persons to whom the Software is
1414
// furnished to do so, subject to the following conditions:
15-
//
15+
//
1616
// The above copyright notice and this permission notice shall be included in
1717
// all copies or substantial portions of the Software.
18-
//
18+
//
1919
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2020
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2121
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -76,8 +76,8 @@ public Document (
7676
{
7777
// --- Mandatory fields
7878

79-
PreviousSelection = new (this);
80-
Selection = new DocumentSelection (this);
79+
PreviousSelection = new ();
80+
Selection = new DocumentSelection ();
8181

8282
Layers = new DocumentLayers (tools, this);
8383
Workspace = new DocumentWorkspace (actions, tools, this);
@@ -89,7 +89,7 @@ public Document (
8989
this.tools = tools;
9090
this.workspace = workspace;
9191

92-
// --- Post-initialization
92+
// --- Post-initialization
9393

9494
if (file is not null) {
9595

@@ -285,7 +285,7 @@ public ColorBgra GetComputedPixel (PointI position)
285285
/// <param name="canvasOnly">false for the whole selection, true for the part only on our canvas</param>
286286
public RectangleI GetSelectedBounds (bool canvasOnly)
287287
{
288-
RectangleI bounds = Selection.SelectionPath.GetBounds ();
288+
RectangleI bounds = Selection.GetBounds ().ToInt ();
289289

290290
if (canvasOnly)
291291
bounds = ClampToImageSize (bounds);

Pinta.Core/Classes/DocumentSelection.cs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,15 @@
2626

2727
using System;
2828
using System.Collections.Generic;
29-
using System.Linq;
3029
using Cairo;
3130
using ClipperLib;
3231

3332
namespace Pinta.Core;
3433

3534
public sealed class DocumentSelection
3635
{
37-
private readonly Document owning_document;
38-
internal DocumentSelection (Document owningDocument)
36+
internal DocumentSelection ()
3937
{
40-
this.owning_document = owningDocument;
4138
}
4239

4340
private Path? selection_path;
@@ -62,7 +59,7 @@ public bool Visible {
6259
public Path SelectionPath {
6360
get {
6461
if (selection_path == null) {
65-
using Context g = new (owning_document.Layers.CurrentUserLayer.Surface);
62+
using Context g = CairoExtensions.CreatePathContext ();
6663
selection_path = g.CreatePolygonPath (ConvertToPolygonSet (SelectionPolygons));
6764
}
6865

@@ -95,7 +92,7 @@ public void Clip (Context g)
9592
/// </summary>
9693
public DocumentSelection Clone ()
9794
{
98-
return new (owning_document) {
95+
return new () {
9996
SelectionPolygons = [.. SelectionPolygons],
10097
Origin = new PointD (Origin.X, Origin.Y),
10198
End = new PointD (End.X, End.Y),
@@ -126,7 +123,7 @@ public static List<List<IntPoint>> ConvertToPolygons (IReadOnlyList<IReadOnlyLis
126123
/// </summary>
127124
/// <param name="clipperPolygons">A Clipper Polygon collection.</param>
128125
/// <returns>A Pinta Polygon set.</returns>
129-
public static IReadOnlyList<IReadOnlyList<PointI>> ConvertToPolygonSet (IReadOnlyList<IReadOnlyList<IntPoint>> clipperPolygons)
126+
private static IReadOnlyList<IReadOnlyList<PointI>> ConvertToPolygonSet (IReadOnlyList<IReadOnlyList<IntPoint>> clipperPolygons)
130127
{
131128
var resultingPolygonSet = new PointI[clipperPolygons.Count][];
132129

@@ -174,7 +171,7 @@ public DocumentSelection Transform (Matrix transform)
174171
transform.TransformPoint (ref origin);
175172
transform.TransformPoint (ref end);
176173

177-
return new (owning_document) {
174+
return new () {
178175
SelectionPolygons = newPolygons,
179176
Origin = origin,
180177
End = end,
@@ -330,7 +327,7 @@ public void CreateRectangleSelection (RectangleD r)
330327
/// <param name='imageSize'>
331328
/// The size of the document.
332329
/// </param>
333-
public void Invert (Core.Size imageSize)
330+
public void Invert (Size imageSize)
334331
{
335332
List<List<IntPoint>> resultingPolygons = [];
336333

@@ -419,8 +416,8 @@ public RectangleD GetBounds ()
419416
double maxY = double.MinValue;
420417

421418
// Calculate the minimum rectangular bounds that surround the current selection.
422-
foreach (var li in SelectionPolygons) {
423-
foreach (var ip in li) {
419+
foreach (List<IntPoint> li in SelectionPolygons) {
420+
foreach (IntPoint ip in li) {
424421
minX = Math.Min (minX, ip.X);
425422
minY = Math.Min (minY, ip.Y);
426423
maxX = Math.Max (maxX, ip.X);

Pinta.Core/Extensions/Cairo/CairoExtensions.Core.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,19 @@ public static ImageSurface Clone (this ImageSurface surf)
5757
return newsurf;
5858
}
5959

60-
public static Path Clone (this Path path)
60+
/// <summary>
61+
/// Placeholder surface used for <see cref="CreatePathContext"/>
62+
/// Another option would be to use a different surface type, like
63+
/// cairo_recording_surface_create(), but an empty image works okay.
64+
/// </summary>
65+
private static readonly ImageSurface empty_surface = CreateImageSurface (Format.Argb32, 0, 0);
66+
67+
/// <summary>
68+
/// Creates a Cairo context without a backing image surface, which can only be used for building a Cairo.Path.
69+
/// </summary>
70+
public static Context CreatePathContext ()
6171
{
62-
Document doc = PintaCore.Workspace.ActiveDocument;
63-
using Context g = new (doc.Layers.CurrentUserLayer.Surface);
64-
g.AppendPath (path);
65-
return g.CopyPath ();
72+
return new Context (empty_surface);
6673
}
6774

6875
/// <summary>

Pinta.Core/Extensions/Cairo/CairoExtensions.Geometry.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,6 @@ public static RectangleD PathExtents (this Context context)
8585
y2 - y1);
8686
}
8787

88-
public static RectangleI GetBounds (this Path path)
89-
{
90-
Document doc = PintaCore.Workspace.ActiveDocument;
91-
using Context g = new (doc.Layers.CurrentUserLayer.Surface);
92-
g.AppendPath (path);
93-
return g.PathExtents ().ToInt ();
94-
}
95-
9688
public static RectangleI GetBounds (this ImageSurface surf)
9789
=> new (0, 0, surf.Width, surf.Height);
9890

Pinta.Core/Managers/LivePreviewManager.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ public async void Start (BaseEffect effect)
8282
workspace.ImageSize.Width,
8383
workspace.ImageSize.Height);
8484

85-
Cairo.Path? selectionPath = selection.Visible ? selection.SelectionPath : null;
86-
RenderBounds = (selectionPath != null) ? selectionPath.GetBounds () : LivePreviewSurface.GetBounds ();
85+
RenderBounds = selection.Visible ? selection.GetBounds ().ToInt () : LivePreviewSurface.GetBounds ();
8786
RenderBounds = workspace.ClampToImageSize (RenderBounds);
8887

8988
const uint UPDATE_MILLISECONDS = 100;

Pinta.Effects/Dialogs/Effects.LevelsDialog.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ private void UpdateInputHistogram ()
316316
Document doc = workspace.ActiveDocument;
317317

318318
ImageSurface surface = doc.Layers.CurrentUserLayer.Surface;
319-
RectangleI rect = doc.Selection.SelectionPath.GetBounds ();
319+
RectangleI rect = doc.Selection.GetBounds ().ToInt ();
320320
histogram_input.Histogram.UpdateHistogram (surface, rect);
321321
UpdateOutputHistogram ();
322322
}

Pinta.Tools/Tools/MoveSelectedTool.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
//
1+
//
22
// MoveSelectedTool.cs
3-
//
3+
//
44
// Author:
55
// Jonathan Pobst <[email protected]>
6-
//
6+
//
77
// Copyright (c) 2010 Jonathan Pobst
8-
//
8+
//
99
// Permission is hereby granted, free of charge, to any person obtaining a copy
1010
// of this software and associated documentation files (the "Software"), to deal
1111
// in the Software without restriction, including without limitation the rights
1212
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1313
// copies of the Software, and to permit persons to whom the Software is
1414
// furnished to do so, subject to the following conditions:
15-
//
15+
//
1616
// The above copyright notice and this permission notice shall be included in
1717
// all copies or substantial portions of the Software.
18-
//
18+
//
1919
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2020
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2121
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -58,7 +58,7 @@ public MoveSelectedTool (IServiceProvider services) : base (services)
5858
public override int Priority => 5;
5959

6060
protected override RectangleD GetSourceRectangle (Document document)
61-
=> document.Selection.SelectionPath.GetBounds ().ToDouble ();
61+
=> document.Selection.GetBounds ();
6262

6363
protected override void OnStartTransform (Document document)
6464
{

Pinta.Tools/Tools/MoveSelectionTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public MoveSelectionTool (IServiceProvider services) : base (services)
6060
public override bool IsSelectionTool => true;
6161

6262
protected override RectangleD GetSourceRectangle (Document document)
63-
=> document.Selection.SelectionPath.GetBounds ().ToDouble ();
63+
=> document.Selection.GetBounds ();
6464

6565
protected override void OnStartTransform (Document document)
6666
{

Pinta/MainWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ private bool HandleDrop (Gtk.DropTarget sender, Gtk.DropTarget.DropSignalArgs ar
630630

631631
private void ZoomToSelection_Activated (object sender, EventArgs e)
632632
{
633-
PintaCore.Workspace.ActiveWorkspace.ZoomToCanvasRectangle (PintaCore.Workspace.ActiveDocument.Selection.SelectionPath.GetBounds ().ToDouble ());
633+
PintaCore.Workspace.ActiveWorkspace.ZoomToCanvasRectangle (PintaCore.Workspace.ActiveDocument.Selection.GetBounds ());
634634
}
635635

636636
private void ZoomToWindow_Activated (object sender, EventArgs e)

0 commit comments

Comments
 (0)