示例#1
0
        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);
        }
示例#2
0
        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();
            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.SetColorBgra(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();
        }
示例#3
0
        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);
        }