예제 #1
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;
                    }
                }
            }
        }
예제 #2
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            PointD start = new PointD (0, 0);
            double theta = ((double)(Data.Angle + 180) * 2 * Math.PI) / 360.0;
            double alpha = (double)Data.Distance;
            PointD end = new PointD ((float)alpha * Math.Cos (theta), (float)(-alpha * Math.Sin (theta)));

            if (Data.Centered) {
                start.X = -end.X / 2.0f;
                start.Y = -end.Y / 2.0f;

                end.X /= 2.0f;
                end.Y /= 2.0f;
            }

            PointD[] points = new PointD[((1 + Data.Distance) * 3) / 2];

            if (points.Length == 1) {
                points[0] = new PointD (0, 0);
            } else {
                for (int i = 0; i < points.Length; ++i) {
                    float frac = (float)i / (float)(points.Length - 1);
                    points[i] = Utility.Lerp (start, end, frac);
                }
            }

            ColorBgra* samples = stackalloc ColorBgra[points.Length];

            ColorBgra* src_dataptr = (ColorBgra*)src.DataPtr;
            int src_width = src.Width;
            int src_height = src.Height;

            foreach (Gdk.Rectangle rect in rois) {

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

                    for (int x = rect.Left; x <= rect.GetRight (); ++x) {
                        int sampleCount = 0;

                        PointD a = new PointD ((float)x + points[0].X, (float)y + points[0].Y);
                        PointD b = new PointD ((float)x + points[points.Length - 1].X, (float)y + points[points.Length - 1].Y);

                        for (int j = 0; j < points.Length; ++j) {
                            PointD pt = new PointD (points[j].X + (float)x, points[j].Y + (float)y);

                            if (pt.X >= 0 && pt.Y >= 0 && pt.X <= (src_width - 1) && pt.Y <= (src_height - 1)) {
                                samples[sampleCount] = src.GetBilinearSample (src_dataptr, src_width, src_height, (float)pt.X, (float)pt.Y);
                                ++sampleCount;
                            }
                        }

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