public void RenderMask(ISurface <ColorAlpha8> dstMask, PointInt32 renderOffset) { RectInt32 sourceRect = new RectInt32(renderOffset, dstMask.Size <ColorAlpha8>()); if (Interlocked.Exchange(ref this.haveFetchedStamp, 1) == 0) { this.lazyStampMaskDevBitmap.EnsureEvaluated(); } foreach (PointInt32 num2 in this.tileMathHelper.EnumerateTileOffsets(sourceRect)) { TileData tileData = this.GetTileData(num2); RectInt32 tileSourceRect = this.tileMathHelper.GetTileSourceRect(num2); RectInt32 num4 = RectInt32.Intersect(tileSourceRect, sourceRect); PointInt32 num5 = new PointInt32(num4.X - tileSourceRect.X, num4.Y - tileSourceRect.Y); RectInt32 bounds = new RectInt32(num4.X - sourceRect.X, num4.Y - sourceRect.Y, num4.Width, num4.Height); ISurface <ColorAlpha8> surface = dstMask.CreateWindow <ColorAlpha8>(bounds); object sync = tileData.Sync; lock (sync) { this.UpdateTileWhileLocked(tileData); if (tileData.Mask == null) { surface.Clear(); } else { tileData.Mask.Render(surface, num5); } } } }
public void Render(ISurface <TPixel> dst, PointInt32 renderOffset) { dst.Clear <TPixel>(); SizeInt32 size = dst.Size <TPixel>(); RectInt32 num2 = new RectInt32(renderOffset, size); PointInt32 location = new PointInt32(renderOffset.X - this.offset.X, renderOffset.Y - this.offset.Y); RectInt32 a = new RectInt32(location, size); RectInt32 num5 = RectInt32.Intersect(a, this.source.Bounds <TPixel>()); if (num5.HasPositiveArea) { PointInt32 num6 = new PointInt32(num5.X - a.X, num5.Y - a.Y); RectInt32 bounds = new RectInt32(num6, num5.Size); if (bounds.Location.IsZero && (bounds.Size == size)) { this.source.Render(dst, location); } else { using (ISurface <TPixel> surface = dst.CreateWindow <TPixel>(bounds)) { this.source.Render(surface, num5.Location); } } } }
private static ISurface <ColorAlpha8> UseTileOrToSurfaceWithEdgePadding(IRenderer <ColorAlpha8> source, RectInt32 bounds, ColorAlpha8 padding) { if (source.Bounds <ColorAlpha8>().Contains(bounds)) { return(source.UseTileOrToSurface(bounds)); } ISurface <ColorAlpha8> surface = SurfaceAllocator.Alpha8.Allocate <ColorAlpha8>(bounds.Size, AllocationOptions.ZeroFillNotRequired); surface.Clear(padding); RectInt32 num2 = RectInt32.Intersect(source.Bounds <ColorAlpha8>(), bounds); PointInt32 location = new PointInt32(num2.Location.X - bounds.Location.X, num2.Location.Y - bounds.Location.Y); RectInt32 num4 = new RectInt32(location, num2.Size); using (ISurfaceWindow <ColorAlpha8> window = surface.CreateWindow <ColorAlpha8>(num4)) { source.Render(window, num2.Location); } return(surface); }
public void RenderMask(ISurface <ColorAlpha8> dstMask, PointInt32 renderOffset, ICancellationToken cancelToken) { Validate.Begin().IsNotNull <ISurface <ColorAlpha8> >(dstMask, "dstMask").IsNotNull <ICancellationToken>(cancelToken, "cancelToken").Check(); cancelToken.ThrowIfCancellationRequested <ICancellationToken>(); RectInt32 sourceRect = new RectInt32(renderOffset, dstMask.Size <ColorAlpha8>()); if (Interlocked.Exchange(ref this.haveFetchedStamp, 1) == 0) { cancelToken.ThrowIfCancellationRequested <ICancellationToken>(); this.lazyStampMaskDevBitmap.EnsureEvaluated(); } foreach (PointInt32 num2 in this.tileMathHelper.EnumerateTileOffsets(sourceRect)) { cancelToken.ThrowIfCancellationRequested <ICancellationToken>(); TileData tileData = this.GetTileData(num2); RectInt32 tileSourceRect = this.tileMathHelper.GetTileSourceRect(num2); RectInt32 num4 = RectInt32.Intersect(tileSourceRect, sourceRect); PointInt32 num5 = new PointInt32(num4.X - tileSourceRect.X, num4.Y - tileSourceRect.Y); RectInt32 bounds = new RectInt32(num4.X - sourceRect.X, num4.Y - sourceRect.Y, num4.Width, num4.Height); ISurface <ColorAlpha8> surface = dstMask.CreateWindow <ColorAlpha8>(bounds); object sync = tileData.Sync; lock (sync) { cancelToken.ThrowIfCancellationRequested <ICancellationToken>(); this.UpdateTileWhileLocked(tileData, cancelToken); cancelToken.ThrowIfCancellationRequested <ICancellationToken>(); if (tileData.Mask == null) { surface.Clear(); } else { tileData.Mask.Render(surface, num5); } } cancelToken.ThrowIfCancellationRequested <ICancellationToken>(); } }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { historyWorkspace.VerifyAccess(); BitmapLayer layer = (BitmapLayer)historyWorkspace.Document.Layers[this.layerIndex]; Surface layerSurface = layer.Surface; TileMathHelper tileMathHelper = new TileMathHelper(layerSurface.Width, layerSurface.Height, this.rendererTileEdgeLog2); TileMathHelper tileGroupMathHelper = new TileMathHelper(layerSurface.Width, layerSurface.Height, this.rendererTileEdgeLog2 + 3); HistoryMemento actionHM = null; ManualResetEvent taskFinishedEvent = new ManualResetEvent(false); ThreadTask <Unit> commitTask = historyWorkspace.TaskManager.StartNewThreadTask(delegate(Task task) { SegmentedList <RectInt32> list = tileGroupMathHelper.EnumerateTilesClippedToSourceRect(this.rendererClipRect).ToSegmentedList <RectInt32>(); ListUtil.FisherYatesShuffle <RectInt32>(list); ConcurrentQueue <ISurface <ColorBgra> > queue = new ConcurrentQueue <ISurface <ColorBgra> >(); ConcurrentQueue <RectInt32> changedTiles = new ConcurrentQueue <RectInt32>(); ConcurrentQueue <TupleStruct <RectInt32, ISurface <ColorBgra> > > changedTileGroups = new ConcurrentQueue <TupleStruct <RectInt32, ISurface <ColorBgra> > >(); double progressIncrement = 1.0 / ((double)Math.Max(1, list.Count)); task.Progress = 0.0; Work.ParallelForEach <RectInt32>(WaitType.Blocking, list, delegate(RectInt32 tileGroupRect) { ISurface <ColorBgra> dst = RetryManager.RunMemorySensitiveOperation <ISurfaceRef <ColorBgra> >(() => SurfaceAllocator.Bgra.Allocate <ColorBgra>(tileGroupRect.Size, AllocationOptions.ZeroFillNotRequired)); this.renderer.Render(dst, tileGroupRect.Location); bool flag = false; foreach (RectInt32 num in tileMathHelper.EnumerateTilesClippedToSourceRect(tileGroupRect)) { RectInt32 bounds = RectInt32.Offset(num, -tileGroupRect.Location); using (ISurface <ColorBgra> surface2 = layerSurface.CreateWindow(num)) { using (ISurface <ColorBgra> surface3 = dst.CreateWindow <ColorBgra>(bounds)) { if (!SurfaceBgraUtil.ArePixelsEqual(surface2, surface3)) { flag = true; changedTiles.Enqueue(num); } } } } if (flag) { changedTileGroups.Enqueue(TupleStruct.Create <RectInt32, ISurface <ColorBgra> >(tileGroupRect, dst)); } else { DisposableUtil.Free <ISurface <ColorBgra> >(ref dst); } task.IncrementProgressBy(progressIncrement); }, WorkItemQueuePriority.Normal, null); task.Progress = null; if (changedTiles.Count == 0) { actionHM = null; } else { SegmentedList <RectInt32> scans = new SegmentedList <RectInt32>(changedTiles.Count, 7); scans.AddRange(changedTiles); ScansHelpers.SortScansByTopLeft(scans); ScansHelpers.ConsolidateSortedScansInPlace(scans); actionHM = new BitmapHistoryMemento(this.historyMementoName, this.historyMementoImage, historyWorkspace, this.layerIndex, scans); this.EnterCriticalRegion(); Work.ParallelForEach <TupleStruct <RectInt32, ISurface <ColorBgra> > >(WaitType.Blocking, changedTileGroups, delegate(TupleStruct <RectInt32, ISurface <ColorBgra> > tileInfo) { using (ISurface <ColorBgra> surface = layerSurface.CreateWindow(tileInfo.Item1)) { tileInfo.Item2.Render(surface, PointInt32.Zero); } tileInfo.Item2.Dispose(); }, WorkItemQueuePriority.Normal, null); foreach (RectInt32 num in scans) { layer.Invalidate(num); } } }, ApartmentState.MTA); commitTask.ResultAsync <Unit>().Receive(delegate(Result <Unit> r) { taskFinishedEvent.Set(); }).Observe(); if (!taskFinishedEvent.WaitOne(this.delayUntilProgressDialogMs)) { string headerText = PdnResources.GetString("ApplyRendererToBitmapLayerHistoryFunction.ProgressDialog.HeaderText"); string headerTextFormat = PdnResources.GetString("ApplyRendererToBitmapLayerHistoryFunction.ProgressDialog.HeaderText.Format"); using (TaskProgressDialog progressDialog = new TaskProgressDialog()) { Action updateHeaderText = delegate { progressDialog.VerifyAccess(); if (!progressDialog.IsDisposed) { string text1; double?progress = commitTask.Progress; if (!progress.HasValue) { text1 = headerText; } else { text1 = string.Format(headerTextFormat, (progress.Value * 100.0).ToString("N0")); } progressDialog.HeaderText = text1; } }; progressDialog.Text = this.historyMementoName; progressDialog.Icon = this.historyMementoImage.Reference.ToIcon(); progressDialog.CloseOnFinished = true; progressDialog.ShowCancelButton = false; progressDialog.Task = commitTask; updateHeaderText(); commitTask.ProgressChanged += delegate(object s, ValueEventArgs <double?> e) { PdnSynchronizationContext.Instance.EnsurePosted(updateHeaderText); }; progressDialog.ShowDialog(historyWorkspace.Window); } } if (!commitTask.TaskResult.IsError) { return(actionHM); } if (commitTask.TaskResult.Error is OutOfMemoryException) { throw new OutOfMemoryException(null, commitTask.TaskResult.Error); } throw new AggregateException(null, commitTask.TaskResult.Error); }