예제 #1
0
        public static unsafe void FillStencilFromPoint <TBitVector2D>(IRenderer <ColorBgra> sampleSource, TBitVector2D stencilBuffer, PointInt32 startPt, byte tolerance, Func <bool> isCancellationRequestedFn, out RectInt32 bounds) where TBitVector2D : IBitVector2D
        {
            Validate.IsNotNull <IRenderer <ColorBgra> >(sampleSource, "sampleSource");
            int width  = sampleSource.Width;
            int height = sampleSource.Height;

            if ((width > stencilBuffer.Width) || (height > stencilBuffer.Height))
            {
                throw new ArgumentException();
            }
            if (!sampleSource.CheckPointValue <ColorBgra>(startPt))
            {
                bounds = RectInt32.Empty;
            }
            else
            {
                int num3 = sampleSource.Width;
                int num4 = sampleSource.Height;
                using (RendererRowCache <ColorBgra> cache = new RendererRowCache <ColorBgra>(sampleSource))
                {
                    int num5 = 0x7fffffff;
                    int num6 = 0x7fffffff;
                    int num7 = -2147483648;
                    int num8 = -2147483648;
                    Queue <PointInt32> queue = new Queue <PointInt32>(0x10);
                    queue.Enqueue(startPt);
                    cache.AddRowRef(startPt.Y - 1);
                    cache.AddRowRef(startPt.Y);
                    cache.AddRowRef(startPt.Y + 1);
                    ColorBgra start = *((ColorBgra *)(((void *)cache.GetRow(startPt.Y)) + (startPt.X * sizeof(ColorBgra))));
                    while (queue.Any <PointInt32>())
                    {
                        if (isCancellationRequestedFn())
                        {
                            bounds = RectInt32.Empty;
                            return;
                        }
                        PointInt32 pt = queue.Dequeue();
                        try
                        {
                            if (sampleSource.CheckPointValue <ColorBgra>(pt))
                            {
                                ColorBgra *row   = (ColorBgra *)cache.GetRow(pt.Y);
                                int        x     = pt.X - 1;
                                int        num11 = pt.X;
                                while (((x >= 0) && !stencilBuffer.Get(x, pt.Y)) && CheckColor(start, row[x], tolerance))
                                {
                                    stencilBuffer.Set(x, pt.Y, true);
                                    x--;
                                }
                                while (((num11 < num3) && !stencilBuffer.Get(num11, pt.Y)) && CheckColor(start, row[num11], tolerance))
                                {
                                    stencilBuffer.Set(num11, pt.Y, true);
                                    num11++;
                                }
                                x++;
                                num11--;
                                if (pt.Y > 0)
                                {
                                    cache.AddRowRef(pt.Y - 2);
                                    cache.AddRowRef(pt.Y - 1);
                                    cache.AddRowRef(pt.Y);
                                    try
                                    {
                                        ColorBgra *bgraPtr2 = (ColorBgra *)cache.GetRow(pt.Y - 1);
                                        int        num12    = x;
                                        int        num13    = x;
                                        for (int i = x; i <= num11; i++)
                                        {
                                            if (!stencilBuffer.Get(i, pt.Y - 1) && CheckColor(start, bgraPtr2[i], tolerance))
                                            {
                                                num13++;
                                            }
                                            else
                                            {
                                                if ((num13 - num12) > 0)
                                                {
                                                    queue.Enqueue(new PointInt32(num12, pt.Y - 1));
                                                    cache.AddRowRef(pt.Y - 2);
                                                    cache.AddRowRef(pt.Y - 1);
                                                    cache.AddRowRef(pt.Y);
                                                }
                                                num13++;
                                                num12 = num13;
                                            }
                                        }
                                        if ((num13 - num12) > 0)
                                        {
                                            queue.Enqueue(new PointInt32(num12, pt.Y - 1));
                                            cache.AddRowRef(pt.Y - 2);
                                            cache.AddRowRef(pt.Y - 1);
                                            cache.AddRowRef(pt.Y);
                                        }
                                    }
                                    finally
                                    {
                                        cache.ReleaseRowRef(pt.Y - 2);
                                        cache.ReleaseRowRef(pt.Y - 1);
                                        cache.ReleaseRowRef(pt.Y);
                                    }
                                }
                                if (pt.Y < (num4 - 1))
                                {
                                    cache.AddRowRef(pt.Y);
                                    cache.AddRowRef(pt.Y + 1);
                                    cache.AddRowRef(pt.Y + 2);
                                    try
                                    {
                                        ColorBgra *bgraPtr3 = (ColorBgra *)cache.GetRow(pt.Y + 1);
                                        int        num15    = x;
                                        int        num16    = x;
                                        for (int j = x; j <= num11; j++)
                                        {
                                            if (!stencilBuffer.Get(j, pt.Y + 1) && CheckColor(start, bgraPtr3[j], tolerance))
                                            {
                                                num16++;
                                            }
                                            else
                                            {
                                                if ((num16 - num15) > 0)
                                                {
                                                    queue.Enqueue(new PointInt32(num15, pt.Y + 1));
                                                    cache.AddRowRef(pt.Y);
                                                    cache.AddRowRef(pt.Y + 1);
                                                    cache.AddRowRef(pt.Y + 2);
                                                }
                                                num16++;
                                                num15 = num16;
                                            }
                                        }
                                        if ((num16 - num15) > 0)
                                        {
                                            queue.Enqueue(new PointInt32(num15, pt.Y + 1));
                                            cache.AddRowRef(pt.Y);
                                            cache.AddRowRef(pt.Y + 1);
                                            cache.AddRowRef(pt.Y + 2);
                                        }
                                    }
                                    finally
                                    {
                                        cache.ReleaseRowRef(pt.Y);
                                        cache.ReleaseRowRef(pt.Y + 1);
                                        cache.ReleaseRowRef(pt.Y + 2);
                                    }
                                }
                                num5 = Math.Min(num5, x);
                                num6 = Math.Min(num6, pt.Y);
                                num7 = Math.Max(num7, num11);
                                num8 = Math.Max(num8, pt.Y);
                            }
                            continue;
                        }
                        finally
                        {
                            cache.ReleaseRowRef(pt.Y - 1);
                            cache.ReleaseRowRef(pt.Y);
                            cache.ReleaseRowRef(pt.Y + 1);
                        }
                    }
                    bounds = RectInt32.FromEdges(num5, num6, num7, num8);
                }
            }
        }