protected unsafe override void OnFillRegionComputed(Point[][] polygonSet) { SimpleHistoryItem hist = new SimpleHistoryItem (Icon, Name); hist.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayer); PintaCore.Layers.ToolLayer.Clear (); ImageSurface surface = PintaCore.Layers.ToolLayer.Surface; ColorBgra* surf_data_ptr = (ColorBgra*)surface.DataPtr; int surf_width = surface.Width; for (int x = 0; x < stencil.Width; x++) for (int y = 0; y < stencil.Height; y++) if (stencil.GetUnchecked (x, y)) surface.SetPixel (surf_data_ptr, surf_width, x, y, fill_color); using (Context g = new Context (PintaCore.Layers.CurrentLayer.Surface)) { g.AppendPath (PintaCore.Layers.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip (); g.Antialias = Antialias.Subpixel; g.SetSource (surface); g.Paint (); } PintaCore.History.PushNewItem (hist); PintaCore.Workspace.Invalidate (); }
// Called from asynchronously from Renderer.OnCompletion () void HandleApply () { Debug.WriteLine ("LivePreviewManager.HandleApply()"); var item = new SimpleHistoryItem (effect.Icon, effect.Name); item.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayerIndex); using (var ctx = new Cairo.Context (layer.Surface)) { ctx.Save (); ctx.AppendPath (PintaCore.Layers.SelectionPath); ctx.FillRule = Cairo.FillRule.EvenOdd; ctx.Clip (); ctx.Operator = Cairo.Operator.Source; ctx.SetSourceSurface (live_preview_surface, (int)layer.Offset.X, (int)layer.Offset.Y); ctx.Paint (); ctx.Restore (); } PintaCore.History.PushNewItem (item); FireLivePreviewEndedEvent(RenderStatus.Completed, null); live_preview_enabled = false; PintaCore.Workspace.Invalidate (); //TODO keep track of dirty bounds. CleanUp (); }
// Called from asynchronously from Renderer.OnCompletion () void HandleApply() { Debug.WriteLine("LivePreviewManager.HandleApply()"); var item = new SimpleHistoryItem(effect.Icon, effect.Name); item.TakeSnapshotOfLayer(PintaCore.Layers.CurrentLayerIndex); using (var ctx = new Cairo.Context(layer.Surface)) { ctx.Save(); PintaCore.Workspace.ActiveDocument.Selection.Clip(ctx); ctx.Operator = Cairo.Operator.Source; layer.Draw(ctx, live_preview_surface, 1); ctx.Restore(); } PintaCore.History.PushNewItem(item); FireLivePreviewEndedEvent(RenderStatus.Completed, null); live_preview_enabled = false; PintaCore.Workspace.Invalidate(); //TODO keep track of dirty bounds. CleanUp(); }
private void DoRotate(RotateZoomData rotateZoomData) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit (); var oldSurface = doc.CurrentLayer.Surface.Clone (); doc.CurrentLayer.Rotate (rotateZoomData.Angle); doc.Workspace.Invalidate (); var historyItem = new SimpleHistoryItem ("Menu.Layers.RotateZoom.png", Catalog.GetString ("Rotate / Zoom Layer"), oldSurface, doc.CurrentLayerIndex); doc.History.PushNewItem (historyItem); }
private void HandlePintaCoreActionsLayersMergeLayerDownActivated(object sender, EventArgs e) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit(); CompoundHistoryItem hist = new CompoundHistoryItem("Menu.Layers.MergeLayerDown.png", Catalog.GetString("Merge Layer Down")); DeleteLayerHistoryItem h1 = new DeleteLayerHistoryItem(string.Empty, string.Empty, doc.CurrentLayer, doc.CurrentLayerIndex); SimpleHistoryItem h2 = new SimpleHistoryItem(string.Empty, string.Empty, doc.Layers[doc.CurrentLayerIndex - 1].Surface.Clone(), doc.CurrentLayerIndex - 1); hist.Push(h1); hist.Push(h2); doc.MergeCurrentLayerDown(); doc.History.PushNewItem(hist); }
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 ().ToPremultipliedAlpha (); 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.SetColorBgraUnchecked (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 (); }
private void HandlePintaCoreActionsImageFlattenActivated(object sender, EventArgs e) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit(); CompoundHistoryItem hist = new CompoundHistoryItem("Menu.Image.Flatten.png", Catalog.GetString("Flatten")); SimpleHistoryItem h1 = new SimpleHistoryItem(string.Empty, string.Empty, doc.Layers[0].Surface.Clone(), 0); hist.Push(h1); for (int i = 1; i < doc.Layers.Count; i++) { hist.Push(new DeleteLayerHistoryItem(string.Empty, string.Empty, doc.Layers[i], i)); } doc.FlattenImage(); doc.History.PushNewItem(hist); }
private void HandlePintaCoreActionsLayersMergeLayerDownActivated(object sender, EventArgs e) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit(); int bottomLayerIndex = doc.Layers.CurrentUserLayerIndex - 1; var oldBottomSurface = doc.Layers.UserLayers[bottomLayerIndex].Surface.Clone(); CompoundHistoryItem hist = new CompoundHistoryItem(Resources.Icons.LayerMergeDown, Translations.GetString("Merge Layer Down")); DeleteLayerHistoryItem h1 = new DeleteLayerHistoryItem(string.Empty, string.Empty, doc.Layers.CurrentUserLayer, doc.Layers.CurrentUserLayerIndex); doc.Layers.MergeCurrentLayerDown(); SimpleHistoryItem h2 = new SimpleHistoryItem(string.Empty, string.Empty, oldBottomSurface, bottomLayerIndex); hist.Push(h1); hist.Push(h2); doc.History.PushNewItem(hist); }
// Called from asynchronously from Renderer.OnCompletion () void HandleApply() { Debug.WriteLine("LivePreviewManager.HandleApply()"); using (var ctx = new Cairo.Context(layer.Surface)) { ctx.Save(); PintaCore.Workspace.ActiveDocument.Selection.Clip(ctx); layer.DrawWithOperator(ctx, live_preview_surface, Cairo.Operator.Source); ctx.Restore(); } PintaCore.Workspace.ActiveDocument.History.PushNewItem(history_item); history_item = null !; FireLivePreviewEndedEvent(RenderStatus.Completed, null); live_preview_enabled = false; PintaCore.Workspace.Invalidate(); //TODO keep track of dirty bounds. CleanUp(); }
// Clean up resources when live preview is disabled. void CleanUp() { Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + " LivePreviewManager.CleanUp()"); live_preview_enabled = false; if (effect != null) { if (effect.EffectData != null) { effect.EffectData.PropertyChanged -= EffectData_PropertyChanged; } effect = null !; } live_preview_surface?.Dispose(); live_preview_surface = null !; if (renderer != null) { renderer.Dispose(); renderer = null !; } if (history_item != null) { history_item.Dispose(); history_item = null !; } // Hide progress dialog and clean up events. var dialog = PintaCore.Chrome.ProgressDialog; dialog.Hide(); dialog.Canceled -= HandleProgressDialogCancel; PintaCore.Chrome.MainWindowBusy = false; }
protected unsafe override void OnFillRegionComputed(Point[][] polygonSet) { SimpleHistoryItem hist = new SimpleHistoryItem (Icon, Name); hist.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayer); using (Context g = new Context (PintaCore.Layers.CurrentLayer.Surface)) { g.AppendPath (PintaCore.Layers.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip (); // Reset FillRule to the default g.FillRule = FillRule.Winding; g.AppendPath (g.CreatePolygonPath (polygonSet)); g.Antialias = Antialias.Subpixel; g.Color = fill_color; g.Fill (); } PintaCore.History.PushNewItem (hist); PintaCore.Workspace.Invalidate (); }
private void HandlePintaCoreActionsImageFlattenActivated(object sender, EventArgs e) { PintaCore.Layers.FinishSelection (); CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Image.Flatten.png", Catalog.GetString ("Flatten")); SimpleHistoryItem h1 = new SimpleHistoryItem (string.Empty, string.Empty, PintaCore.Layers[0].Surface.Clone (), 0); hist.Push (h1); for (int i = 1; i < PintaCore.Layers.Count; i++) hist.Push (new DeleteLayerHistoryItem (string.Empty, string.Empty, PintaCore.Layers[i], i)); PintaCore.Layers.FlattenImage (); PintaCore.History.PushNewItem (hist); }
private void StopEditing() { // If we don't have an open document, some of this stuff will crash if (!PintaCore.Workspace.HasOpenDocuments) return; if (!is_editing) return; try { Document doc = PintaCore.Workspace.ActiveDocument; doc.ToolLayer.Clear (); doc.ToolLayer.Hidden = true; if (engine.EditMode == EditingMode.Editing) { SimpleHistoryItem hist = new SimpleHistoryItem (Icon, Name); hist.TakeSnapshotOfLayer (doc.CurrentLayerIndex); // Redraw the text without the cursor, // and on to the real layer RedrawText (false, false); doc.History.PushNewItem (hist); } engine.Clear (); doc.Workspace.Invalidate (old_bounds); old_bounds = Rectangle.Zero; is_editing = false; } catch (Exception) { // Just ignore the error } }
private void HandlePintaCoreActionsLayersMergeLayerDownActivated(object sender, EventArgs e) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit (); CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Layers.MergeLayerDown.png", Catalog.GetString ("Merge Layer Down")); DeleteLayerHistoryItem h1 = new DeleteLayerHistoryItem (string.Empty, string.Empty, doc.CurrentLayer, doc.CurrentLayerIndex); SimpleHistoryItem h2 = new SimpleHistoryItem (string.Empty, string.Empty, doc.Layers[doc.CurrentLayerIndex - 1].Surface.Clone (), doc.CurrentLayerIndex - 1); hist.Push (h1); hist.Push (h2); doc.MergeCurrentLayerDown (); doc.History.PushNewItem (hist); }
private void HandleSepiaActivated(object sender, EventArgs e) { PintaCore.Layers.FinishSelection (); SimpleHistoryItem hist = new SimpleHistoryItem ("Menu.Adjustments.Sepia.png", Mono.Unix.Catalog.GetString ("Sepia")); hist.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayerIndex); PintaCore.Layers.Sepia (); PintaCore.History.PushNewItem (hist); }
// Clean up resources when live preview is disabled. void CleanUp () { Debug.WriteLine (DateTime.Now.ToString("HH:mm:ss:ffff") + " LivePreviewManager.CleanUp()"); live_preview_enabled = false; if (effect != null) { if (effect.EffectData != null) effect.EffectData.PropertyChanged -= EffectData_PropertyChanged; effect = null; } live_preview_surface = null; if (renderer != null) { renderer.Dispose (); renderer = null; } if (history_item != null) { history_item.Dispose (); history_item = null; } // Hide progress dialog and clean up events. var dialog = PintaCore.Chrome.ProgressDialog; dialog.Hide (); dialog.Canceled -= HandleProgressDialogCancel; PintaCore.Chrome.MainWindowBusy = false; }
// Called from asynchronously from Renderer.OnCompletion () void HandleApply () { Debug.WriteLine ("LivePreviewManager.HandleApply()"); var item = new SimpleHistoryItem (effect.Icon, effect.Name); item.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayerIndex); using (var ctx = new Cairo.Context (layer.Surface)) { ctx.Save (); ctx.AppendPath (PintaCore.Workspace.ActiveDocument.Selection.SelectionPath); ctx.FillRule = Cairo.FillRule.EvenOdd; ctx.Clip (); ctx.Operator = Cairo.Operator.Source; ctx.SetSourceSurface (live_preview_surface, (int)layer.Offset.X, (int)layer.Offset.Y); ctx.Paint (); ctx.Restore (); } PintaCore.History.PushNewItem (item); FireLivePreviewEndedEvent(RenderStatus.Completed, null); live_preview_enabled = false; PintaCore.Workspace.Invalidate (); //TODO keep track of dirty bounds. CleanUp (); }
private void HandlePintaCoreActionsLayersMergeLayerDownActivated(object sender, EventArgs e) { PintaCore.Layers.FinishSelection (); CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Layers.MergeLayerDown.png", Mono.Unix.Catalog.GetString ("Merge Layer Down")); DeleteLayerHistoryItem h1 = new DeleteLayerHistoryItem (string.Empty, string.Empty, PintaCore.Layers.CurrentLayer, PintaCore.Layers.CurrentLayerIndex); SimpleHistoryItem h2 = new SimpleHistoryItem (string.Empty, string.Empty, PintaCore.Layers[PintaCore.Layers.CurrentLayerIndex - 1].Surface.Clone (), PintaCore.Layers.CurrentLayerIndex - 1); hist.Push (h1); hist.Push (h2); PintaCore.Layers.MergeCurrentLayerDown (); PintaCore.History.PushNewItem (hist); }
private void HandlePintaCoreActionsImageFlattenActivated(object sender, EventArgs e) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit (); CompoundHistoryItem hist = new CompoundHistoryItem ("Menu.Image.Flatten.png", Catalog.GetString ("Flatten")); SimpleHistoryItem h1 = new SimpleHistoryItem (string.Empty, string.Empty, doc.Layers[0].Surface.Clone (), 0); hist.Push (h1); for (int i = 1; i < doc.Layers.Count; i++) hist.Push (new DeleteLayerHistoryItem (string.Empty, string.Empty, doc.Layers[i], i)); doc.FlattenImage (); doc.History.PushNewItem (hist); }
public bool PerformEffect(BaseEffect effect) { PintaCore.Layers.FinishSelection (); if (effect.IsConfigurable) { bool result = effect.LaunchConfiguration (); if (!result) return false; } SimpleHistoryItem hist = new SimpleHistoryItem (effect.Icon, effect.Text); hist.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayerIndex); // Use the existing ToolLayer instead of creating a new temp layer Layer tmp_layer = PintaCore.Layers.ToolLayer; tmp_layer.Clear (); ImageSurface dest = tmp_layer.Surface; Gdk.Rectangle roi = PintaCore.Layers.SelectionPath.GetBounds ().ToGdkRectangle (); roi = PintaCore.Workspace.ClampToImageSize (roi); if (PintaCore.System.RenderThreads <= 1) { effect.RenderEffect (PintaCore.Layers.CurrentLayer.Surface, dest, new Gdk.Rectangle[] { roi }); } else { List<Thread> threads = new List<Thread> (); foreach (Gdk.Rectangle rect in SplitRectangle (roi, PintaCore.System.RenderThreads)) { Thread t = new Thread (new ParameterizedThreadStart (ParallelRender)); t.Start (new StateInfo (PintaCore.Layers.CurrentLayer.Surface, dest, effect, rect)); threads.Add (t); } foreach (Thread t in threads) t.Join (); } using (Context g = new Context (PintaCore.Layers.CurrentLayer.Surface)) { g.AppendPath (PintaCore.Layers.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip (); g.SetSource (dest); g.Paint (); } PintaCore.Workspace.Invalidate (); PintaCore.History.PushNewItem (hist); return true; }
// Called from asynchronously from Renderer.OnCompletion () void HandleApply () { Debug.WriteLine ("LivePreviewManager.HandleApply()"); using (var ctx = new Cairo.Context (layer.Surface)) { ctx.Save (); PintaCore.Workspace.ActiveDocument.Selection.Clip (ctx); ctx.Operator = Cairo.Operator.Source; layer.Draw(ctx, live_preview_surface, 1); ctx.Restore (); } PintaCore.History.PushNewItem (history_item); history_item = null; FireLivePreviewEndedEvent(RenderStatus.Completed, null); live_preview_enabled = false; PintaCore.Workspace.Invalidate (); //TODO keep track of dirty bounds. CleanUp (); }
public void Start(BaseEffect effect) { if (live_preview_enabled) { throw new InvalidOperationException("LivePreviewManager.Start() called while live preview is already enabled."); } // Create live preview surface. // Start rendering. // Listen for changes to effectConfiguration object, and restart render if needed. live_preview_enabled = true; apply_live_preview_flag = false; cancel_live_preview_flag = false; layer = PintaCore.Layers.CurrentLayer; this.effect = effect; //TODO Use the current tool layer instead. live_preview_surface = new Cairo.ImageSurface(Cairo.Format.Argb32, PintaCore.Workspace.ImageSize.Width, PintaCore.Workspace.ImageSize.Height); // Handle selection path. PintaCore.Tools.Commit(); selection_path = (PintaCore.Layers.ShowSelection) ? PintaCore.Workspace.ActiveDocument.Selection.SelectionPath : null; render_bounds = (selection_path != null) ? selection_path.GetBounds() : live_preview_surface.GetBounds(); render_bounds = PintaCore.Workspace.ClampToImageSize(render_bounds); history_item = new SimpleHistoryItem(effect.Icon, effect.Name); history_item.TakeSnapshotOfLayer(PintaCore.Layers.CurrentLayerIndex); // Paint the pre-effect layer surface into into the working surface. using (var ctx = new Cairo.Context(live_preview_surface)) { layer.Draw(ctx, layer.Surface, 1); } if (effect.EffectData != null) { effect.EffectData.PropertyChanged += EffectData_PropertyChanged; } if (Started != null) { Started(this, new LivePreviewStartedEventArgs()); } var settings = new AsyncEffectRenderer.Settings() { ThreadCount = PintaCore.System.RenderThreads, TileWidth = render_bounds.Width, TileHeight = 1, ThreadPriority = ThreadPriority.BelowNormal }; Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss:ffff") + "Start Live preview."); renderer = new Renderer(this, settings); renderer.Start(effect, layer.Surface, live_preview_surface, render_bounds); if (effect.IsConfigurable) { if (!effect.LaunchConfiguration()) { PintaCore.Chrome.MainWindowBusy = true; Cancel(); } else { PintaCore.Chrome.MainWindowBusy = true; Apply(); } } else { PintaCore.Chrome.MainWindowBusy = true; Apply(); } }
public void Start (BaseEffect effect) { if (live_preview_enabled) throw new InvalidOperationException ("LivePreviewManager.Start() called while live preview is already enabled."); // Create live preview surface. // Start rendering. // Listen for changes to effectConfiguration object, and restart render if needed. live_preview_enabled = true; apply_live_preview_flag = false; cancel_live_preview_flag = false; layer = PintaCore.Layers.CurrentLayer; this.effect = effect; //TODO Use the current tool layer instead. live_preview_surface = new Cairo.ImageSurface (Cairo.Format.Argb32, PintaCore.Workspace.ImageSize.Width, PintaCore.Workspace.ImageSize.Height); // Handle selection path. PintaCore.Tools.Commit (); selection_path = (PintaCore.Layers.ShowSelection) ? PintaCore.Workspace.ActiveDocument.Selection.SelectionPath : null; render_bounds = (selection_path != null) ? selection_path.GetBounds () : live_preview_surface.GetBounds (); render_bounds = PintaCore.Workspace.ClampToImageSize (render_bounds); history_item = new SimpleHistoryItem (effect.Icon, effect.Name); history_item.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayerIndex); // Paint the pre-effect layer surface into into the working surface. using (var ctx = new Cairo.Context (live_preview_surface)) { layer.Draw(ctx, layer.Surface, 1); } if (effect.EffectData != null) effect.EffectData.PropertyChanged += EffectData_PropertyChanged; if (Started != null) { Started (this, new LivePreviewStartedEventArgs()); } var settings = new AsyncEffectRenderer.Settings () { ThreadCount = PintaCore.System.RenderThreads, TileWidth = render_bounds.Width, TileHeight = 1, ThreadPriority = ThreadPriority.BelowNormal }; Debug.WriteLine (DateTime.Now.ToString("HH:mm:ss:ffff") + "Start Live preview."); renderer = new Renderer (this, settings); renderer.Start (effect, layer.Surface, live_preview_surface, render_bounds); if (effect.IsConfigurable) { if (!effect.LaunchConfiguration ()) { PintaCore.Chrome.MainWindowBusy = true; Cancel (); } else { PintaCore.Chrome.MainWindowBusy = true; Apply (); } } else { PintaCore.Chrome.MainWindowBusy = true; Apply (); } }
private void HandleAutoLevelActivated(object sender, EventArgs e) { PintaCore.Layers.FinishSelection (); SimpleHistoryItem hist = new SimpleHistoryItem ("Menu.Adjustments.AutoLevel.png", Mono.Unix.Catalog.GetString ("Auto Level")); hist.TakeSnapshotOfLayer (PintaCore.Layers.CurrentLayerIndex); PintaCore.Layers.CurrentLayer.AutoLevel (); PintaCore.Workspace.Invalidate (); PintaCore.History.PushNewItem (hist); }