/** * gdk_pixbuf_composite_color_simple: * @src: a #GdkPixbuf * @dest_width: the width of destination image * @dest_height: the height of destination image * @interp_type: the interpolation type for the transformation. * @overall_alpha: overall alpha for source image (0..255) * @check_size: the size of checks in the checkboard (must be a power of two) * @color1: the color of check at upper left * @color2: the color of the other check * * Creates a new #GdkPixbuf by scaling @src to @dest_width x * @dest_height and compositing the result with a checkboard of colors * @color1 and @color2. * * Return value: (transfer full): the new #GdkPixbuf, or %NULL if not enough memory could be * allocated for it. **/ GdkPixbuf * gdk_pixbuf_composite_color_simple (const GdkPixbuf *src, int dest_width, int dest_height, GdkInterpType interp_type, int overall_alpha, int check_size, guint32 color1, guint32 color2) { GdkPixbuf *dest; g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL); g_return_val_if_fail (dest_width > 0, NULL); g_return_val_if_fail (dest_height > 0, NULL); g_return_val_if_fail (overall_alpha >= 0 && overall_alpha <= 255, NULL); dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height); if (!dest) return NULL; gdk_pixbuf_composite_color (src, dest, 0, 0, dest_width, dest_height, 0, 0, (double) dest_width / src->width, (double) dest_height / src->height, interp_type, overall_alpha, 0, 0, check_size, color1, color2); return dest; }
gboolean expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) { GdkPixbuf *dest; gdk_window_set_back_pixmap (widget->window, NULL, FALSE); dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, event->area.width, event->area.height); gdk_pixbuf_composite_color (pixbuf, dest, 0, 0, event->area.width, event->area.height, -event->area.x, -event->area.y, (double) widget->allocation.width / gdk_pixbuf_get_width (pixbuf), (double) widget->allocation.height / gdk_pixbuf_get_height (pixbuf), interp_type, overall_alpha, event->area.x, event->area.y, 16, 0xaaaaaa, 0x555555); gdk_pixbuf_render_to_drawable (dest, widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, 0, event->area.x, event->area.y, event->area.width, event->area.height, GDK_RGB_DITHER_NORMAL, event->area.x, event->area.y); gdk_pixbuf_unref (dest); return TRUE; }
GdkPixbuf * file_utils_load_thumbnail (const gchar *filename) { GimpThumbnail *thumbnail = NULL; GdkPixbuf *pixbuf = NULL; gchar *uri; g_return_val_if_fail (filename != NULL, NULL); uri = g_filename_to_uri (filename, NULL, NULL); if (uri) { thumbnail = gimp_thumbnail_new (); gimp_thumbnail_set_uri (thumbnail, uri); pixbuf = gimp_thumbnail_load_thumb (thumbnail, GIMP_THUMBNAIL_SIZE_NORMAL, NULL); } g_free (uri); if (pixbuf) { gint width = gdk_pixbuf_get_width (pixbuf); gint height = gdk_pixbuf_get_height (pixbuf); if (gdk_pixbuf_get_n_channels (pixbuf) != 3) { GdkPixbuf *tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); gdk_pixbuf_composite_color (pixbuf, tmp, 0, 0, width, height, 0, 0, 1.0, 1.0, GDK_INTERP_NEAREST, 255, 0, 0, GIMP_CHECK_SIZE_SM, 0x66666666, 0x99999999); g_object_unref (pixbuf); pixbuf = tmp; } } return pixbuf; }
static void expose_func (GtkWidget *drawing_area, GdkEventExpose *event, gpointer data) { GdkPixbuf *pixbuf; pixbuf = (GdkPixbuf *)g_object_get_data (G_OBJECT (drawing_area), "pixbuf"); if (gdk_pixbuf_get_has_alpha (pixbuf)) { GdkPixbuf *dest; cairo_t *cr; gdk_window_set_back_pixmap (drawing_area->window, NULL, FALSE); dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, event->area.width, event->area.height); gdk_pixbuf_composite_color (pixbuf, dest, 0, 0, event->area.width, event->area.height, -event->area.x, -event->area.y, (double) drawing_area->allocation.width / gdk_pixbuf_get_width (pixbuf), (double) drawing_area->allocation.height / gdk_pixbuf_get_height (pixbuf), GDK_INTERP_BILINEAR, 255, event->area.x, event->area.y, 16, 0xaaaaaa, 0x555555); cr = gdk_cairo_create (drawing_area->window); gdk_cairo_set_source_pixbuf (cr, dest, 0, 0); gdk_cairo_rectangle (cr, &event->area); cairo_fill (cr); cairo_destroy (cr); g_object_unref (dest); } else { gdk_draw_rgb_image (drawing_area->window, drawing_area->style->white_gc, event->area.x, event->area.y, event->area.width, event->area.height, GDK_RGB_DITHER_NORMAL, gdk_pixbuf_get_pixels (pixbuf) + (event->area.y * gdk_pixbuf_get_rowstride (pixbuf)) + (event->area.x * gdk_pixbuf_get_n_channels (pixbuf)), gdk_pixbuf_get_rowstride (pixbuf)); } }
/* * The data that is passed to this function is either freed here or * owned by the returned pixbuf. */ static GdkPixbuf * gimp_pixbuf_from_data (guchar *data, gint width, gint height, gint bpp, GimpPixbufTransparency alpha) { GdkPixbuf *pixbuf; switch (bpp) { case 1: pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); { guchar *src = data; guchar *pixels = gdk_pixbuf_get_pixels (pixbuf); gint rowstride = gdk_pixbuf_get_rowstride (pixbuf); gint y; for (y = 0; y < height; y++) { guchar *dest = pixels; gint x; for (x = 0; x < width; x++, src += 1, dest += 3) { dest[0] = dest[1] = dest[2] = src[0]; } pixels += rowstride; } g_free (data); } bpp = 3; break; case 2: pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); { guchar *src = data; guchar *pixels = gdk_pixbuf_get_pixels (pixbuf); gint rowstride = gdk_pixbuf_get_rowstride (pixbuf); gint y; for (y = 0; y < height; y++) { guchar *dest = pixels; gint x; for (x = 0; x < width; x++, src += 2, dest += 4) { dest[0] = dest[1] = dest[2] = src[0]; dest[3] = src[1]; } pixels += rowstride; } g_free (data); } bpp = 4; break; case 3: pixbuf = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, FALSE, 8, width, height, width * bpp, (GdkPixbufDestroyNotify) g_free, NULL); break; case 4: pixbuf = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * bpp, (GdkPixbufDestroyNotify) g_free, NULL); break; default: g_return_val_if_reached (NULL); return NULL; } if (bpp == 4) { GdkPixbuf *tmp; gint check_size = 0; switch (alpha) { case GIMP_PIXBUF_KEEP_ALPHA: return pixbuf; case GIMP_PIXBUF_SMALL_CHECKS: check_size = GIMP_CHECK_SIZE_SM; break; case GIMP_PIXBUF_LARGE_CHECKS: check_size = GIMP_CHECK_SIZE; break; } tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); gdk_pixbuf_composite_color (pixbuf, tmp, 0, 0, width, height, 0, 0, 1.0, 1.0, GDK_INTERP_NEAREST, 255, 0, 0, check_size, 0x66666666, 0x99999999); g_object_unref (pixbuf); pixbuf = tmp; } return pixbuf; }
/* 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 }