📄 pixbuf-render.c
字号:
tmp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, rect.width, rect.height); gdk_pixbuf_scale (partial_src, tmp_pixbuf, 0, 0, rect.width, rect.height, dest_x - rect.x, dest_y - rect.y, x_scale, y_scale, GDK_INTERP_BILINEAR); g_object_unref (partial_src); x_offset = 0; y_offset = 0; } if (tmp_pixbuf) { if (mask) { gdk_pixbuf_render_threshold_alpha (tmp_pixbuf, mask, x_offset, y_offset, rect.x, rect.y, rect.width, rect.height, 128); } gdk_draw_pixbuf (window, NULL, tmp_pixbuf, x_offset, y_offset, rect.x, rect.y, rect.width, rect.height, GDK_RGB_DITHER_NORMAL, 0, 0); g_object_unref (tmp_pixbuf); }}ThemePixbuf *theme_pixbuf_new (void){ ThemePixbuf *result = g_new0 (ThemePixbuf, 1); result->filename = NULL; result->pixbuf = NULL; result->stretch = TRUE; result->border_left = 0; result->border_right = 0; result->border_bottom = 0; result->border_top = 0; return result;}voidtheme_pixbuf_destroy (ThemePixbuf *theme_pb){ theme_pixbuf_set_filename (theme_pb, NULL); g_free (theme_pb);}void theme_pixbuf_set_filename (ThemePixbuf *theme_pb, const char *filename){ if (theme_pb->pixbuf) { g_cache_remove (pixbuf_cache, theme_pb->pixbuf); theme_pb->pixbuf = NULL; } g_free (theme_pb->filename); if (filename) theme_pb->filename = g_strdup (filename); else theme_pb->filename = NULL;}static guintcompute_hint (GdkPixbuf *pixbuf, gint x0, gint x1, gint y0, gint y1){ int i, j; int hints = THEME_CONSTANT_ROWS | THEME_CONSTANT_COLS | THEME_MISSING; int n_channels = gdk_pixbuf_get_n_channels (pixbuf); guchar *data = gdk_pixbuf_get_pixels (pixbuf); int rowstride = gdk_pixbuf_get_rowstride (pixbuf); if (x0 == x1 || y0 == y1) return 0; for (i = y0; i < y1; i++) { guchar *p = data + i * rowstride + x0 * n_channels; guchar r = p[0]; guchar g = p[1]; guchar b = p[2]; guchar a = 0; if (n_channels == 4) a = p[3]; for (j = x0; j < x1 ; j++) { if (n_channels != 4 || p[3] != 0) { hints &= ~THEME_MISSING; if (!(hints & THEME_CONSTANT_ROWS)) goto cols; } if (r != *(p++) || g != *(p++) || b != *(p++) || (n_channels != 4 && a != *(p++))) { hints &= ~THEME_CONSTANT_ROWS; if (!(hints & THEME_MISSING)) goto cols; } } } cols: for (i = y0 + 1; i < y1; i++) { guchar *base = data + y0 * rowstride + x0 * n_channels; guchar *p = data + i * rowstride + x0 * n_channels; if (memcmp (p, base, n_channels * (x1 - x0)) != 0) { hints &= ~THEME_CONSTANT_COLS; return hints; } } return hints;}static voidtheme_pixbuf_compute_hints (ThemePixbuf *theme_pb){ int i, j; gint width = gdk_pixbuf_get_width (theme_pb->pixbuf); gint height = gdk_pixbuf_get_height (theme_pb->pixbuf); if (theme_pb->border_left + theme_pb->border_right > width || theme_pb->border_top + theme_pb->border_bottom > height) { g_warning ("Invalid borders specified for theme pixmap:\n" " %s,\n" "borders don't fit within the image", theme_pb->filename); if (theme_pb->border_left + theme_pb->border_right > width) { theme_pb->border_left = width / 2; theme_pb->border_right = (width + 1) / 2; } if (theme_pb->border_bottom + theme_pb->border_top > height) { theme_pb->border_top = height / 2; theme_pb->border_bottom = (height + 1) / 2; } } for (i = 0; i < 3; i++) { gint y0, y1; switch (i) { case 0: y0 = 0; y1 = theme_pb->border_top; break; case 1: y0 = theme_pb->border_top; y1 = height - theme_pb->border_bottom; break; default: y0 = height - theme_pb->border_bottom; y1 = height; break; } for (j = 0; j < 3; j++) { gint x0, x1; switch (j) { case 0: x0 = 0; x1 = theme_pb->border_left; break; case 1: x0 = theme_pb->border_left; x1 = width - theme_pb->border_right; break; default: x0 = width - theme_pb->border_right; x1 = width; break; } theme_pb->hints[i][j] = compute_hint (theme_pb->pixbuf, x0, x1, y0, y1); } } }voidtheme_pixbuf_set_border (ThemePixbuf *theme_pb, gint left, gint right, gint top, gint bottom){ theme_pb->border_left = left; theme_pb->border_right = right; theme_pb->border_top = top; theme_pb->border_bottom = bottom; if (theme_pb->pixbuf) theme_pixbuf_compute_hints (theme_pb);}voidtheme_pixbuf_set_stretch (ThemePixbuf *theme_pb, gboolean stretch){ theme_pb->stretch = stretch; if (theme_pb->pixbuf) theme_pixbuf_compute_hints (theme_pb);}static GdkPixbuf *pixbuf_cache_value_new (gchar *filename){ GError *err = NULL; GdkPixbuf *result = gdk_pixbuf_new_from_file (filename, &err); if (!result) { g_warning ("Pixbuf theme: Cannot load pixmap file %s: %s\n", filename, err->message); g_error_free (err); } return result;}GdkPixbuf *theme_pixbuf_get_pixbuf (ThemePixbuf *theme_pb){ if (!theme_pb->pixbuf) { if (!pixbuf_cache) pixbuf_cache = g_cache_new ((GCacheNewFunc)pixbuf_cache_value_new, (GCacheDestroyFunc)g_object_unref, (GCacheDupFunc)g_strdup, (GCacheDestroyFunc)g_free, g_str_hash, g_direct_hash, g_str_equal); theme_pb->pixbuf = g_cache_insert (pixbuf_cache, theme_pb->filename); if (theme_pb->stretch) theme_pixbuf_compute_hints (theme_pb); } return theme_pb->pixbuf;}voidtheme_pixbuf_render (ThemePixbuf *theme_pb, GdkWindow *window, GdkBitmap *mask, GdkRectangle *clip_rect, guint component_mask, gboolean center, gint x, gint y, gint width, gint height){ GdkPixbuf *pixbuf = theme_pixbuf_get_pixbuf (theme_pb); gint src_x[4], src_y[4], dest_x[4], dest_y[4]; gint pixbuf_width = gdk_pixbuf_get_width (pixbuf); gint pixbuf_height = gdk_pixbuf_get_height (pixbuf); if (!pixbuf) return; if (theme_pb->stretch) { if (component_mask & COMPONENT_ALL) component_mask = (COMPONENT_ALL - 1) & ~component_mask; src_x[0] = 0; src_x[1] = theme_pb->border_left; src_x[2] = pixbuf_width - theme_pb->border_right; src_x[3] = pixbuf_width; src_y[0] = 0; src_y[1] = theme_pb->border_top; src_y[2] = pixbuf_height - theme_pb->border_bottom; src_y[3] = pixbuf_height; dest_x[0] = x; dest_x[1] = x + theme_pb->border_left; dest_x[2] = x + width - theme_pb->border_right; dest_x[3] = x + width; if (dest_x[1] > dest_x[2]) { component_mask &= ~(COMPONENT_NORTH | COMPONENT_SOUTH | COMPONENT_CENTER); dest_x[1] = dest_x[2] = (dest_x[1] + dest_x[2]) / 2; } dest_y[0] = y; dest_y[1] = y + theme_pb->border_top; dest_y[2] = y + height - theme_pb->border_bottom; dest_y[3] = y + height; if (dest_y[1] > dest_y[2]) { component_mask &= ~(COMPONENT_EAST | COMPONENT_WEST | COMPONENT_CENTER); dest_y[1] = dest_y[2] = (dest_y[1] + dest_y[2]) / 2; }#define RENDER_COMPONENT(X1,X2,Y1,Y2) \ pixbuf_render (pixbuf, theme_pb->hints[Y1][X1], window, mask, clip_rect, \ src_x[X1], src_y[Y1], \ src_x[X2] - src_x[X1], src_y[Y2] - src_y[Y1], \ dest_x[X1], dest_y[Y1], \ dest_x[X2] - dest_x[X1], dest_y[Y2] - dest_y[Y1]); if (component_mask & COMPONENT_NORTH_WEST) RENDER_COMPONENT (0, 1, 0, 1); if (component_mask & COMPONENT_NORTH) RENDER_COMPONENT (1, 2, 0, 1); if (component_mask & COMPONENT_NORTH_EAST) RENDER_COMPONENT (2, 3, 0, 1); if (component_mask & COMPONENT_WEST) RENDER_COMPONENT (0, 1, 1, 2); if (component_mask & COMPONENT_CENTER) RENDER_COMPONENT (1, 2, 1, 2); if (component_mask & COMPONENT_EAST) RENDER_COMPONENT (2, 3, 1, 2); if (component_mask & COMPONENT_SOUTH_WEST) RENDER_COMPONENT (0, 1, 2, 3); if (component_mask & COMPONENT_SOUTH) RENDER_COMPONENT (1, 2, 2, 3); if (component_mask & COMPONENT_SOUTH_EAST) RENDER_COMPONENT (2, 3, 2, 3); } else { if (center) { x += (width - pixbuf_width) / 2; y += (height - pixbuf_height) / 2; pixbuf_render (pixbuf, 0, window, NULL, clip_rect, 0, 0, pixbuf_width, pixbuf_height, x, y, pixbuf_width, pixbuf_height); } else { GdkPixmap *tmp_pixmap; GdkGC *tmp_gc; GdkGCValues gc_values; tmp_pixmap = gdk_pixmap_new (window, pixbuf_width, pixbuf_height, -1); tmp_gc = gdk_gc_new (tmp_pixmap); gdk_draw_pixbuf (tmp_pixmap, tmp_gc, pixbuf, 0, 0, 0, 0, pixbuf_width, pixbuf_height, GDK_RGB_DITHER_NORMAL, 0, 0); g_object_unref (tmp_gc); gc_values.fill = GDK_TILED; gc_values.tile = tmp_pixmap; tmp_gc = gdk_gc_new_with_values (window, &gc_values, GDK_GC_FILL | GDK_GC_TILE); if (clip_rect) gdk_draw_rectangle (window, tmp_gc, TRUE, clip_rect->x, clip_rect->y, clip_rect->width, clip_rect->height); else gdk_draw_rectangle (window, tmp_gc, TRUE, x, y, width, height); g_object_unref (tmp_gc); g_object_unref (tmp_pixmap); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -