[gtk/wip/baedert/css-values: 72/102] cssimagelinear: Use count+array for the color stops, not GArray



commit 00aa4f0597a5af148fcf7f5fe6cd0d082f97ff7a
Author: Timm Bäder <mail baedert org>
Date:   Sat Jan 11 09:05:07 2020 +0100

    cssimagelinear: Use count+array for the color stops, not GArray
    
    This makse sense but will also make later changes to GtkCssImageLinear
    simpler.

 gtk/gtkcssimagelinear.c        | 176 ++++++++++++++++++++++-------------------
 gtk/gtkcssimagelinearprivate.h |   8 +-
 2 files changed, 99 insertions(+), 85 deletions(-)
---
diff --git a/gtk/gtkcssimagelinear.c b/gtk/gtkcssimagelinear.c
index df9efc8b6a..52e9a33e2a 100644
--- a/gtk/gtkcssimagelinear.c
+++ b/gtk/gtkcssimagelinear.c
@@ -36,13 +36,13 @@ gtk_css_image_linear_get_repeating_start_end (GtkCssImageLinear *linear,
                                               double            *start,
                                               double            *end)
 {
-  GtkCssImageLinearColorStop *stop;
+  const GtkCssImageLinearColorStop *stop;
   double pos;
   guint i;
 
   g_assert (linear->repeating);
 
-  stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, 0);
+  stop = &linear->color_stops[0];
   if (stop->offset == NULL)
     *start = 0;
   else
@@ -50,9 +50,9 @@ gtk_css_image_linear_get_repeating_start_end (GtkCssImageLinear *linear,
 
   *end = *start;
 
-  for (i = 0; i < linear->stops->len; i++)
+  for (i = 0; i < linear->n_stops; i++)
     {
-      stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
+      stop = &linear->color_stops[i];
 
       if (stop->offset == NULL)
         continue;
@@ -190,8 +190,7 @@ gtk_css_image_linear_snapshot (GtkCssImage        *image,
         {
           /* repeating gradients with all color stops sharing the same offset
            * get the color of the last color stop */
-          GtkCssImageLinearColorStop *stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop,
-                                                             linear->stops->len - 1);
+          const GtkCssImageLinearColorStop *stop = &linear->color_stops[linear->n_stops - 1];
 
           gtk_snapshot_append_color (snapshot,
                                      gtk_css_color_value_get_rgba (stop->color),
@@ -207,20 +206,18 @@ gtk_css_image_linear_snapshot (GtkCssImage        *image,
 
   offset = start;
   last = -1;
-  stops = g_newa (GskColorStop, linear->stops->len);
+  stops = g_newa (GskColorStop, linear->n_stops);
 
-  for (i = 0; i < linear->stops->len; i++)
+  for (i = 0; i < linear->n_stops; i++)
     {
-      GtkCssImageLinearColorStop *stop;
+      const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
       double pos, step;
-      
-      stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
 
       if (stop->offset == NULL)
         {
           if (i == 0)
             pos = 0.0;
-          else if (i + 1 == linear->stops->len)
+          else if (i + 1 == linear->n_stops)
             pos = 1.0;
           else
             continue;
@@ -235,7 +232,7 @@ gtk_css_image_linear_snapshot (GtkCssImage        *image,
       step = (pos - offset) / (i - last);
       for (last = last + 1; last <= i; last++)
         {
-          stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, last);
+          stop = &linear->color_stops[last];
 
           offset += step;
 
@@ -255,7 +252,7 @@ gtk_css_image_linear_snapshot (GtkCssImage        *image,
           &GRAPHENE_POINT_INIT (width / 2 + x * (start - 0.5), height / 2 + y * (start - 0.5)),
           &GRAPHENE_POINT_INIT (width / 2 + x * (end - 0.5),   height / 2 + y * (end - 0.5)),
           stops,
-          linear->stops->len);
+          linear->n_stops);
     }
   else
     {
@@ -265,13 +262,14 @@ gtk_css_image_linear_snapshot (GtkCssImage        *image,
           &GRAPHENE_POINT_INIT (width / 2 + x * (start - 0.5), height / 2 + y * (start - 0.5)),
           &GRAPHENE_POINT_INIT (width / 2 + x * (end - 0.5),   height / 2 + y * (end - 0.5)),
           stops,
-          linear->stops->len);
+          linear->n_stops);
     }
 }
 
 static guint
 gtk_css_image_linear_parse_color_stop (GtkCssImageLinear *self,
-                                       GtkCssParser      *parser)
+                                       GtkCssParser      *parser,
+                                       GArray            *stop_array)
 {
   GtkCssImageLinearColorStop stop;
 
@@ -295,14 +293,15 @@ gtk_css_image_linear_parse_color_stop (GtkCssImageLinear *self,
       stop.offset = NULL;
     }
 
-  g_array_append_val (self->stops, stop);
+  g_array_append_val (stop_array, stop);
 
   return 1;
 }
 
 static guint
 gtk_css_image_linear_parse_first_arg (GtkCssImageLinear *linear,
-                                      GtkCssParser      *parser)
+                                      GtkCssParser      *parser,
+                                      GArray            *stop_array)
 {
   guint i;
 
@@ -363,31 +362,37 @@ gtk_css_image_linear_parse_first_arg (GtkCssImageLinear *linear,
       linear->angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
       if (linear->angle == NULL)
         return 0;
-      
+
       return 1;
     }
   else
     {
       linear->side = 1 << GTK_CSS_BOTTOM;
-      if (!gtk_css_image_linear_parse_color_stop (linear, parser))
+      if (!gtk_css_image_linear_parse_color_stop (linear, parser, stop_array))
         return 0;
 
       return 2;
     }
 }
 
+typedef struct
+{
+  GtkCssImageLinear *self;
+  GArray *stop_array;
+} ParseData;
+
 static guint
 gtk_css_image_linear_parse_arg (GtkCssParser *parser,
                                 guint         arg,
-                                gpointer      data)
+                                gpointer      user_data)
 {
-  GtkCssImageLinear *self = data;
+  ParseData *parse_data = user_data;
+  GtkCssImageLinear *self = parse_data->self;
 
   if (arg == 0)
-    return gtk_css_image_linear_parse_first_arg (self, parser);
+    return gtk_css_image_linear_parse_first_arg (self, parser, parse_data->stop_array);
   else
-    return gtk_css_image_linear_parse_color_stop (self, parser);
-
+    return gtk_css_image_linear_parse_color_stop (self, parser, parse_data->stop_array);
 }
 
 static gboolean
@@ -395,6 +400,8 @@ gtk_css_image_linear_parse (GtkCssImage  *image,
                             GtkCssParser *parser)
 {
   GtkCssImageLinear *self = GTK_CSS_IMAGE_LINEAR (image);
+  ParseData parse_data;
+  gboolean success;
 
   if (gtk_css_parser_has_function (parser, "repeating-linear-gradient"))
     self->repeating = TRUE;
@@ -406,7 +413,22 @@ gtk_css_image_linear_parse (GtkCssImage  *image,
       return FALSE;
     }
 
-  return gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_linear_parse_arg, self);
+  parse_data.self = self;
+  parse_data.stop_array = g_array_new (TRUE, FALSE, sizeof (GtkCssImageLinearColorStop));
+
+  success = gtk_css_parser_consume_function (parser, 3, G_MAXUINT, gtk_css_image_linear_parse_arg, 
&parse_data);
+
+  if (!success)
+    {
+      g_array_free (parse_data.stop_array, TRUE);
+    }
+  else
+    {
+      self->n_stops = parse_data.stop_array->len;
+      self->color_stops = (GtkCssImageLinearColorStop *)g_array_free (parse_data.stop_array, FALSE);
+    }
+
+  return success;
 }
 
 static void
@@ -446,15 +468,13 @@ gtk_css_image_linear_print (GtkCssImage *image,
       g_string_append (string, ", ");
     }
 
