예제 #1
0
        public static unsafe void FillStencilFromPoint(ImageSurface surface, IBitVector2D stencil, Point start, int tolerance, 
		                                                out Rectangle boundingBox, Gdk.Region limitRegion, bool limitToSelection)
        {
            ColorBgra cmp = surface.GetColorBgra (start.X, start.Y);
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;
            Gdk.Rectangle[] scans;

            stencil.Clear (false);

            if (limitToSelection) {
                using (Gdk.Region excluded = Gdk.Region.Rectangle (new Gdk.Rectangle (0, 0, stencil.Width, stencil.Height))) {
                    excluded.Xor (limitRegion);
                    scans = excluded.GetRectangles ();
                }
            } else {
                scans = new Gdk.Rectangle[0];
            }

            foreach (Gdk.Rectangle rect in scans) {
                stencil.Set (rect, true);
            }

            Queue<Point> queue = new Queue<Point> (16);
            queue.Enqueue (start);

            while (queue.Count > 0) {
                Point pt = queue.Dequeue ();

                ColorBgra* rowPtr = surface.GetRowAddressUnchecked (pt.Y);
                int localLeft = pt.X - 1;
                int localRight = pt.X;

                while (localLeft >= 0 &&
                       !stencil.GetUnchecked (localLeft, pt.Y) &&
                       CheckColor (cmp, rowPtr[localLeft], tolerance)) {
                    stencil.SetUnchecked (localLeft, pt.Y, true);
                    --localLeft;
                }

                while (localRight < surface.Width &&
                       !stencil.GetUnchecked (localRight, pt.Y) &&
                       CheckColor (cmp, rowPtr[localRight], tolerance)) {
                    stencil.SetUnchecked (localRight, pt.Y, true);
                    ++localRight;
                }

                ++localLeft;
                --localRight;

                if (pt.Y > 0) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrUp = surface.GetRowAddressUnchecked (pt.Y - 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y - 1) &&
                            CheckColor (cmp, rowPtrUp[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y - 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y - 1));
                    }
                }

                if (pt.Y < surface.Height - 1) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrDown = surface.GetRowAddressUnchecked (pt.Y + 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y + 1) &&
                            CheckColor (cmp, rowPtrDown[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y + 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y + 1));
                    }
                }

                if (localLeft < left) {
                    left = localLeft;
                }

                if (localRight > right) {
                    right = localRight;
                }

                if (pt.Y < top) {
                    top = pt.Y;
                }

                if (pt.Y > bottom) {
                    bottom = pt.Y;
                }
            }

            foreach (Gdk.Rectangle rect in scans)
                stencil.Set (rect, false);

            boundingBox = new Rectangle (left, top, right - left + 1, bottom - top + 1);
        }
예제 #2
0
        private ColorBgra ComputeCellColor(int x, int y, ImageSurface src, int cellSize, Gdk.Rectangle srcBounds)
        {
            Gdk.Rectangle cell = GetCellBox (x, y, cellSize);
            cell.Intersect (srcBounds);

            int left = cell.Left;
            int right = cell.Right - 1;
            int bottom = cell.Bottom - 1;
            int top = cell.Top;

            ColorBgra colorTopLeft = src.GetColorBgra (left, top);
            ColorBgra colorTopRight = src.GetColorBgra (right, top);
            ColorBgra colorBottomLeft = src.GetColorBgra (left, bottom);
            ColorBgra colorBottomRight = src.GetColorBgra (right, bottom);

            ColorBgra c = ColorBgra.BlendColors4W16IP (colorTopLeft, 16384, colorTopRight, 16384, colorBottomLeft, 16384, colorBottomRight, 16384);

            return c;
        }
