Esempio n. 1
0
        private unsafe void ApplyAndSwap(ImageSurface dst, bool swap)
        {
            dst.Flush();

            var       dest_width = dst.Width;
            var       dst_ptr    = (ColorBgra *)dst.DataPtr;
            var       mask_index = 0;
            ColorBgra swap_pixel;

            fixed(ColorBgra *fixed_ptr = pixels)
            {
                var pixel_ptr = fixed_ptr;

                dst_ptr += bounds.X + bounds.Y * dest_width;

                for (int y = bounds.Y; y <= bounds.GetBottom(); y++)
                {
                    for (int x = bounds.X; x <= bounds.GetRight(); x++)
                    {
                        if (bitmask[mask_index++])
                        {
                            if (swap)
                            {
                                swap_pixel = *dst_ptr;
                                *dst_ptr     = *pixel_ptr;
                                *pixel_ptr++ = swap_pixel;
                            }
                            else
                            {
                                *dst_ptr = *pixel_ptr++;
                            }
                        }

                        dst_ptr++;
                    }

                    dst_ptr += dest_width - bounds.Width;
                }
            }

            dst.MarkDirty();
        }
Esempio n. 2
0
        protected override unsafe void AddSurfaceRectangleToHistogram(ImageSurface surface, Gdk.Rectangle rect)
        {
            long[] histogramB = histogram[0];
            long[] histogramG = histogram[1];
            long[] histogramR = histogram[2];

            int rect_right = rect.GetRight();

            for (int y = rect.Y; y <= rect.GetBottom(); ++y)
            {
                ColorBgra *ptr = surface.GetPointAddressUnchecked(rect.X, y);
                for (int x = rect.X; x <= rect_right; ++x)
                {
                    ++histogramB[ptr->B];
                    ++histogramG[ptr->G];
                    ++histogramR[ptr->R];
                    ++ptr;
                }
            }
        }
Esempio n. 3
0
        protected unsafe override void OnMouseMove(object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point)
        {
            Document doc = PintaCore.Workspace.ActiveDocument;

            ColorBgra old_color;
            ColorBgra new_color;

            if (mouse_button == 1)
            {
                old_color = PintaCore.Palette.PrimaryColor.ToColorBgra();
                new_color = PintaCore.Palette.SecondaryColor.ToColorBgra();
            }
            else if (mouse_button == 3)
            {
                old_color = PintaCore.Palette.SecondaryColor.ToColorBgra();
                new_color = PintaCore.Palette.PrimaryColor.ToColorBgra();
            }
            else
            {
                last_point = point_empty;
                return;
            }

            int x = (int)point.X;
            int y = (int)point.Y;

            if (last_point.Equals(point_empty))
            {
                last_point = new Point(x, y);
            }

            if (doc.Workspace.PointInCanvas(point))
            {
                surface_modified = true;
            }

            ImageSurface surf      = doc.CurrentUserLayer.Surface;
            ImageSurface tmp_layer = doc.ToolLayer.Surface;

            Gdk.Rectangle roi = GetRectangleFromPoints(last_point, new Point(x, y));

            roi         = PintaCore.Workspace.ClampToImageSize(roi);
            myTolerance = (int)(Tolerance * 256);

            tmp_layer.Flush();

            ColorBgra *tmp_data_ptr  = (ColorBgra *)tmp_layer.DataPtr;
            int        tmp_width     = tmp_layer.Width;
            ColorBgra *surf_data_ptr = (ColorBgra *)surf.DataPtr;
            int        surf_width    = surf.Width;

            // The stencil lets us know if we've already checked this
            // pixel, providing a nice perf boost
            // Maybe this should be changed to a BitVector2DSurfaceAdapter?
            for (int i = roi.X; i <= roi.GetRight(); i++)
            {
                for (int j = roi.Y; j <= roi.GetBottom(); j++)
                {
                    if (stencil[i, j])
                    {
                        continue;
                    }

                    if (IsColorInTolerance(new_color, surf.GetColorBgraUnchecked(surf_data_ptr, surf_width, i, j)))
                    {
                        *tmp_layer.GetPointAddressUnchecked(tmp_data_ptr, tmp_width, i, j) = AdjustColorDifference(new_color, old_color, surf.GetColorBgraUnchecked(surf_data_ptr, surf_width, i, j));
                    }

                    stencil[i, j] = true;
                }
            }

            tmp_layer.MarkDirty();

            using (Context g = new Context(surf)) {
                g.AppendPath(doc.Selection.SelectionPath);
                g.FillRule = FillRule.EvenOdd;
                g.Clip();

                g.Antialias = UseAntialiasing ? Antialias.Subpixel : Antialias.None;

                g.MoveTo(last_point.X, last_point.Y);
                g.LineTo(x, y);

                g.LineWidth = BrushWidth;
                g.LineJoin  = LineJoin.Round;
                g.LineCap   = LineCap.Round;

                g.SetSource(tmp_layer);

                g.Stroke();
            }

            doc.Workspace.Invalidate(roi);

            last_point = new Point(x, y);
        }
