Пример #1
0
        /// <summary>
        /// Provides a default implementation for performing dst = F(dst, src) or F(src) over some rectangle
        /// of interest. May be slightly faster than calling the other multi-parameter Apply method, as less
        /// variables are used in the implementation, thus inducing less register pressure.
        /// </summary>
        /// <param name="dst">The Surface to write pixels to, and from which pixels are read and used as the lhs parameter for calling the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b>.</param>
        /// <param name="dstOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the dst Surface.</param>
        /// <param name="src">The Surface to read pixels from for the rhs parameter given to the method <b>ColorBgra Apply(ColorBgra, ColorBgra)</b>b>.</param></param>
        /// <param name="srcOffset">The pixel offset that defines the upper-left of the rectangle-of-interest for the src Surface.</param>
        /// <param name="roiSize">The size of the rectangles-of-interest for all Surfaces.</param>
        public void ApplyBase(ImageSurface dst, Gdk.Point dstOffset, ImageSurface src, Gdk.Point srcOffset, Gdk.Size roiSize)
        {
            // Create bounding rectangles for each Surface
            Gdk.Rectangle dstRect = new Gdk.Rectangle(dstOffset, roiSize);

            if (dstRect.Width == 0 || dstRect.Height == 0)
            {
                return;
            }

            Gdk.Rectangle srcRect = new Gdk.Rectangle(srcOffset, roiSize);

            if (srcRect.Width == 0 || srcRect.Height == 0)
            {
                return;
            }

            // Clip those rectangles to those Surface's bounding rectangles
            Gdk.Rectangle dstClip = Gdk.Rectangle.Intersect(dstRect, dst.GetBounds());
            Gdk.Rectangle srcClip = Gdk.Rectangle.Intersect(srcRect, src.GetBounds());

            // If any of those Rectangles actually got clipped, then throw an exception
            if (dstRect != dstClip)
            {
                throw new ArgumentOutOfRangeException
                      (
                          "roiSize",
                          "Destination roi out of bounds" +
                          string.Format(", dst.Size=({0},{1}", dst.Width, dst.Height) +
                          ", dst.Bounds=" + dst.GetBounds().ToString() +
                          ", dstOffset=" + dstOffset.ToString() +
                          string.Format(", src.Size=({0},{1}", src.Width, src.Height) +
                          ", srcOffset=" + srcOffset.ToString() +
                          ", roiSize=" + roiSize.ToString() +
                          ", dstRect=" + dstRect.ToString() +
                          ", dstClip=" + dstClip.ToString() +
                          ", srcRect=" + srcRect.ToString() +
                          ", srcClip=" + srcClip.ToString()
                      );
            }

            if (srcRect != srcClip)
            {
                throw new ArgumentOutOfRangeException("roiSize", "Source roi out of bounds");
            }

            // Cache the width and height properties
            int width  = roiSize.Width;
            int height = roiSize.Height;

            // Do the work.
            unsafe {
                for (int row = 0; row < height; ++row)
                {
                    ColorBgra *dstPtr = dst.GetPointAddress(dstOffset.X, dstOffset.Y + row);
                    ColorBgra *srcPtr = src.GetPointAddress(srcOffset.X, srcOffset.Y + row);
                    Apply(dstPtr, srcPtr, width);
                }
            }
        }
Пример #2
0
        public void Draw(ImageSurface dst)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("PlacedSurface");
            }

            using (Cairo.Context g = new Cairo.Context(dst)) {
                g.Save();

                Rectangle r = what.GetBounds().ToCairoRectangle();

                // We need to use the source operator to fully replace the old
                // data.  Or else we may paint transparent on top of it and
                // it will still be visible.  [Bug #670411]
                using (Path p = g.CreateRectanglePath(new Rectangle(where.X, where.Y, r.Width, r.Height))) {
                    g.AppendPath(p);
                    g.Clip();
                    g.Operator = Operator.Source;
                    g.DrawPixbuf(what.ToPixbuf(), new Cairo.Point(where.X, where.Y));
                }

                g.Restore();
            }
        }
