Пример #1
0
        protected unsafe override void OnMouseMove(Document document, ToolMouseEventArgs e)
        {
            ColorBgra old_color;
            ColorBgra new_color;

            // This should have been created in OnMouseDown
            if (stencil is null)
            {
                return;
            }

            if (mouse_button == MouseButton.Left)
            {
                old_color = Palette.PrimaryColor.ToColorBgra();
                new_color = Palette.SecondaryColor.ToColorBgra();
            }
            else if (mouse_button == MouseButton.Right)
            {
                old_color = Palette.SecondaryColor.ToColorBgra();
                new_color = Palette.PrimaryColor.ToColorBgra();
            }
            else
            {
                last_point = point_empty;
                return;
            }

            var x = e.Point.X;
            var y = e.Point.Y;

            if (last_point.Equals(point_empty))
            {
                last_point = new Point(x, y);
            }

            if (document.Workspace.PointInCanvas(e.PointDouble))
            {
                surface_modified = true;
            }

            var surf      = document.Layers.CurrentUserLayer.Surface;
            var tmp_layer = document.Layers.ToolLayer.Surface;

            var roi = CairoExtensions.GetRectangleFromPoints(last_point, new Point(x, y), BrushWidth + 2);

            roi = workspace.ClampToImageSize(roi);
            var myTolerance = (int)(Tolerance * 256);

            tmp_layer.Flush();

            var tmp_data_ptr  = (ColorBgra *)tmp_layer.DataPtr;
            var tmp_width     = tmp_layer.Width;
            var surf_data_ptr = (ColorBgra *)surf.DataPtr;
            var surf_width    = surf.Width;

            // The stencil lets us know if we've already checked this
            // pixel, providing a nice perf boost
            // Maybe this should be changed to a BitVector2DSurfaceAdapter?
            for (var i = roi.X; i <= roi.GetRight(); i++)
            {
                for (var j = roi.Y; j <= roi.GetBottom(); j++)
                {
                    if (stencil[i, j])
                    {
                        continue;
                    }

                    if (ColorBgra.ColorsWithinTolerance(new_color, surf.GetColorBgraUnchecked(surf_data_ptr, surf_width, i, j), myTolerance))
                    {
                        *tmp_layer.GetPointAddressUnchecked(tmp_data_ptr, tmp_width, i, j) = AdjustColorDifference(new_color, old_color, surf.GetColorBgraUnchecked(surf_data_ptr, surf_width, i, j));
                    }

                    stencil[i, j] = true;
                }
            }

            tmp_layer.MarkDirty();

            using (var g = document.CreateClippedContext()) {
                g.Antialias = UseAntialiasing ? Antialias.Subpixel : Antialias.None;

                g.MoveTo(last_point.X, last_point.Y);
                g.LineTo(x, y);

                g.LineWidth = BrushWidth;
                g.LineJoin  = LineJoin.Round;
                g.LineCap   = LineCap.Round;

                g.SetSource(tmp_layer);

                g.Stroke();
            }

            document.Workspace.Invalidate(roi);

            last_point = new Point(x, y);
        }