示例#1
0
        /// <summary>
        /// Draws an area of the SurfaceBox.
        /// </summary>
        /// <param name="ra">The rendering surface object to draw to.</param>
        /// <param name="offset">The virtual offset of ra, in client (destination) coordinates.</param>
        /// <remarks>
        /// If drawing to ra.Surface or ra.Bitmap, copy the roi of the source surface to (0,0) of ra.Surface or ra.Bitmap
        /// If drawing to ra.Graphics, copy the roi of the surface to (roi.X, roi.Y) of ra.Graphics
        /// </remarks>
        private unsafe void DrawArea(RenderArgs ra, Point offset)
        {
            if (surface == null)
            {
                return;
            }

            if (renderContext == null || (renderContext.windows != null && renderContext.windows.Length != Processor.LogicalCpuCount))
            {
                renderContext              = new RenderContext();
                renderContext.owner        = this;
                renderContext.waitCallback = new WaitCallback(renderContext.RenderThreadMethod);
                renderContext.windows      = new Surface[Processor.LogicalCpuCount];
                renderContext.offsets      = new Point[Processor.LogicalCpuCount];
                renderContext.rects        = new Rectangle[Processor.LogicalCpuCount];
            }

            Utility.SplitRectangle(ra.Bounds, renderContext.rects);

            for (int i = 0; i < renderContext.rects.Length; ++i)
            {
                if (renderContext.rects[i].Width > 0 && renderContext.rects[i].Height > 0)
                {
                    renderContext.offsets[i] = new Point(renderContext.rects[i].X + offset.X, renderContext.rects[i].Y + offset.Y);
                    renderContext.windows[i] = ra.Surface.CreateWindow(renderContext.rects[i]);
                }
                else
                {
                    renderContext.windows[i] = null;
                }
            }

            for (int i = 0; i < renderContext.windows.Length; ++i)
            {
                if (renderContext.windows[i] != null)
                {
                    this.threadPool.QueueUserWorkItem(renderContext.waitCallback, BoxedConstants.GetInt32(i));
                }
            }

            this.threadPool.Drain();
        }
示例#2
0
        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;
        }