protected override void OnMouseMove(object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point) { Document doc = PintaCore.Workspace.ActiveDocument; if (mouse_button == 1) { StrokeColor = PintaCore.Palette.PrimaryColor; FillColor = PintaCore.Palette.SecondaryColor; } else if (mouse_button == 3) { StrokeColor = PintaCore.Palette.SecondaryColor; FillColor = PintaCore.Palette.PrimaryColor; } else { LastPoint = point_empty; return; } // TODO: also multiply by pressure StrokeColor = new Color(StrokeColor.R, StrokeColor.G, StrokeColor.B, StrokeColor.A * active_brush.StrokeAlphaMultiplier); int x = (int)point.X; int y = (int)point.Y; if (LastPoint.Equals(point_empty)) { LastPoint = new Point(x, y); } if (doc.Workspace.PointInCanvas(point)) { surface_modified = true; } var surf = doc.CurrentUserLayer.Surface; var invalidate_rect = Gdk.Rectangle.Zero; var brush_width = BrushWidth; Surface = surf; using (Drawable = new Context(surf)) { Drawable.AppendPath(doc.Selection.SelectionPath); Drawable.FillRule = FillRule.EvenOdd; Drawable.Clip(); Drawable.Antialias = UseAntialiasing ? Antialias.Subpixel : Antialias.None; Drawable.LineWidth = brush_width; Drawable.LineJoin = LineJoin.Round; Drawable.LineCap = BrushWidth == 1 ? LineCap.Butt : LineCap.Round; Drawable.Color = StrokeColor; active_brush.Tool = this; invalidate_rect = active_brush.DoMouseMove(x, y, LastPoint.X, LastPoint.Y); active_brush.Tool = null; } Surface = null; Drawable = null; // If we draw partially offscreen, Cairo gives us a bogus // dirty rectangle, so redraw everything. if (doc.Workspace.IsPartiallyOffscreen(invalidate_rect)) { doc.Workspace.Invalidate(); } else { doc.Workspace.Invalidate(doc.ClampToImageSize(invalidate_rect)); } LastPoint = new Point(x, y); }