[gtk+] cellrenderer: Move snapshotting down into cell renderers



commit 677c5bdedf7870e08b246439ba4dddbad5c87028
Author: Benjamin Otte <otte redhat com>
Date:   Fri Dec 23 09:09:42 2016 +0100

    cellrenderer: Move snapshotting down into cell renderers
    
    Now that every call to GtkCellArea is a snapshot call and no more cairo
    calls are left, move the actual differentiation between Cairo and
    Snapshot down to the cell renderer.

 docs/reference/gtk/gtk4-sections.txt |    4 +-
 gtk/gtkcellarea.c                    |  115 +++++++++-------------------------
 gtk/gtkcellarea.h                    |   15 +----
 gtk/gtkcellrenderer.c                |   91 +++++++++++++++++++--------
 gtk/gtkcellrenderer.h                |   12 +++-
 5 files changed, 110 insertions(+), 127 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index d6a9260..d2faa2c 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4052,7 +4052,7 @@ gtk_cell_area_has_renderer
 gtk_cell_area_foreach
 gtk_cell_area_foreach_alloc
 gtk_cell_area_event
-gtk_cell_area_render
+gtk_cell_area_snapshot
 gtk_cell_area_get_cell_allocation
 gtk_cell_area_get_cell_at_position
 gtk_cell_area_create_context
@@ -4170,7 +4170,7 @@ GtkCellRendererClass
 gtk_cell_renderer_class_set_accessible_type
 gtk_cell_renderer_get_aligned_area
 gtk_cell_renderer_get_size
-gtk_cell_renderer_render
+gtk_cell_renderer_snapshot
 gtk_cell_renderer_activate
 gtk_cell_renderer_start_editing
 gtk_cell_renderer_stop_editing
diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c
index c50ea1e..63305e0 100644
--- a/gtk/gtkcellarea.c
+++ b/gtk/gtkcellarea.c
@@ -390,10 +390,10 @@ static gint      gtk_cell_area_real_event                          (GtkCellArea
                                                                     GdkEvent             *event,
                                                                     const GdkRectangle   *cell_area,
                                                                     GtkCellRendererState  flags);
