Beispiel #1
0
 public void QueueDirtyRegion (Gdk.Rectangle region)
 {
     region.Intersect (Allocation);
     QueueDrawArea (region.X, region.Y, region.Width, region.Height);
 }
		public unsafe static void ExponentialBlur (this DockySurface self, int radius, Gdk.Rectangle area)
		{
			if (radius < 1)
				return;
			
			area.Intersect (new Gdk.Rectangle (0, 0, self.Width, self.Height));
			
			int alpha = (int) ((1 << AlphaPrecision) * (1.0 - Math.Exp (-2.3 / (radius + 1.0))));
			int height = self.Height;
			int width = self.Width;
			
			ImageSurface original;
			bool owned;
			if (self.Internal is ImageSurface) {
				original = self.Internal  as ImageSurface;
				owned = true;
			} else {
				original = new ImageSurface (Format.Argb32, width, height);
				owned = false;
			}
			
			if (!owned) {
				using (Cairo.Context cr = new Cairo.Context (original)) {
					cr.Operator = Operator.Source;
					cr.SetSource (self.Internal);
					cr.Paint ();
					(cr.Target as IDisposable).Dispose ();
				}
			}
			
			byte* pixels = (byte*) original.DataPtr;
			
			// Process Rows
			Thread th = new Thread ((ThreadStart) delegate {
				ExponentialBlurRows (pixels, width, height, 0, height / 2, area.X, area.Right, alpha);
			});
			th.Start ();
			
			ExponentialBlurRows (pixels, width, height, height / 2, height, area.X, area.Right, alpha);
			th.Join ();
			
			// Process Columns
			th = new Thread ((ThreadStart) delegate {
				ExponentialBlurColumns (pixels, width, height, 0, width / 2, area.Y, area.Bottom, alpha);
			});
			th.Start ();
			
			ExponentialBlurColumns (pixels, width, height, width / 2, width, area.Y, area.Bottom, alpha);
			th.Join ();
			
			original.MarkDirty ();
			
			if (!owned) {
				self.Context.Operator = Operator.Source;
				self.Context.SetSource (original);
				self.Context.Paint ();
				self.Context.Operator = Operator.Over;
				
				(original as IDisposable).Dispose ();
				original.Destroy ();
			}
		}