static void select_area_expose (GtkWidget *widget, GdkEventExpose *event) { GtkStyle *style = gtk_widget_get_style (widget); gdouble width = widget->allocation.width; gdouble height = widget->allocation.height; gdouble dx = 1.0 / width; gdouble dy = 1.0 / height; guchar *buf = g_alloca (3 * event->area.width * event->area.height); guchar *dest = buf; gdouble y; gint i, j; for (j = 0, y = event->area.y / height; j < event->area.height; j++, y += dy) { guchar *d = dest; gdouble r = calc (0, y, 0); gdouble g = calc (0, y, 120); gdouble b = calc (0, y, 240); gdouble dr = calc (dx, y, 0) - r; gdouble dg = calc (dx, y, 120) - g; gdouble db = calc (dx, y, 240) - b; r += event->area.x * dr; g += event->area.x * dg; b += event->area.x * db; for (i = 0; i < event->area.width; i++) { d[0] = CLAMP ((gint) r, 0, 255); d[1] = CLAMP ((gint) g, 0, 255); d[2] = CLAMP ((gint) b, 0, 255); r += dr; g += dg; b += db; d += 3; } dest += event->area.width * 3; } gdk_draw_rgb_image_dithalign (widget->window, style->fg_gc[widget->state], event->area.x, event->area.y, event->area.width, event->area.height, GDK_RGB_DITHER_MAX, buf, 3 * event->area.width, -event->area.x, -event->area.y); }
/** * gimp_canvas_draw_rgb: * @canvas: a #GimpCanvas widget * @style: one of the enumerated #GimpCanvasStyle's. * @x: X coordinate of the upper left corner. * @y: Y coordinate of the upper left corner. * @width: width of the rectangle to be drawn. * @height: height of the rectangle to be drawn. * @rgb_buf: pixel data for the image to be drawn. * @rowstride: the rowstride in @rgb_buf. * @xdith: x offset for dither alignment. * @ydith: y offset for dither alignment. * * Draws an RGB image on the canvas in the specified style. **/ void gimp_canvas_draw_rgb (GimpCanvas *canvas, GimpCanvasStyle style, gint x, gint y, gint width, gint height, guchar *rgb_buf, gint rowstride, gint xdith, gint ydith) { if (! gimp_canvas_ensure_style (canvas, style)) return; gdk_draw_rgb_image_dithalign (GTK_WIDGET (canvas)->window, canvas->gc[style], x, y, width, height, GDK_RGB_DITHER_MAX, rgb_buf, rowstride, xdith, ydith); }
/* Expose callback for the drawing area */ static gint expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) { guchar *pixels; int rowstride; rowstride = gdk_pixbuf_get_rowstride (frame); pixels = gdk_pixbuf_get_pixels (frame) + rowstride * event->area.y + event->area.x * 3; gdk_draw_rgb_image_dithalign (widget->window, widget->style->black_gc, event->area.x, event->area.y, event->area.width, event->area.height, GDK_RGB_DITHER_NORMAL, pixels, rowstride, event->area.x, event->area.y); return TRUE; }
static gboolean gimp_color_area_expose (GtkWidget *widget, GdkEventExpose *event) { GimpColorArea *area = GIMP_COLOR_AREA (widget); guchar *buf; if (! area->buf || ! GTK_WIDGET_DRAWABLE (widget)) return FALSE; if (area->needs_render) gimp_color_area_render (area); buf = area->buf + event->area.y * area->rowstride + event->area.x * 3; gdk_draw_rgb_image_dithalign (widget->window, widget->style->black_gc, event->area.x, event->area.y, event->area.width, event->area.height, GDK_RGB_DITHER_MAX, buf, area->rowstride, event->area.x, event->area.y); if (area->draw_border) gdk_draw_rectangle (widget->window, widget->style->fg_gc[widget->state], FALSE, 0, 0, area->width - 1, area->height - 1); return FALSE; }
/* Paints a rectangle of the dirty region */ static void paint_rectangle (ImageView *view, ArtIRect *rect, GdkInterpType interp_type) { ImageViewPrivate *priv; int scaled_width, scaled_height; int width, height; int xofs, yofs; ArtIRect r, d; GdkPixbuf *tmp; int check_size; guint32 check_1, check_2; priv = view->priv; compute_scaled_size (view, priv->zoomx, priv->zoomy, &scaled_width, &scaled_height); width = GTK_WIDGET (view)->allocation.width; height = GTK_WIDGET (view)->allocation.height; /* Compute image offsets with respect to the window */ if (scaled_width < width) xofs = (width - scaled_width) / 2; else xofs = -priv->xofs; if (scaled_height < height) yofs = (height - scaled_height) / 2; else yofs = -priv->yofs; /* Draw background if necessary, in four steps */ /* Top */ if (yofs > 0) { r.x0 = 0; r.y0 = 0; r.x1 = width; r.y1 = yofs; paint_background (view, &r, rect); } /* Left */ if (xofs > 0) { r.x0 = 0; r.y0 = yofs; r.x1 = xofs; r.y1 = yofs + scaled_height; paint_background (view, &r, rect); } /* Right */ if (xofs >= 0) { r.x0 = xofs + scaled_width; r.y0 = yofs; r.x1 = width; r.y1 = yofs + scaled_height; if (r.x0 < r.x1) paint_background (view, &r, rect); } /* Bottom */ if (yofs >= 0) { r.x0 = 0; r.y0 = yofs + scaled_height; r.x1 = width; r.y1 = height; if (r.y0 < r.y1) paint_background (view, &r, rect); } /* Draw the scaled image * * FIXME: this is not using the color correction tables! */ if (!priv->pixbuf) return; r.x0 = xofs; r.y0 = yofs; r.x1 = xofs + scaled_width; r.y1 = yofs + scaled_height; art_irect_intersect (&d, &r, rect); if (art_irect_empty (&d)) return; /* Short-circuit the fast case to avoid a memcpy() */ if (unity_zoom (priv) && gdk_pixbuf_get_colorspace (priv->pixbuf) == GDK_COLORSPACE_RGB && !gdk_pixbuf_get_has_alpha (priv->pixbuf) && gdk_pixbuf_get_bits_per_sample (priv->pixbuf) == 8) { guchar *pixels; int rowstride; rowstride = gdk_pixbuf_get_rowstride (priv->pixbuf); pixels = (gdk_pixbuf_get_pixels (priv->pixbuf) + (d.y0 - yofs) * rowstride + 3 * (d.x0 - xofs)); gdk_draw_rgb_image_dithalign (GTK_WIDGET (view)->window, GTK_WIDGET (view)->style->black_gc, d.x0, d.y0, d.x1 - d.x0, d.y1 - d.y0, priv->dither, pixels, rowstride, d.x0 - xofs, d.y0 - yofs); return; } /* For all other cases, create a temporary pixbuf */ #ifdef PACK_RGBA tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, d.x1 - d.x0, d.y1 - d.y0); #else tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, d.x1 - d.x0, d.y1 - d.y0); #endif if (!tmp) { g_message ("paint_rectangle(): Could not allocate temporary pixbuf of " "size (%d, %d); skipping", d.x1 - d.x0, d.y1 - d.y0); return; } /* Compute check parameters */ switch (priv->check_type) { case CHECK_TYPE_DARK: check_1 = CHECK_BLACK; check_2 = CHECK_DARK; break; case CHECK_TYPE_MIDTONE: check_1 = CHECK_DARK; check_2 = CHECK_LIGHT; break; case CHECK_TYPE_LIGHT: check_1 = CHECK_LIGHT; check_2 = CHECK_WHITE; break; case CHECK_TYPE_BLACK: check_1 = check_2 = CHECK_BLACK; break; case CHECK_TYPE_GRAY: check_1 = check_2 = CHECK_GRAY; break; case CHECK_TYPE_WHITE: check_1 = check_2 = CHECK_WHITE; break; default: g_assert_not_reached (); return; } switch (priv->check_size) { case CHECK_SIZE_SMALL: check_size = CHECK_SMALL; break; case CHECK_SIZE_MEDIUM: check_size = CHECK_MEDIUM; break; case CHECK_SIZE_LARGE: check_size = CHECK_LARGE; break; default: g_assert_not_reached (); return; } /* Draw! */ gdk_pixbuf_composite_color (priv->pixbuf, tmp, 0, 0, d.x1 - d.x0, d.y1 - d.y0, -(d.x0 - xofs), -(d.y0 - yofs), priv->zoomx, priv->zoomy, unity_zoom (priv) ? GDK_INTERP_NEAREST : interp_type, 255, d.x0 - xofs, d.y0 - yofs, check_size, check_1, check_2); #ifdef PACK_RGBA pack_pixbuf (tmp); #endif gdk_draw_rgb_image_dithalign (GTK_WIDGET (view)->window, GTK_WIDGET (view)->style->black_gc, d.x0, d.y0, d.x1 - d.x0, d.y1 - d.y0, priv->dither, gdk_pixbuf_get_pixels (tmp), gdk_pixbuf_get_rowstride (tmp), d.x0 - xofs, d.y0 - yofs); g_object_unref (tmp); #if 0 gdk_draw_line (GTK_WIDGET (view)->window, GTK_WIDGET (view)->style->black_gc, d.x0, d.y0, d.x1 - 1, d.y1 - 1); gdk_draw_line (GTK_WIDGET (view)->window, GTK_WIDGET (view)->style->black_gc, d.x1 - 1, d.y0, d.x0, d.y1 - 1); #endif }