public DrawInRegionVisitor(Gdk.Region region, Cairo.Context context, IDrawingView view)
 {
     this.context = context;
     this.region = region;
     this.view = view;
     this.figures = new List<Figure> ();
 }
Пример #2
0
 public static Gdk.Region RectanglesToRegion(Gdk.Rectangle[] rects)
 {
     Gdk.Region reg = Gdk.Region.Rectangle(Gdk.Rectangle.Zero);
     foreach (Gdk.Rectangle r in rects)
     {
         reg.UnionWithRect(r);
     }
     return(reg);
 }
Пример #3
0
        protected override void OnMouseDown(Gtk.DrawingArea canvas, Gtk.ButtonPressEventArgs args, PointD point)
        {
            Document doc = PintaCore.Workspace.ActiveDocument;

            Point pos = new Point((int)point.X, (int)point.Y);

            // Don't do anything if we're outside the canvas
            if (pos.X < 0 || pos.X >= doc.ImageSize.Width)
            {
                return;
            }
            if (pos.Y < 0 || pos.Y >= doc.ImageSize.Height)
            {
                return;
            }

            base.OnMouseDown(canvas, args, point);

            Gdk.Region currentRegion = Gdk.Region.Rectangle(doc.GetSelectedBounds(true));

            // See if the mouse click is valid
            if (!currentRegion.PointIn(pos.X, pos.Y) && limitToSelection)
            {
                currentRegion.Dispose();
                currentRegion = null;
                return;
            }

            ImageSurface surface         = doc.CurrentUserLayer.Surface;
            ImageSurface stencil_surface = new ImageSurface(Format.Argb32, (int)surface.Width, (int)surface.Height);

            IBitVector2D stencilBuffer = new BitVector2DSurfaceAdapter(stencil_surface);
            int          tol           = (int)(Tolerance * Tolerance * 256);
            Rectangle    boundingBox;

            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);
            }

            stencil = stencilBuffer;
            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);
            }
        }
Пример #4
0
        protected void RedrawCanvas()
        {
            if (this.GdkWindow == null)
            {
                return;
            }

            using (Gdk.Region region = this.GdkWindow.ClipRegion)
            {
                this.GdkWindow.InvalidateRegion(region, true);
                this.GdkWindow.ProcessUpdates(true);
            }
        }
Пример #5
0
        private void RenderBackground(Gdk.Window window, Gdk.Region region)
        {
            Cairo.Context cr = Gdk.CairoHelper.Create(window);

            cr.Color = new Cairo.Color(0xe7 / (double)0xff,
                                       0xea / (double)0xff, 0xfd / (double)0xff);

            CairoExtensions.RoundedRectangle(cr,
                                             Allocation.X, Allocation.Y,
                                             Allocation.Width, Allocation.Height, 5);

            cr.Fill();

            CairoExtensions.DisposeContext(cr);
        }
Пример #6
0
        private void RenderBackground(Gdk.Window window, Gdk.Region region)
        {
            var cr = Gdk.CairoHelper.Create(window);

            var grad = new Cairo.LinearGradient(0, 0, 0, Allocation.Height);

            grad.AddColorStop(0, CairoExtensions.RgbToColor(0xffffff));
            grad.AddColorStop(1, CairoExtensions.RgbToColor(0xc3c3c3));
            cr.Pattern = grad;
            cr.Rectangle(0, 0, Allocation.Width, Allocation.Height);
            cr.Fill();
            grad.Destroy();

            CairoExtensions.DisposeContext(cr);
        }
        public static void FillRegion(this Context g, Gdk.Region region, Color color)
        {
            g.Save();

            g.Color = color;

            foreach (Gdk.Rectangle r in region.GetRectangles())
            {
                g.MoveTo(r.X, r.Y);
                g.LineTo(r.X + r.Width, r.Y);
                g.LineTo(r.X + r.Width, r.Y + r.Height);
                g.LineTo(r.X, r.Y + r.Height);
                g.LineTo(r.X, r.Y);

                g.Color = color;

                g.StrokeExtents();
                g.Fill();
            }

            g.Restore();
        }
