public PasteHistoryItem(Gdk.Pixbuf pasteImage, Path oldPath, bool oldShowSelection) { Text = Catalog.GetString ("Paste"); Icon = Stock.Paste; paste_image = pasteImage; old_path = oldPath; old_show_selection = oldShowSelection; }
/// <summary> /// Indicate that the selection has changed. /// </summary> public void MarkDirty() { if (selection_path != null) { selection_path.Dispose (); selection_path = null; } // Notify any listeners. if (SelectionModified != null) SelectionModified.Invoke(this, EventArgs.Empty); }
private void Render(Clutter.CairoTexture texture, int with_state, bool outwards) { texture.Clear(); Cairo.Context context = texture.Create(); double lwidth = 1; double hlwidth = lwidth * 0.5; //Draw outline rectangles: context.Rectangle(hlwidth, hlwidth, texture.Width - lwidth, texture.Height - lwidth); context.SetSourceRGB(1.0, 1.0, 1.0); context.LineWidth = lwidth; context.StrokePreserve(); double sat = (with_state == 0 ? 0.4 : (with_state == 1 ? 0.6 : 0.8)); context.SetSourceRGB(sat, sat, sat); context.Fill(); double dim = 4; context.MoveTo(-dim, 0); context.LineTo(outwards ? 0 : -dim, outwards ? 0 : dim); context.LineTo(0, dim); context.MoveTo(-dim, dim); context.LineTo(0, 0); context.ClosePath(); Cairo.Path arrow = context.CopyPath(); context.NewPath(); double margin = 2 + hlwidth; PointD center = new PointD(texture.Width * 0.5, texture.Height * 0.5); PointD transl = new PointD(center.X - margin, -(center.Y - margin)); context.LineWidth = lwidth; sat = (with_state == 1 ? 0.0 : 1.0); context.SetSourceRGB(sat, sat, sat); context.Translate(center.X, center.Y); for (int i = 0; i < 4; i++) { context.Rotate(Math.PI * 0.5 * i); context.Translate(transl.X, transl.Y); context.AppendPath(arrow); context.Stroke(); context.Translate(-transl.X, -transl.Y); } ((IDisposable)arrow).Dispose(); ((IDisposable)context.Target).Dispose(); ((IDisposable)context).Dispose(); }
protected override void OnMouseDown (Gtk.DrawingArea canvas, Gtk.ButtonPressEventArgs args, Cairo.PointD point) { if (is_drawing) return; hist = new SelectionHistoryItem (Icon, Name); hist.TakeSnapshot (); combine_mode = PintaCore.Workspace.SelectionHandler.DetermineCombineMode (args); path = null; is_drawing = true; var doc = PintaCore.Workspace.ActiveDocument; doc.PreviousSelection.Dispose (); doc.PreviousSelection = doc.Selection.Clone(); }
private void Swap() { Path swap_path = PintaCore.Layers.SelectionPath; PointD swap_offset = PintaCore.Layers.SelectionLayer.Offset; PintaCore.Layers.SelectionPath = old_path; PintaCore.Layers.SelectionLayer.Offset = old_offset; old_path = swap_path; old_offset = swap_offset; if (lifted) { // Grab the original surface ImageSurface surf = PintaCore.Layers[layer_index].Surface; // Undo to the "old" surface PintaCore.Layers[layer_index].Surface = old_surface; // Store the original surface for Redo old_surface = surf; is_lifted = !is_lifted; doc.ShowSelectionLayer = is_lifted; } PintaCore.Workspace.Invalidate (); }
protected override void OnMouseUp(Gtk.DrawingArea canvas, Gtk.ButtonReleaseEventArgs args, Cairo.PointD point) { Document doc = PintaCore.Workspace.ActiveDocument; doc.ToolLayer.Hidden = true; if (surface_modified) PintaCore.History.PushNewItem (new SimpleHistoryItem (Icon, Name, undo_surface, doc.CurrentUserLayerIndex)); else if (undo_surface != null) (undo_surface as IDisposable).Dispose (); surface_modified = false; ImageSurface surf = doc.CurrentUserLayer.Surface; using (Context g = new Context (surf)) { g.AppendPath (doc.Selection.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip (); g.Antialias = UseAntialiasing ? Antialias.Subpixel : Antialias.None; if (path != null) { g.AppendPath (path); (path as IDisposable).Dispose (); path = null; } g.ClosePath (); g.LineWidth = BrushWidth; g.LineJoin = LineJoin.Round; g.LineCap = LineCap.Round; g.FillRule = FillRule.EvenOdd; if (FillShape && StrokeShape) { g.Color = fill_color; g.FillPreserve (); g.Color = outline_color; g.Stroke (); } else if (FillShape) { g.Color = outline_color; g.Fill (); } else { g.Color = outline_color; g.Stroke (); } } doc.Workspace.Invalidate (); }
/// <summary> /// Disposes of the old Selection, but allows for reusability. /// </summary> public void DisposeSelectionPreserve() { Path old = SelectionPath; SelectionPath = null; if (old != null) { (old as IDisposable).Dispose(); } }
/// <summary> /// Reset (clear) the Selection. /// </summary> /// <param name="selectionSurface"></param> /// <param name="imageSize"></param> public void ResetSelection(Surface selectionSurface, Gdk.Size imageSize) { using (Cairo.Context g = new Cairo.Context(selectionSurface)) { SelectionPath = g.CreateRectanglePath(new Rectangle(0, 0, imageSize.Width, imageSize.Height)); } SelectionPolygons.Clear(); }
protected override void OnMouseDown(Gtk.DrawingArea canvas, Gtk.ButtonPressEventArgs args, Cairo.PointD point) { base.OnMouseDown (canvas, args, point); path = null; }
/// <summary> /// Create an elliptical Selection from a bounding Rectangle. /// </summary> /// <param name="selectionSurface">The selection surface to use for calculating the elliptical Path.</param> /// <param name="r">The bounding Rectangle surrounding the ellipse.</param> public void CreateEllipseSelection(Surface selectionSurface, Rectangle r) { using (Context g = new Context(selectionSurface)) { SelectionPath = g.CreateEllipsePath(r); } //These values were calculated in the static CreateEllipsePath method //in Pinta.Core.CairoExtensions, so they were used here as well. double rx = r.Width / 2; //1/2 of the bounding Rectangle Width. double ry = r.Height / 2; //1/2 of the bounding Rectangle Height. double cx = r.X + rx; //The middle of the bounding Rectangle, horizontally speaking. double cy = r.Y + ry; //The middle of the bounding Rectangle, vertically speaking. double c1 = 0.552285; //A constant factor used to give the least approximation error. //Clear the Selection Polygons collection to start from a clean slate. SelectionPolygons.Clear(); //Calculate an appropriate interval at which to increment t based on //the bounding Rectangle's Width and Height properties. The increment //for t determines how many intermediate Points to calculate for the //ellipse. For each curve, t will go from tInterval to 1. The lower //the value of tInterval, the higher number of intermediate Points //that will be calculated and stored into the Polygon collection. double tInterval = 1d / (r.Width + r.Height); //Create a new Polygon to store the upcoming ellipse. List<IntPoint> newPolygon = new List<IntPoint>(); //These values were also calculated in the CreateEllipsePath method. This is where //the ellipse's 4 curves (and all of the Points on each curve) are determined. //Note: each curve is consecutive to the previous one, but they *do not* overlap, //other than the first/last Point (which is how it is supposed to work). //The starting Point. newPolygon.Add(new IntPoint((long)(cx + rx), (long)cy)); //Curve 1. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx + rx, cy, cx + rx, cy - c1 * ry, cx + c1 * rx, cy - ry, cx, cy - ry)); //Curve 2. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx, cy - ry, cx - c1 * rx, cy - ry, cx - rx, cy - c1 * ry, cx - rx, cy)); //Curve 3. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx - rx, cy, cx - rx, cy + c1 * ry, cx - c1 * rx, cy + ry, cx, cy + ry)); //Curve 4. newPolygon.AddRange(CalculateCurvePoints(tInterval, cx, cy + ry, cx + c1 * rx, cy + ry, cx + rx, cy + c1 * ry, cx + rx, cy)); //Add the newly calculated elliptical Polygon. SelectionPolygons.Add(newPolygon); }
protected override void OnMouseUp(Gtk.DrawingArea canvas, Gtk.ButtonReleaseEventArgs args, Cairo.PointD point) { base.OnMouseUp (canvas, args, point); ImageSurface surf = PintaCore.Layers.CurrentLayer.Surface; using (Context g = new Context (surf)) { if (path != null) { g.AppendPath (path); (path as IDisposable).Dispose (); path = null; } g.FillRule = FillRule.EvenOdd; g.ClosePath (); Path old = PintaCore.Layers.SelectionPath; PintaCore.Layers.SelectionPath = g.CopyPath (); (old as IDisposable).Dispose (); } PintaCore.Workspace.Invalidate (); }
protected override void OnMouseMove(object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point) { Document doc = PintaCore.Workspace.ActiveDocument; if (!is_drawing) return; double x = Utility.Clamp (point.X, 0, doc.ImageSize.Width - 1); double y = Utility.Clamp (point.Y, 0, doc.ImageSize.Height - 1); doc.ShowSelection = true; ImageSurface surf = doc.SelectionLayer.Surface; using (Context g = new Context (surf)) { g.Antialias = Antialias.Subpixel; if (path != null) { g.AppendPath (path); (path as IDisposable).Dispose (); } else { g.MoveTo (x, y); } g.LineTo (x, y); lassoPolygon.Add(new IntPoint((long)x, (long)y)); path = g.CopyPath (); g.FillRule = FillRule.EvenOdd; g.ClosePath (); doc.Selection.DisposeSelectionPreserve(); doc.Selection.SelectionPath = g.CopyPath (); } doc.Workspace.Invalidate (); }
protected override void OnMouseDown(Gtk.DrawingArea canvas, Gtk.ButtonPressEventArgs args, Cairo.PointD point) { surface_modified = false; undo_surface = PintaCore.Layers.CurrentLayer.Surface.Clone (); path = null; PintaCore.Layers.ToolLayer.Clear (); PintaCore.Layers.ToolLayer.Hidden = false; }
private void savePath() { this.path = canvas.Context.CopyPathFlat(); canvas.Context.NewPath(); }
public override void Crop(Gdk.Rectangle rect, Path path) { base.Crop (rect, path); if (IsTextLayerSetup) { TextLayer.Crop (rect, path); } }
private void Swap() { // Swap the selection paths, and whether the // selection path should be visible Document doc = PintaCore.Workspace.ActiveDocument; Path swap_path = doc.SelectionPath; bool swap_show_sel = doc.ShowSelection; doc.SelectionPath = old_path; doc.ShowSelection = old_show_selection; old_path = swap_path; old_show_selection = swap_show_sel; }
/// <summary> /// Create a rectangular Selection from a Rectangle. /// </summary> /// <param name="selectionSurface">The selection surface to use for calculating the rectangular Path.</param> /// <param name="r">The Rectangle.</param> public void CreateRectangleSelection(Surface selectionSurface, Rectangle r) { using (Context g = new Context(selectionSurface)) { SelectionPath = g.CreateRectanglePath(r); } //Clear the Selection Polygons collection to start from a clean slate. SelectionPolygons.Clear(); //The 4 corners of the Rectangle. int corner1X = (int)Math.Round(r.X); int corner1Y = (int)Math.Round(r.Y); int corner2X = (int)Math.Round(r.X + r.Width); int corner2Y = (int)Math.Round(r.Y + r.Height); //Create a new Polygon to store the upcoming rectangle. List<IntPoint> newPolygon = new List<IntPoint>(); //Store each of the 4 corners of the Rectangle in the Polygon, and then store //the first corner again. It is important to note that the order of the //corners being added (clockwise) and the first/last Point being the same //should be kept this way; otherwise, problems could result. newPolygon.Add(new IntPoint(corner1X, corner1Y)); newPolygon.Add(new IntPoint(corner2X, corner1Y)); newPolygon.Add(new IntPoint(corner2X, corner2Y)); newPolygon.Add(new IntPoint(corner1X, corner2Y)); newPolygon.Add(new IntPoint(corner1X, corner1Y)); //Add the newly calculated rectangular Polygon. SelectionPolygons.Add(newPolygon); }
public override void Crop (Gdk.Rectangle rect, Path selection) { base.Crop (rect, selection); foreach (ReEditableLayer rel in ReEditableLayers) { if (rel.IsLayerSetup) rel.Layer.Crop (rect, selection); } }
public void TakeSnapshot() { old_path = PintaCore.Layers.SelectionPath.Clone (); show_selection = PintaCore.Layers.ShowSelection; }
protected override void OnMouseMove(object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point) { if (!is_drawing) return; double x = Utility.Clamp (point.X, 0, PintaCore.Workspace.ImageSize.Width - 1); double y = Utility.Clamp (point.Y, 0, PintaCore.Workspace.ImageSize.Height - 1); PintaCore.Layers.ShowSelection = true; ImageSurface surf = PintaCore.Layers.ToolLayer.Surface; using (Context g = new Context (surf)) { g.Antialias = Antialias.Subpixel; if (path != null) { g.AppendPath (path); (path as IDisposable).Dispose (); } g.LineTo (x, y); path = g.CopyPath (); g.FillRule = FillRule.EvenOdd; g.ClosePath (); Path old = PintaCore.Layers.SelectionPath; PintaCore.Layers.SelectionPath = g.CopyPath (); (old as IDisposable).Dispose (); } PintaCore.Workspace.Invalidate (); }
private void Swap() { Path swap_path = PintaCore.Layers.SelectionPath; bool swap_show = PintaCore.Layers.ShowSelection; PintaCore.Layers.SelectionPath = old_path; PintaCore.Layers.ShowSelection = show_selection; old_path = swap_path; show_selection = swap_show; PintaCore.Workspace.Invalidate (); }
protected override void OnMouseUp(Gtk.DrawingArea canvas, Gtk.ButtonReleaseEventArgs args, Cairo.PointD point) { Document doc = PintaCore.Workspace.ActiveDocument; base.OnMouseUp (canvas, args, point); ImageSurface surf = doc.SelectionLayer.Surface; using (Context g = new Context (surf)) { if (path != null) { g.AppendPath (path); (path as IDisposable).Dispose (); path = null; } g.FillRule = FillRule.EvenOdd; g.ClosePath (); doc.Selection.DisposeSelectionPreserve(); doc.Selection.SelectionPath = g.CopyPath (); } doc.Selection.SelectionPolygons.Add(lassoPolygon.ToList()); lassoPolygon.Clear(); doc.Workspace.Invalidate (); }
/// <summary> /// Indicate that the selection has changed. /// </summary> public void MarkDirty() { if (selection_path != null) { selection_path.Dispose (); selection_path = null; } }
public void Crop(Gdk.Rectangle rect, Path path) { ImageSurface dest = new ImageSurface (Format.Argb32, rect.Width, rect.Height); using (Context g = new Context (dest)) { // Move the selected content to the upper left g.Translate (-rect.X, -rect.Y); g.Antialias = Antialias.None; // Respect the selected path g.AppendPath (path); g.FillRule = Cairo.FillRule.EvenOdd; g.Clip (); g.SetSource (Surface); g.Paint (); } (Surface as IDisposable).Dispose (); Surface = dest; }
static void CropImageToRectangle (Document doc, Gdk.Rectangle rect, Path selection) { if (rect.Width > 0 && rect.Height > 0) { ResizeHistoryItem hist = new ResizeHistoryItem(doc.ImageSize); hist.Icon = "Menu.Image.Crop.png"; hist.Text = Catalog.GetString("Crop to Selection"); hist.StartSnapshotOfImage(); hist.RestoreSelection = doc.Selection.Clone(); doc.Workspace.Canvas.GdkWindow.FreezeUpdates(); double original_scale = doc.Workspace.Scale; doc.ImageSize = rect.Size; doc.Workspace.CanvasSize = rect.Size; doc.Workspace.Scale = original_scale; PintaCore.Actions.View.UpdateCanvasScale(); doc.Workspace.Canvas.GdkWindow.ThawUpdates(); foreach (var layer in doc.UserLayers) layer.Crop (rect, selection); hist.FinishSnapshotOfImage(); doc.History.PushNewItem(hist); doc.ResetSelectionPaths(); doc.Workspace.Invalidate(); } }
/// <summary> /// Create a rectangular Selection from a Rectangle. /// </summary> /// <param name="selectionSurface">The selection surface to use for calculating the rectangular Path.</param> /// <param name="r">The Rectangle.</param> public void CreateRectangleSelection(Surface selectionSurface, Rectangle r) { using (Context g = new Context(selectionSurface)) { SelectionPath = g.CreateRectanglePath(r); } //Clear the Selection Polygons collection to start from a clean slate. SelectionPolygons.Clear(); SelectionPolygons.Add (CreateRectanglePolygon (r)); }
public void AppendPath(Path path) { CheckDisposed (); NativeMethods.cairo_append_path (handle, path.Handle); }
/// <summary> /// Inverts the selection. /// </summary> /// <param name="surface"> /// Surface for the selection path. /// </param> /// <param name='imageSize'> /// The size of the document. /// </param> public void Invert(Surface surface, Gdk.Size imageSize) { List<List<IntPoint>> resultingPolygons = new List<List<IntPoint>> (); var documentPolygon = CreateRectanglePolygon (new Rectangle (0, 0, imageSize.Width, imageSize.Height)); // Create a rectangle that is the size of the entire image, // and subtract all of the polygons in the current selection from it. SelectionClipper.AddPolygon (documentPolygon, PolyType.ptSubject); SelectionClipper.AddPolygons (SelectionPolygons, PolyType.ptClip); SelectionClipper.Execute (ClipType.ctDifference, resultingPolygons); SelectionClipper.Clear (); SelectionPolygons = resultingPolygons; using (Context g = new Context (surface)) { SelectionPath = g.CreatePolygonPath (ConvertToPolygonSet (resultingPolygons)); } }
protected override void OnMouseDown(Gtk.DrawingArea canvas, Gtk.ButtonPressEventArgs args, Cairo.PointD point) { Document doc = PintaCore.Workspace.ActiveDocument; surface_modified = false; undo_surface = doc.CurrentUserLayer.Surface.Clone (); path = null; doc.ToolLayer.Clear (); doc.ToolLayer.Hidden = false; }
public void AppendPath(Path path) { NativeMethods.cairo_append_path (handle, path.Handle); }
protected override void OnMouseMove(object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point) { Document doc = PintaCore.Workspace.ActiveDocument; if ((args.Event.State & Gdk.ModifierType.Button1Mask) == Gdk.ModifierType.Button1Mask) { outline_color = PintaCore.Palette.PrimaryColor; fill_color = PintaCore.Palette.SecondaryColor; } else if ((args.Event.State & Gdk.ModifierType.Button3Mask) == Gdk.ModifierType.Button3Mask) { outline_color = PintaCore.Palette.SecondaryColor; fill_color = PintaCore.Palette.PrimaryColor; } else { last_point = point_empty; return; } int x = (int)point.X; int y = (int)point.Y; if (last_point.Equals (point_empty)) { last_point = new Point (x, y); return; } if (doc.Workspace.PointInCanvas (point)) surface_modified = true; doc.ToolLayer.Clear (); ImageSurface surf = doc.ToolLayer.Surface; using (Context g = new Context (surf)) { doc.Selection.Clip(g); g.Antialias = UseAntialiasing ? Antialias.Subpixel : Antialias.None; if (path != null) { g.AppendPath (path); (path as IDisposable).Dispose (); } else { g.MoveTo (x, y); } g.LineTo (x, y); path = g.CopyPath (); g.ClosePath (); g.LineWidth = BrushWidth; g.LineJoin = LineJoin.Round; g.LineCap = LineCap.Round; g.FillRule = FillRule.EvenOdd; if (FillShape && StrokeShape) { g.Color = fill_color; g.FillPreserve (); g.Color = outline_color; g.Stroke (); } else if (FillShape) { g.Color = outline_color; g.Fill (); } else { g.Color = outline_color; g.Stroke (); } } doc.Workspace.Invalidate (); last_point = new Point (x, y); }