Esempio n. 4
0
        private ColorBgra[] GetPixelsFromPoint(PointD point)
        {
            var doc = PintaCore.Workspace.ActiveDocument;
            var x = (int)point.X;
            var y = (int)point.Y;
            var size = SampleSize;
            var half = size / 2;

            // Short circuit for single pixel
            if (size == 1)
                return new ColorBgra[] { GetPixel (x, y) };

            // Find the pixels we need (clamp to the size of the image)
            var rect = new Gdk.Rectangle (x - half, y - half, size, size);
            rect.Intersect (new Gdk.Rectangle (Gdk.Point.Zero, doc.ImageSize));

            var pixels = new List<ColorBgra> ();

            for (int i = rect.Left; i <= rect.GetRight (); i++)
                for (int j = rect.Top; j <= rect.GetBottom (); j++)
                    pixels.Add (GetPixel (i, j));

            return pixels.ToArray ();
        }
Esempio n. 5
0
		public static unsafe SurfaceDiff Create (ImageSurface original, ImageSurface updated_surf, bool force = false)
		{
			if (original.Width != updated_surf.Width || original.Height != updated_surf.Height) {
				// If the surface changed size, only throw an error if the user forced the use of a diff.
				if (force) {
					throw new InvalidOperationException ("SurfaceDiff requires surfaces to be same size.");
				} else {
					return null;
				}
			}

			// Cache some pinvokes
			var orig_width = original.Width;
			var orig_height = original.Height;

#if DEBUG_DIFF
			Console.WriteLine ("Original surface size: {0}x{1}", orig_width, orig_height);
			System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
			timer.Start();
#endif

			// STEP 1 - Find the bounds of the changed pixels.
			var orig_ptr = (int*)original.DataPtr;
			var updated_ptr = (int*)updated_surf.DataPtr;

			DiffBounds diff_bounds = new DiffBounds (orig_width, orig_height);
			object diff_bounds_lock = new Object();

			// Split up the work among several threads, each of which processes one row at a time
			// and updates the bounds of the changed pixels it has seen so far. At the end, the
			// results from each thread are merged together to find the overall bounds of the changed
			// pixels.
			Parallel.For<DiffBounds>(0, orig_height, () => new DiffBounds (orig_width, orig_height),
                     		(row, loop, my_bounds) => {

					var offset = row * orig_width;
					var orig = orig_ptr + offset;
					var updated = updated_ptr + offset;
					bool change_in_row = false;

					for (int i = 0; i < orig_width; ++i) {
						if (*(orig++) != *(updated++)) {
							change_in_row = true;
							my_bounds.left = System.Math.Min(my_bounds.left, i);
							my_bounds.right = System.Math.Max(my_bounds.right, i);
						}				
					}

					if (change_in_row) {
						my_bounds.top = System.Math.Min(my_bounds.top, row);
						my_bounds.bottom = System.Math.Max(my_bounds.bottom, row);
					}

					return my_bounds;

			},	(my_bounds) => {
					lock (diff_bounds_lock) {
						diff_bounds.Merge (my_bounds);
					}
					return;
			});

			var bounds = new Gdk.Rectangle (diff_bounds.left, diff_bounds.top,
			                                diff_bounds.right - diff_bounds.left + 1,
			                                diff_bounds.bottom - diff_bounds.top + 1);

#if DEBUG_DIFF
			Console.WriteLine ("Truncated surface size: {0}x{1}", bounds.Width, bounds.Height);
#endif

			// STEP 2 - Create a bitarray of whether each pixel in the bounds has changed, and count
			// how many changed pixels we need to store.
			var bitmask = new BitArray (bounds.Width * bounds.Height);
			int index = 0;
			int num_changed = 0;

			int bottom = bounds.GetBottom ();
			int right = bounds.GetRight ();
			int bounds_x = bounds.X;
			int bounds_y = bounds.Y;

			for (int y = bounds_y; y <= bottom; ++y) {
				var offset = y * orig_width;
				var updated = updated_ptr + offset + bounds_x;
				var orig = orig_ptr + offset + bounds_x;

				for (int x = bounds_x; x <= right; ++x) {
					bool changed = *(orig++) != *(updated++);
					bitmask[index++] = changed;
					if (changed) {
						num_changed++;
					}
				}
			}			

			var savings = 100 - (float)num_changed / (float)(orig_width * orig_height) * 100;
#if DEBUG_DIFF
			Console.WriteLine ("Compressed bitmask: {0}/{1} = {2}%", num_changed, orig_height * orig_width, 100 - savings);
#endif

			if (!force && savings < MINIMUM_SAVINGS_PERCENT) {
#if DEBUG_DIFF
				Console.WriteLine ("Savings too small, returning null");
#endif
				return null;
			}

			// Store the old pixels.
			var pixels = new ColorBgra[num_changed];
			var new_ptr = (ColorBgra*)original.DataPtr;
			int mask_index = 0;

			fixed (ColorBgra* fixed_ptr = pixels) {
				var pixel_ptr = fixed_ptr;

				for (int y = bounds_y; y <= bottom; ++y) {
					var new_pixel_ptr = new_ptr + bounds_x + y * orig_width;

					for (int x = bounds_x; x <= right; ++x) {
						if (bitmask[mask_index++]) {
							*pixel_ptr++ = *new_pixel_ptr;
						}

						new_pixel_ptr++;
					}
				}
			}

#if DEBUG_DIFF
			timer.Stop();
			System.Console.WriteLine("SurfaceDiff time: " + timer.ElapsedMilliseconds);
#endif

			return new SurfaceDiff (bitmask, bounds, pixels);
		}