-static void      gtk_cell_area_real_render                         (GtkCellArea          *area,
+static void      gtk_cell_area_real_snapshot                       (GtkCellArea          *area,
                                                                     GtkCellAreaContext   *context,
                                                                     GtkWidget            *widget,
-                                                                    cairo_t              *cr,
+                                                                    GtkSnapshot          *snapshot,
                                                                     const GdkRectangle   *background_area,
                                                                     const GdkRectangle   *cell_area,
                                                                     GtkCellRendererState  flags,
@@ -487,7 +487,7 @@ typedef struct {
 typedef struct {
   GtkCellArea         *area;
   GtkWidget           *widget;
-  cairo_t             *cr;
+  GtkSnapshot         *snapshot;
   GdkRectangle         focus_rect;
   GtkCellRendererState render_flags;
   guint                paint_focus : 1;
@@ -653,7 +653,7 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
   class->foreach          = gtk_cell_area_real_foreach;
   class->foreach_alloc    = gtk_cell_area_real_foreach_alloc;
   class->event            = gtk_cell_area_real_event;
-  class->render           = gtk_cell_area_real_render;
+  class->snapshot         = gtk_cell_area_real_snapshot;
   class->apply_attributes = gtk_cell_area_real_apply_attributes;
 
   /* geometry */
@@ -1110,10 +1110,10 @@ gtk_cell_area_real_event (GtkCellArea          *area,
 }
 
 static gboolean
-render_cell (GtkCellRenderer        *renderer,
-             const GdkRectangle     *cell_area,
-             const GdkRectangle     *cell_background,
-             CellRenderData         *data)
+snapshot_cell (GtkCellRenderer        *renderer,
+               const GdkRectangle     *cell_area,
+               const GdkRectangle     *cell_background,
+               CellRenderData         *data)
 {
   GtkCellRenderer      *focus_cell;
   GtkCellRendererState  flags;
@@ -1145,27 +1145,27 @@ render_cell (GtkCellRenderer        *renderer,
         }
     }
 
-  gtk_cell_renderer_render (renderer, data->cr, data->widget,
-                            cell_background, &inner_area, flags);
+  gtk_cell_renderer_snapshot (renderer, data->snapshot, data->widget,
+                              cell_background, &inner_area, flags);
 
   return FALSE;
 }
 
 static void
-gtk_cell_area_real_render (GtkCellArea          *area,
-                           GtkCellAreaContext   *context,
-                           GtkWidget            *widget,
-                           cairo_t              *cr,
-                           const GdkRectangle   *background_area,
-                           const GdkRectangle   *cell_area,
-                           GtkCellRendererState  flags,
-                           gboolean              paint_focus)
+gtk_cell_area_real_snapshot (GtkCellArea          *area,
+                             GtkCellAreaContext   *context,
+                             GtkWidget            *widget,
+                             GtkSnapshot          *snapshot,
+                             const GdkRectangle   *background_area,
+                             const GdkRectangle   *cell_area,
+                             GtkCellRendererState  flags,
+                             gboolean              paint_focus)
 {
   CellRenderData render_data =
     {
       area,
       widget,
-      cr,
+      snapshot,
       { 0, },
       flags,
       paint_focus,
@@ -1188,7 +1188,7 @@ gtk_cell_area_real_render (GtkCellArea          *area,
     render_data.focus_all = TRUE;
 
   gtk_cell_area_foreach_alloc (area, context, widget, cell_area, background_area,
-                               (GtkCellAllocCallback)render_cell, &render_data);
+                               (GtkCellAllocCallback) snapshot_cell, &render_data);
 
   if (render_data.paint_focus &&
       render_data.focus_rect.width != 0 &&
@@ -1203,17 +1203,11 @@ gtk_cell_area_real_render (GtkCellArea          *area,
       renderer_state = gtk_cell_renderer_get_state (NULL, widget, flags);
       gtk_style_context_set_state (style_context, renderer_state);
 
-      cairo_save (cr);
-
-      gdk_cairo_rectangle (cr, background_area);
-      cairo_clip (cr);
-
-      gtk_render_focus (style_context, cr,
-                        render_data.focus_rect.x,     render_data.focus_rect.y,
-                        render_data.focus_rect.width, render_data.focus_rect.height);
+      gtk_snapshot_render_focus (snapshot, style_context,
+                                 render_data.focus_rect.x,     render_data.focus_rect.y,
+                                 render_data.focus_rect.width, render_data.focus_rect.height);
 
       gtk_style_context_restore (style_context);
-      cairo_restore (cr);
     }
 }
 
@@ -1805,50 +1799,6 @@ gtk_cell_area_event (GtkCellArea          *area,
 }
 
 /**
- * gtk_cell_area_render:
- * @area: a #GtkCellArea
- * @context: the #GtkCellAreaContext for this row of data.
- * @widget: the #GtkWidget that @area is rendering to
- * @cr: the #cairo_t to render with
- * @background_area: the @widget relative coordinates for @area’s background
- * @cell_area: the @widget relative coordinates for @area
- * @flags: the #GtkCellRendererState for @area in this row.
- * @paint_focus: whether @area should paint focus on focused cells for focused rows or not.
- *
- * Renders @area’s cells according to @area’s layout onto @widget at
- * the given coordinates.
- *
- * Since: 3.0
- */
-void
-gtk_cell_area_render (GtkCellArea          *area,
-                      GtkCellAreaContext   *context,
-                      GtkWidget            *widget,
-                      cairo_t              *cr,
-                      const GdkRectangle   *background_area,
-                      const GdkRectangle   *cell_area,
-                      GtkCellRendererState  flags,
-                      gboolean              paint_focus)
-{
-  GtkCellAreaClass *class;
-
-  g_return_if_fail (GTK_IS_CELL_AREA (area));
-  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
-  g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (cr != NULL);
-  g_return_if_fail (background_area != NULL);
-  g_return_if_fail (cell_area != NULL);
-
-  class = GTK_CELL_AREA_GET_CLASS (area);
-
-  if (class->render)
-    class->render (area, context, widget, cr, background_area, cell_area, flags, paint_focus);
-  else
-    g_warning ("GtkCellAreaClass::render not implemented for '%s'",
-               g_type_name (G_TYPE_FROM_INSTANCE (area)));
-}
-
-/**
  * gtk_cell_area_snapshot:
  * @area: a #GtkCellArea
  * @context: the #GtkCellAreaContext for this row of data.
@@ -1874,7 +1824,7 @@ gtk_cell_area_snapshot (GtkCellArea          *area,
                         GtkCellRendererState  flags,
                         gboolean              paint_focus)
 {
-  cairo_t *cr;
+  GtkCellAreaClass *class;
 
   g_return_if_fail (GTK_IS_CELL_AREA (area));
   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
@@ -1883,16 +1833,13 @@ gtk_cell_area_snapshot (GtkCellArea          *area,
   g_return_if_fail (background_area != NULL);
   g_return_if_fail (cell_area != NULL);
 
-  cr = gtk_snapshot_append_cairo_node (snapshot,
-                                       &GRAPHENE_RECT_INIT (
-                                           background_area->x,
-                                           background_area->y,
-                                           background_area->width,
-                                           background_area->height
-                                       ),
-                                       "CellArea<%s>", G_OBJECT_TYPE_NAME (area));
-  gtk_cell_area_render (area, context, widget, cr, background_area, cell_area, flags, paint_focus);
-  cairo_destroy (cr);
+  class = GTK_CELL_AREA_GET_CLASS (area);
+
+  if (class->snapshot)
+    class->snapshot (area, context, widget, snapshot, background_area, cell_area, flags, paint_focus);
+  else
+    g_warning ("GtkCellAreaClass::snapshot not implemented for '%s'",
+               g_type_name (G_TYPE_FROM_INSTANCE (area)));
 }
 
 static gboolean
diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h
index d719ba2..ac1fc19 100644
--- a/gtk/gtkcellarea.h
+++ b/gtk/gtkcellarea.h
@@ -112,7 +112,7 @@ struct _GtkCellArea
  * @event: Handle an event in the area, this is generally used to activate
  *     a cell at the event location for button events but can also be used
  *     to generically pass events to #GtkWidgets drawn onto the area.
- * @render: Actually render the area’s cells to the specified rectangle,
+ * @snapshot: Actually snapshot the area’s cells to the specified rectangle,
  *     @background_area should be correctly distributed to the cells
  *     corresponding background areas.
  * @apply_attributes: Apply the cell attributes to the cells. This is
@@ -198,10 +198,10 @@ struct _GtkCellAreaClass
                                                           GdkEvent                *event,
                                                           const GdkRectangle      *cell_area,
                                                           GtkCellRendererState     flags);
-  void               (* render)                          (GtkCellArea             *area,
+  void               (* snapshot)                        (GtkCellArea             *area,
                                                           GtkCellAreaContext      *context,
                                                           GtkWidget               *widget,
-                                                          cairo_t                 *cr,
+                                                          GtkSnapshot             *snapshot,
                                                           const GdkRectangle      *background_area,
                                                           const GdkRectangle      *cell_area,
                                                           GtkCellRendererState     flags,
@@ -308,15 +308,6 @@ gint                  gtk_cell_area_event                          (GtkCellArea
                                                                     GdkEvent             *event,
                                                                     const GdkRectangle   *cell_area,
                                                                     GtkCellRendererState  flags);
-GDK_AVAILABLE_IN_ALL
-void                  gtk_cell_area_render                         (GtkCellArea          *area,
-                                                                    GtkCellAreaContext   *context,
-                                                                    GtkWidget            *widget,
-                                                                    cairo_t              *cr,
-                                                                    const GdkRectangle   *background_area,
-                                                                    const GdkRectangle   *cell_area,
-                                                                    GtkCellRendererState  flags,
-                                                                    gboolean              paint_focus);
 GDK_AVAILABLE_IN_3_90
 void                  gtk_cell_area_snapshot                       (GtkCellArea          *area,
                                                                     GtkCellAreaContext   *context,
diff --git a/gtk/gtkcellrenderer.c b/gtk/gtkcellrenderer.c
index b4b03bd..048f82a 100644
--- a/gtk/gtkcellrenderer.c
+++ b/gtk/gtkcellrenderer.c
@@ -43,7 +43,7 @@
  * CellRenderer keep any permanent state around.  Instead, any state is set
  * just prior to use using #GObjects property system.  Then, the
  * cell is measured using gtk_cell_renderer_get_size(). Finally, the cell
- * is rendered in the correct location using gtk_cell_renderer_render().
+ * is rendered in the correct location using gtk_cell_renderer_snapshot().
  *
  * There are a number of rules that must be followed when writing a new
  * #GtkCellRenderer.  First and foremost, it’s important that a certain set
@@ -83,6 +83,12 @@ static void gtk_cell_renderer_set_property  (GObject              *object,
 static void set_cell_bg_color               (GtkCellRenderer      *cell,
                                             GdkRGBA              *rgba);
 
+static void gtk_cell_renderer_real_snapshot (GtkCellRenderer      *cell,
+                                             GtkSnapshot          *snapshot,
+                                             GtkWidget            *widget,
+                                             const GdkRectangle   *background_area,
+                                             const GdkRectangle   *cell_area,
+                                             GtkCellRendererState  flags);
 /* Fallback GtkCellRenderer    implementation to use remaining ->get_size() implementations */
 static GtkSizeRequestMode gtk_cell_renderer_real_get_request_mode(GtkCellRenderer         *cell);
 static void gtk_cell_renderer_real_get_preferred_width           (GtkCellRenderer         *cell,
@@ -203,6 +209,7 @@ gtk_cell_renderer_class_init (GtkCellRendererClass *class)
   object_class->set_property = gtk_cell_renderer_set_property;
 
   class->render = NULL;
+  class->snapshot = gtk_cell_renderer_real_snapshot;
   class->get_size = NULL;
   class->get_request_mode               = gtk_cell_renderer_real_get_request_mode;
   class->get_preferred_width            = gtk_cell_renderer_real_get_preferred_width;
@@ -680,7 +687,7 @@ set_cell_bg_color (GtkCellRenderer *cell,
  *
  * Obtains the width and height needed to render the cell. Used by view 
  * widgets to determine the appropriate size for the cell_area passed to
- * gtk_cell_renderer_render().  If @cell_area is not %NULL, fills in the
+ * gtk_cell_renderer_snapshot().  If @cell_area is not %NULL, fills in the
  * x and y offsets (if set) of the cell relative to this location. 
  *
  * Please note that the values set in @width and @height, as well as those 
@@ -716,9 +723,9 @@ gtk_cell_renderer_get_size (GtkCellRenderer    *cell,
 }
 
 /**
- * gtk_cell_renderer_render:
+ * gtk_cell_renderer_snapshot:
  * @cell: a #GtkCellRenderer
- * @cr: a cairo context to draw to
+ * @snapshot: a #GtkSnapshot to draw to
  * @widget: the widget owning @window
  * @background_area: entire cell area (including tree expanders and maybe 
  *    padding on the sides)
@@ -732,14 +739,16 @@ gtk_cell_renderer_get_size (GtkCellRenderer    *cell,
  * blank space around the cell, and also the area containing the tree expander;
  * so the @background_area rectangles for all cells tile to cover the entire
  * @window.
+ *
+ * Since: 3.90
  **/
 void
-gtk_cell_renderer_render (GtkCellRenderer      *cell,
-                          cairo_t              *cr,
-                          GtkWidget            *widget,
-                          const GdkRectangle   *background_area,
-                          const GdkRectangle   *cell_area,
-                          GtkCellRendererState  flags)
+gtk_cell_renderer_snapshot (GtkCellRenderer      *cell,
+                            GtkSnapshot          *snapshot,
+                            GtkWidget            *widget,
+                            const GdkRectangle   *background_area,
+                            const GdkRectangle   *cell_area,
+                            GtkCellRendererState  flags)
 {
   gboolean selected = FALSE;
   GtkCellRendererPrivate *priv = cell->priv;
@@ -747,22 +756,28 @@ gtk_cell_renderer_render (GtkCellRenderer      *cell,
   GtkStateFlags state;
 
   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
-  g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
-  g_return_if_fail (cr != NULL);
+  g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot != NULL);
+  g_return_if_fail (snapshot != NULL);
 
   selected = (flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED;
 
-  cairo_save (cr);
-
   if (priv->cell_background_set && !selected)
     {
-      gdk_cairo_rectangle (cr, background_area);
-      gdk_cairo_set_source_rgba (cr, &priv->cell_background);
-      cairo_fill (cr);
+      gtk_snapshot_append_color_node (snapshot,
+                                      &priv->cell_background,
+                                      &GRAPHENE_RECT_INIT (
+                                          background_area->x, background_area->y,
+                                          background_area->width, background_area->height
+                                      ),
+                                      "CellBackground");
     }
 
-  gdk_cairo_rectangle (cr, background_area);
-  cairo_clip (cr);
+  gtk_snapshot_push_clip (snapshot,
+                          &GRAPHENE_RECT_INIT (
+                              background_area->x, background_area->y,
+                              background_area->width, background_area->height
+                          ),
+                          "CellClip");
 
   context = gtk_widget_get_style_context (widget);
 
@@ -772,14 +787,14 @@ gtk_cell_renderer_render (GtkCellRenderer      *cell,
   state = gtk_cell_renderer_get_state (cell, widget, flags);
   gtk_style_context_set_state (context, state);
 
-  GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
-                                              cr,
-                                             widget,
-                                             background_area,
-                                             cell_area,
-                                             flags);
+  GTK_CELL_RENDERER_GET_CLASS (cell)->snapshot (cell,
+                                                snapshot,
+                                                widget,
+                                                background_area,
+                                                cell_area,
+                                                flags);
   gtk_style_context_restore (context);
-  cairo_restore (cr);
+  gtk_snapshot_pop_and_append (snapshot);
 }
 
 /**
@@ -1241,6 +1256,30 @@ gtk_cell_renderer_stop_editing (GtkCellRenderer *cell,
 }
 
 static void
+gtk_cell_renderer_real_snapshot (GtkCellRenderer      *cell,
+                                 GtkSnapshot          *snapshot,
+                                 GtkWidget            *widget,
+                                 const GdkRectangle   *background_area,
+                                 const GdkRectangle   *cell_area,
+                                 GtkCellRendererState  flags)
+{
+  cairo_t *cr;
+
+  g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
+
+  cr = gtk_snapshot_append_cairo_node (snapshot,
+                                       &GRAPHENE_RECT_INIT (
+                                           background_area->x,
+                                           background_area->y,
+                                           background_area->width,
+                                           background_area->height
+                                       ),
+                                       "CellFallback<%s>", G_OBJECT_TYPE_NAME (cell));
+  GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell, cr, widget, background_area, cell_area, flags);
+  cairo_destroy (cr);
+}
+
+static void
 gtk_cell_renderer_real_get_preferred_size (GtkCellRenderer   *cell,
                                            GtkWidget         *widget,
                                            GtkOrientation     orientation,
diff --git a/gtk/gtkcellrenderer.h b/gtk/gtkcellrenderer.h
index 71b5465..6ac40b3 100644
--- a/gtk/gtkcellrenderer.h
+++ b/gtk/gtkcellrenderer.h
@@ -151,6 +151,12 @@ struct _GtkCellRendererClass
                                                           const GdkRectangle   *background_area,
                                                           const GdkRectangle   *cell_area,
                                                           GtkCellRendererState  flags);
+  void               (* snapshot)                        (GtkCellRenderer      *cell,
+                                                          GtkSnapshot          *snapshot,
+                                                          GtkWidget            *widget,
+                                                          const GdkRectangle   *background_area,
+                                                          const GdkRectangle   *cell_area,
+                                                          GtkCellRendererState  flags);
   gboolean           (* activate)                        (GtkCellRenderer      *cell,
                                                           GdkEvent             *event,
                                                           GtkWidget            *widget,
@@ -229,9 +235,9 @@ void             gtk_cell_renderer_get_size       (GtkCellRenderer      *cell,
                                                    gint                 *y_offset,
                                                    gint                 *width,
                                                    gint                 *height);
-GDK_AVAILABLE_IN_ALL
-void             gtk_cell_renderer_render         (GtkCellRenderer      *cell,
-                                                   cairo_t              *cr,
+GDK_AVAILABLE_IN_3_90
+void             gtk_cell_renderer_snapshot       (GtkCellRenderer      *cell,
+                                                   GtkSnapshot          *snapshot,
                                                   GtkWidget            *widget,
                                                   const GdkRectangle   *background_area,
                                                   const GdkRectangle   *cell_area,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]