-  for (i = 0; i < linear->stops->len; i++)
+  for (i = 0; i < linear->n_stops; i++)
     {
-      GtkCssImageLinearColorStop *stop;
-      
+      const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
+
       if (i > 0)
         g_string_append (string, ", ");
 
-      stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
-
       _gtk_css_value_print (stop->color, string);
 
       if (stop->offset)
@@ -463,7 +483,7 @@ gtk_css_image_linear_print (GtkCssImage *image,
           _gtk_css_value_print (stop->offset, string);
         }
     }
-  
+
   g_string_append (string, ")");
 }
 
@@ -484,17 +504,16 @@ gtk_css_image_linear_compute (GtkCssImage      *image,
 
   if (linear->angle)
     copy->angle = _gtk_css_value_compute (linear->angle, property_id, provider, style, parent_style);
-  
-  g_array_set_size (copy->stops, linear->stops->len);
-  for (i = 0; i < linear->stops->len; i++)
+
+  copy->n_stops = linear->n_stops;
+  copy->color_stops = g_malloc (sizeof (GtkCssImageLinearColorStop) * copy->n_stops);
+  for (i = 0; i < linear->n_stops; i++)
     {
-      GtkCssImageLinearColorStop *stop, *scopy;
+      const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
+      GtkCssImageLinearColorStop *scopy = &copy->color_stops[i];
 
-      stop = &g_array_index (linear->stops, GtkCssImageLinearColorStop, i);
-      scopy = &g_array_index (copy->stops, GtkCssImageLinearColorStop, i);
-              
       scopy->color = _gtk_css_value_compute (stop->color, property_id, provider, style, parent_style);
-      
+
       if (stop->offset)
         {
           scopy->offset = _gtk_css_value_compute (stop->offset, property_id, provider, style, parent_style);
@@ -528,7 +547,7 @@ gtk_css_image_linear_transition (GtkCssImage *start_image,
   end = GTK_CSS_IMAGE_LINEAR (end_image);
 
   if ((start->repeating != end->repeating)
-      || (start->stops->len != end->stops->len))
+      || (start->n_stops != end->n_stops))
     return GTK_CSS_IMAGE_CLASS (_gtk_css_image_linear_parent_class)->transition (start_image, end_image, 
property_id, progress);
 
   result = g_object_new (GTK_TYPE_CSS_IMAGE_LINEAR, NULL);
@@ -542,43 +561,45 @@ gtk_css_image_linear_transition (GtkCssImage *start_image,
     result->angle = _gtk_css_value_transition (start->angle, end->angle, property_id, progress);
   if (result->angle == NULL)
     goto fail;
-  
-  for (i = 0; i < start->stops->len; i++)
-    {
-      GtkCssImageLinearColorStop stop, *start_stop, *end_stop;
 
-      start_stop = &g_array_index (start->stops, GtkCssImageLinearColorStop, i);
-      end_stop = &g_array_index (end->stops, GtkCssImageLinearColorStop, i);
+  /* Maximum amountof stops */
+  result->color_stops = g_malloc (sizeof (GtkCssImageLinearColorStop) * start->n_stops);
+  result->n_stops = 0;
+  for (i = 0; i < start->n_stops; i++)
+    {
+      const GtkCssImageLinearColorStop *start_stop = &start->color_stops[i];
+      const GtkCssImageLinearColorStop *end_stop = &end->color_stops[i];
+      GtkCssImageLinearColorStop *stop = &result->color_stops[i];
 
       if ((start_stop->offset != NULL) != (end_stop->offset != NULL))
         goto fail;
 
       if (start_stop->offset == NULL)
         {
-          stop.offset = NULL;
+          stop->offset = NULL;
         }
       else
         {
-          stop.offset = _gtk_css_value_transition (start_stop->offset,
-                                                   end_stop->offset,
-                                                   property_id,
-                                                   progress);
-          if (stop.offset == NULL)
+          stop->offset = _gtk_css_value_transition (start_stop->offset,
+                                                    end_stop->offset,
+                                                    property_id,
+                                                    progress);
+          if (stop->offset == NULL)
             goto fail;
         }
 
-      stop.color = _gtk_css_value_transition (start_stop->color,
-                                              end_stop->color,
-                                              property_id,
-                                              progress);
-      if (stop.color == NULL)
+      stop->color = _gtk_css_value_transition (start_stop->color,
+                                               end_stop->color,
+                                               property_id,
+                                               progress);
+      if (stop->color == NULL)
         {
-          if (stop.offset)
-            _gtk_css_value_unref (stop.offset);
+          if (stop->offset)
+            _gtk_css_value_unref (stop->offset);
           goto fail;
         }
 
-      g_array_append_val (result->stops, stop);
+      result->n_stops ++;
     }
 
   return GTK_CSS_IMAGE (result);
@@ -599,15 +620,13 @@ gtk_css_image_linear_equal (GtkCssImage *image1,
   if (linear1->repeating != linear2->repeating ||
       linear1->side != linear2->side ||
       (linear1->side == 0 && !_gtk_css_value_equal (linear1->angle, linear2->angle)) ||
-      linear1->stops->len != linear2->stops->len)
+      linear1->n_stops != linear2->n_stops)
     return FALSE;
 
-  for (i = 0; i < linear1->stops->len; i++)
+  for (i = 0; i < linear1->n_stops; i++)
     {
-      GtkCssImageLinearColorStop *stop1, *stop2;
-
-      stop1 = &g_array_index (linear1->stops, GtkCssImageLinearColorStop, i);
-      stop2 = &g_array_index (linear2->stops, GtkCssImageLinearColorStop, i);
+      const GtkCssImageLinearColorStop *stop1 = &linear1->color_stops[i];
+      const GtkCssImageLinearColorStop *stop2 = &linear2->color_stops[i];
 
       if (!_gtk_css_value_equal0 (stop1->offset, stop2->offset) ||
           !_gtk_css_value_equal (stop1->color, stop2->color))
@@ -621,12 +640,17 @@ static void
 gtk_css_image_linear_dispose (GObject *object)
 {
   GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (object);
+  guint i;
 
-  if (linear->stops)
+  for (i = 0; i < linear->n_stops; i ++)
     {
-      g_array_free (linear->stops, TRUE);
-      linear->stops = NULL;
+      GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
+
+      _gtk_css_value_unref (stop->color);
+      if (stop->offset)
+        _gtk_css_value_unref (stop->offset);
     }
+  g_free (linear->color_stops);
 
   linear->side = 0;
   if (linear->angle)
@@ -654,20 +678,8 @@ _gtk_css_image_linear_class_init (GtkCssImageLinearClass *klass)
   object_class->dispose = gtk_css_image_linear_dispose;
 }
 
-static void
-gtk_css_image_clear_color_stop (gpointer color_stop)
-{
-  GtkCssImageLinearColorStop *stop = color_stop;
-
-  _gtk_css_value_unref (stop->color);
-  if (stop->offset)
-    _gtk_css_value_unref (stop->offset);
-}
-
 static void
 _gtk_css_image_linear_init (GtkCssImageLinear *linear)
 {
-  linear->stops = g_array_new (FALSE, FALSE, sizeof (GtkCssImageLinearColorStop));
-  g_array_set_clear_func (linear->stops, gtk_css_image_clear_color_stop);
 }
 
diff --git a/gtk/gtkcssimagelinearprivate.h b/gtk/gtkcssimagelinearprivate.h
index 42d6907743..438b8396ec 100644
--- a/gtk/gtkcssimagelinearprivate.h
+++ b/gtk/gtkcssimagelinearprivate.h
@@ -45,10 +45,12 @@ struct _GtkCssImageLinear
 {
   GtkCssImage parent;
 
-  guint        side;  /* side the gradient should go to or 0 for angle */
-  GtkCssValue *angle;
-  GArray *stops;
+  guint side;  /* side the gradient should go to or 0 for angle */
   guint repeating :1;
+  GtkCssValue *angle;
+
+  guint n_stops;
+  GtkCssImageLinearColorStop *color_stops;
 };
 
 struct _GtkCssImageLinearClass


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