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