private IRenderer <ColorAlpha8> CreateMaskRenderer() { IRenderer <ColorAlpha8> renderer; byte x = (byte)Math.Round((double)(this.changes.Tolerance * 255.0), MidpointRounding.AwayFromZero); byte tolerance = ByteUtil.FastScale(x, x); PointInt32 pt = this.changes.OriginPointInt32; if (!this.sampleSource.Bounds <ColorBgra>().Contains(pt)) { return(new FillRendererAlpha8(this.sampleSource.Width, this.sampleSource.Height, ColorAlpha8.Transparent)); } ColorBgra pointSlow = this.sampleSource.GetPointSlow(pt); base.ThrowIfCancellationRequested(); if (this.changes.FloodMode == FloodMode.Global) { renderer = new FillStencilByColorRenderer(this.sampleSource, pointSlow, tolerance, this); } else { RectInt32 num5; BitVector2D source = new BitVector2D(this.sampleSource.Width, this.sampleSource.Height); BitVector2DStruct stencilBuffer = new BitVector2DStruct(source); source.Clear(true); base.ThrowIfCancellationRequested(); foreach (RectInt32 num6 in this.changes.ClippingMask.EnumerateInteriorScans()) { source.Set(num6, false); base.ThrowIfCancellationRequested(); } BitVector2D other = source.Clone(); base.ThrowIfCancellationRequested(); FloodFillAlgorithm.FillStencilFromPoint <BitVector2DStruct>(this.sampleSource, stencilBuffer, pt, tolerance, this, out num5); base.ThrowIfCancellationRequested(); source.Xor(other); base.ThrowIfCancellationRequested(); renderer = new BitVector2DToAlpha8Renderer <BitVector2DStruct>(stencilBuffer); } if (this.changes.Antialiasing) { return(new FeatheredMaskRenderer(this.sampleSource, pointSlow, renderer, tolerance, this)); } return(renderer); }
public void SaveRegion(GeometryRegion saveMeRegion, Rectangle saveMeBounds) { var activeLayer = (BitmapLayer)ActiveLayer; if (_savedTiles == null) { _savedTiles = new BitVector2D( (activeLayer.Width + SaveTileGranularity - 1) / SaveTileGranularity, (activeLayer.Height + SaveTileGranularity - 1) / SaveTileGranularity); _savedTiles.Clear(false); } Rectangle regionBounds; if (saveMeRegion == null) { regionBounds = saveMeBounds; } else { regionBounds = saveMeRegion.GetBoundsInt(); } Rectangle bounds = Rectangle.Union(regionBounds, saveMeBounds); bounds.Intersect(activeLayer.Bounds); int leftTile = bounds.Left / SaveTileGranularity; int topTile = bounds.Top / SaveTileGranularity; int rightTile = (bounds.Right - 1) / SaveTileGranularity; int bottomTile = (bounds.Bottom - 1) / SaveTileGranularity; for (int tileY = topTile; tileY <= bottomTile; ++tileY) { Rectangle rowAccumBounds = Rectangle.Empty; for (int tileX = leftTile; tileX <= rightTile; ++tileX) { if (!_savedTiles.Get(tileX, tileY)) { Rectangle tileBounds = new Rectangle(tileX * SaveTileGranularity, tileY * SaveTileGranularity, SaveTileGranularity, SaveTileGranularity); tileBounds.Intersect(activeLayer.Bounds); if (rowAccumBounds == Rectangle.Empty) { rowAccumBounds = tileBounds; } else { rowAccumBounds = Rectangle.Union(rowAccumBounds, tileBounds); } _savedTiles.Set(tileX, tileY, true); } else { if (rowAccumBounds != Rectangle.Empty) { using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds), src = activeLayer.Surface.CreateWindow(rowAccumBounds)) { dst.CopySurface(src); } rowAccumBounds = Rectangle.Empty; } } } if (rowAccumBounds != Rectangle.Empty) { using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds), src = activeLayer.Surface.CreateWindow(rowAccumBounds)) { dst.CopySurface(src); } rowAccumBounds = Rectangle.Empty; } } if (this._saveRegion != null) { this._saveRegion.Dispose(); this._saveRegion = null; } if (saveMeRegion != null) { this._saveRegion = saveMeRegion.Clone(); } }