protected override Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface, int x, int y, int lastX, int lastY) { // Cairo does not support a single-pixel-long single-pixel-wide line if (x == lastX && y == lastY && g.LineWidth == 1 && PintaCore.Workspace.ActiveWorkspace.PointInCanvas(new PointD(x, y))) { surface.Flush(); ColorBgra source = surface.GetColorBgraUnchecked(x, y); source = UserBlendOps.NormalBlendOp.ApplyStatic(source, strokeColor.ToColorBgra()); surface.SetColorBgra(source, x, y); surface.MarkDirty(); return(new Gdk.Rectangle(x - 1, y - 1, 3, 3)); } g.MoveTo(lastX + 0.5, lastY + 0.5); g.LineTo(x + 0.5, y + 0.5); g.StrokePreserve(); Gdk.Rectangle dirty = g.FixedStrokeExtents().ToGdkRectangle(); // For some reason (?!) we need to inflate the dirty // rectangle for small brush widths in zoomed images dirty.Inflate(1, 1); return(dirty); }
protected override Gdk.Rectangle OnMouseMove (Context g, Color strokeColor, ImageSurface surface, int x, int y, int lastX, int lastY) { // Cairo does not support a single-pixel-long single-pixel-wide line if (x == lastX && y == lastY && g.LineWidth == 1 && PintaCore.Workspace.ActiveWorkspace.PointInCanvas (new PointD(x,y))) { surface.Flush (); ColorBgra source = surface.GetColorBgraUnchecked (x, y); source = UserBlendOps.NormalBlendOp.ApplyStatic (source, strokeColor.ToColorBgra ()); surface.SetColorBgra (source, x, y); surface.MarkDirty (); return new Gdk.Rectangle (x - 1, y - 1, 3, 3); } g.MoveTo (lastX + 0.5, lastY + 0.5); g.LineTo (x + 0.5, y + 0.5); g.StrokePreserve (); Gdk.Rectangle dirty = g.FixedStrokeExtents ().ToGdkRectangle (); // For some reason (?!) we need to inflate the dirty // rectangle for small brush widths in zoomed images dirty.Inflate (1, 1); return dirty; }
protected unsafe override void OnFillRegionComputed(IBitVector2D stencil) { Document doc = PintaCore.Workspace.ActiveDocument; ImageSurface surf = doc.ToolLayer.Surface; using (var g = new Context(surf)) { g.Operator = Operator.Source; g.SetSource(doc.CurrentUserLayer.Surface); g.Paint(); } SimpleHistoryItem hist = new SimpleHistoryItem(Icon, Name); hist.TakeSnapshotOfLayer(doc.CurrentUserLayer); ColorBgra color = fill_color.ToColorBgra().ToPremultipliedAlpha(); ColorBgra *dstPtr = (ColorBgra *)surf.DataPtr; int width = surf.Width; surf.Flush(); // Color in any pixel that the stencil says we need to fill Parallel.For(0, stencil.Height, y => { int stencil_width = stencil.Width; for (int x = 0; x < stencil_width; ++x) { if (stencil.GetUnchecked(x, y)) { surf.SetColorBgraUnchecked(dstPtr, width, color, x, y); } } }); surf.MarkDirty(); // Transfer the temp layer to the real one, // respecting any selection area using (var g = doc.CreateClippedContext()) { g.Operator = Operator.Source; g.SetSource(surf); g.Paint(); } doc.ToolLayer.Clear(); doc.History.PushNewItem(hist); doc.Workspace.Invalidate(); }
private void Draw(DrawingArea drawingarea1, Color tool_color, Cairo.PointD point, bool first_pixel) { int x = (int)point.X; int y = (int) point.Y; if (last_point.Equals (point_empty)) { last_point = new Point (x, y); if (!first_pixel) return; } Document doc = PintaCore.Workspace.ActiveDocument; if (doc.Workspace.PointInCanvas (point)) surface_modified = true; ImageSurface surf = PintaCore.Layers.CurrentLayer.Surface; if (first_pixel) { // Does Cairo really not support a single-pixel-long single-pixel-wide line? surf.Flush (); int shiftedX = (int)point.X; int shiftedY = (int)point.Y; ColorBgra source = surf.GetColorBgraUnchecked (shiftedX, shiftedY); source = UserBlendOps.NormalBlendOp.ApplyStatic (source, tool_color.ToColorBgra ()); surf.SetColorBgra (source, shiftedX, shiftedY); surf.MarkDirty (); } else { using (Context g = new Context (surf)) { g.AppendPath (doc.Selection.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip (); g.Antialias = Antialias.None; // Adding 0.5 forces cairo into the correct square: // See https://bugs.launchpad.net/bugs/672232 g.MoveTo (last_point.X + 0.5, last_point.Y + 0.5); g.LineTo (x + 0.5, y + 0.5); g.Color = tool_color; g.LineWidth = 1; g.LineCap = LineCap.Square; g.Stroke (); } } Gdk.Rectangle r = GetRectangleFromPoints (last_point, new Point (x, y)); doc.Workspace.Invalidate (r); last_point = new Point (x, y); }
private void Draw(DrawingArea drawingarea1, Color tool_color, Cairo.PointD point, bool first_pixel) { int x = (int)point.X; int y = (int)point.Y; if (last_point.Equals(point_empty)) { last_point = new Point(x, y); if (!first_pixel) { return; } } Document doc = PintaCore.Workspace.ActiveDocument; if (doc.Workspace.PointInCanvas(point)) { surface_modified = true; } ImageSurface surf = doc.CurrentUserLayer.Surface; if (first_pixel && doc.Workspace.PointInCanvas(point)) { // Does Cairo really not support a single-pixel-long single-pixel-wide line? surf.Flush(); int shiftedX = (int)point.X; int shiftedY = (int)point.Y; ColorBgra source = surf.GetColorBgraUnchecked(shiftedX, shiftedY); if (UseAlphaBlending) { source = UserBlendOps.NormalBlendOp.ApplyStatic(source, tool_color.ToColorBgra()); } else { source = tool_color.ToColorBgra(); } surf.SetColorBgra(source.ToPremultipliedAlpha(), shiftedX, shiftedY); surf.MarkDirty(); } else { using (Context g = new Context(surf)) { g.AppendPath(doc.Selection.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip(); g.Antialias = Antialias.None; // Adding 0.5 forces cairo into the correct square: // See https://bugs.launchpad.net/bugs/672232 g.MoveTo(last_point.X + 0.5, last_point.Y + 0.5); g.LineTo(x + 0.5, y + 0.5); g.SetSourceColor(tool_color); if (UseAlphaBlending) { g.SetBlendMode(BlendMode.Normal); } else { g.Operator = Operator.Source; } g.LineWidth = 1; g.LineCap = LineCap.Square; g.Stroke(); } } Gdk.Rectangle r = GetRectangleFromPoints(last_point, new Point(x, y)); doc.Workspace.Invalidate(doc.ClampToImageSize(r)); last_point = new Point(x, y); }