예제 #3
0
파일: FloodTool.cs 프로젝트: deckarep/Pinta
        public static unsafe void FillStencilFromPoint(ImageSurface surface, IBitVector2D stencil, Point start, int tolerance, out Rectangle boundingBox)
        {
            ColorBgra cmp = surface.GetColorBgra (start.X, start.Y);
            int top = int.MaxValue;
            int bottom = int.MinValue;
            int left = int.MaxValue;
            int right = int.MinValue;

            stencil.Clear (false);

            Queue<Point> queue = new Queue<Point> (16);
            queue.Enqueue (start);

            while (queue.Count > 0) {
                Point pt = queue.Dequeue ();

                ColorBgra* rowPtr = surface.GetRowAddressUnchecked (pt.Y);
                int localLeft = pt.X - 1;
                int localRight = pt.X;

                while (localLeft >= 0 &&
                       !stencil.GetUnchecked (localLeft, pt.Y) &&
                       CheckColor (cmp, rowPtr[localLeft], tolerance)) {
                    stencil.SetUnchecked (localLeft, pt.Y, true);
                    --localLeft;
                }

                while (localRight < surface.Width &&
                       !stencil.GetUnchecked (localRight, pt.Y) &&
                       CheckColor (cmp, rowPtr[localRight], tolerance)) {
                    stencil.SetUnchecked (localRight, pt.Y, true);
                    ++localRight;
                }

                ++localLeft;
                --localRight;

                if (pt.Y > 0) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrUp = surface.GetRowAddressUnchecked (pt.Y - 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y - 1) &&
                            CheckColor (cmp, rowPtrUp[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y - 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y - 1));
                    }
                }

                if (pt.Y < surface.Height - 1) {
                    int sleft = localLeft;
                    int sright = localLeft;
                    ColorBgra* rowPtrDown = surface.GetRowAddressUnchecked (pt.Y + 1);

                    for (int sx = localLeft; sx <= localRight; ++sx) {
                        if (!stencil.GetUnchecked (sx, pt.Y + 1) &&
                            CheckColor (cmp, rowPtrDown[sx], tolerance)) {
                            ++sright;
                        } else {
                            if (sright - sleft > 0) {
                                queue.Enqueue (new Point (sleft, pt.Y + 1));
                            }

                            ++sright;
                            sleft = sright;
                        }
                    }

                    if (sright - sleft > 0) {
                        queue.Enqueue (new Point (sleft, pt.Y + 1));
                    }
                }

                if (localLeft < left) {
                    left = localLeft;
                }

                if (localRight > right) {
                    right = localRight;
                }

                if (pt.Y < top) {
                    top = pt.Y;
                }

                if (pt.Y > bottom) {
                    bottom = pt.Y;
                }
            }

            boundingBox = new Rectangle (left, top, right + 1, bottom + 1);
        }
예제 #4
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            ColorBgra colPrimary = PintaCore.Palette.PrimaryColor.ToColorBgra ();
            ColorBgra colSecondary = PintaCore.Palette.SecondaryColor.ToColorBgra ();
            ColorBgra colTransparent = ColorBgra.Transparent;

            int aaSampleCount = Data.Quality * Data.Quality;
            Cairo.PointD* aaPoints = stackalloc Cairo.PointD[aaSampleCount];
            Utility.GetRgssOffsets (aaPoints, aaSampleCount, Data.Quality);
            ColorBgra* samples = stackalloc ColorBgra[aaSampleCount];

            TransformData td;

            foreach (Gdk.Rectangle rect in rois) {

                for (int y = rect.Top; y < rect.Bottom; y++) {
                    ColorBgra* dstPtr = dst.GetPointAddressUnchecked (rect.Left, y);

                    double relativeY = y - Data.CenterOffset.Y;

                    for (int x = rect.Left; x < rect.Right; x++) {
                        double relativeX = x - Data.CenterOffset.X;

                        int sampleCount = 0;

                        for (int p = 0; p < aaSampleCount; ++p) {
                            td.X = relativeX + aaPoints[p].X;
                            td.Y = relativeY - aaPoints[p].Y;

                            InverseTransform (ref td);

                            float sampleX = (float)(td.X + Data.CenterOffset.X);
                            float sampleY = (float)(td.Y + Data.CenterOffset.Y);

                            ColorBgra sample = colPrimary;

                            if (IsOnSurface (src, sampleX, sampleY)) {
                                sample = src.GetBilinearSample (sampleX, sampleY);
                            } else {
                                switch (Data.EdgeBehavior) {
                                case WarpEdgeBehavior.Clamp:
                                    sample = src.GetBilinearSampleClamped (sampleX, sampleY);
                                    break;

                                case WarpEdgeBehavior.Wrap:
                                    sample = src.GetBilinearSampleWrapped (sampleX, sampleY);
                                    break;

                                case WarpEdgeBehavior.Reflect:
                                    sample = src.GetBilinearSampleClamped (ReflectCoord (sampleX, src.Width), ReflectCoord (sampleY, src.Height));

                                    break;

                                case WarpEdgeBehavior.Primary:
                                    sample = colPrimary;
                                    break;

                                case WarpEdgeBehavior.Secondary:
                                    sample = colSecondary;
                                    break;

                                case WarpEdgeBehavior.Transparent:
                                    sample = colTransparent;
                                    break;

                                case WarpEdgeBehavior.Original:
                                    sample = src.GetColorBgra (x, y);
                                    break;
                                default:

                                    break;
                                }
                            }

                            samples[sampleCount] = sample;
                            ++sampleCount;
                        }

                        *dstPtr = ColorBgra.Blend (samples, sampleCount);
                        ++dstPtr;
                    }
                }
            }
        }