Skip to content

Commit

Permalink
[Fixes bug #663676] Since I can't get the fill path set correctly for…
Browse files Browse the repository at this point in the history
… Cairo to do the fill, do the fill from the stencil and then copy it to the user layer. Seems to be just as fast, maybe faster.
  • Loading branch information
jpobst committed Dec 28, 2010
1 parent 5de7aba commit 2a20973
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 18 deletions.
9 changes: 9 additions & 0 deletions Pinta.Core/Extensions/CairoExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,15 @@ public unsafe static void SetColorBgra (this Cairo.ImageSurface surf, ColorBgra
*dstPtr = color;
}

public unsafe static void SetColorBgra (this Cairo.ImageSurface surf, ColorBgra* surfDataPtr, int surfWidth, ColorBgra color, int x, int y)
{
ColorBgra* dstPtr = surfDataPtr;

dstPtr += (x) + (y * surfWidth);

*dstPtr = color;
}

public unsafe static ColorBgra GetColorBgra (this Cairo.ImageSurface surf, ColorBgra* surfDataPtr, int surfWidth, int x, int y)
{
ColorBgra* dstPtr = surfDataPtr;
Expand Down
18 changes: 11 additions & 7 deletions Pinta.Tools/FloodTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public abstract class FloodTool : BaseTool
#region Protected Properties
protected bool IsContinguousMode { get { return (bool)mode_button.SelectedItem.Tag; } }
protected float Tolerance { get { return (float)(tolerance_slider.Slider.Value / 100); } }
protected virtual bool CalculatePolygonSet { get { return true; } }

protected bool LimitToSelection {
get { return limitToSelection; }
Expand Down Expand Up @@ -130,18 +131,20 @@ protected override void OnMouseDown (Gtk.DrawingArea canvas, Gtk.ButtonPressEven
int tol = (int)(Tolerance * Tolerance * 256);
Rectangle boundingBox;

surface.Flush ();

if (IsContinguousMode)
FillStencilFromPoint (surface, stencilBuffer, pos, tol, out boundingBox, currentRegion, limitToSelection);
else
FillStencilByColor (surface, stencilBuffer, surface.GetColorBgra (pos.X, pos.Y), tol, out boundingBox, currentRegion, LimitToSelection);

surface.MarkDirty ();
stencil = stencilBuffer;

Point[][] polygonSet = stencilBuffer.CreatePolygonSet (boundingBox, 0, 0);
OnFillRegionComputed (polygonSet);
OnFillRegionComputed (stencilBuffer);

// If a derived tool is only going to use the stencil,
// don't waste time building the polygon set
if (CalculatePolygonSet) {
Point[][] polygonSet = stencilBuffer.CreatePolygonSet (boundingBox, 0, 0);
OnFillRegionComputed (polygonSet);
}
}
#endregion

Expand Down Expand Up @@ -352,7 +355,8 @@ public unsafe static void FillStencilByColor (ImageSurface surface, IBitVector2D
boundingBox = new Rectangle (left, top, right - left + 1, bottom - top + 1);
}

protected abstract void OnFillRegionComputed (Point[][] polygonSet);
protected virtual void OnFillRegionComputed (Point[][] polygonSet) {}
protected virtual void OnFillRegionComputed (IBitVector2D stencil) {}
#endregion
}
}
33 changes: 22 additions & 11 deletions Pinta.Tools/PaintBucketTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public override string StatusBarText {
}
public override Gdk.Key ShortcutKey { get { return Gdk.Key.F; } }
public override int Priority { get { return 21; } }
protected override bool CalculatePolygonSet { get { return false; } }

protected override void OnMouseDown (Gtk.DrawingArea canvas, Gtk.ButtonPressEventArgs args, PointD point)
{
Expand All @@ -57,28 +58,38 @@ protected override void OnMouseDown (Gtk.DrawingArea canvas, Gtk.ButtonPressEven

base.OnMouseDown (canvas, args, point);
}
protected unsafe override void OnFillRegionComputed (Point[][] polygonSet)

protected unsafe override void OnFillRegionComputed (IBitVector2D stencil)
{
Document doc = PintaCore.Workspace.ActiveDocument;
ImageSurface surf = doc.ToolLayer.Surface;
surf.Clear ();

SimpleHistoryItem hist = new SimpleHistoryItem (Icon, Name);
hist.TakeSnapshotOfLayer (doc.CurrentLayer);

using (var g = doc.CreateClippedContext ()) {
// Reset FillRule to the default
g.FillRule = FillRule.Winding;
ColorBgra color = fill_color.ToColorBgra ();
ColorBgra* dstPtr = (ColorBgra*)surf.DataPtr;
int width = surf.Width;

using (Path poly = g.CreatePolygonPath (polygonSet))
g.AppendPath (poly);
surf.Flush ();

g.Antialias = Antialias.Subpixel;
// Color in any pixel that the stencil says we need to fill
for (int x = 0; x < stencil.Width; x++)
for (int y = 0; y < stencil.Height; y++)
if (stencil.GetUnchecked (x, y))
surf.SetColorBgra (dstPtr, width, color, x, y);

g.Color = fill_color;
g.Fill ();
surf.MarkDirty ();

// Transfer the temp layer to the real one,
// respecting any selection area
using (var g = doc.CreateClippedContext ()) {
g.SetSource (surf);
g.Paint ();
}

doc.History.PushNewItem (hist);
doc.History.PushNewItem (hist);
doc.Workspace.Invalidate ();
}
}
Expand Down

0 comments on commit 2a20973

Please sign in to comment.