Пример #3
0
        public void Apply(ImageSurface surface, Gdk.Rectangle[] roi, int startIndex, int length)
        {
            Gdk.Rectangle regionBounds = Utility.GetRegionBounds(roi, startIndex, length);

            if (regionBounds != Gdk.Rectangle.Intersect(surface.GetBounds(), regionBounds))
            {
                throw new ArgumentOutOfRangeException("roi", "Region is out of bounds");
            }

            unsafe {
                for (int x = startIndex; x < startIndex + length; ++x)
                {
                    ApplyRectangle(surface, roi[x]);
                }
            }
        }
Пример #4
0
        public void Draw(ImageSurface dst, PixelOp pixelOp)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("PlacedSurface");
            }

            Gdk.Rectangle dstRect = Bounds;
            Gdk.Rectangle dstClip = Gdk.Rectangle.Intersect(dstRect, dst.GetBounds());

            if (dstClip.Width > 0 && dstClip.Height > 0)
            {
                int dtX = dstClip.X - where.X;
                int dtY = dstClip.Y - where.Y;

                pixelOp.Apply(dst, dstClip.Location, what, new Gdk.Point(dtX, dtY), dstClip.Size);
            }
        }
Пример #5
0
        /// <summary>
        /// Gets the final pixel color for the given point, taking layers, opacity, and blend modes into account.
        /// </summary>
        public ColorBgra GetComputedPixel(int x, int y)
        {
            using (var dst = new ImageSurface(Format.Argb32, 1, 1)) {
                using (var g = new Context(dst)) {
                    foreach (var layer in GetLayersToPaint())
                    {
                        var color = layer.Surface.GetColorBgraUnchecked(x, y).ToCairoColor();

                        g.SetBlendMode(layer.BlendMode);
                        g.SetSourceColor(color);

                        g.Rectangle(dst.GetBounds().ToCairoRectangle());
                        g.PaintWithAlpha(layer.Opacity);
                    }
                }

                return(dst.GetPixel(0, 0).ToColorBgra());
            }
        }
Пример #6
0
        unsafe public override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            var cellSize = Data.CellSize;

            Gdk.Rectangle src_bounds  = src.GetBounds();
            Gdk.Rectangle dest_bounds = dest.GetBounds();

            foreach (var rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); ++y)
                {
                    int yEnd = y + 1;

                    for (int x = rect.Left; x <= rect.GetRight(); ++x)
                    {
                        var cellRect = GetCellBox(x, y, cellSize);
                        cellRect.Intersect(dest_bounds);
                        var color = ComputeCellColor(x, y, src, cellSize, src_bounds);

                        int xEnd = Math.Min(rect.GetRight(), cellRect.GetRight());
                        yEnd = Math.Min(rect.GetBottom(), cellRect.GetBottom());

                        for (int y2 = y; y2 <= yEnd; ++y2)
                        {
                            ColorBgra *ptr = dest.GetPointAddressUnchecked(x, y2);

                            for (int x2 = x; x2 <= xEnd; ++x2)
                            {
                                ptr->Bgra = color.Bgra;
                                ++ptr;
                            }
                        }

                        x = xEnd;
                    }

                    y = yEnd;
                }
            }
        }
