protected override Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface, int x, int y, int lastX, int lastY) { // Cairo does not support a single-pixel-long single-pixel-wide line if (x == lastX && y == lastY && g.LineWidth == 1 && PintaCore.Workspace.ActiveWorkspace.PointInCanvas(new PointD(x, y))) { surface.Flush(); ColorBgra source = surface.GetColorBgraUnchecked(x, y); source = UserBlendOps.NormalBlendOp.ApplyStatic(source, strokeColor.ToColorBgra()); surface.SetColorBgra(source.ToPremultipliedAlpha(), x, y); surface.MarkDirty(); return(new Gdk.Rectangle(x - 1, y - 1, 3, 3)); } g.MoveTo(lastX + 0.5, lastY + 0.5); g.LineTo(x + 0.5, y + 0.5); g.StrokePreserve(); Gdk.Rectangle dirty = g.FixedStrokeExtents().ToGdkRectangle(); // For some reason (?!) we need to inflate the dirty // rectangle for small brush widths in zoomed images dirty.Inflate(1, 1); return(dirty); }
public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { dest.Flush(); foreach (Gdk.Rectangle rect in rois) { time ^= System.Environment.TickCount; time = time * 17 + 7; Random rnd = new Random(time); for (int y = rect.Top; y <= rect.GetBottom(); y++) { ColorBgra *srcRowPtr = src.GetPointAddressUnchecked(rect.Left, y); ColorBgra *dstRowPtr = dest.GetPointAddressUnchecked(rect.Left, y); ColorBgra *dstRowEndPtr = dstRowPtr + rect.Width; while (dstRowPtr < dstRowEndPtr) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); col.A = (byte)(rnd.Next() & 255); *dstRowPtr = col.ToPremultipliedAlpha(); ++dstRowPtr; ++srcRowPtr; } } } }
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.GetRight(); int bottom = cell.GetBottom(); int top = cell.Top; ColorBgra colorTopLeft = src.GetColorBgraUnchecked(left, top).ToStraightAlpha(); ColorBgra colorTopRight = src.GetColorBgraUnchecked(right, top).ToStraightAlpha(); ColorBgra colorBottomLeft = src.GetColorBgraUnchecked(left, bottom).ToStraightAlpha(); ColorBgra colorBottomRight = src.GetColorBgraUnchecked(right, bottom).ToStraightAlpha(); ColorBgra c = ColorBgra.BlendColors4W16IP(colorTopLeft, 16384, colorTopRight, 16384, colorBottomLeft, 16384, colorBottomRight, 16384); return(c.ToPremultipliedAlpha()); }
public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { dest.Flush(); foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y <= rect.GetBottom(); y++) { ColorBgra *srcRowPtr = src.GetPointAddressUnchecked(rect.Left, y); ColorBgra *dstRowPtr = dest.GetPointAddressUnchecked(rect.Left, y); ColorBgra *dstRowEndPtr = dstRowPtr + rect.Width; while (dstRowPtr < dstRowEndPtr) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); col.A = (byte)(((int)(col.R + col.G + col.B)) / 3); *dstRowPtr = col.ToPremultipliedAlpha(); ++dstRowPtr; ++srcRowPtr; } } } }
public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y <= rect.GetBottom(); y++) { ColorBgra *srcRowPtr = src.GetPointAddressUnchecked(rect.Left, y); ColorBgra *dstRowPtr = dest.GetPointAddressUnchecked(rect.Left, y); ColorBgra *dstRowEndPtr = dstRowPtr + rect.Width; int dither = y & 1; while (dstRowPtr < dstRowEndPtr) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); dither++; int r = col.R, g = col.G, b = col.B;; if ((dither & 1) == 0) { r += 2; g += 2; b += 2; if (r > 255) { r = 255; } if (g > 255) { g = 255; } if (b > 255) { b = 255; } } else { r -= 2; g -= 2; b -= 2; if (r < 0) { r = 0; } if (g < 0) { g = 0; } if (b < 0) { b = 0; } } col.R = (byte)r; col.G = (byte)g; col.B = (byte)b; *dstRowPtr = col.ToPremultipliedAlpha(); ++dstRowPtr; ++srcRowPtr; } } } }
protected override unsafe Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface, int x, int y, int lastX, int lastY) { int rad = (int)(g.LineWidth / 2.0 + 0.5); if (rad < 2) { rad = 2; } Gdk.Rectangle surface_rect = new Gdk.Rectangle(0, 0, surface.Width, surface.Height); Gdk.Rectangle brush_rect = new Gdk.Rectangle(x - rad, y - rad, 2 * rad, 2 * rad); Gdk.Rectangle dest_rect = Gdk.Rectangle.Intersect(surface_rect, brush_rect); if ((dest_rect.Width > 1) && (dest_rect.Height > 1)) { //Allow Clipping through a temporary surface ImageSurface tmp_surface = new ImageSurface(Format.Argb32, dest_rect.Width, dest_rect.Height); using (Context g2 = new Context(tmp_surface)) { g2.Operator = Operator.Source; g2.SetSourceSurface(surface, -dest_rect.Left, -dest_rect.Top); g2.Rectangle(new Rectangle(0, 0, dest_rect.Width, dest_rect.Height)); g2.Fill(); } //Flush to make sure all drawing operations are finished tmp_surface.Flush(); ColorBgra[,] tmp = new ColorBgra[dest_rect.Width, dest_rect.Height]; for (int iy = 0; iy < dest_rect.Height; iy++) { ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy); for (int ix = 0; ix < dest_rect.Width; ix++) { tmp[ix, iy] = (*srcRowPtr).ToStraightAlpha(); srcRowPtr++; } } for (int iy = 1; iy < dest_rect.Height - 1; iy++) { ColorBgra *dstRowPtr = tmp_surface.GetPointAddressUnchecked(1, iy); int dy = dest_rect.Top + iy - y; for (int ix = 1; ix < dest_rect.Width - 1; ix++) { int dx = dest_rect.Left + ix - x; if ((dx * dx + dy * dy) < rad * rad) { ColorBgra col = ColorBgra.Black; col.R = (byte)((2 * tmp[ix, iy].R + tmp[ix - 1, iy].R + tmp[ix + 1, iy].R + tmp[ix, iy - 1].R + tmp[ix, iy + 1].R + 3) / 6); col.G = (byte)((2 * tmp[ix, iy].G + tmp[ix - 1, iy].G + tmp[ix + 1, iy].G + tmp[ix, iy - 1].G + tmp[ix, iy + 1].G + 3) / 6); col.B = (byte)((2 * tmp[ix, iy].B + tmp[ix - 1, iy].B + tmp[ix + 1, iy].B + tmp[ix, iy - 1].B + tmp[ix, iy + 1].B + 3) / 6); col.A = (byte)((2 * tmp[ix, iy].A + tmp[ix - 1, iy].A + tmp[ix + 1, iy].A + tmp[ix, iy - 1].A + tmp[ix, iy + 1].A + 3) / 6); *dstRowPtr = col.ToPremultipliedAlpha(); } dstRowPtr++; } } //Draw the final result on the surface g.Operator = Operator.Source; g.SetSourceSurface(tmp_surface, dest_rect.Left, dest_rect.Top); g.Rectangle(new Rectangle(dest_rect.Left, dest_rect.Top, dest_rect.Width, dest_rect.Height)); g.Fill(); } return(Gdk.Rectangle.Zero); }
protected override unsafe Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface, int x, int y, int lastX, int lastY) { int rad = (int)(g.LineWidth / 2.0) + 1; Gdk.Rectangle surface_rect = new Gdk.Rectangle(0, 0, surface.Width, surface.Height); Gdk.Rectangle brush_rect = new Gdk.Rectangle(x - rad, y - rad, 2 * rad, 2 * rad); Gdk.Rectangle dest_rect = Gdk.Rectangle.Intersect(surface_rect, brush_rect); //Initialize lookup table when first used (to prevent slower startup of the application) if (lut_factor == null) { lut_factor = new byte[LUT_Resolution + 1, LUT_Resolution + 1]; for (int dy = 0; dy < LUT_Resolution + 1; dy++) { for (int dx = 0; dx < LUT_Resolution + 1; dx++) { double d = Math.Sqrt(dx * dx + dy * dy) / LUT_Resolution; if (d > 1.0) { lut_factor [dx, dy] = 0; } else { lut_factor [dx, dy] = (byte)(Math.Cos(Math.Sqrt(d) * Math.PI / 2.0) * 255.0); } } } } if ((dest_rect.Width > 0) && (dest_rect.Height > 0)) { //Allow Clipping through a temporary surface ImageSurface tmp_surface = new ImageSurface(Format.Argb32, dest_rect.Width, dest_rect.Height); using (Context g2 = new Context(tmp_surface)) { g2.Operator = Operator.Source; g2.SetSourceSurface(surface, -dest_rect.Left, -dest_rect.Top); g2.Rectangle(new Rectangle(0, 0, dest_rect.Width, dest_rect.Height)); g2.Fill(); } //Flush to make sure all drawing operations are finished tmp_surface.Flush(); int mean_r = 0, mean_g = 0, mean_b = 0; int max_diff_r = 1, max_diff_g = 1, max_diff_b = 1; int sz = 0; byte[,] factors = new byte[dest_rect.Right - dest_rect.Left, dest_rect.Bottom - dest_rect.Top]; for (int iy = dest_rect.Top; iy < dest_rect.Bottom; iy++) { ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy - dest_rect.Top); for (int ix = dest_rect.Left; ix < dest_rect.Right; ix++) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); int dx = ((ix - x) * LUT_Resolution) / rad; if (dx < 0) { dx = -dx; } int dy = ((iy - y) * LUT_Resolution) / rad; if (dy < 0) { dy = -dy; } int factor = lut_factor[dx, dy]; sz += factor; mean_r += col.R * factor; mean_g += col.G * factor; mean_b += col.B * factor; srcRowPtr++; } } if (sz > 0) { mean_r /= sz; mean_g /= sz; mean_b /= sz; } for (int iy = dest_rect.Top; iy < dest_rect.Bottom; iy++) { ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy - dest_rect.Top); for (int ix = dest_rect.Left; ix < dest_rect.Right; ix++) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); int dr = col.R - mean_r; int dg = col.G - mean_g; int db = col.B - mean_b; if (dr < 0) { dr = -dr; } if (dg < 0) { dg = -dg; } if (db < 0) { db = -db; } if (dr > max_diff_r) { max_diff_r = dr; } if (dg > max_diff_g) { max_diff_g = dg; } if (db > max_diff_b) { max_diff_b = db; } srcRowPtr++; } } for (int iy = dest_rect.Top; iy < dest_rect.Bottom; iy++) { ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy - dest_rect.Top); int dy = ((iy - y) * LUT_Resolution) / rad; if (dy < 0) { dy = -dy; } for (int ix = dest_rect.Left; ix < dest_rect.Right; ix++) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); int dx = ((ix - x) * LUT_Resolution) / rad; if (dx < 0) { dx = -dx; } int dr = ((col.R - mean_r) * 2 * LUT_Resolution) / max_diff_r; int dg = ((col.G - mean_g) * 2 * LUT_Resolution) / max_diff_g; int db = ((col.B - mean_b) * 2 * LUT_Resolution) / max_diff_b; if (dr < 0) { dr = -dr; } if (dg < 0) { dg = -dg; } if (db < 0) { db = -db; } if (dr > LUT_Resolution) { dr = LUT_Resolution; } if (dg > LUT_Resolution) { dg = LUT_Resolution; } if (db > LUT_Resolution) { db = LUT_Resolution; } int factor; if ((max_diff_r > 32) || (max_diff_g > 32) || (max_diff_b > 32)) { factor = lut_factor[dx, dy] * lut_factor[dg, (dr + db) / 2]; col.A = (byte)((col.A * (0xFFFF - factor)) / 0xFFFF); } else { factor = lut_factor[dx, dy]; col.A = (byte)((col.A * (0xFF - factor)) / 0xFF); } *srcRowPtr = col.ToPremultipliedAlpha(); srcRowPtr++; } } //Draw the final result on the surface g.Operator = Operator.Source; g.SetSourceSurface(tmp_surface, dest_rect.Left, dest_rect.Top); g.Rectangle(new Rectangle(dest_rect.Left, dest_rect.Top, dest_rect.Width, dest_rect.Height)); g.Fill(); } return(Gdk.Rectangle.Zero); }
private void Draw(DrawingArea drawingarea1, Color tool_color, Cairo.PointD point, bool first_pixel) { int x = (int)point.X; int y = (int)point.Y; if (last_point.Equals(point_empty)) { last_point = new Point(x, y); if (!first_pixel) { return; } } Document doc = PintaCore.Workspace.ActiveDocument; if (doc.Workspace.PointInCanvas(point)) { surface_modified = true; } ImageSurface surf = doc.CurrentUserLayer.Surface; if (first_pixel && doc.Workspace.PointInCanvas(point)) { // Does Cairo really not support a single-pixel-long single-pixel-wide line? surf.Flush(); int shiftedX = (int)point.X; int shiftedY = (int)point.Y; ColorBgra source = surf.GetColorBgraUnchecked(shiftedX, shiftedY); if (UseAlphaBlending) { source = UserBlendOps.NormalBlendOp.ApplyStatic(source, tool_color.ToColorBgra()); } else { source = tool_color.ToColorBgra(); } surf.SetColorBgra(source.ToPremultipliedAlpha(), shiftedX, shiftedY); surf.MarkDirty(); } else { using (Context g = new Context(surf)) { g.AppendPath(doc.Selection.SelectionPath); g.FillRule = FillRule.EvenOdd; g.Clip(); g.Antialias = Antialias.None; // Adding 0.5 forces cairo into the correct square: // See https://bugs.launchpad.net/bugs/672232 g.MoveTo(last_point.X + 0.5, last_point.Y + 0.5); g.LineTo(x + 0.5, y + 0.5); g.SetSourceColor(tool_color); if (UseAlphaBlending) { g.SetBlendMode(BlendMode.Normal); } else { g.Operator = Operator.Source; } g.LineWidth = 1; g.LineCap = LineCap.Square; g.Stroke(); } } Gdk.Rectangle r = GetRectangleFromPoints(last_point, new Point(x, y)); doc.Workspace.Invalidate(doc.ClampToImageSize(r)); last_point = new Point(x, y); }
protected override unsafe Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface, int x, int y, int lastX, int lastY) { int rad = (int)(g.LineWidth / 2.0) + 1; int stroke_a = (int)(255.0 * strokeColor.A); int stroke_r = (int)(255.0 * strokeColor.R); int stroke_g = (int)(255.0 * strokeColor.G); int stroke_b = (int)(255.0 * strokeColor.B); int stroke_cb = (-173 * stroke_r - 339 * stroke_g + 512 * stroke_b) >> 9; int stroke_cr = (512 * stroke_r - 429 * stroke_g - 83 * stroke_b) >> 9; Gdk.Rectangle surface_rect = new Gdk.Rectangle(0, 0, surface.Width, surface.Height); Gdk.Rectangle brush_rect = new Gdk.Rectangle(x - rad, y - rad, 2 * rad, 2 * rad); Gdk.Rectangle dest_rect = Gdk.Rectangle.Intersect(surface_rect, brush_rect); //Initialize lookup table when first used (to prevent slower startup of the application) if (lut_factor == null) { lut_factor = new byte[LUT_Resolution + 1, LUT_Resolution + 1]; for (int dy = 0; dy < LUT_Resolution + 1; dy++) { for (int dx = 0; dx < LUT_Resolution + 1; dx++) { double d = Math.Sqrt(dx * dx + dy * dy) / LUT_Resolution; if (d > 1.0) { lut_factor [dx, dy] = 0; } else { lut_factor [dx, dy] = (byte)(Math.Cos(Math.Sqrt(d) * Math.PI / 2.0) * 255); } } } } if ((dest_rect.Width > 0) && (dest_rect.Height > 0)) { //Allow Clipping through a temporary surface ImageSurface tmp_surface = new ImageSurface(Format.Argb32, dest_rect.Width, dest_rect.Height); using (Context g2 = new Context(tmp_surface)) { g2.Operator = Operator.Source; g2.SetSourceSurface(surface, -dest_rect.Left, -dest_rect.Top); g2.Rectangle(new Rectangle(0, 0, dest_rect.Width, dest_rect.Height)); g2.Fill(); } //Flush to make sure all drawing operations are finished tmp_surface.Flush(); for (int iy = dest_rect.Top; iy < dest_rect.Bottom; iy++) { ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy - dest_rect.Top); int dy = ((iy - y) * LUT_Resolution) / rad; if (dy < 0) { dy = -dy; } for (int ix = dest_rect.Left; ix < dest_rect.Right; ix++) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); int dx = ((ix - x) * LUT_Resolution) / rad; if (dx < 0) { dx = -dx; } int force = (lut_factor[dx, dy] * stroke_a); int col_y = (306 * col.R + 601 * col.G + 117 * col.B + 256) >> 9; int red = (256 * col_y + 359 * stroke_cr + 256) >> 9; int green = (256 * col_y - 88 * stroke_cb - 183 * stroke_cr + 256) >> 9; int blue = (256 * col_y + 454 * stroke_cb + 256) >> 9; if (red > 255) { red = 255; } if (red < 0) { red = 0; } if (green > 255) { green = 255; } if (green < 0) { green = 0; } if (blue > 255) { blue = 255; } if (blue < 0) { blue = 0; } col.R = (byte)((col.R * (255 * 255 - force) + red * force + 32512) / (255 * 255)); col.G = (byte)((col.G * (255 * 255 - force) + green * force + 32512) / (255 * 255)); col.B = (byte)((col.B * (255 * 255 - force) + blue * force + 32512) / (255 * 255)); *srcRowPtr = col.ToPremultipliedAlpha(); srcRowPtr++; } } //Draw the final result on the surface g.Operator = Operator.Source; g.SetSourceSurface(tmp_surface, dest_rect.Left, dest_rect.Top); g.Rectangle(new Rectangle(dest_rect.Left, dest_rect.Top, dest_rect.Width, dest_rect.Height)); g.Fill(); } return(Gdk.Rectangle.Zero); }
protected override unsafe Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface, int x, int y, int lastX, int lastY) { int rad = (int)(g.LineWidth / 2.0 + 0.5); rad /= 2; rad *= 2; if (rad < 2) { rad = 2; } //Initialize lookup table when first used (to prevent slower startup of the application) if (lut_factor == null) { lut_factor = new byte[LUT_Resolution + 1, LUT_Resolution + 1]; for (int dy = 0; dy < LUT_Resolution + 1; dy++) { for (int dx = 0; dx < LUT_Resolution + 1; dx++) { double d = Math.Sqrt(dx * dx + dy * dy) / LUT_Resolution; if (d > 1.0) { lut_factor [dx, dy] = 0; } else { lut_factor [dx, dy] = (byte)(Math.Cos(Math.Sqrt(d) * Math.PI / 2.0) * 255.0); } } } } Gdk.Rectangle surface_rect = new Gdk.Rectangle(0, 0, surface.Width, surface.Height); Gdk.Rectangle brush_rect = new Gdk.Rectangle(x - rad, y - rad, 2 * rad, 2 * rad); Gdk.Rectangle dest_rect = Gdk.Rectangle.Intersect(surface_rect, brush_rect); if ((dest_rect.Width > 1) && (dest_rect.Height > 1)) { //Allow Clipping through a temporary surface ImageSurface tmp_surface = new ImageSurface(Format.Argb32, dest_rect.Width, dest_rect.Height); using (Context g2 = new Context(tmp_surface)) { g2.Operator = Operator.Source; g2.SetSourceSurface(surface, -dest_rect.Left, -dest_rect.Top); g2.Rectangle(new Rectangle(0, 0, dest_rect.Width, dest_rect.Height)); g2.Fill(); } //Flush to make sure all drawing operations are finished tmp_surface.Flush(); int[,] mean_r = new int[dest_rect.Width / 2 + 1, dest_rect.Height / 2 + 1]; int[,] mean_g = new int[dest_rect.Width / 2 + 1, dest_rect.Height / 2 + 1]; int[,] mean_b = new int[dest_rect.Width / 2 + 1, dest_rect.Height / 2 + 1]; int[,] mean_a = new int[dest_rect.Width / 2 + 1, dest_rect.Height / 2 + 1]; int[,] mean_c = new int[dest_rect.Width / 2 + 1, dest_rect.Height / 2 + 1]; for (int iy = 0; iy < dest_rect.Height / 2; iy++) { for (int ix = 0; ix < dest_rect.Width / 2; ix++) { mean_a[ix, iy] = 0; mean_r[ix, iy] = 0; mean_g[ix, iy] = 0; mean_b[ix, iy] = 0; mean_c[ix, iy] = 0; } } for (int iy = 0; iy < dest_rect.Height; iy++) { ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy); for (int ix = 0; ix < dest_rect.Width; ix++) { ColorBgra col = (*srcRowPtr).ToStraightAlpha(); int pos_x = ix >> 1, pos_y = iy >> 1; mean_r[pos_x, pos_y] += col.R; mean_g[pos_x, pos_y] += col.G; mean_b[pos_x, pos_y] += col.B; mean_a[pos_x, pos_y] += col.A; mean_c[pos_x, pos_y]++; srcRowPtr++; } } for (int iy = 0; iy < dest_rect.Height; iy++) { ColorBgra *dstRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy); int dy = ((iy + dest_rect.Top - y) * LUT_Resolution) / rad; if (dy < 0) { dy = -dy; } for (int ix = 0; ix < dest_rect.Width; ix++) { ColorBgra col = (*dstRowPtr).ToStraightAlpha(); int dx = ((ix + dest_rect.Left - x) * LUT_Resolution) / rad; if (dx < 0) { dx = -dx; } int factor = lut_factor[dx, dy]; int pos_x = ix >> 1, pos_y = iy >> 1; int count = mean_c[pos_x, pos_y]; int red = col.R + (col.R - mean_r[pos_x, pos_y] / count); int green = col.G + (col.G - mean_g[pos_x, pos_y] / count); int blue = col.B + (col.B - mean_b[pos_x, pos_y] / count); int alpha = col.A + (col.A - mean_a[pos_x, pos_y] / count); /* * int diff_red = (4*red - tmp[ix-1,iy].R - tmp[ix,iy-1].R - tmp[ix+1,iy].R - tmp[ix,iy+1].R)/4; * int diff_green = (4*green - tmp[ix-1,iy].G - tmp[ix,iy-1].G - tmp[ix+1,iy].G - tmp[ix,iy+1].G)/4; * int diff_blue = (4*blue - tmp[ix-1,iy].B - tmp[ix,iy-1].B - tmp[ix+1,iy].B - tmp[ix,iy+1].B)/4; * int diff_alpha = (4*alpha - tmp[ix-1,iy].A - tmp[ix,iy-1].A - tmp[ix+1,iy].A - tmp[ix,iy+1].A)/4; */ //red -= diff_red; //if ((red & 255) != 0) { //Negative or grater than 255 if (red > 255) { red = 255; } if (red < 0) { red = 0; } //} //green -= diff_green; //if ((green & 255) != 0) { //Negative or grater than 255 if (green > 255) { green = 255; } if (green < 0) { green = 0; } //} //blue -= diff_blue; //if ((blue & 255) != 0) { //Negative or grater than 255 if (blue > 255) { blue = 255; } if (blue < 0) { blue = 0; } //} //alpha -= diff_alpha; //if ((alpha & 255) != 0) { //Negative or grater than 255 if (alpha > 255) { alpha = 255; } if (alpha < 0) { alpha = 0; } col.R = (byte)((red * factor + col.R * (512 - factor)) >> 9); col.G = (byte)((green * factor + col.G * (512 - factor)) >> 9); col.B = (byte)((blue * factor + col.B * (512 - factor)) >> 9); col.A = (byte)((alpha * factor + col.A * (512 - factor)) >> 9); *dstRowPtr = col.ToPremultipliedAlpha(); dstRowPtr++; } } //Draw the final result on the surface g.Operator = Operator.Source; g.SetSourceSurface(tmp_surface, dest_rect.Left, dest_rect.Top); g.Rectangle(new Rectangle(dest_rect.Left, dest_rect.Top, dest_rect.Width, dest_rect.Height)); g.Fill(); } return(Gdk.Rectangle.Zero); }