Commit 63b25ac4 authored by Behdad Esfahbod's avatar Behdad Esfahbod Committed by Behdad Esfahbod

Bug 563752 – pangocairo backend recreates cairo_surface_t for background

2008-12-08  Behdad Esfahbod  <behdad@gnome.org>

        Bug 563752 – pangocairo backend recreates cairo_surface_t for
        background drawing

        * src/vte.c (vte_terminal_paint),
        (vte_terminal_set_scroll_background),
        (vte_terminal_background_update):
        * src/vtedraw.c (_vte_draw_new), (_vte_draw_set_background_solid),
        (_vte_draw_set_background_image),
        (_vte_draw_set_background_scroll), (_vte_draw_draw_rectangle):
        * src/vtedraw.h:
        * src/vtepangocairo.c (_vte_pangocairo_destroy),
        (_vte_pangocairo_set_background_solid),
        (_vte_pangocairo_set_background_image),
        (_vte_pangocairo_set_background_scroll), (_vte_pangocairo_clear),
        (_vte_pangocairo_clip), (set_source_color_alpha):
        * src/vteskel.c:
        Cleanup vte_draw background API.  Use a cached cairo_pattern_t in
        pangocairo backend.

        Also, queue background update on scroll_background change.


svn path=/trunk/; revision=2335
parent d849a020
2008-12-08 Behdad Esfahbod <behdad@gnome.org>
Bug 563752 pangocairo backend recreates cairo_surface_t for
background drawing
* src/vte.c (vte_terminal_paint),
(vte_terminal_set_scroll_background),
(vte_terminal_background_update):
* src/vtedraw.c (_vte_draw_new), (_vte_draw_set_background_solid),
(_vte_draw_set_background_image),
(_vte_draw_set_background_scroll), (_vte_draw_draw_rectangle):
* src/vtedraw.h:
* src/vtepangocairo.c (_vte_pangocairo_destroy),
(_vte_pangocairo_set_background_solid),
(_vte_pangocairo_set_background_image),
(_vte_pangocairo_set_background_scroll), (_vte_pangocairo_clear),
(_vte_pangocairo_clip), (set_source_color_alpha):
* src/vteskel.c:
Cleanup vte_draw background API. Use a cached cairo_pattern_t in
pangocairo backend.
Also, queue background update on scroll_background change.
2008-12-07 Behdad Esfahbod <behdad@gnome.org>
Bug 163213 Cursor should remain visible when selected
......
......@@ -10759,15 +10759,15 @@ vte_terminal_paint(GtkWidget *widget, GdkRegion *region)
if (terminal->pvt->bg_transparent) {
int x, y;
gdk_window_get_origin(widget->window, &x, &y);
_vte_draw_set_scroll(terminal->pvt->draw, x, y);
_vte_draw_set_background_scroll(terminal->pvt->draw, x, y);
} else {
if (terminal->pvt->scroll_background) {
_vte_draw_set_scroll(terminal->pvt->draw,
0,
terminal->pvt->screen->scroll_delta *
terminal->char_height);
_vte_draw_set_background_scroll(terminal->pvt->draw,
0,
terminal->pvt->screen->scroll_delta *
terminal->char_height);
} else {
_vte_draw_set_scroll(terminal->pvt->draw, 0, 0);
_vte_draw_set_background_scroll(terminal->pvt->draw, 0, 0);
}
}
......@@ -12175,6 +12175,8 @@ vte_terminal_set_scroll_background(VteTerminal *terminal, gboolean scroll)
pvt->scroll_background = scroll;
g_object_notify (G_OBJECT (terminal), "scroll-background");
vte_terminal_queue_background_update(terminal);
}
/**
......@@ -12362,8 +12364,7 @@ vte_terminal_background_update(VteTerminal *terminal)
bgcolor.red, bgcolor.green, bgcolor.blue,
bgcolor.pixel);
gdk_window_set_background(terminal->widget.window, &bgcolor);
_vte_draw_set_background_color (terminal->pvt->draw, &bgcolor);
_vte_draw_set_background_opacity (terminal->pvt->draw, terminal->pvt->bg_opacity);
_vte_draw_set_background_solid (terminal->pvt->draw, &bgcolor, terminal->pvt->bg_opacity);
/* If we're transparent, and either have no root image or are being
* told to update it, get a new copy of the root window. */
......
......@@ -107,14 +107,6 @@ _vte_draw_init_default (struct _vte_draw *draw)
}
static void
_vte_draw_update_requires_clear (struct _vte_draw *draw)
{
draw->requires_clear = draw->impl->always_requires_clear
|| draw->bg_type != VTE_BG_SOURCE_NONE
|| draw->bg_opacity != 0xFFFF;
}
struct _vte_draw *
_vte_draw_new (GtkWidget *widget)
{
......@@ -123,8 +115,6 @@ _vte_draw_new (GtkWidget *widget)
/* Create the structure. */
draw = g_slice_new0 (struct _vte_draw);
draw->widget = g_object_ref (widget);
draw->bg_type = VTE_BG_SOURCE_NONE;
draw->bg_opacity = 0xffff;
/* Allow the user to specify her preferred backends */
if (!_vte_draw_init_user (draw) &&
......@@ -135,7 +125,7 @@ _vte_draw_new (GtkWidget *widget)
draw->impl = &_vte_draw_skel;
}
_vte_draw_update_requires_clear (draw);
draw->requires_clear = draw->impl->always_requires_clear;
_vte_debug_print (VTE_DEBUG_DRAW,
"draw_new (%s)\n", draw->impl->name);
......@@ -225,18 +215,14 @@ _vte_draw_end (struct _vte_draw *draw)
}
void
_vte_draw_set_background_opacity (struct _vte_draw *draw,
guint16 opacity)
_vte_draw_set_background_solid(struct _vte_draw *draw,
GdkColor *color,
guint16 opacity)
{
draw->bg_opacity = opacity;
_vte_draw_update_requires_clear (draw);
}
draw->requires_clear = draw->impl->always_requires_clear || opacity != 0xFFFF;
void
_vte_draw_set_background_color (struct _vte_draw *draw,
GdkColor *color)
{
draw->bg_color = *color;
if (draw->impl->set_background_solid)
draw->impl->set_background_solid (draw, color, opacity);
}
void
......@@ -247,14 +233,26 @@ _vte_draw_set_background_image (struct _vte_draw *draw,
const GdkColor *color,
double saturation)
{
draw->bg_type = type;
_vte_draw_update_requires_clear (draw);
if (type != VTE_BG_SOURCE_NONE)
draw->requires_clear = TRUE;
if (draw->impl->set_background_image)
draw->impl->set_background_image (draw, type, pixbuf, filename,
color, saturation);
}
void
_vte_draw_set_background_scroll (struct _vte_draw *draw,
gint x, gint y)
{
_vte_debug_print (VTE_DEBUG_DRAW,
"draw_set_scroll (%d, %d)\n",
x, y);
if (draw->impl->set_background_scroll)
draw->impl->set_background_scroll (draw, x, y);
}
gboolean
_vte_draw_requires_clear (struct _vte_draw *draw)
{
......@@ -427,14 +425,3 @@ _vte_draw_draw_rectangle (struct _vte_draw *draw,
}
}
}
void
_vte_draw_set_scroll (struct _vte_draw *draw, gint x, gint y)
{
_vte_debug_print (VTE_DEBUG_DRAW,
"draw_set_scroll (%d, %d)\n",
x, y);
draw->scrollx = x;
draw->scrolly = y;
}
......@@ -68,12 +68,17 @@ struct _vte_draw_impl {
GdkColormap* (*get_colormap)(struct _vte_draw *draw);
void (*start)(struct _vte_draw *draw);
void (*end)(struct _vte_draw *draw);
void (*set_background_solid)(struct _vte_draw *,
GdkColor *color,
guint16 opacity);
void (*set_background_image)(struct _vte_draw *,
enum VteBgSourceType type,
GdkPixbuf *pixbuf,
const char *file,
const GdkColor *color,
double saturation);
void (*set_background_scroll)(struct _vte_draw *,
gint, gint);
void (*clip)(struct _vte_draw *, GdkRegion *);
gboolean always_requires_clear;
void (*clear)(struct _vte_draw *, gint, gint, gint, gint);
......@@ -99,12 +104,6 @@ struct _vte_draw {
gboolean started;
guint16 bg_opacity;
GdkColor bg_color;
enum VteBgSourceType bg_type;
gint scrollx, scrolly;
gboolean requires_clear;
const struct _vte_draw_impl *impl;
......@@ -129,33 +128,30 @@ GdkColormap *_vte_draw_get_colormap(struct _vte_draw *draw,
void _vte_draw_start(struct _vte_draw *draw);
void _vte_draw_end(struct _vte_draw *draw);
/* Set the background color, a background pixbuf (if you want transparency,
you'll have to do that yourself), and clear an area to the default. */
void _vte_draw_set_background_opacity(struct _vte_draw *draw,
guint16 opacity);
void _vte_draw_set_background_color(struct _vte_draw *draw,
GdkColor *color);
void _vte_draw_set_background_solid(struct _vte_draw *draw,
GdkColor *color,
guint16 opacity);
void _vte_draw_set_background_image(struct _vte_draw *draw,
enum VteBgSourceType type,
GdkPixbuf *pixbuf,
const char *file,
const GdkColor *color,
double saturation);
gboolean _vte_draw_requires_clear (struct _vte_draw *draw);
void _vte_draw_set_background_scroll(struct _vte_draw *draw,
gint x, gint y);
gboolean _vte_draw_clip(struct _vte_draw *draw, GdkRegion *region);
gboolean _vte_draw_requires_clear (struct _vte_draw *draw);
void _vte_draw_clear(struct _vte_draw *draw,
gint x, gint y, gint width, gint height);
/* Set the font which will be used to draw text. */
void _vte_draw_set_text_font(struct _vte_draw *draw,
const PangoFontDescription *fontdesc,
VteTerminalAntiAlias anti_alias);
/* Read font metrics. */
void _vte_draw_get_text_metrics(struct _vte_draw *draw,
gint *width, gint *height, gint *ascent);
int _vte_draw_get_char_width(struct _vte_draw *draw, gunichar c, int columns);
/* Draw text or rectangles. */
void _vte_draw_text(struct _vte_draw *draw,
struct _vte_draw_text_request *requests, gsize n_requests,
GdkColor *color, guchar alpha);
......@@ -163,6 +159,7 @@ gboolean _vte_draw_char(struct _vte_draw *draw,
struct _vte_draw_text_request *request,
GdkColor *color, guchar alpha);
gboolean _vte_draw_has_char(struct _vte_draw *draw, gunichar c);
void _vte_draw_fill_rectangle(struct _vte_draw *draw,
gint x, gint y, gint width, gint height,
GdkColor *color, guchar alpha);
......@@ -170,9 +167,6 @@ void _vte_draw_draw_rectangle(struct _vte_draw *draw,
gint x, gint y, gint width, gint height,
GdkColor *color, guchar alpha);
/* Set the scrolling offset for painting in a pixbuf background. */
void _vte_draw_set_scroll(struct _vte_draw *draw, gint x, gint y);
G_END_DECLS
#endif
......@@ -750,26 +750,11 @@ font_info_get_unichar_info (struct font_info *info,
struct _vte_pangocairo_data {
struct font_info *font;
cairo_pattern_t *bg_pattern;
cairo_t *cr;
GdkPixmap *pixmap;
gint pixmapw, pixmaph;
};
static void
set_source_color_alpha (cairo_t *cr,
const GdkColor *color,
guchar alpha)
{
cairo_set_source_rgba (cr,
color->red / 65535.,
color->green / 65535.,
color->blue / 65535.,
alpha / 255.);
}
static void
_vte_pangocairo_create (struct _vte_draw *draw, GtkWidget *widget)
{
......@@ -784,9 +769,9 @@ _vte_pangocairo_destroy (struct _vte_draw *draw)
{
struct _vte_pangocairo_data *data = draw->impl_data;
if (data->pixmap != NULL) {
g_object_unref (data->pixmap);
data->pixmap = NULL;
if (data->bg_pattern != NULL) {
cairo_pattern_destroy (data->bg_pattern);
data->bg_pattern = NULL;
}
if (data->font != NULL) {
......@@ -816,6 +801,22 @@ _vte_pangocairo_end (struct _vte_draw *draw)
}
}
static void
_vte_pangocairo_set_background_solid(struct _vte_draw *draw,
GdkColor *color,
guint16 opacity)
{
struct _vte_pangocairo_data *data = draw->impl_data;
if (data->bg_pattern)
cairo_pattern_destroy (data->bg_pattern);
data->bg_pattern = cairo_pattern_create_rgba (color->red / 65535.,
color->green / 65535.,
color->blue / 65535.,
opacity / 65535.);
}
static void
_vte_pangocairo_set_background_image (struct _vte_draw *draw,
enum VteBgSourceType type,
......@@ -826,34 +827,56 @@ _vte_pangocairo_set_background_image (struct _vte_draw *draw,
{
struct _vte_pangocairo_data *data = draw->impl_data;
GdkPixmap *pixmap;
GdkScreen *screen;
if (data->pixmap != NULL) {
g_object_unref(data->pixmap);
if (type == VTE_BG_SOURCE_NONE)
return;
if (data->bg_pattern) {
cairo_pattern_destroy (data->bg_pattern);
data->bg_pattern = NULL;
}
screen = gtk_widget_get_screen(draw->widget);
pixmap = vte_bg_get_pixmap(vte_bg_get_for_screen(screen),
type, pixbuf, file,
color, saturation,
_vte_draw_get_colormap(draw, TRUE));
pixmap = vte_bg_get_pixmap (vte_bg_get_for_screen (gtk_widget_get_screen (draw->widget)),
type, pixbuf, file,
color, saturation,
_vte_draw_get_colormap(draw, TRUE));
data->pixmap = NULL;
data->pixmapw = data->pixmaph = 0;
if (pixmap) {
gdk_drawable_get_size(pixmap, &data->pixmapw, &data->pixmaph);
data->pixmap = pixmap;
/* Ugh... We need to create a dummy cairo_t */
cairo_surface_t *surface;
cairo_t *cr;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
cr = cairo_create (surface);
gdk_cairo_set_source_pixmap (cr, pixmap, 0, 0);
data->bg_pattern = cairo_pattern_reference (cairo_get_source (cr));
cairo_destroy (cr);
cairo_surface_destroy (surface);
/* Transfer the pixmap ownership to the pattern */
cairo_pattern_set_user_data (data->bg_pattern,
(cairo_user_data_key_t *) data,
pixmap,
(cairo_destroy_func_t) g_object_unref);
cairo_pattern_set_extend (data->bg_pattern, CAIRO_EXTEND_REPEAT);
}
}
static void
_vte_pangocairo_clip (struct _vte_draw *draw,
GdkRegion *region)
_vte_pangocairo_set_background_scroll (struct _vte_draw *draw,
gint x, gint y)
{
struct _vte_pangocairo_data *data = draw->impl_data;
cairo_matrix_t matrix;
gdk_cairo_region(data->cr, region);
cairo_clip (data->cr);
g_return_if_fail (data->bg_pattern != NULL);
cairo_matrix_init_translate (&matrix, x, y);
cairo_pattern_set_matrix (data->bg_pattern, &matrix);
}
static void
......@@ -862,18 +885,22 @@ _vte_pangocairo_clear (struct _vte_draw *draw,
{
struct _vte_pangocairo_data *data = draw->impl_data;
g_return_if_fail (data->bg_pattern != NULL);
cairo_rectangle (data->cr, x, y, width, height);
cairo_set_operator (data->cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source (data->cr, data->bg_pattern);
cairo_fill (data->cr);
}
if (data->pixmap == NULL) {
set_source_color_alpha (data->cr, &draw->bg_color, draw->bg_opacity >> 8);
} else {
gdk_cairo_set_source_pixmap (data->cr, data->pixmap,
-draw->scrollx, -draw->scrolly);
cairo_pattern_set_extend (cairo_get_source (data->cr), CAIRO_EXTEND_REPEAT);
}
static void
_vte_pangocairo_clip (struct _vte_draw *draw,
GdkRegion *region)
{
struct _vte_pangocairo_data *data = draw->impl_data;
cairo_fill (data->cr);
gdk_cairo_region(data->cr, region);
cairo_clip (data->cr);
}
static void
......@@ -913,6 +940,18 @@ _vte_pangocairo_get_char_width (struct _vte_draw *draw, gunichar c, int columns)
return uinfo->width;
}
static void
set_source_color_alpha (cairo_t *cr,
const GdkColor *color,
guchar alpha)
{
cairo_set_source_rgba (cr,
color->red / 65535.,
color->green / 65535.,
color->blue / 65535.,
alpha / 255.);
}
static void
_vte_pangocairo_draw_text (struct _vte_draw *draw,
struct _vte_draw_text_request *requests, gsize n_requests,
......@@ -1027,7 +1066,9 @@ const struct _vte_draw_impl _vte_draw_pangocairo = {
NULL, /* get_colormap */
_vte_pangocairo_start,
_vte_pangocairo_end,
_vte_pangocairo_set_background_solid,
_vte_pangocairo_set_background_image,
_vte_pangocairo_set_background_scroll,
_vte_pangocairo_clip,
FALSE, /* always_requires_clear */
_vte_pangocairo_clear,
......
......@@ -69,7 +69,9 @@ const struct _vte_draw_impl _vte_draw_skel = {
NULL, /* get_colormap */
NULL, /* start */
NULL, /* end */
NULL, /* set_background_solid */
NULL, /* set_background_image */
NULL, /* set_background_scroll */
NULL, /* clip */
TRUE, /* always_requires_clear */
_vte_skel_clear,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment