summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2018-07-14 05:26:33 +0200
committerBenjamin Otte <otte@redhat.com>2018-07-14 05:27:54 +0200
commitcbb1e74bb5be69d9538c71a47e238248e474bea5 (patch)
tree08754b1e8fc623232aeea03b2eabd7e740a7dd90
parent6afb6bb9d2c81136cddab97a541b1f8a863757da (diff)
downloadgtk+-cbb1e74bb5be69d9538c71a47e238248e474bea5.tar.gz
textview: Only create cairo context in gtktextdisplay.c
Everything else is done using GtkSnapshot now, including renaming the draw_layer vfunc to snapshot_layer.
-rw-r--r--demos/widget-factory/widget-factory.c35
-rw-r--r--gtk/gtktextdisplay.c20
-rw-r--r--gtk/gtktextdisplayprivate.h11
-rw-r--r--gtk/gtktextutil.c6
-rw-r--r--gtk/gtktextview.c68
-rw-r--r--gtk/gtktextview.h8
-rw-r--r--tests/testtextview.c67
7 files changed, 99 insertions, 116 deletions
diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c
index d0e2cafbb1..e0027e97f0 100644
--- a/demos/widget-factory/widget-factory.c
+++ b/demos/widget-factory/widget-factory.c
@@ -1080,7 +1080,7 @@ set_accel (GtkApplication *app, GtkWidget *widget)
typedef struct
{
GtkTextView tv;
- GdkPixbuf *pixbuf;
+ GdkTexture *texture;
} MyTextView;
typedef GtkTextViewClass MyTextViewClass;
@@ -1093,18 +1093,23 @@ my_text_view_init (MyTextView *tv)
}
static void
-my_tv_draw_layer (GtkTextView *widget,
- GtkTextViewLayer layer,
- cairo_t *cr)
+my_tv_snapshot_layer (GtkTextView *widget,
+ GtkTextViewLayer layer,
+ GtkSnapshot *snapshot)
{
MyTextView *tv = (MyTextView *)widget;
- if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->pixbuf)
+ if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT && tv->texture)
{
- cairo_save (cr);
- gdk_cairo_set_source_pixbuf (cr, tv->pixbuf, 0.0, 0.0);
- cairo_paint_with_alpha (cr, 0.333);
- cairo_restore (cr);
+ gtk_snapshot_push_opacity (snapshot, 0.333);
+ gtk_snapshot_append_texture (snapshot,
+ tv->texture,
+ &GRAPHENE_RECT_INIT(
+ 0, 0,
+ gdk_texture_get_width (tv->texture),
+ gdk_texture_get_height (tv->texture)
+ ));
+ gtk_snapshot_pop (snapshot);
}
}
@@ -1113,7 +1118,7 @@ my_tv_finalize (GObject *object)
{
MyTextView *tv = (MyTextView *)object;
- g_clear_object (&tv->pixbuf);
+ g_clear_object (&tv->texture);
G_OBJECT_CLASS (my_text_view_parent_class)->finalize (object);
}
@@ -1125,20 +1130,24 @@ my_text_view_class_init (MyTextViewClass *class)
GObjectClass *o_class = G_OBJECT_CLASS (class);
o_class->finalize = my_tv_finalize;
- tv_class->draw_layer = my_tv_draw_layer;
+ tv_class->snapshot_layer = my_tv_snapshot_layer;
}
static void
my_text_view_set_background (MyTextView *tv, const gchar *filename)
{
GError *error = NULL;
+ GFile *file;
- g_clear_object (&tv->pixbuf);
+ g_clear_object (&tv->texture);
if (filename == NULL)
return;
- tv->pixbuf = gdk_pixbuf_new_from_file (filename, &error);
+ file = g_file_new_for_path (filename);
+ tv->texture = gdk_texture_new_from_file (file, &error);
+ g_object_unref (file);
+
if (error)
{
g_warning ("%s", error->message);
diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c
index 1e935012ed..066bcef121 100644
--- a/gtk/gtktextdisplay.c
+++ b/gtk/gtktextdisplay.c
@@ -816,9 +816,10 @@ get_text_renderer (void)
}
void
-gtk_text_layout_draw (GtkTextLayout *layout,
- GtkWidget *widget,
- cairo_t *cr)
+gtk_text_layout_snapshot (GtkTextLayout *layout,
+ GtkWidget *widget,
+ GtkSnapshot *snapshot,
+ const GdkRectangle *clip)
{
GtkStyleContext *context;
gint offset_y;
@@ -827,23 +828,22 @@ gtk_text_layout_draw (GtkTextLayout *layout,
gboolean have_selection;
GSList *line_list;
GSList *tmp_list;
- GdkRectangle clip;
+ cairo_t *cr;
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
g_return_if_fail (layout->default_style != NULL);
g_return_if_fail (layout->buffer != NULL);
- g_return_if_fail (cr != NULL);
-
- if (!gdk_cairo_get_clip_rectangle (cr, &clip))
- return;
+ g_return_if_fail (snapshot != NULL);
context = gtk_widget_get_style_context (widget);
- line_list = gtk_text_layout_get_lines (layout, clip.y, clip.y + clip.height, &offset_y);
+ line_list = gtk_text_layout_get_lines (layout, clip->y, clip->y + clip->height, &offset_y);
if (line_list == NULL)
return; /* nothing on the screen */
+ cr = gtk_snapshot_append_cairo (snapshot,
+ &GRAPHENE_RECT_INIT(clip->x, clip->y, clip->width, clip->height));
text_renderer = get_text_renderer ();
text_renderer_begin (text_renderer, widget, cr);
@@ -933,4 +933,6 @@ gtk_text_layout_draw (GtkTextLayout *layout,
text_renderer_end (text_renderer);
g_slist_free (line_list);
+
+ cairo_destroy (cr);
}
diff --git a/gtk/gtktextdisplayprivate.h b/gtk/gtktextdisplayprivate.h
index ce6bc7168e..e4385e5b47 100644
--- a/gtk/gtktextdisplayprivate.h
+++ b/gtk/gtktextdisplayprivate.h
@@ -86,13 +86,14 @@ G_BEGIN_DECLS
/* The drawable should be pre-initialized to your preferred background.
* widget - Widget to grab some style info from
- * cr - Context to render to, matrix set so that (0, 0)
+ * snapshot - Snapshot to render to, matrix set so that (0, 0)
* is the top left of the layout
+ * clip - visible area
*/
-GDK_AVAILABLE_IN_ALL
-void gtk_text_layout_draw (GtkTextLayout *layout,
- GtkWidget *widget,
- cairo_t *cr);
+void gtk_text_layout_snapshot (GtkTextLayout *layout,
+ GtkWidget *widget,
+ GtkSnapshot *snapshot,
+ const GdkRectangle *clip);
G_END_DECLS
diff --git a/gtk/gtktextutil.c b/gtk/gtktextutil.c
index 0298f88f03..9858bec5ad 100644
--- a/gtk/gtktextutil.c
+++ b/gtk/gtktextutil.c
@@ -276,7 +276,6 @@ gtk_text_util_create_rich_drag_icon (GtkWidget *widget,
GtkTextAttributes *style;
PangoContext *ltr_context, *rtl_context;
GtkTextIter iter;
- cairo_t *cr;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
@@ -333,12 +332,9 @@ gtk_text_util_create_rich_drag_icon (GtkWidget *widget,
layout_height = MIN (layout_height, DRAG_ICON_MAX_HEIGHT);
snapshot = gtk_snapshot_new ();
- cr = gtk_snapshot_append_cairo (snapshot,
- &GRAPHENE_RECT_INIT (0, 0, layout_width, layout_height));
- gtk_text_layout_draw (layout, widget, cr);
+ gtk_text_layout_snapshot (layout, widget, snapshot, &(GdkRectangle) { 0, 0, layout_width, layout_height });
- cairo_destroy (cr);
g_object_unref (layout);
g_object_unref (new_buffer);
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 11cfecd986..357a7cb3b7 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -5303,8 +5303,8 @@ gtk_text_view_motion (GtkEventController *controller,
}
static void
-gtk_text_view_paint (GtkWidget *widget,
- cairo_t *cr)
+gtk_text_view_paint (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GtkTextView *text_view;
GtkTextViewPrivate *priv;
@@ -5335,19 +5335,24 @@ gtk_text_view_paint (GtkWidget *widget,
area->width, area->height);
#endif
- cairo_save (cr);
- cairo_translate (cr, -priv->xoffset, -priv->yoffset);
+ gtk_snapshot_offset (snapshot, -priv->xoffset, -priv->yoffset);
- gtk_text_layout_draw (priv->layout,
- widget,
- cr);
+ gtk_text_layout_snapshot (priv->layout,
+ widget,
+ snapshot,
+ &(GdkRectangle) {
+ priv->xoffset,
+ priv->yoffset,
+ gtk_widget_get_width (widget),
+ gtk_widget_get_height (widget)
+ });
- cairo_restore (cr);
+ gtk_snapshot_offset (snapshot, priv->xoffset, priv->yoffset);
}
static void
-draw_text (GtkWidget *widget,
- cairo_t *cr)
+draw_text (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
GtkTextViewPrivate *priv = text_view->priv;
@@ -5355,32 +5360,30 @@ draw_text (GtkWidget *widget,
context = gtk_widget_get_style_context (widget);
gtk_style_context_save_to_node (context, text_view->priv->text_window->css_node);
- gtk_render_background (context, cr,
- -priv->xoffset, -priv->yoffset - priv->top_margin,
- MAX (SCREEN_WIDTH (text_view), priv->width),
- MAX (SCREEN_HEIGHT (text_view), priv->height));
- gtk_render_frame (context, cr,
- -priv->xoffset, -priv->yoffset - priv->top_margin,
- MAX (SCREEN_WIDTH (text_view), priv->width),
- MAX (SCREEN_HEIGHT (text_view), priv->height));
+ gtk_snapshot_render_background (snapshot, context,
+ -priv->xoffset, -priv->yoffset - priv->top_margin,
+ MAX (SCREEN_WIDTH (text_view), priv->width),
+ MAX (SCREEN_HEIGHT (text_view), priv->height));
+ gtk_snapshot_render_frame (snapshot, context,
+ -priv->xoffset, -priv->yoffset - priv->top_margin,
+ MAX (SCREEN_WIDTH (text_view), priv->width),
+ MAX (SCREEN_HEIGHT (text_view), priv->height));
gtk_style_context_restore (context);
- if (GTK_TEXT_VIEW_GET_CLASS (text_view)->draw_layer != NULL)
+ if (GTK_TEXT_VIEW_GET_CLASS (text_view)->snapshot_layer != NULL)
{
- cairo_save (cr);
- cairo_translate (cr, -priv->xoffset, -priv->yoffset);
- GTK_TEXT_VIEW_GET_CLASS (text_view)->draw_layer (text_view, GTK_TEXT_VIEW_LAYER_BELOW_TEXT, cr);
- cairo_restore (cr);
+ gtk_snapshot_offset (snapshot, -priv->xoffset, -priv->yoffset);
+ GTK_TEXT_VIEW_GET_CLASS (text_view)->snapshot_layer (text_view, GTK_TEXT_VIEW_LAYER_BELOW_TEXT, snapshot);
+ gtk_snapshot_offset (snapshot, priv->xoffset, priv->yoffset);
}
- gtk_text_view_paint (widget, cr);
+ gtk_text_view_paint (widget, snapshot);
- if (GTK_TEXT_VIEW_GET_CLASS (text_view)->draw_layer != NULL)
+ if (GTK_TEXT_VIEW_GET_CLASS (text_view)->snapshot_layer != NULL)
{
- cairo_save (cr);
- cairo_translate (cr, -priv->xoffset, -priv->yoffset);
- GTK_TEXT_VIEW_GET_CLASS (text_view)->draw_layer (text_view, GTK_TEXT_VIEW_LAYER_ABOVE_TEXT, cr);
- cairo_restore (cr);
+ gtk_snapshot_offset (snapshot, -priv->xoffset, -priv->yoffset);
+ GTK_TEXT_VIEW_GET_CLASS (text_view)->snapshot_layer (text_view, GTK_TEXT_VIEW_LAYER_ABOVE_TEXT, snapshot);
+ gtk_snapshot_offset (snapshot, priv->xoffset, priv->yoffset);
}
}
@@ -5413,7 +5416,6 @@ gtk_text_view_snapshot (GtkWidget *widget,
GSList *tmp_list;
GtkStyleContext *context;
graphene_rect_t bounds;
- cairo_t *cr;
graphene_rect_init (&bounds,
0, 0,
@@ -5422,17 +5424,13 @@ gtk_text_view_snapshot (GtkWidget *widget,
gtk_snapshot_push_clip (snapshot, &bounds);
- cr = gtk_snapshot_append_cairo (snapshot, &bounds);
-
context = gtk_widget_get_style_context (widget);
text_window_set_padding (GTK_TEXT_VIEW (widget), context);
DV(g_print (">Exposed ("G_STRLOC")\n"));
- cairo_save (cr);
- draw_text (widget, cr);
- cairo_destroy (cr);
+ draw_text (widget, snapshot);
paint_border_window (GTK_TEXT_VIEW (widget), snapshot, priv->left_window, context);
paint_border_window (GTK_TEXT_VIEW (widget), snapshot, priv->right_window, context);
diff --git a/gtk/gtktextview.h b/gtk/gtktextview.h
index 89629948d8..09840f29e8 100644
--- a/gtk/gtktextview.h
+++ b/gtk/gtktextview.h
@@ -72,7 +72,7 @@ typedef enum
* @GTK_TEXT_VIEW_LAYER_ABOVE_TEXT: The layer rendered above the text.
*
* Used to reference the layers of #GtkTextView for the purpose of customized
- * drawing with the ::draw_layer vfunc.
+ * drawing with the ::snapshot_layer vfunc.
*/
typedef enum
{
@@ -143,7 +143,7 @@ struct _GtkTextView
* @create_buffer: The create_buffer vfunc is called to create a #GtkTextBuffer
* for the text view. The default implementation is to just call
* gtk_text_buffer_new().
- * @draw_layer: The draw_layer vfunc is called before and after the text
+ * @snapshot_layer: The snapshot_layer vfunc is called before and after the text
* view is drawing its own text. Applications can override this vfunc
* in a subclass to draw customized content underneath or above the
* text. In the %GTK_TEXT_VIEW_LAYER_BELOW_TEXT and %GTK_TEXT_VIEW_LAYER_ABOVE_TEXT
@@ -177,9 +177,9 @@ struct _GtkTextViewClass
void (* paste_clipboard) (GtkTextView *text_view);
void (* toggle_overwrite) (GtkTextView *text_view);
GtkTextBuffer * (* create_buffer) (GtkTextView *text_view);
- void (* draw_layer) (GtkTextView *text_view,
+ void (* snapshot_layer) (GtkTextView *text_view,
GtkTextViewLayer layer,
- cairo_t *cr);
+ GtkSnapshot *snapshot);
gboolean (* extend_selection) (GtkTextView *text_view,
GtkTextExtendSelection granularity,
const GtkTextIter *location,
diff --git a/tests/testtextview.c b/tests/testtextview.c
index f24014f273..d746ec2419 100644
--- a/tests/testtextview.c
+++ b/tests/testtextview.c
@@ -13,25 +13,25 @@ typedef struct {
G_DEFINE_TYPE (MyTextView, my_text_view, GTK_TYPE_TEXT_VIEW);
-static void draw_background (GtkWidget *widget, cairo_t *cr);
+static void snapshot_background (GtkWidget *widget, GtkSnapshot *snapshot);
static void
my_text_view_init (MyTextView *text_view)
{
}
-static void my_text_view_draw_layer (GtkTextView *textview,
- GtkTextViewLayer layer,
- cairo_t *cr)
+static void my_text_view_snapshot_layer (GtkTextView *textview,
+ GtkTextViewLayer layer,
+ GtkSnapshot *snapshot)
{
if (layer == GTK_TEXT_VIEW_LAYER_BELOW_TEXT)
- draw_background (GTK_WIDGET (textview), cr);
+ snapshot_background (GTK_WIDGET (textview), snapshot);
}
static void
my_text_view_class_init (MyTextViewClass *klass)
{
- GTK_TEXT_VIEW_CLASS (klass)->draw_layer = my_text_view_draw_layer;
+ GTK_TEXT_VIEW_CLASS (klass)->snapshot_layer = my_text_view_snapshot_layer;
}
static void
@@ -142,51 +142,28 @@ insert_text (GtkTextBuffer *buffer)
#define CHECK_DARK (1.0 / 3.0)
#define CHECK_LIGHT (2.0 / 3.0)
-static cairo_pattern_t *
-get_checkered (void)
-{
- /* need to respect pixman's stride being a multiple of 4 */
- static unsigned char data[8] = { 0xFF, 0x00, 0x00, 0x00,
- 0x00, 0xFF, 0x00, 0x00 };
- static cairo_surface_t *checkered = NULL;
- cairo_pattern_t *pattern;
-
- if (checkered == NULL)
- {
- checkered = cairo_image_surface_create_for_data (data,
- CAIRO_FORMAT_A8,
- 2, 2, 4);
- }
-
- pattern = cairo_pattern_create_for_surface (checkered);
- cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
- cairo_pattern_set_filter (pattern, CAIRO_FILTER_NEAREST);
-
- return pattern;
-}
-
static void
-draw_background (GtkWidget *widget, cairo_t *cr)
+snapshot_background (GtkWidget *widget,
+ GtkSnapshot *snapshot)
{
GdkRectangle visible_rect;
- cairo_pattern_t *pat;
-
- cairo_save (cr);
gtk_text_view_get_visible_rect (GTK_TEXT_VIEW (widget), &visible_rect);
- cairo_translate (cr, -visible_rect.x, -visible_rect.y);
-
- cairo_set_source_rgb (cr, CHECK_DARK, CHECK_DARK, CHECK_DARK);
- cairo_paint (cr);
-
- cairo_set_source_rgb (cr, CHECK_LIGHT, CHECK_LIGHT, CHECK_LIGHT);
- cairo_scale (cr, CHECK_SIZE, CHECK_SIZE);
-
- pat = get_checkered ();
- cairo_mask (cr, pat);
- cairo_pattern_destroy (pat);
- cairo_restore (cr);
+ gtk_snapshot_append_color (snapshot,
+ &(GdkRGBA) { CHECK_DARK, CHECK_DARK, CHECK_DARK, 1.0 },
+ &GRAPHENE_RECT_INIT(visible_rect.x, visible_rect.y, visible_rect.width, visible_rect.height));
+
+ gtk_snapshot_push_repeat (snapshot,
+ &GRAPHENE_RECT_INIT(visible_rect.x, visible_rect.y, visible_rect.width, visible_rect.height),
+ &GRAPHENE_RECT_INIT(visible_rect.x, visible_rect.y, CHECK_SIZE * 2, CHECK_SIZE * 2));
+ gtk_snapshot_append_color (snapshot,
+ &(GdkRGBA) { CHECK_LIGHT, CHECK_LIGHT, CHECK_LIGHT, 1.0 },
+ &GRAPHENE_RECT_INIT(visible_rect.x, visible_rect.y, CHECK_SIZE, CHECK_SIZE));
+ gtk_snapshot_append_color (snapshot,
+ &(GdkRGBA) { CHECK_LIGHT, CHECK_LIGHT, CHECK_LIGHT, 1.0 },
+ &GRAPHENE_RECT_INIT(visible_rect.x + CHECK_SIZE, visible_rect.y + CHECK_SIZE, CHECK_SIZE, CHECK_SIZE));
+ gtk_snapshot_pop (snapshot);
}
int