revno 3457 From: Eiichi Sato Date: Tue 2010-09-14 06:30:22 +0900 Branch-Nick: gnome-terminal Subject: Added background image scaling --- src/profile-editor.c | 4 + src/profile-preferences.glade | 79 ++++++++++++++++--- src/terminal-profile.c | 4 + src/terminal-profile.h | 10 ++ src/terminal-screen.c | 167 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 249 insertions(+), 15 deletions(-) === modified file 'src/profile-editor.c' --- old/src/profile-editor.c 2010-08-10 12:29:33 +0000 +++ new/src/profile-editor.c 2010-09-13 21:30:22 +0000 @@ -141,18 +141,21 @@ if (bg_type == TERMINAL_BACKGROUND_IMAGE) { SET_SENSITIVE ("background-image-filechooser", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_IMAGE_FILE)); + SET_SENSITIVE ("background-image-stylechooser", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_IMAGE_STYLE)); SET_SENSITIVE ("scroll-background-checkbutton", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_SCROLL_BACKGROUND)); SET_SENSITIVE ("darken-background-vbox", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_DARKNESS)); } else if (bg_type == TERMINAL_BACKGROUND_TRANSPARENT) { SET_SENSITIVE ("background-image-filechooser", FALSE); + SET_SENSITIVE ("background-image-stylechooser", FALSE); SET_SENSITIVE ("scroll-background-checkbutton", FALSE); SET_SENSITIVE ("darken-background-vbox", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_DARKNESS)); } else { SET_SENSITIVE ("background-image-filechooser", FALSE); + SET_SENSITIVE ("background-image-stylechooser", FALSE); SET_SENSITIVE ("scroll-background-checkbutton", FALSE); SET_SENSITIVE ("darken-background-vbox", FALSE); } @@ -866,6 +869,7 @@ CONNECT ("allow-bold-checkbutton", TERMINAL_PROFILE_ALLOW_BOLD); CONNECT ("background-colorpicker", TERMINAL_PROFILE_BACKGROUND_COLOR); CONNECT ("background-image-filechooser", TERMINAL_PROFILE_BACKGROUND_IMAGE_FILE); + CONNECT ("background-image-stylechooser", TERMINAL_PROFILE_BACKGROUND_IMAGE_STYLE); CONNECT ("backspace-binding-combobox", TERMINAL_PROFILE_BACKSPACE_BINDING); CONNECT ("bold-color-same-as-fg-checkbox", TERMINAL_PROFILE_BOLD_COLOR_SAME_AS_FG); CONNECT ("bold-colorpicker", TERMINAL_PROFILE_BOLD_COLOR); === modified file 'src/profile-preferences.glade' --- old/src/profile-preferences.glade 2010-04-09 21:31:30 +0000 +++ new/src/profile-preferences.glade 2010-09-13 21:30:22 +0000 @@ -2089,11 +2089,13 @@ 6 - + True + 2 + 2 False - 12 - + 0 + 12 True @@ -2114,12 +2116,42 @@ 0 - 0 - False - False - - - + 0 + 1 + 0 + 1 + fill + + + + + + True + St_yle: + True + False + GTK_JUSTIFY_CENTER + False + False + 0 + 0.5 + 0 + 0 + background-image-stylechooser + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + fill + + + True @@ -2132,11 +2164,34 @@ -1 - 0 - True - True + 1 + 2 + 0 + 1 + expand|fill + + + + True + Tiled +Centered +Scaled +Scaled Fill +Stretched + False + True + + + 1 + 2 + 1 + 2 + expand|fill + + + 0 === modified file 'src/terminal-profile.c' --- old/src/terminal-profile.c 2010-08-10 12:29:33 +0000 +++ new/src/terminal-profile.c 2010-09-13 21:30:22 +0000 @@ -52,6 +52,7 @@ PROP_BACKGROUND_DARKNESS, PROP_BACKGROUND_IMAGE, PROP_BACKGROUND_IMAGE_FILE, + PROP_BACKGROUND_IMAGE_STYLE, PROP_BACKGROUND_TYPE, PROP_BACKSPACE_BINDING, PROP_BOLD_COLOR, @@ -93,6 +94,7 @@ #define KEY_BACKGROUND_COLOR "background_color" #define KEY_BACKGROUND_DARKNESS "background_darkness" #define KEY_BACKGROUND_IMAGE_FILE "background_image" +#define KEY_BACKGROUND_IMAGE_STYLE "background_image_style" #define KEY_BACKGROUND_TYPE "background_type" #define KEY_BACKSPACE_BINDING "backspace_binding" #define KEY_BOLD_COLOR "bold_color" @@ -133,6 +135,7 @@ #define DEFAULT_BOLD_COLOR_SAME_AS_FG (TRUE) #define DEFAULT_BACKGROUND_DARKNESS (0.5) #define DEFAULT_BACKGROUND_IMAGE_FILE ("") +#define DEFAULT_BACKGROUND_IMAGE_STYLE (TERMINAL_BACKGROUND_IMAGE_STYLE_TILED) #define DEFAULT_BACKGROUND_IMAGE (NULL) #define DEFAULT_BACKGROUND_TYPE (TERMINAL_BACKGROUND_SOLID) #define DEFAULT_BACKSPACE_BINDING (VTE_ERASE_ASCII_DELETE) @@ -1326,6 +1329,7 @@ TERMINAL_PROFILE_PROPERTY_ENUM (EXIT_ACTION, TERMINAL_TYPE_EXIT_ACTION, DEFAULT_EXIT_ACTION, KEY_EXIT_ACTION); TERMINAL_PROFILE_PROPERTY_ENUM (SCROLLBAR_POSITION, TERMINAL_TYPE_SCROLLBAR_POSITION, DEFAULT_SCROLLBAR_POSITION, KEY_SCROLLBAR_POSITION); TERMINAL_PROFILE_PROPERTY_ENUM (TITLE_MODE, TERMINAL_TYPE_TITLE_MODE, DEFAULT_TITLE_MODE, KEY_TITLE_MODE); + TERMINAL_PROFILE_PROPERTY_ENUM (BACKGROUND_IMAGE_STYLE, TERMINAL_TYPE_BACKGROUND_IMAGE_STYLE, DEFAULT_BACKGROUND_IMAGE_STYLE, KEY_BACKGROUND_IMAGE_STYLE); TERMINAL_PROFILE_PROPERTY_INT (DEFAULT_SIZE_COLUMNS, 1, 1024, DEFAULT_DEFAULT_SIZE_COLUMNS, KEY_DEFAULT_SIZE_COLUMNS); TERMINAL_PROFILE_PROPERTY_INT (DEFAULT_SIZE_ROWS, 1, 1024, DEFAULT_DEFAULT_SIZE_ROWS, KEY_DEFAULT_SIZE_ROWS); === modified file 'src/terminal-profile.h' --- old/src/terminal-profile.h 2010-08-10 12:29:33 +0000 +++ new/src/terminal-profile.h 2010-09-13 21:30:22 +0000 @@ -56,6 +56,15 @@ TERMINAL_BACKGROUND_TRANSPARENT } TerminalBackgroundType; +typedef enum +{ + TERMINAL_BACKGROUND_IMAGE_STYLE_TILED, + TERMINAL_BACKGROUND_IMAGE_STYLE_CENTERED, + TERMINAL_BACKGROUND_IMAGE_STYLE_SCALED, + TERMINAL_BACKGROUND_IMAGE_STYLE_SCALED_FILL, + TERMINAL_BACKGROUND_IMAGE_STYLE_STRETCHED, +} TerminalBackgroundImageStyle; + #define TERMINAL_PALETTE_SIZE 16 #define TERMINAL_PALETTE_TANGO 0 @@ -70,6 +79,7 @@ #define TERMINAL_PROFILE_BACKGROUND_DARKNESS "background-darkness" #define TERMINAL_PROFILE_BACKGROUND_IMAGE "background-image" #define TERMINAL_PROFILE_BACKGROUND_IMAGE_FILE "background-image-file" +#define TERMINAL_PROFILE_BACKGROUND_IMAGE_STYLE "background-image-style" #define TERMINAL_PROFILE_BACKGROUND_TYPE "background-type" #define TERMINAL_PROFILE_BACKSPACE_BINDING "backspace-binding" #define TERMINAL_PROFILE_BOLD_COLOR "bold-color" === modified file 'src/terminal-screen.c' --- old/src/terminal-screen.c 2010-09-04 20:50:32 +0000 +++ new/src/terminal-screen.c 2010-09-13 21:30:22 +0000 @@ -70,6 +70,9 @@ gboolean user_title; /* title was manually set */ GSList *match_tags; guint launch_child_source_id; + + gint prev_height; + gint prev_width; }; enum @@ -137,6 +140,11 @@ int row, int *flavor); +static void terminal_screen_refresh_background_image (VteTerminal *terminal); +static void terminal_screen_set_background_image (VteTerminal *terminal, GdkPixbuf *pixbuf, gint style); + +static void terminal_screen_size_allocate (GtkWidget *widget, GtkAllocation *allocation); + static guint signals[LAST_SIGNAL]; #define USERCHARS "-[:alnum:]" @@ -509,6 +517,7 @@ widget_class->drag_data_received = terminal_screen_drag_data_received; widget_class->button_press_event = terminal_screen_button_press; widget_class->popup_menu = terminal_screen_popup_menu; + widget_class->size_allocate = terminal_screen_size_allocate; terminal_class->child_exited = terminal_screen_child_exited; @@ -900,6 +909,129 @@ } static void +terminal_screen_set_background_image (VteTerminal *terminal, GdkPixbuf *pixbuf, gint style) +{ + if (G_IS_OBJECT (pixbuf)) + { + g_object_ref (pixbuf); + g_object_set_data_full (G_OBJECT (terminal), "background-image", pixbuf, g_object_unref); + } + else + { + g_object_set_data_full (G_OBJECT (terminal), "background-image", NULL, NULL); + } + g_object_set_data (G_OBJECT (terminal), "image-style", GINT_TO_POINTER (style)); + terminal_screen_refresh_background_image (terminal); +} + +static guint32 +_gdk_color_to_int(const GdkColor *color) +{ + if (!color) + return 0; + + guint32 rgba = (((color->red & 0xff00) << 8) + | (color->green & 0xff00) + | (color->blue & 0xff00 >> 8)) << 8; + return rgba; +} + +static void +terminal_screen_refresh_background_image (VteTerminal *terminal) +{ + gint window_width, window_height, image_width, image_height; + gdouble scale; + gpointer image; + gint image_style; + GdkPixbuf *scaled = NULL; + GtkAllocation allocation; + guint32 bg_color = 0; + + image = g_object_get_data (G_OBJECT (terminal), "background-image"); + if (!GDK_IS_PIXBUF (image)) + { + vte_terminal_set_background_image (terminal, NULL); + return; + } + + gtk_widget_get_allocation (GTK_WIDGET (terminal), &allocation); + window_height = allocation.height; + window_width = allocation.width; + image_width = gdk_pixbuf_get_width (GDK_PIXBUF (image)); + image_height = gdk_pixbuf_get_height (GDK_PIXBUF (image)); + + if (window_width < 2 && window_height < 2) + { + vte_terminal_set_background_image (terminal, NULL); + return; + } + + bg_color = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (terminal), "background-color")); + + image_style = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (terminal), "image-style")); + switch (image_style) + { + case TERMINAL_BACKGROUND_IMAGE_STYLE_TILED: + scaled = gdk_pixbuf_copy (GDK_PIXBUF (image)); + break; + + case TERMINAL_BACKGROUND_IMAGE_STYLE_CENTERED: + scaled = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (GDK_PIXBUF (image)), + gdk_pixbuf_get_has_alpha (GDK_PIXBUF (image)), + gdk_pixbuf_get_bits_per_sample (GDK_PIXBUF (image)), + window_width, window_height); + gdk_pixbuf_fill (GDK_PIXBUF (scaled), bg_color); + gdk_pixbuf_scale (GDK_PIXBUF (image), scaled, + window_width < image_width ? 0 : (window_width - image_width) / 2.0, + window_height < image_height ? 0 : (window_height - image_height) / 2.0, + window_width < image_width ? window_width : image_width, + window_height < image_height ? window_height : image_height, + (window_width - image_width) / 2.0, (window_height - image_height) / 2.0, 1.0, 1.0, GDK_INTERP_HYPER); + + break; + + case TERMINAL_BACKGROUND_IMAGE_STYLE_SCALED: + scaled = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (GDK_PIXBUF (image)), + gdk_pixbuf_get_has_alpha (GDK_PIXBUF (image)), + gdk_pixbuf_get_bits_per_sample (GDK_PIXBUF (image)), + window_width, window_height); + gdk_pixbuf_fill (GDK_PIXBUF (scaled), bg_color); + scale = MIN ((gdouble)window_width / (gdouble)image_width, (gdouble)window_height / (gdouble)image_height); + gdk_pixbuf_scale (GDK_PIXBUF (image), scaled, + (window_width - image_width * scale) / 2.0, (window_height - image_height * scale) / 2.0, + image_width * scale, image_height * scale, + (window_width - image_width * scale) / 2.0 , (window_height - image_height * scale) / 2.0, + scale, scale, GDK_INTERP_HYPER); + break; + + case TERMINAL_BACKGROUND_IMAGE_STYLE_SCALED_FILL: + scaled = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (GDK_PIXBUF (image)), + gdk_pixbuf_get_has_alpha (GDK_PIXBUF (image)), + gdk_pixbuf_get_bits_per_sample (GDK_PIXBUF (image)), + window_width, window_height); + scale = MAX ((gdouble)window_width / (gdouble)image_width, (gdouble)window_height / (gdouble)image_height); + gdk_pixbuf_scale (GDK_PIXBUF (image), scaled, 0, 0, window_width, window_height, + (window_width - image_width * scale) / 2.0 , (window_height - image_height * scale) / 2.0, + scale, scale, GDK_INTERP_HYPER); + break; + + case TERMINAL_BACKGROUND_IMAGE_STYLE_STRETCHED: + scaled = gdk_pixbuf_scale_simple (GDK_PIXBUF (image), window_width, window_height, GDK_INTERP_HYPER); + break; + + default: + scaled = NULL; + } + + if (scaled) + { + vte_terminal_set_background_image (terminal, GDK_PIXBUF (scaled)); + g_object_unref (G_OBJECT (scaled)); + } + +} + +static void terminal_screen_profile_notify_cb (TerminalProfile *profile, GParamSpec *pspec, TerminalScreen *screen) @@ -1002,6 +1134,7 @@ if (!prop_name || prop_name == I_(TERMINAL_PROFILE_BACKGROUND_TYPE) || prop_name == I_(TERMINAL_PROFILE_BACKGROUND_IMAGE) || + prop_name == I_(TERMINAL_PROFILE_BACKGROUND_IMAGE_STYLE) || prop_name == I_(TERMINAL_PROFILE_BACKGROUND_DARKNESS) || prop_name == I_(TERMINAL_PROFILE_SCROLL_BACKGROUND)) { @@ -1009,14 +1142,15 @@ if (bg_type == TERMINAL_BACKGROUND_IMAGE) { - vte_terminal_set_background_image (vte_terminal, - terminal_profile_get_property_object (profile, TERMINAL_PROFILE_BACKGROUND_IMAGE)); + terminal_screen_set_background_image (VTE_TERMINAL (vte_terminal), + terminal_profile_get_property_object (profile, TERMINAL_PROFILE_BACKGROUND_IMAGE), + terminal_profile_get_property_enum (profile, TERMINAL_PROFILE_BACKGROUND_IMAGE_STYLE)); vte_terminal_set_scroll_background (vte_terminal, terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_SCROLL_BACKGROUND)); } else { - vte_terminal_set_background_image (vte_terminal, NULL); + terminal_screen_set_background_image (VTE_TERMINAL (vte_terminal), NULL, 0); vte_terminal_set_scroll_background (vte_terminal, FALSE); } @@ -1073,6 +1207,7 @@ const GdkColor *fg_color, *bg_color, *bold_color; GdkColor fg, bg; guint n_colors; + TerminalBackgroundType bg_type; style = gtk_widget_get_style (GTK_WIDGET (screen)); if (!style) @@ -1103,6 +1238,13 @@ if (bold_color) vte_terminal_set_color_bold (VTE_TERMINAL (screen), bold_color); vte_terminal_set_background_tint_color (VTE_TERMINAL (screen), &bg); + + bg_type = terminal_profile_get_property_enum (profile, TERMINAL_PROFILE_BACKGROUND_TYPE); + if (bg_type == TERMINAL_BACKGROUND_IMAGE) + { + g_object_set_data (G_OBJECT (screen), "background-color", GINT_TO_POINTER (_gdk_color_to_int (&bg))); + terminal_screen_refresh_background_image (VTE_TERMINAL (screen)); + } } void @@ -1841,6 +1983,25 @@ } static void +terminal_screen_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + if (GTK_WIDGET_CLASS (terminal_screen_parent_class)->size_allocate) + GTK_WIDGET_CLASS (terminal_screen_parent_class)->size_allocate (widget, allocation); + + TerminalScreen *screen = TERMINAL_SCREEN (widget); + TerminalScreenPrivate *priv = screen->priv; + + /* if size changed */ + if (priv->prev_height != allocation->height + || priv->prev_width != allocation->width) + { + terminal_screen_refresh_background_image (VTE_TERMINAL (widget)); + priv->prev_height = allocation->height; + priv->prev_width = allocation->width; + } +} + +static void terminal_screen_child_exited (VteTerminal *terminal) { TerminalScreen *screen = TERMINAL_SCREEN (terminal); -- bzr-export-patch 3457