Esempio n. 6
0
        //same as RenderRect, except the histogram is alpha-weighted instead of keeping a separate alpha channel histogram.
        public unsafe void RenderRectWithAlpha(
            int rad,
            ImageSurface src,
            ImageSurface dst,
            Gdk.Rectangle rect)
        {
            int width  = src.Width;
            int height = src.Height;

            int *leadingEdgeX = stackalloc int[rad + 1];
            int  stride       = src.Stride / sizeof(ColorBgra);

            // approximately (rad + 0.5)^2
            int cutoff = ((rad * 2 + 1) * (rad * 2 + 1) + 2) / 4;

            for (int v = 0; v <= rad; ++v)
            {
                for (int u = 0; u <= rad; ++u)
                {
                    if (u * u + v * v <= cutoff)
                    {
                        leadingEdgeX[v] = u;
                    }
                }
            }

            const int hLength = 256;
            int *     hb      = stackalloc int[hLength];
            int *     hg      = stackalloc int[hLength];
            int *     hr      = stackalloc int[hLength];
            uint      hSize   = (uint)(sizeof(int) * hLength);

            for (int y = rect.Top; y <= rect.GetBottom(); y++)
            {
                SetToZero(hb, hSize);
                SetToZero(hg, hSize);
                SetToZero(hr, hSize);

                int area = 0;
                int sum  = 0;

                ColorBgra *ps = src.GetPointAddressUnchecked(rect.Left, y);
                ColorBgra *pd = dst.GetPointAddressUnchecked(rect.Left, y);

                // assert: v + y >= 0
                int top = -Math.Min(rad, y);

                // assert: v + y <= height - 1
                int bottom = Math.Min(rad, height - 1 - y);

                // assert: u + x >= 0
                int left = -Math.Min(rad, rect.Left);

                // assert: u + x <= width - 1
                int right = Math.Min(rad, width - 1 - rect.Left);

                for (int v = top; v <= bottom; ++v)
                {
                    ColorBgra *psamp = src.GetPointAddressUnchecked(rect.Left + left, y + v);

                    for (int u = left; u <= right; ++u)
                    {
                        byte w = psamp->A;
                        if ((u * u + v * v) <= cutoff)
                        {
                            ++area;
                            sum          += w;
                            hb[psamp->B] += w;
                            hg[psamp->G] += w;
                            hr[psamp->R] += w;
                        }

                        ++psamp;
                    }
                }

                for (int x = rect.Left; x <= rect.GetRight(); x++)
                {
                    *pd = ApplyWithAlpha(*ps, area, sum, hb, hg, hr);

                    // assert: u + x >= 0
                    left = -Math.Min(rad, x);

                    // assert: u + x <= width - 1
                    right = Math.Min(rad + 1, width - 1 - x);

                    // Subtract trailing edge top half
                    int v = -1;

                    while (v >= top)
                    {
                        int u = leadingEdgeX[-v];

                        if (-u >= left)
                        {
                            break;
                        }

                        --v;
                    }

                    while (v >= top)
                    {
                        int        u = leadingEdgeX[-v];
                        ColorBgra *p = unchecked (ps + (v * stride)) - u;
                        byte       w = p->A;

                        hb[p->B] -= w;
                        hg[p->G] -= w;
                        hr[p->R] -= w;
                        sum      -= w;
                        --area;

                        --v;
                    }

                    // add leading edge top half
                    v = -1;
                    while (v >= top)
                    {
                        int u = leadingEdgeX[-v];

                        if (u + 1 <= right)
                        {
                            break;
                        }

                        --v;
                    }

                    while (v >= top)
                    {
                        int        u = leadingEdgeX[-v];
                        ColorBgra *p = unchecked (ps + (v * stride)) + u + 1;
                        byte       w = p->A;

                        hb[p->B] += w;
                        hg[p->G] += w;
                        hr[p->R] += w;
                        sum      += w;
                        ++area;

                        --v;
                    }

                    // Subtract trailing edge bottom half
                    v = 0;

                    while (v <= bottom)
                    {
                        int u = leadingEdgeX[v];

                        if (-u >= left)
                        {
                            break;
                        }

                        ++v;
                    }

                    while (v <= bottom)
                    {
                        int        u = leadingEdgeX[v];
                        ColorBgra *p = ps + v * stride - u;
                        byte       w = p->A;

                        hb[p->B] -= w;
                        hg[p->G] -= w;
                        hr[p->R] -= w;
                        sum      -= w;
                        --area;

                        ++v;
                    }

                    // add leading edge bottom half
                    v = 0;

                    while (v <= bottom)
                    {
                        int u = leadingEdgeX[v];

                        if (u + 1 <= right)
                        {
                            break;
                        }

                        ++v;
                    }

                    while (v <= bottom)
                    {
                        int        u = leadingEdgeX[v];
                        ColorBgra *p = ps + v * stride + u + 1;
                        byte       w = p->A;

                        hb[p->B] += w;
                        hg[p->G] += w;
                        hr[p->R] += w;
                        sum      += w;
                        ++area;

                        ++v;
                    }

                    ++ps;
                    ++pd;
                }
            }
        }
Esempio n. 7
0
        public static unsafe SurfaceDiff Create(ImageSurface original, ImageSurface updated_surf, bool force = false)
        {
            if (original.Width != updated_surf.Width || original.Height != updated_surf.Height)
            {
                // If the surface changed size, only throw an error if the user forced the use of a diff.
                if (force)
                {
                    throw new InvalidOperationException("SurfaceDiff requires surfaces to be same size.");
                }
                else
                {
                    return(null);
                }
            }

            // Cache some pinvokes
            var orig_width  = original.Width;
            var orig_height = original.Height;

#if DEBUG_DIFF
            Console.WriteLine("Original surface size: {0}x{1}", orig_width, orig_height);
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();
#endif

            // STEP 1 - Find the bounds of the changed pixels.
            var orig_ptr    = (int *)original.DataPtr;
            var updated_ptr = (int *)updated_surf.DataPtr;

            DiffBounds diff_bounds      = new DiffBounds(orig_width, orig_height);
            object     diff_bounds_lock = new Object();

            // Split up the work among several threads, each of which processes one row at a time
            // and updates the bounds of the changed pixels it has seen so far. At the end, the
            // results from each thread are merged together to find the overall bounds of the changed
            // pixels.
            Parallel.For <DiffBounds>(0, orig_height, () => new DiffBounds(orig_width, orig_height),
                                      (row, loop, my_bounds) => {
                var offset         = row * orig_width;
                var orig           = orig_ptr + offset;
                var updated        = updated_ptr + offset;
                bool change_in_row = false;

                for (int i = 0; i < orig_width; ++i)
                {
                    if (*(orig++) != *(updated++))
                    {
                        change_in_row   = true;
                        my_bounds.left  = System.Math.Min(my_bounds.left, i);
                        my_bounds.right = System.Math.Max(my_bounds.right, i);
                    }
                }

                if (change_in_row)
                {
                    my_bounds.top    = System.Math.Min(my_bounds.top, row);
                    my_bounds.bottom = System.Math.Max(my_bounds.bottom, row);
                }

                return(my_bounds);
            }, (my_bounds) => {
                lock (diff_bounds_lock) {
                    diff_bounds.Merge(my_bounds);
                }
                return;
            });

            var bounds = new Gdk.Rectangle(diff_bounds.left, diff_bounds.top,
                                           diff_bounds.right - diff_bounds.left + 1,
                                           diff_bounds.bottom - diff_bounds.top + 1);

#if DEBUG_DIFF
            Console.WriteLine("Truncated surface size: {0}x{1}", bounds.Width, bounds.Height);
#endif

            // STEP 2 - Create a bitarray of whether each pixel in the bounds has changed, and count
            // how many changed pixels we need to store.
            var bitmask     = new BitArray(bounds.Width * bounds.Height);
            int index       = 0;
            int num_changed = 0;

            int bottom   = bounds.GetBottom();
            int right    = bounds.GetRight();
            int bounds_x = bounds.X;
            int bounds_y = bounds.Y;

            for (int y = bounds_y; y <= bottom; ++y)
            {
                var offset  = y * orig_width;
                var updated = updated_ptr + offset + bounds_x;
                var orig    = orig_ptr + offset + bounds_x;

                for (int x = bounds_x; x <= right; ++x)
                {
                    bool changed = *(orig++) != *(updated++);
                    bitmask[index++] = changed;
                    if (changed)
                    {
                        num_changed++;
                    }
                }
            }

            var savings = 100 - (float)num_changed / (float)(orig_width * orig_height) * 100;
#if DEBUG_DIFF
            Console.WriteLine("Compressed bitmask: {0}/{1} = {2}%", num_changed, orig_height * orig_width, 100 - savings);
#endif

            if (!force && savings < MINIMUM_SAVINGS_PERCENT)
            {
#if DEBUG_DIFF
                Console.WriteLine("Savings too small, returning null");
#endif
                return(null);
            }

            // Store the old pixels.
            var pixels     = new ColorBgra[num_changed];
            var new_ptr    = (ColorBgra *)original.DataPtr;
            int mask_index = 0;

            fixed(ColorBgra *fixed_ptr = pixels)
            {
                var pixel_ptr = fixed_ptr;

                for (int y = bounds_y; y <= bottom; ++y)
                {
                    var new_pixel_ptr = new_ptr + bounds_x + y * orig_width;

                    for (int x = bounds_x; x <= right; ++x)
                    {
                        if (bitmask[mask_index++])
                        {
                            *pixel_ptr++ = *new_pixel_ptr;
                        }

                        new_pixel_ptr++;
                    }
                }
            }

#if DEBUG_DIFF
            timer.Stop();
            System.Console.WriteLine("SurfaceDiff time: " + timer.ElapsedMilliseconds);
#endif

            return(new SurfaceDiff(bitmask, bounds, pixels));
        }
