public MaskedSurface(Surface source, PdnGraphicsPath path) { RectangleF boundsF = path.GetBounds(); Rectangle bounds = Utility.RoundRectangle(boundsF); Rectangle boundsClipped = Rectangle.Intersect(bounds, source.Bounds); Rectangle boundsRead; if (bounds != boundsClipped) { PdnRegion region = new PdnRegion(path); region.Intersect(source.Bounds); SetPathField(PdnGraphicsPath.FromRegion(region)); this.region = region; boundsRead = region.GetBoundsInt(); } else { SetPathField(path.Clone()); this.region = new PdnRegion(this.path); boundsRead = boundsClipped; } if (boundsRead.Width > 0 && boundsRead.Height > 0) { this.surface = new Surface(boundsRead.Size); this.surface.CopySurface(source, boundsRead); } else { this.surface = null; } }
private void DrawSelectionTinting(Graphics g, PdnGraphicsPath outline) { if (outline == null) { return; } CompositingMode oldCM = g.CompositingMode; g.CompositingMode = CompositingMode.SourceOver; SmoothingMode oldSM = g.SmoothingMode; g.SmoothingMode = SmoothingMode.AntiAlias; PixelOffsetMode oldPOM = g.PixelOffsetMode; g.PixelOffsetMode = PixelOffsetMode.None; Region oldClipRegion = null; RectangleF outlineBounds = outline.GetBounds(); if (outlineBounds.Left < 0 || outlineBounds.Top < 0 || outlineBounds.Right >= this.SourceSize.Width || outlineBounds.Bottom >= this.SourceSize.Height) { oldClipRegion = g.Clip; Region newClipRegion = oldClipRegion.Clone(); newClipRegion.Intersect(new Rectangle(0, 0, this.SourceSize.Width, this.SourceSize.Height)); g.Clip = newClipRegion; newClipRegion.Dispose(); } g.FillPath(InteriorBrush, outline); if (oldClipRegion != null) { g.Clip = oldClipRegion; oldClipRegion.Dispose(); } g.PixelOffsetMode = oldPOM; g.SmoothingMode = oldSM; g.CompositingMode = oldCM; }
public unsafe void Draw(Surface dst, Matrix transform, ResamplingAlgorithm sampling) { if (this.disposed) { throw new ObjectDisposedException("MaskedSurface"); } if (this.surface == null || !transform.IsInvertible) { return; } PdnRegion theRegion; Rectangle regionBounds; if (this.path == null) { theRegion = this.region.Clone(); regionBounds = this.region.GetBoundsInt(); theRegion.Transform(transform); } else { using (PdnGraphicsPath mPath = this.shadowPath.Clone()) { regionBounds = Rectangle.Truncate(mPath.GetBounds()); mPath.Transform(transform); theRegion = new PdnRegion(mPath); } } DrawContext dc = new DrawContext(); dc.boundsX = regionBounds.X; dc.boundsY = regionBounds.Y; Matrix inverse = transform.Clone(); inverse.Invert(); dc.inverses = new Matrix[Processor.LogicalCpuCount]; for (int i = 0; i < dc.inverses.Length; ++i) { dc.inverses[i] = inverse.Clone(); } // change in source-[X|Y] w.r.t. destination-[X|Y] PointF[] pts = new PointF[] { new PointF(1, 0), new PointF(0, 1) }; inverse.TransformVectors(pts); inverse.Dispose(); inverse = null; dc.dsxddx = pts[0].X; if (Math.Abs(dc.dsxddx) > fp_MaxValue) { dc.dsxddx = 0.0f; } dc.dsyddx = pts[0].Y; if (Math.Abs(dc.dsyddx) > fp_MaxValue) { dc.dsyddx = 0.0f; } dc.dsxddy = pts[1].X; if (Math.Abs(dc.dsxddy) > fp_MaxValue) { dc.dsxddy = 0.0f; } dc.dsyddy = pts[1].Y; if (Math.Abs(dc.dsyddy) > fp_MaxValue) { dc.dsyddy = 0.0f; } dc.fp_dsxddx = (int)(dc.dsxddx * fp_MultFactor); dc.fp_dsyddx = (int)(dc.dsyddx * fp_MultFactor); dc.fp_dsxddy = (int)(dc.dsxddy * fp_MultFactor); dc.fp_dsyddy = (int)(dc.dsyddy * fp_MultFactor); dc.dst = dst; dc.src = this.surface; Rectangle[] scans = theRegion.GetRegionScansReadOnlyInt(); if (scans.Length == 1) { dc.dstScans = new Rectangle[Processor.LogicalCpuCount]; Utility.SplitRectangle(scans[0], dc.dstScans); } else { dc.dstScans = scans; } WaitCallback wc; switch (sampling) { case ResamplingAlgorithm.NearestNeighbor: wc = new WaitCallback(dc.DrawScansNearestNeighbor); break; case ResamplingAlgorithm.Bilinear: wc = new WaitCallback(dc.DrawScansBilinear); break; default: throw new System.ComponentModel.InvalidEnumArgumentException(); } for (int i = 0; i < Processor.LogicalCpuCount; ++i) { if (i == Processor.LogicalCpuCount - 1) { // Don't queue the last work item into a separate thread wc(BoxedConstants.GetInt32(i)); } else { threadPool.QueueUserWorkItem(wc, BoxedConstants.GetInt32(i)); } } threadPool.Drain(); for (int i = 0; i < Processor.LogicalCpuCount; ++i) { dc.inverses[i].Dispose(); dc.inverses[i] = null; } dc.src = null; theRegion.Dispose(); theRegion = null; }