Пример #7
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            if (Data.Amount == 0)
            {
                // Copy src to dest
                return;
            }

            int        src_width    = src.Width;
            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;
            int        dst_width    = dst.Width;
            ColorBgra *dst_data_ptr = (ColorBgra *)dst.DataPtr;

            Gdk.Rectangle src_bounds = src.GetBounds();

            long w   = dst.Width;
            long h   = dst.Height;
            long fox = (long)(dst.Width * Data.Offset.X * 32768.0);
            long foy = (long)(dst.Height * Data.Offset.Y * 32768.0);
            long fcx = fox + (w << 15);
            long fcy = foy + (h << 15);
            long fz  = Data.Amount;

            const int n = 64;

            foreach (Gdk.Rectangle rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(dst_data_ptr, dst_width, rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y);

                    for (int x = rect.Left; x <= rect.GetRight(); ++x)
                    {
                        long fx = (x << 16) - fcx;
                        long fy = (y << 16) - fcy;

                        int sr = 0;
                        int sg = 0;
                        int sb = 0;
                        int sa = 0;
                        int sc = 0;

                        sr += srcPtr->R * srcPtr->A;
                        sg += srcPtr->G * srcPtr->A;
                        sb += srcPtr->B * srcPtr->A;
                        sa += srcPtr->A;
                        ++sc;

                        for (int i = 0; i < n; ++i)
                        {
                            fx -= ((fx >> 4) * fz) >> 10;
                            fy -= ((fy >> 4) * fz) >> 10;

                            int u = (int)(fx + fcx + 32768 >> 16);
                            int v = (int)(fy + fcy + 32768 >> 16);

                            if (src_bounds.Contains(u, v))
                            {
                                ColorBgra *srcPtr2 = src.GetPointAddressUnchecked(src_data_ptr, src_width, u, v);

                                sr += srcPtr2->R * srcPtr2->A;
                                sg += srcPtr2->G * srcPtr2->A;
                                sb += srcPtr2->B * srcPtr2->A;
                                sa += srcPtr2->A;
                                ++sc;
                            }
                        }

                        if (sa != 0)
                        {
                            *dstPtr = ColorBgra.FromBgra(
                                Utility.ClampToByte(sb / sa),
                                Utility.ClampToByte(sg / sa),
                                Utility.ClampToByte(sr / sa),
                                Utility.ClampToByte(sa / sc));
                        }
                        else
                        {
                            dstPtr->Bgra = 0;
                        }

                        ++srcPtr;
                        ++dstPtr;
                    }
                }
            }
        }
Пример #8
0
        public unsafe void RenderColorDifferenceEffect(double[][] weights, ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            Gdk.Rectangle src_rect = src.GetBounds();

            // Cache these for a massive performance boost
            int        src_width    = src.Width;
            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;

            foreach (Gdk.Rectangle rect in rois)
            {
                // loop through each line of target rectangle
                for (int y = rect.Y; y < rect.Y + rect.Height; ++y)
                {
                    int fyStart = 0;
                    int fyEnd   = 3;

                    if (y == src_rect.Y)
                    {
                        fyStart = 1;
                    }
                    if (y == src_rect.Y + src_rect.Height - 1)
                    {
                        fyEnd = 2;
                    }

                    // loop through each point in the line
                    ColorBgra *dstPtr = dest.GetPointAddressUnchecked(rect.X, y);

                    for (int x = rect.X; x < rect.X + rect.Width; ++x)
                    {
                        int fxStart = 0;
                        int fxEnd   = 3;

                        if (x == src_rect.X)
                        {
                            fxStart = 1;
                        }

                        if (x == src_rect.X + src_rect.Width - 1)
                        {
                            fxEnd = 2;
                        }

                        // loop through each weight
                        double rSum = 0.0;
                        double gSum = 0.0;
                        double bSum = 0.0;

                        for (int fy = fyStart; fy < fyEnd; ++fy)
                        {
                            for (int fx = fxStart; fx < fxEnd; ++fx)
                            {
                                double    weight = weights[fy][fx];
                                ColorBgra c      = src.GetPointUnchecked(src_data_ptr, src_width, x - 1 + fx, y - 1 + fy);

                                rSum += weight * (double)c.R;
                                gSum += weight * (double)c.G;
                                bSum += weight * (double)c.B;
                            }
                        }

                        int iRsum = (int)rSum;
                        int iGsum = (int)gSum;
                        int iBsum = (int)bSum;

                        if (iRsum > 255)
                        {
                            iRsum = 255;
                        }

                        if (iGsum > 255)
                        {
                            iGsum = 255;
                        }

                        if (iBsum > 255)
                        {
                            iBsum = 255;
                        }

                        if (iRsum < 0)
                        {
                            iRsum = 0;
                        }

                        if (iGsum < 0)
                        {
                            iGsum = 0;
                        }

                        if (iBsum < 0)
                        {
                            iBsum = 0;
                        }

                        *dstPtr = ColorBgra.FromBgra((byte)iBsum, (byte)iGsum, (byte)iRsum, 255);
                        ++dstPtr;
                    }
                }
            }
        }