public void GetDefaultContentClip(TChanges changes, out RectInt32 clipRect, out IRenderer <ColorAlpha8> clipMaskRenderer) { if (this.tool.Selection.IsEmpty) { clipMaskRenderer = null; clipRect = this.tool.Document.Bounds(); } else { GeometryList cachedClippingMask = this.tool.Selection.GetCachedClippingMask(); clipRect = RectInt32.Intersect(cachedClippingMask.Bounds.Int32Bound, this.tool.Document.Bounds()); SelectionRenderingQuality drawingSettingValue = changes.GetDrawingSettingValue <SelectionRenderingQuality>(this.tool.ToolSettings.Selection.RenderingQuality); Result <IRenderer <ColorAlpha8> > cachedLazyClippingMaskRenderer = this.tool.Selection.GetCachedLazyClippingMaskRenderer(drawingSettingValue); SizeInt32 size = this.tool.Document.Size(); clipMaskRenderer = LazyRenderer.Create <ColorAlpha8>(size, cachedLazyClippingMaskRenderer); } }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { GeometryList cachedClippingMask = historyWorkspace.Selection.GetCachedClippingMask(); if (historyWorkspace.Selection.IsEmpty || (cachedClippingMask.Bounds.Area < 1.0)) { return(null); } Document oldDocument = historyWorkspace.Document; RectInt32 b = cachedClippingMask.Bounds.GetInt32Bound(1E-05); RectInt32 oldClipBounds = RectInt32.Intersect(oldDocument.Bounds(), b); Document document = new Document(oldClipBounds.Width, oldClipBounds.Height); document.ReplaceMetadataFrom(oldDocument); RectInt32 newClipBounds = new RectInt32(0, 0, oldClipBounds.Width, oldClipBounds.Height); SelectionRenderingQuality quality = historyWorkspace.ToolSettings.Selection.RenderingQuality.Value; Result <IRenderer <ColorAlpha8> > oldClipMaskRendererLazy = historyWorkspace.Selection.GetCachedLazyClippingMaskRenderer(quality); LazyResult <ClippedRenderer <ColorAlpha8> > newClipMaskRendererLazy = LazyResult.New <ClippedRenderer <ColorAlpha8> >(() => new ClippedRenderer <ColorAlpha8>(oldClipMaskRendererLazy.Value, oldClipBounds), LazyThreadSafetyMode.ExecutionAndPublication, new VistaCriticalSection(0)); SelectionData selectionData = historyWorkspace.Selection.Save(); System.Threading.Tasks.Task <SelectionHistoryMemento> task = System.Threading.Tasks.Task.Factory.StartNew <SelectionHistoryMemento>(() => new SelectionHistoryMemento(null, null, historyWorkspace, selectionData)); System.Threading.Tasks.Task <ReplaceDocumentHistoryMemento> task2 = System.Threading.Tasks.Task.Factory.StartNew <ReplaceDocumentHistoryMemento>(() => new ReplaceDocumentHistoryMemento(null, null, historyWorkspace, oldDocument), TaskCreationOptions.LongRunning); int count = oldDocument.Layers.Count; System.Threading.Tasks.Task <BitmapLayer>[] items = new System.Threading.Tasks.Task <BitmapLayer> [count]; for (int i = 0; i < count; i++) { int iP = i; items[iP] = System.Threading.Tasks.Task.Factory.StartNew <BitmapLayer>(delegate { if (iP == 0) { newClipMaskRendererLazy.EnsureEvaluated(); } BitmapLayer layer = (BitmapLayer)oldDocument.Layers[iP]; Surface croppedSurface = layer.Surface.CreateWindow(oldClipBounds); BitmapLayer newLayer = RetryManager.RunMemorySensitiveOperation <BitmapLayer>(() => new BitmapLayer(croppedSurface)); newLayer.LoadProperties(layer.SaveProperties()); Parallel.ForEach <RectInt32>(newClipBounds.GetTiles(TilingStrategy.Tiles, 7), delegate(RectInt32 newTileRect) { ISurface <ColorBgra> surface = newLayer.Surface.CreateWindow(newTileRect); IRenderer <ColorAlpha8> mask = new ClippedRenderer <ColorAlpha8>(newClipMaskRendererLazy.Value, newTileRect); surface.MultiplyAlphaChannel(mask); }); return(newLayer); }); } List <TupleStruct <System.Threading.Tasks.Task, double> > collection = new List <TupleStruct <System.Threading.Tasks.Task, double> >(); collection.AddTuple <System.Threading.Tasks.Task, double>(task, 0.1); collection.AddTuple <System.Threading.Tasks.Task, double>(task2, 1.0); for (int j = 0; j < items.Length; j++) { collection.AddTuple <System.Threading.Tasks.Task, double>(items[j], 0.1); } PaintDotNet.Threading.Tasks.Task <Unit> task3 = historyWorkspace.TaskManager.CreateFrameworkTasksWrapper(collection); historyWorkspace.WaitWithProgress(task3, HistoryMementoImage, HistoryMementoName, PdnResources.GetString("Effects.ApplyingDialog.Description")); document.Layers.AddRange <Layer>(items.Select <System.Threading.Tasks.Task <BitmapLayer>, BitmapLayer>(t => t.Result)); SelectionHistoryMemento result = task.Result; ReplaceDocumentHistoryMemento memento2 = task2.Result; base.EnterCriticalRegion(); historyWorkspace.Document = document; HistoryMemento[] mementos = new HistoryMemento[] { result, memento2 }; return(HistoryMemento.Combine(HistoryMementoName, HistoryMementoImage, mementos)); }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { if (historyWorkspace.Selection.IsEmpty) { return(null); } SelectionHistoryMemento memento = new SelectionHistoryMemento(StaticName, StaticImage, historyWorkspace); GeometryList selectedPath = historyWorkspace.Selection.GetCachedGeometryList(); SelectionRenderingQuality selectionRenderingQuality = historyWorkspace.ToolSettings.Selection.RenderingQuality.Value; Result <IReadOnlyList <RectInt32> > selectedPathScansLazy = historyWorkspace.Selection.GetCachedLazyClippingMaskScans(); RectInt32 documentBounds = historyWorkspace.Document.Bounds(); Func <GeometryList> invertedPathFn = delegate { if ((selectionRenderingQuality == SelectionRenderingQuality.Aliased) || selectedPath.IsPixelated) { GeometryList list2 = GeometryList.FromNonOverlappingSortedScans(selectedPathScansLazy.Value); list2.AddRect(documentBounds); SegmentedList <RectInt32> scans = new SegmentedList <RectInt32>(); foreach (RectInt32 num in list2.EnumerateInteriorScans()) { if (documentBounds.Contains(num)) { scans.Add(num); } else if (documentBounds.IntersectsWith(num)) { scans.Add(RectInt32.Intersect(documentBounds, num)); } } return(GeometryList.FromNonOverlappingScans(scans)); } GeometryList lhs = documentBounds.Contains(selectedPath.Bounds) ? selectedPath : GeometryList.ClipToRect(selectedPath, documentBounds); return(GeometryList.Combine(lhs, GeometryCombineMode.Xor, documentBounds)); }; ThreadTask <GeometryList> task = historyWorkspace.TaskManager.StartNewThreadTask <GeometryList>(task => invertedPathFn(), ApartmentState.MTA); ManualResetEvent taskFinishedEvent = new ManualResetEvent(false); task.ResultAsync <GeometryList>().Receive(delegate(Result <GeometryList> r) { taskFinishedEvent.Set(); }).Observe(); if (!taskFinishedEvent.WaitOne(0x3e8)) { using (TaskProgressDialog dialog = new TaskProgressDialog()) { dialog.Task = task; dialog.Text = StaticName; dialog.Icon = StaticImage.Reference.ToIcon(); dialog.HeaderText = PdnResources.GetString("SaveConfigDialog.Finishing.Text"); dialog.ShowDialog(historyWorkspace.Window); } } Result <GeometryList> taskResult = task.TaskResult; if (taskResult.IsError) { if (taskResult.Error is OutOfMemoryException) { throw new OutOfMemoryException(null, taskResult.Error); } throw new AggregateException(null, taskResult.Error); } GeometryList geometry = task.TaskResult.Value; base.EnterCriticalRegion(); using (historyWorkspace.Selection.UseChangeScope()) { historyWorkspace.Selection.Reset(); geometry.Freeze(); historyWorkspace.Selection.SetContinuation(geometry, SelectionCombineMode.Replace); historyWorkspace.Selection.CommitContinuation(); } return(memento); }