public SelectionGeometryCache(IDirect2DFactory factory, PaintDotNet.Canvas.SelectionSnapshot selectionSnapshot) { this.factory = factory; this.selectionSnapshot = selectionSnapshot; this.geometry = LazyResult.New <IGeometry>(() => this.factory.CreateGeometry(selectionSnapshot.GeometryList.Value), LazyThreadSafetyMode.ExecutionAndPublication, new SingleUseCriticalSection()); this.pixelatedGeometry = LazyResult.New <IGeometry>(() => GeometryHelpers.ToDirect2DGeometryDestructive(this.factory, ScansHelpers.ConvertNonOverlappingScansToPolygons(selectionSnapshot.PixelatedScans.Value), FillMode.Alternate, FigureBegin.Filled, FigureEnd.Closed), LazyThreadSafetyMode.ExecutionAndPublication, new SingleUseCriticalSection()); }
private bool CanContinueRedrawing(IBitmap <ColorAlpha8> interiorMask = null, IBitmap <ColorAlpha8>[] dashedOutlineMasks = null) { if (base.IsDisposed) { this.redrawThreadFactory = null; DisposableUtil.Free <SelectionGeometryCache>(ref this.redrawThreadGeometryCache); DisposableUtil.Free <IBitmap <ColorAlpha8> >(ref interiorMask); DisposableUtil.FreeContents <IBitmap <ColorAlpha8> >(dashedOutlineMasks); base.SyncContext.Post(delegate(object _) { this.EndRedraw(RectDouble.Zero, RectFloat.Zero, null, null); }); return(false); } return(true); }
protected override void Dispose(bool disposing) { if (disposing) { DisposableUtil.Free <IBitmap <ColorAlpha8> >(ref this.renderedInteriorMask); DisposableUtil.FreeContents <IBitmap <ColorAlpha8> >(this.renderedDashedOutlineMasks); if (!this.isRedrawing) { this.redrawThreadFactory = null; DisposableUtil.Free <SelectionGeometryCache>(ref this.redrawThreadGeometryCache); } this.ClearDeviceBitmapPool(); } base.Dispose(disposing); }
private void RenderMask(ISurface <ColorAlpha8> dstMask, PointInt32 renderOffset) { int width = dstMask.Width; int height = dstMask.Height; bool flag = false; SizeInt32 size = new SizeInt32(width, height); RectInt32 rectangle = new RectInt32(renderOffset, size); if (!flag && this.matrix.HasInverse) { Matrix3x2Double inverse = this.matrix.Inverse; PointDouble pt = inverse.Transform(rectangle.TopLeft); PointDouble num7 = inverse.Transform(rectangle.TopRight); PointDouble num8 = inverse.Transform(rectangle.BottomLeft); PointDouble num9 = inverse.Transform(rectangle.BottomRight); RectDouble srcCoverageBounds = this.srcCoverageBounds; if ((srcCoverageBounds.Contains(pt) && srcCoverageBounds.Contains(num7)) && (srcCoverageBounds.Contains(num8) && srcCoverageBounds.Contains(num9))) { dstMask.Clear(ColorAlpha8.Opaque); flag = true; } } if (!flag) { GeometryRelation relation; IDirect2DFactory perThread = Direct2DFactory.PerThread; using (IRectangleGeometry geometry = perThread.CreateRectangleGeometry(rectangle)) { base.ThrowIfCancellationRequested(); using (IRectangleGeometry geometry2 = perThread.CreateRectangleGeometry(this.srcCoverageBounds)) { base.ThrowIfCancellationRequested(); relation = geometry.CompareWithGeometry(geometry2, new Matrix3x2Float?((Matrix3x2Float)this.matrix), null); base.ThrowIfCancellationRequested(); } } switch (relation) { case GeometryRelation.IsContained: dstMask.Clear(ColorAlpha8.Opaque); flag = true; break; case GeometryRelation.Disjoint: dstMask.Clear(ColorAlpha8.Transparent); flag = true; break; } } if (!flag) { using (IDrawingContext context = DrawingContext.FromSurface(dstMask, FactorySource.PerThread)) { base.ThrowIfCancellationRequested(); context.Clear(null); context.AntialiasMode = AntialiasMode.PerPrimitive; using (context.UseTranslateTransform((float)-renderOffset.X, (float)-renderOffset.Y, MatrixMultiplyOrder.Prepend)) { using (context.UseTransformMultiply((Matrix3x2Float)this.matrix, MatrixMultiplyOrder.Prepend)) { context.FillRectangle(this.srcCoverageBounds, whiteBrush); } } } } }
public static IDirect2DFactory CreateRef(this IDirect2DFactory objectRef) => ((IDirect2DFactory)objectRef.CreateRef(typeof(IDirect2DFactory)));
private void RedrawOnBackgroundThread() { if (base.CheckAccess()) { ExceptionUtil.ThrowInvalidOperationException(); } if (this.redrawThreadFactory == null) { this.redrawThreadFactory = new Direct2DFactory(Direct2DFactoryType.MultiThreaded, DebugLevel.None); } if ((this.redrawThreadGeometryCache == null) || (this.redrawThreadGeometryCache.SelectionSnapshot != this.redrawRenderParams.SelectionSnapshot)) { DisposableUtil.Free <SelectionGeometryCache>(ref this.redrawThreadGeometryCache); this.redrawThreadGeometryCache = new SelectionGeometryCache(this.redrawThreadFactory, this.redrawRenderParams.SelectionSnapshot); } double scaleRatio = this.redrawRenderParams.ScaleRatio; PointDouble location = this.redrawRenderParams.ViewportCanvasBounds.Location; SizeDouble viewportSize = this.redrawRenderParams.ViewportSize; SizeInt32 num5 = SizeDouble.Ceiling(viewportSize); RectDouble b = RectDouble.Inflate(CanvasCoordinateConversions.ConvertExtentToViewport(CanvasCoordinateConversions.ConvertCanvasToExtent(this.redrawRenderParams.SelectionSnapshot.GeometryList.Value.Bounds, scaleRatio), scaleRatio, location), (double)this.outlineStrokeWidthPx, (double)this.outlineStrokeWidthPx); RectDouble a = new RectDouble(PointDouble.Zero, viewportSize); RectDouble renderViewportBounds = RectDouble.Intersect(a, b); RectInt32 viewportRect = renderViewportBounds.Int32Bound; RectDouble extentRect = CanvasCoordinateConversions.ConvertViewportToExtent(viewportRect, scaleRatio, location); RectDouble renderCanvasBounds = CanvasCoordinateConversions.ConvertExtentToCanvas(extentRect, scaleRatio); if (!viewportRect.HasPositiveArea) { base.SyncContext.Post((SendOrPostCallback)(_ => this.EndRedraw(renderViewportBounds, RectFloat.Zero, null, null))); } else { IBitmap <ColorAlpha8> interiorMask; float scale; PointFloat offset; Result <IGeometry> lazyGeometry; IBitmap <ColorAlpha8>[] dashedOutlineMasks; RectFloat maskSourceRect; SelectionSnapshot selectionSnapshot = this.redrawRenderParams.SelectionSnapshot; SelectionGeometryCache redrawThreadGeometryCache = this.redrawThreadGeometryCache; bool flag = this.redrawRenderParams.SelectionRenderingQuality == SelectionRenderingQuality.Aliased; if (!flag) { lazyGeometry = redrawThreadGeometryCache.Geometry; } else { bool flag3 = selectionSnapshot.IsRectilinear.Value; bool flag4 = selectionSnapshot.IsPixelated.Value; if (flag3 & flag4) { lazyGeometry = redrawThreadGeometryCache.Geometry; } else { lazyGeometry = redrawThreadGeometryCache.PixelatedGeometry; } } bool flag2 = !flag && this.redrawRenderParams.IsOutlineAntialiased; AntialiasMode antialiasMode = ((flag || !flag2) || selectionSnapshot.IsRectilinear.Value) ? AntialiasMode.Aliased : AntialiasMode.PerPrimitive; if (this.CanContinueRedrawing(null, null)) { scale = (float)this.redrawRenderParams.ScaleRatio; float x = -((float)renderCanvasBounds.X); float y = -((float)renderCanvasBounds.Y); offset = new PointFloat(x, y); interiorMask = BitmapAllocator.Alpha8.Allocate(viewportRect.Size, AllocationOptions.ZeroFillNotRequired); try { RetryManager.RunMemorySensitiveOperation(delegate { using (IDrawingContext context = DrawingContext.FromBitmap(this.redrawThreadFactory, interiorMask)) { context.Clear(null); IBrush interiorBrush = context.GetCachedOrCreateResource <IBrush>(whiteBrush); this.RenderSelection(context, scale, offset, this.redrawRenderParams, lazyGeometry, interiorBrush, null, null, antialiasMode); } }); } catch (OutOfMemoryException) { } if (this.CanContinueRedrawing(interiorMask, null)) { int num15; dashedOutlineMasks = new IBitmap <ColorAlpha8> [SelectionCanvasLayer.DashLength]; for (int i = 0; i < dashedOutlineMasks.Length; i = num15) { if ((!this.redrawRenderParams.IsOutlineAnimated && (i != 0)) && (i != (SelectionCanvasLayer.DashLength / 2))) { dashedOutlineMasks[i] = null; } else { dashedOutlineMasks[i] = BitmapAllocator.Alpha8.Allocate(viewportRect.Size, AllocationOptions.ZeroFillNotRequired); try { RetryManager.RunMemorySensitiveOperation(delegate { using (IDrawingContext context = DrawingContext.FromBitmap(this.redrawThreadFactory, dashedOutlineMasks[i])) { context.Clear(null); StrokeStyle resourceSource = SelectionCanvasLayer.GetDashedStrokeStyle(i); IStrokeStyle outlineStrokeStyle = context.GetCachedOrCreateResource <IStrokeStyle>(resourceSource); IBrush cachedOrCreateResource = context.GetCachedOrCreateResource <IBrush>(whiteBrush); this.RenderSelection(context, scale, offset, this.redrawRenderParams, lazyGeometry, null, cachedOrCreateResource, outlineStrokeStyle, antialiasMode); } }); } catch (OutOfMemoryException) { } if (!this.CanContinueRedrawing(interiorMask, dashedOutlineMasks)) { return; } } num15 = i + 1; } maskSourceRect = new RectFloat(PointFloat.Zero, interiorMask.Size); base.SyncContext.Post(_ => this.EndRedraw(renderCanvasBounds, maskSourceRect, interiorMask, dashedOutlineMasks), null); } } } }