Пример #8
0
        public unsafe static void FillStencilByColor(ImageSurface surface, IBitVector2D stencil, ColorBgra cmp, int tolerance,
                                                     out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection)
        {
            int top    = int.MaxValue;
            int bottom = int.MinValue;
            int left   = int.MaxValue;
            int right  = int.MinValue;

            Gdk.Rectangle[] scans;

            stencil.Clear(false);

            if (limitToSelection)
            {
                using (Gdk.Region excluded = Gdk.Region.Rectangle(new Gdk.Rectangle(0, 0, stencil.Width, stencil.Height))) {
                    excluded.Xor(limitRegion);
                    scans = excluded.GetRectangles();
                }
            }
            else
            {
                scans = new Gdk.Rectangle[0];
            }

            foreach (Gdk.Rectangle rect in scans)
            {
                stencil.Set(rect, true);
            }

            Parallel.For(0, surface.Height, y =>
            {
                bool foundPixelInRow = false;
                ColorBgra *ptr       = surface.GetRowAddressUnchecked(y);

                int surfaceWidth = surface.Width;
                for (int x = 0; x < surfaceWidth; ++x)
                {
                    if (CheckColor(cmp, *ptr, tolerance))
                    {
                        stencil.SetUnchecked(x, y, true);

                        if (x < left)
                        {
                            left = x;
                        }

                        if (x > right)
                        {
                            right = x;
                        }

                        foundPixelInRow = true;
                    }

                    ++ptr;
                }

                if (foundPixelInRow)
                {
                    if (y < top)
                    {
                        top = y;
                    }

                    if (y >= bottom)
                    {
                        bottom = y;
                    }
                }
            });

            foreach (Gdk.Rectangle rect in scans)
            {
                stencil.Set(rect, false);
            }

            boundingBox = new Rectangle(left, top, right - left + 1, bottom - top + 1);
        }
Пример #9
0
        public unsafe static void FillStencilFromPoint(ImageSurface surface, IBitVector2D stencil, Point start, int tolerance,
                                                       out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection)
        {
            ColorBgra cmp    = surface.GetColorBgra(start.X, start.Y);
            int       top    = int.MaxValue;
            int       bottom = int.MinValue;
            int       left   = int.MaxValue;
            int       right  = int.MinValue;

            Gdk.Rectangle[] scans;

            stencil.Clear(false);

            if (limitToSelection)
            {
                using (Gdk.Region excluded = Gdk.Region.Rectangle(new Gdk.Rectangle(0, 0, stencil.Width, stencil.Height))) {
                    excluded.Xor(limitRegion);
                    scans = excluded.GetRectangles();
                }
            }
            else
            {
                scans = new Gdk.Rectangle[0];
            }

            foreach (Gdk.Rectangle rect in scans)
            {
                stencil.Set(rect, true);
            }

            Queue <Point> queue = new Queue <Point> (16);

            queue.Enqueue(start);

            while (queue.Count > 0)
            {
                Point pt = queue.Dequeue();

                ColorBgra *rowPtr     = surface.GetRowAddressUnchecked(pt.Y);
                int        localLeft  = pt.X - 1;
                int        localRight = pt.X;

                while (localLeft >= 0 &&
                       !stencil.GetUnchecked(localLeft, pt.Y) &&
                       CheckColor(cmp, rowPtr[localLeft], tolerance))
                {
                    stencil.SetUnchecked(localLeft, pt.Y, true);
                    --localLeft;
                }

                int surfaceWidth = surface.Width;
                while (localRight < surfaceWidth &&
                       !stencil.GetUnchecked(localRight, pt.Y) &&
                       CheckColor(cmp, rowPtr[localRight], tolerance))
                {
                    stencil.SetUnchecked(localRight, pt.Y, true);
                    ++localRight;
                }

                ++localLeft;
                --localRight;

                Action <int> checkRow = (row) =>
                {
                    int        sleft       = localLeft;
                    int        sright      = localLeft;
                    ColorBgra *otherRowPtr = surface.GetRowAddressUnchecked(row);

                    for (int sx = localLeft; sx <= localRight; ++sx)
                    {
                        if (!stencil.GetUnchecked(sx, row) &&
                            CheckColor(cmp, otherRowPtr[sx], tolerance))
                        {
                            ++sright;
                        }
                        else
                        {
                            if (sright - sleft > 0)
                            {
                                queue.Enqueue(new Point(sleft, row));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0)
                    {
                        queue.Enqueue(new Point(sleft, row));
                    }
                };

                if (pt.Y > 0)
                {
                    checkRow(pt.Y - 1);
                }

                if (pt.Y < surface.Height - 1)
                {
                    checkRow(pt.Y + 1);
                }

                if (localLeft < left)
                {
                    left = localLeft;
                }

                if (localRight > right)
                {
                    right = localRight;
                }

                if (pt.Y < top)
                {
                    top = pt.Y;
                }

                if (pt.Y > bottom)
                {
                    bottom = pt.Y;
                }
            }

            foreach (Gdk.Rectangle rect in scans)
            {
                stencil.Set(rect, false);
            }

            boundingBox = new Rectangle(left, top, right - left + 1, bottom - top + 1);
        }
Пример #10
0
        void BeginPaintRegion(Gdk.Region r)
        {
            Gdk.Window win = areaGroup.DrawingArea.GdkWindow;

            win.BeginPaintRegion(r);
        }
Пример #11
0
        /// <summary>
        /// Render the bytes in the highlight range.
        /// </summary>
        /// <param name="h">
        /// A <see cref="Highlight"/>
        /// </param>
        /// <param name="merge">
        /// Whether to visually merge the highlight with adjacent ones left and/or right.
        /// </param>
        /// <remarks>
        /// This method doesn't check whether the merge flags are correct (eg there is indeed
        /// a similar adjacent highlight). It just draws the highlight in such a way as
        /// to appear merged to any similar highlights if they exist.
        ///</remarks>
        internal protected virtual void RenderHighlight(Highlight h, Drawer.HighlightType left, Drawer.HighlightType right)
        {
            if (isAreaRealized == false)
            {
                return;
            }

            int  rstart, bstart, xstart, ystart;
            int  rend, bend, xend, yend;
            bool odd;

            Gdk.GC gc;
            Gdk.GC oddGC;
            Gdk.GC evenGC;
            Gdk.GC leftGC;
            Gdk.GC rightGC;

            oddGC  = drawer.GetBackgroundGC(Drawer.RowType.Odd, h.Type);
            evenGC = drawer.GetBackgroundGC(Drawer.RowType.Even, h.Type);


            GetDisplayInfoByOffset(h.Start, out rstart, out bstart, out xstart, out ystart);
            GetDisplayInfoByOffset(h.End, out rend, out bend, out xend, out yend);

            //System.Console.WriteLine("Start {0:x} {1} {2} x:{3} y:{4}", h.Start, rstart, bstart, xstart, ystart);
            //System.Console.WriteLine("End {0:x} {1} {2} x:{3} y:{4}", h.End, rend, bend, xend, yend);
            bool drawLeft = false;
            int  dxstart  = xstart;

            if (bstart > 0)
            {
                int            digit;
                GetOffsetFlags gof;
                GetOffsetByDisplayInfo(xstart - 1, ystart, out digit, out gof);
                if ((gof & GetOffsetFlags.Abyss) != 0)
                {
                    dxstart -= drawer.Width;
                    drawLeft = true;
                }
            }

            bool drawRight = false;
            int  dxend     = xend;

            if (bend < bpr - 1)
            {
                int            digit;
                GetOffsetFlags gof;
                GetOffsetByDisplayInfo(xend + dpb * drawer.Width, yend, out digit, out gof);
                if ((gof & GetOffsetFlags.Abyss) != 0)
                {
                    dxend    += drawer.Width;
                    drawRight = true;
                }
            }

            // if the whole range is on one row
            if (rstart == rend)
            {
                if (areaGroup.ManualDoubleBuffer)
                {
                    BeginPaint(x + dxstart, y + ystart, dxend - dxstart + dpb * drawer.Width, drawer.Height);
                }
                // odd row?
                odd = (((h.Start / bpr) % 2) == 1);
                if (odd)
                {
                    gc      = oddGC;
                    leftGC  = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);
                    rightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);
                }
                else
                {
                    gc      = evenGC;
                    leftGC  = drawer.GetBackgroundGC(Drawer.RowType.Even, left);
                    rightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);
                }

                //render
                if (drawLeft)
                {
                    backPixmap.DrawRectangle(leftGC, true, x + dxstart, y + ystart, drawer.Width, drawer.Height);
                }
                if (drawRight)
                {
                    backPixmap.DrawRectangle(rightGC, true, x + xend + dpb * drawer.Width, y + yend, drawer.Width, drawer.Height);
                }

                backPixmap.DrawRectangle(gc, true, x + xstart, y + ystart, xend - xstart + dpb * drawer.Width, drawer.Height);

                RenderRangeHelper(h.Type, rstart, bstart, bend - bstart + 1);
            }
            else       // multi-row range

            {
                if (areaGroup.ManualDoubleBuffer)
                {
                    // handle double-buffering
                    Gdk.Region paintRegion = new Gdk.Region();

                    Gdk.Rectangle rectStart = new Gdk.Rectangle(x + dxstart, y + ystart, width - dxstart, drawer.Height);

                    Gdk.Rectangle rectMiddle;
                    if (rend > rstart + 1)
                    {
                        rectMiddle = new Gdk.Rectangle(x, y + ystart + drawer.Height, width, yend - ystart - drawer.Height);
                    }
                    else
                    {
                        rectMiddle = Gdk.Rectangle.Zero;
                    }

                    Gdk.Rectangle rectEnd = new Gdk.Rectangle(x, y + yend, dxend + dpb * drawer.Width, drawer.Height);

                    paintRegion.UnionWithRect(rectStart);
                    paintRegion.UnionWithRect(rectMiddle);
                    paintRegion.UnionWithRect(rectEnd);

                    BeginPaintRegion(paintRegion);
                }

                // render first row
                odd = (((h.Start / bpr) % 2) == 1);
                if (odd)
                {
                    gc      = oddGC;
                    leftGC  = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);
                    rightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);
                }
                else
                {
                    gc      = evenGC;
                    leftGC  = drawer.GetBackgroundGC(Drawer.RowType.Even, left);
                    rightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);
                }

                if (drawLeft)
                {
                    backPixmap.DrawRectangle(leftGC, true, x + dxstart, y + ystart, drawer.Width, drawer.Height);
                }
                backPixmap.DrawRectangle(gc, true, x + xstart, y + ystart, width - xstart, drawer.Height);

                RenderRangeHelper(h.Type, rstart, bstart, bpr - bstart);

                long curOffset = h.Start + bpr - bstart;

                // render middle rows
                for (int i = rstart + 1; i < rend; i++)
                {
                    odd = (((curOffset / bpr) % 2) == 1);
                    if (odd)
                    {
                        gc = oddGC;
                    }
                    else
                    {
                        gc = evenGC;
                    }
                    backPixmap.DrawRectangle(gc, true, x, y + i * drawer.Height, width, drawer.Height);
                    RenderRangeHelper(h.Type, i, 0, bpr);
                    curOffset += bpr;
                }

                // render last row
                odd = (((h.End / bpr) % 2) == 1);
                if (odd)
                {
                    gc      = oddGC;
                    leftGC  = drawer.GetBackgroundGC(Drawer.RowType.Odd, left);
                    rightGC = drawer.GetBackgroundGC(Drawer.RowType.Odd, right);
                }
                else
                {
                    gc      = evenGC;
                    leftGC  = drawer.GetBackgroundGC(Drawer.RowType.Even, left);
                    rightGC = drawer.GetBackgroundGC(Drawer.RowType.Even, right);
                }

                if (drawRight)
                {
                    backPixmap.DrawRectangle(rightGC, true, x + xend + dpb * drawer.Width, y + yend, drawer.Width, drawer.Height);
                }
                backPixmap.DrawRectangle(gc, true, x, y + yend, xend + dpb * drawer.Width, drawer.Height);
                RenderRangeHelper(h.Type, rend, 0, bend + 1);
            }

            if (areaGroup.ManualDoubleBuffer)
            {
                EndPaint();
            }
        }
