public static PdnGraphicsPath FromRegion(PdnRegion region)
        {
            Rectangle bounds = region.GetBoundsInt();

            Rectangle[] scans   = region.GetRegionScansReadOnlyInt();
            BitVector2D stencil = new BitVector2D(bounds.Width, bounds.Height);

            for (int i = 0; i < scans.Length; ++i)
            {
                Rectangle rect = scans[i];
                rect.X -= bounds.X;
                rect.Y -= bounds.Y;

                stencil.SetUnchecked(rect, true);
            }

            PdnGraphicsPath path = PathFromStencil(stencil, new Rectangle(0, 0, stencil.Width, stencil.Height));

            using (Matrix matrix = new Matrix())
            {
                matrix.Reset();
                matrix.Translate(bounds.X, bounds.Y);
                path.Transform(matrix);
            }

            return(path);
        }
Exemple #2
0
        public PdnGraphicsPath CreatePath(bool applyInterimTransform)
        {
            lock (this.syncRoot)
            {
                PdnGraphicsPath returnPath = PdnGraphicsPath.Combine(this.data.basePath, this.data.continuationCombineMode, this.data.continuation);

                if (applyInterimTransform)
                {
                    returnPath.Transform(this.data.interimTransform);
                }

                return(returnPath);
            }
        }
        public static PdnGraphicsPath FromRegions(PdnRegion lhs, CombineMode combineMode, PdnRegion rhs)
        {
            Rectangle   lhsBounds = lhs.GetBoundsInt();
            Rectangle   rhsBounds = rhs.GetBoundsInt();
            int         left      = Math.Min(lhsBounds.Left, rhsBounds.Left);
            int         top       = Math.Min(lhsBounds.Top, rhsBounds.Top);
            int         right     = Math.Max(lhsBounds.Right, rhsBounds.Right);
            int         bottom    = Math.Max(lhsBounds.Bottom, rhsBounds.Bottom);
            Rectangle   bounds    = Rectangle.FromLTRB(left, top, right, bottom);
            BitVector2D stencil   = new BitVector2D(bounds.Width, bounds.Height);

            Rectangle[] lhsScans = lhs.GetRegionScansReadOnlyInt();
            Rectangle[] rhsScans = rhs.GetRegionScansReadOnlyInt();

            switch (combineMode)
            {
            case CombineMode.Complement:
            case CombineMode.Intersect:
            case CombineMode.Replace:
                throw new ArgumentException("combineMode can't be Complement, Intersect, or Replace");

            default:
                break;
            }

            for (int i = 0; i < lhsScans.Length; ++i)
            {
                Rectangle rect = lhsScans[i];
                rect.X -= bounds.X;
                rect.Y -= bounds.Y;

                stencil.SetUnchecked(rect, true);
            }

            for (int i = 0; i < rhsScans.Length; ++i)
            {
                Rectangle rect = rhsScans[i];
                rect.X -= bounds.X;
                rect.Y -= bounds.Y;

                switch (combineMode)
                {
                case CombineMode.Xor:
                    stencil.InvertUnchecked(rect);
                    break;

                case CombineMode.Union:
                    stencil.SetUnchecked(rect, true);
                    break;

                case CombineMode.Exclude:
                    stencil.SetUnchecked(rect, false);
                    break;
                }
            }

            PdnGraphicsPath path = PathFromStencil(stencil, new Rectangle(0, 0, stencil.Width, stencil.Height));

            using (Matrix matrix = new Matrix())
            {
                matrix.Reset();
                matrix.Translate(bounds.X, bounds.Y);
                path.Transform(matrix);
            }

            return(path);
        }
        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;
        }