public DrawInRegionVisitor(Gdk.Region region, Cairo.Context context, IDrawingView view) { this.context = context; this.region = region; this.view = view; this.figures = new List<Figure> (); }
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); }
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); } }
protected void RedrawCanvas() { if (this.GdkWindow == null) { return; } using (Gdk.Region region = this.GdkWindow.ClipRegion) { this.GdkWindow.InvalidateRegion(region, true); this.GdkWindow.ProcessUpdates(true); } }
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); }
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(); }
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); }
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); }
void BeginPaintRegion(Gdk.Region r) { Gdk.Window win = areaGroup.DrawingArea.GdkWindow; win.BeginPaintRegion(r); }
/// <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(); } }
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); }