diff options
author | Benjamin Otte <otte@redhat.com> | 2018-07-14 05:26:33 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2018-07-14 05:27:54 +0200 |
commit | cbb1e74bb5be69d9538c71a47e238248e474bea5 (patch) | |
tree | 08754b1e8fc623232aeea03b2eabd7e740a7dd90 | |
parent | 6afb6bb9d2c81136cddab97a541b1f8a863757da (diff) | |
download | gtk+-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.c | 35 | ||||
-rw-r--r-- | gtk/gtktextdisplay.c | 20 | ||||
-rw-r--r-- | gtk/gtktextdisplayprivate.h | 11 | ||||
-rw-r--r-- | gtk/gtktextutil.c | 6 | ||||
-rw-r--r-- | gtk/gtktextview.c | 68 | ||||
-rw-r--r-- | gtk/gtktextview.h | 8 | ||||
-rw-r--r-- | tests/testtextview.c | 67 |
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 |