Пример #12
0
        private void RenderBackground(Gdk.Window window, Gdk.Region region)
        {
            var cr = Gdk.CairoHelper.Create(window);

            // Box background
            CairoExtensions.RoundedRectangle(cr,
                                             Allocation.X,
                                             Allocation.Y,
                                             Allocation.Width,
                                             Allocation.Height,
                                             3);
            cr.Color = CairoExtensions.RgbToColor(0xf9f9f9);
            cr.Fill();

            // Box border
            cr.LineWidth = 1.0;
            CairoExtensions.RoundedRectangle(cr,
                                             Allocation.X + 0.5,
                                             Allocation.Y + 0.5,
                                             Allocation.Width - 1,
                                             Allocation.Height - 1,
                                             3);
            cr.Color = CairoExtensions.RgbToColor(0x8f8f8f);
            cr.Stroke();

            // Box header background
            CairoExtensions.RoundedRectangle(cr,
                                             Allocation.X + 3,
                                             Allocation.Y + 3,
                                             Allocation.Width - 6,
                                             header.Allocation.Height + 3,
                                             2, CairoCorners.TopLeft | CairoCorners.TopRight);
            cr.Color = CairoExtensions.RgbToColor(0xd7d9d6);
            cr.Fill();

            // Highlight children
            foreach (var item in highlight_widgets)
            {
                var widget = item.Key;
                var flags  = item.Value;

                if (!widget.Visible || !widget.IsMapped)
                {
                    continue;
                }

                if ((flags & HighlightFlags.Background) != 0)
                {
                    cr.Rectangle(
                        Allocation.X + 3,
                        widget.Allocation.Y - Spacing + 2,
                        Allocation.Width - 6,
                        widget.Allocation.Height + Spacing + 2);
                    cr.Color = CairoExtensions.RgbToColor(0xf6f6f6);
                    cr.Fill();
                }

                cr.LineWidth = 1;
                cr.Color     = CairoExtensions.RgbToColor(0x8f8f8f);

                if ((flags & HighlightFlags.TopLine) != 0)
                {
                    cr.MoveTo(
                        Allocation.X + 0.5,
                        widget.Allocation.Y + 0.5);
                    cr.LineTo(
                        Allocation.X + Allocation.Width - 1,
                        widget.Allocation.Y + 0.5);
                    cr.Stroke();
                }

                if ((flags & HighlightFlags.BottomLine) != 0)
                {
                    cr.MoveTo(
                        Allocation.X + 0.5,
                        widget.Allocation.Y + widget.Allocation.Height + 0.5);
                    cr.LineTo(
                        Allocation.X + Allocation.Width - 1,
                        widget.Allocation.Y + widget.Allocation.Height + 0.5);
                    cr.Stroke();
                }
            }

            CairoExtensions.DisposeContext(cr);
        }