Esempio n. 8
0
        public static unsafe SurfaceDiff Create(ImageSurface original, ImageSurface updated, bool force = false)
        {
            if (original.Width != updated.Width || original.Height != updated.Height)
            {
                // If the surface changed size, only throw an error if the user forced the use of a diff.
                if (force)
                {
                    throw new InvalidOperationException("SurfaceDiff requires surfaces to be same size.");
                }
                else
                {
                    return(null);
                }
            }

            // Cache some pinvokes
            var orig_width  = original.Width;
            var orig_height = original.Height;

#if DEBUG_DIFF
            Console.WriteLine("Original surface size: {0}x{1}", orig_width, orig_height);
#endif

            // STEP 1 - Create a bitarray of whether each pixel is changed (true for changed)
            var bitmask = new BitArray(orig_width * orig_height);

            var hit_first_change = false;
            var first_change     = -1;
            var last_change      = -1;

            var orig_ptr    = (int *)original.DataPtr;
            var updated_ptr = (int *)updated.DataPtr;

            for (int i = 0; i < bitmask.Length; i++)
            {
                var changed = *(orig_ptr++) == *(updated_ptr++) ? false : true;
                bitmask.Set(i, changed);

                if (!hit_first_change)
                {
                    if (changed)
                    {
                        first_change     = i;
                        hit_first_change = true;
                    }
                }

                if (changed)
                {
                    last_change = i;
                }
            }

            // STEP 2 - Figure out the bounds of the changed pixels
            var first_row = first_change / orig_width;
            var last_row  = last_change / orig_width + 1;

            // We have to loop through the bitmask to find the first and last column
            first_change     = -1;
            last_change      = -1;
            hit_first_change = false;

            for (int x = 0; x < orig_width; x++)
            {
                for (int y = 0; y < orig_height; y++)
                {
                    var changed = bitmask[x + (y * orig_width)];

                    if (!hit_first_change)
                    {
                        if (changed)
                        {
                            first_change     = (x * orig_height) + y;
                            hit_first_change = true;
                        }
                    }

                    if (changed)
                    {
                        last_change = (x * orig_height) + y;
                    }
                }
            }

            var first_col = first_change / orig_height;
            var last_col  = last_change / orig_height + 1;

            var bounds = new Gdk.Rectangle(first_col, first_row, last_col - first_col, last_row - first_row);

#if DEBUG_DIFF
            Console.WriteLine("Truncated surface size: {0}x{1}", bounds.Width, bounds.Height);
#endif

            // If truncating doesn't save us at least x%, don't bother
            if (100 - (float)(bounds.Width * bounds.Height) / (float)(orig_width * orig_height) * 100 < MINIMUM_SAVINGS_PERCENT)
            {
                bounds = new Gdk.Rectangle(0, 0, orig_width, orig_height);

#if DEBUG_DIFF
                Console.WriteLine("Truncating not worth it, skipping.");
#endif
            }

            // STEP 3 - Truncate our bitarray to the bounding rectangle
            if (bounds.Width != orig_width || bounds.Height != orig_height)
            {
                var new_bitmask = new BitArray(bounds.Width * bounds.Height);

                int index = 0;

                for (int y = bounds.Y; y <= bounds.GetBottom(); y++)
                {
                    for (int x = bounds.X; x <= bounds.GetRight(); x++)
                    {
                        new_bitmask[index++] = bitmask[y * orig_width + x];
                    }
                }

                bitmask = new_bitmask;
            }


            // STEP 4 - Count how many changed pixels we need to store
            var length = 0;

            for (int i = 0; i < bitmask.Length; i++)
            {
                if (bitmask[i])
                {
                    length++;
                }
            }

            var savings = 100 - (float)length / (float)(orig_width * orig_height) * 100;
#if DEBUG_DIFF
            Console.WriteLine("Compressed bitmask: {0}/{1} = {2}%", length, orig_height * orig_width, 100 - savings);
#endif

            if (!force && savings < MINIMUM_SAVINGS_PERCENT)
            {
#if DEBUG_DIFF
                Console.WriteLine("Savings too small, returning null");
#endif
                return(null);
            }

            // Store the old pixels
            var pixels  = new ColorBgra[length];
            var new_ptr = (ColorBgra *)original.DataPtr;

            var mask_index = 0;

            fixed(ColorBgra *fixed_ptr = pixels)
            {
                var pixel_ptr = fixed_ptr;

                new_ptr += bounds.X + bounds.Y * orig_width;

                for (int y = bounds.Y; y <= bounds.GetBottom(); y++)
                {
                    for (int x = bounds.X; x <= bounds.GetRight(); x++)
                    {
                        if (bitmask[mask_index++])
                        {
                            *pixel_ptr++ = *new_ptr;
                        }

                        new_ptr++;
                    }

                    new_ptr += orig_width - bounds.Width;
                }
            }

            return(new SurfaceDiff(bitmask, bounds, pixels));
        }
Esempio n. 9
0
 /// <summary>
 /// There was a bug in gdk-sharp where this returns incorrect values.
 /// We will probably have to use this for a long time until every distro
 /// has an updated gdk.
 /// </summary>
 public static bool ContainsCorrect(this Gdk.Rectangle r, int x, int y)
 {
     return((((x >= r.Left) && (x <= r.GetRight())) && (y >= r.Top)) && (y <= r.GetBottom()));
 }