From df08387e35c1376bc1c5f66f53607b4258c35192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 08:23:17 +0200 Subject: [PATCH 01/18] csscalcvalue: Avoid allocating memory in compute() We already know how many values we're going to have, it's value->n_terms. --- gtk/gtkcsscalcvalue.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/gtk/gtkcsscalcvalue.c b/gtk/gtkcsscalcvalue.c index 55fb47a43e..330f3c0724 100644 --- a/gtk/gtkcsscalcvalue.c +++ b/gtk/gtkcsscalcvalue.c @@ -50,22 +50,21 @@ gtk_css_value_calc_free (GtkCssValue *value) static GtkCssValue *gtk_css_calc_value_new (gsize n_terms); static GtkCssValue * -gtk_css_value_new_from_array (GPtrArray *array) +gtk_css_value_new_from_array (GtkCssValue **values, + guint n_values) { GtkCssValue *result; - - if (array->len > 1) + + if (n_values > 1) { - result = gtk_css_calc_value_new (array->len); - memcpy (result->terms, array->pdata, array->len * sizeof (GtkCssValue *)); + result = gtk_css_calc_value_new (n_values); + memcpy (result->terms, values, n_values * sizeof (GtkCssValue *)); } else { - result = g_ptr_array_index (array, 0); + result = values[0]; } - g_ptr_array_free (array, TRUE); - return result; } @@ -105,26 +104,28 @@ gtk_css_value_calc_compute (GtkCssValue *value, GtkCssStyle *parent_style) { GtkCssValue *result; - GPtrArray *array; gboolean changed = FALSE; gsize i; + GtkCssValue **new_values; + + new_values = g_alloca (sizeof (GtkCssValue *) * value->n_terms); - array = g_ptr_array_new (); for (i = 0; i < value->n_terms; i++) { GtkCssValue *computed = _gtk_css_value_compute (value->terms[i], property_id, provider, style, parent_style); changed |= computed != value->terms[i]; - gtk_css_calc_array_add (array, computed); + new_values[i] = computed; } if (changed) { - result = gtk_css_value_new_from_array (array); + result = gtk_css_value_new_from_array (new_values, value->n_terms); } else { - g_ptr_array_set_free_func (array, (GDestroyNotify) _gtk_css_value_unref); - g_ptr_array_free (array, TRUE); + for (i = 0; i < value->n_terms; i++) + gtk_css_value_unref (new_values[i]); + result = _gtk_css_value_ref (value); } @@ -279,6 +280,7 @@ gtk_css_calc_value_new_sum (GtkCssValue *value1, GtkCssValue *value2) { GPtrArray *array; + GtkCssValue *result; gsize i; array = g_ptr_array_new (); @@ -307,7 +309,10 @@ gtk_css_calc_value_new_sum (GtkCssValue *value1, gtk_css_calc_array_add (array, _gtk_css_value_ref (value2)); } - return gtk_css_value_new_from_array (array); + result = gtk_css_value_new_from_array ((GtkCssValue **)array->pdata, array->len); + g_ptr_array_free (array, TRUE); + + return result; } GtkCssValue * gtk_css_calc_value_parse_sum (GtkCssParser *parser, From b25f93e24c78c639b4fd869d4e42ba9161781c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 09:56:52 +0200 Subject: [PATCH 02/18] Make dimension values and calc values just number values --- gtk/gtkcsscalcvalue.c | 294 ------------- gtk/gtkcsscalcvalueprivate.h | 3 - gtk/gtkcssdimensionvalue.c | 376 ---------------- gtk/gtkcssdimensionvalueprivate.h | 6 - gtk/gtkcssimagecrossfade.c | 2 +- gtk/gtkcssnumbervalue.c | 703 +++++++++++++++++++++++++++--- gtk/gtkcssnumbervalueprivate.h | 24 +- gtk/gtkcssvalue.c | 5 - 8 files changed, 650 insertions(+), 763 deletions(-) diff --git a/gtk/gtkcsscalcvalue.c b/gtk/gtkcsscalcvalue.c index 330f3c0724..ad7380b990 100644 --- a/gtk/gtkcsscalcvalue.c +++ b/gtk/gtkcsscalcvalue.c @@ -21,300 +21,6 @@ #include -struct _GtkCssValue { - GTK_CSS_VALUE_BASE - gsize n_terms; - GtkCssValue * terms[1]; -}; - -static gsize -gtk_css_value_calc_get_size (gsize n_terms) -{ - g_assert (n_terms > 0); - - return sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (n_terms - 1); -} -static void -gtk_css_value_calc_free (GtkCssValue *value) -{ - gsize i; - - for (i = 0; i < value->n_terms; i++) - { - _gtk_css_value_unref (value->terms[i]); - } - - g_slice_free1 (gtk_css_value_calc_get_size (value->n_terms), value); -} - -static GtkCssValue *gtk_css_calc_value_new (gsize n_terms); - -static GtkCssValue * -gtk_css_value_new_from_array (GtkCssValue **values, - guint n_values) -{ - GtkCssValue *result; - - if (n_values > 1) - { - result = gtk_css_calc_value_new (n_values); - memcpy (result->terms, values, n_values * sizeof (GtkCssValue *)); - } - else - { - result = values[0]; - } - - return result; -} - -static void -gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value) -{ - gsize i; - gint calc_term_order; - - calc_term_order = gtk_css_number_value_get_calc_term_order (value); - - for (i = 0; i < array->len; i++) - { - GtkCssValue *sum = gtk_css_number_value_try_add (g_ptr_array_index (array, i), value); - - if (sum) - { - g_ptr_array_index (array, i) = sum; - _gtk_css_value_unref (value); - return; - } - else if (gtk_css_number_value_get_calc_term_order (g_ptr_array_index (array, i)) > calc_term_order) - { - g_ptr_array_insert (array, i, value); - return; - } - } - - g_ptr_array_add (array, value); -} - -static GtkCssValue * -gtk_css_value_calc_compute (GtkCssValue *value, - guint property_id, - GtkStyleProvider *provider, - GtkCssStyle *style, - GtkCssStyle *parent_style) -{ - GtkCssValue *result; - gboolean changed = FALSE; - gsize i; - GtkCssValue **new_values; - - new_values = g_alloca (sizeof (GtkCssValue *) * value->n_terms); - - for (i = 0; i < value->n_terms; i++) - { - GtkCssValue *computed = _gtk_css_value_compute (value->terms[i], property_id, provider, style, parent_style); - changed |= computed != value->terms[i]; - new_values[i] = computed; - } - - if (changed) - { - result = gtk_css_value_new_from_array (new_values, value->n_terms); - } - else - { - for (i = 0; i < value->n_terms; i++) - gtk_css_value_unref (new_values[i]); - - result = _gtk_css_value_ref (value); - } - - return result; -} - - -static gboolean -gtk_css_value_calc_equal (const GtkCssValue *value1, - const GtkCssValue *value2) -{ - gsize i; - - if (value1->n_terms != value2->n_terms) - return FALSE; - - for (i = 0; i < value1->n_terms; i++) - { - if (!_gtk_css_value_equal (value1->terms[i], value2->terms[i])) - return FALSE; - } - - return TRUE; -} - -static void -gtk_css_value_calc_print (const GtkCssValue *value, - GString *string) -{ - gsize i; - - g_string_append (string, "calc("); - _gtk_css_value_print (value->terms[0], string); - - for (i = 1; i < value->n_terms; i++) - { - g_string_append (string, " + "); - _gtk_css_value_print (value->terms[i], string); - } - g_string_append (string, ")"); -} - -static double -gtk_css_value_calc_get (const GtkCssValue *value, - double one_hundred_percent) -{ - double result = 0.0; - gsize i; - - for (i = 0; i < value->n_terms; i++) - { - result += _gtk_css_number_value_get (value->terms[i], one_hundred_percent); - } - - return result; -} - -static GtkCssDimension -gtk_css_value_calc_get_dimension (const GtkCssValue *value) -{ - GtkCssDimension dimension = GTK_CSS_DIMENSION_PERCENTAGE; - gsize i; - - for (i = 0; i < value->n_terms && dimension == GTK_CSS_DIMENSION_PERCENTAGE; i++) - { - dimension = gtk_css_number_value_get_dimension (value->terms[i]); - } - - return dimension; -} - -static gboolean -gtk_css_value_calc_has_percent (const GtkCssValue *value) -{ - gsize i; - - for (i = 0; i < value->n_terms; i++) - { - if (gtk_css_number_value_has_percent (value->terms[i])) - return TRUE; - } - - return FALSE; -} - -static GtkCssValue * -gtk_css_value_calc_multiply (GtkCssValue *value, - double factor) -{ - GtkCssValue *result; - gsize i; - - result = gtk_css_calc_value_new (value->n_terms); - - for (i = 0; i < value->n_terms; i++) - { - result->terms[i] = gtk_css_number_value_multiply (value->terms[i], factor); - } - - return result; -} - -static GtkCssValue * -gtk_css_value_calc_try_add (GtkCssValue *value1, - GtkCssValue *value2) -{ - return NULL; -} - -static gint -gtk_css_value_calc_get_calc_term_order (const GtkCssValue *value) -{ - /* This should never be needed because calc() can't contain calc(), - * but eh... - */ - return 0; -} - -static const GtkCssNumberValueClass GTK_CSS_VALUE_CALC = { - { - "GtkCssCalcValue", - gtk_css_value_calc_free, - gtk_css_value_calc_compute, - gtk_css_value_calc_equal, - gtk_css_number_value_transition, - NULL, - NULL, - gtk_css_value_calc_print - }, - gtk_css_value_calc_get, - gtk_css_value_calc_get_dimension, - gtk_css_value_calc_has_percent, - gtk_css_value_calc_multiply, - gtk_css_value_calc_try_add, - gtk_css_value_calc_get_calc_term_order -}; - -static GtkCssValue * -gtk_css_calc_value_new (gsize n_terms) -{ - GtkCssValue *result; - - result = _gtk_css_value_alloc (>K_CSS_VALUE_CALC.value_class, - gtk_css_value_calc_get_size (n_terms)); - result->n_terms = n_terms; - - return result; -} - -GtkCssValue * -gtk_css_calc_value_new_sum (GtkCssValue *value1, - GtkCssValue *value2) -{ - GPtrArray *array; - GtkCssValue *result; - gsize i; - - array = g_ptr_array_new (); - - if (value1->class == >K_CSS_VALUE_CALC.value_class) - { - for (i = 0; i < value1->n_terms; i++) - { - gtk_css_calc_array_add (array, _gtk_css_value_ref (value1->terms[i])); - } - } - else - { - gtk_css_calc_array_add (array, _gtk_css_value_ref (value1)); - } - - if (value2->class == >K_CSS_VALUE_CALC.value_class) - { - for (i = 0; i < value2->n_terms; i++) - { - gtk_css_calc_array_add (array, _gtk_css_value_ref (value2->terms[i])); - } - } - else - { - gtk_css_calc_array_add (array, _gtk_css_value_ref (value2)); - } - - result = gtk_css_value_new_from_array ((GtkCssValue **)array->pdata, array->len); - g_ptr_array_free (array, TRUE); - - return result; -} - GtkCssValue * gtk_css_calc_value_parse_sum (GtkCssParser *parser, GtkCssNumberParseFlags flags); diff --git a/gtk/gtkcsscalcvalueprivate.h b/gtk/gtkcsscalcvalueprivate.h index 2d113150ff..247d4c8a2a 100644 --- a/gtk/gtkcsscalcvalueprivate.h +++ b/gtk/gtkcsscalcvalueprivate.h @@ -22,9 +22,6 @@ G_BEGIN_DECLS -GtkCssValue * gtk_css_calc_value_new_sum (GtkCssValue *value1, - GtkCssValue *value2); - GtkCssValue * gtk_css_calc_value_parse (GtkCssParser *parser, GtkCssNumberParseFlags flags); diff --git a/gtk/gtkcssdimensionvalue.c b/gtk/gtkcssdimensionvalue.c index 10effe22d7..385661b029 100644 --- a/gtk/gtkcssdimensionvalue.c +++ b/gtk/gtkcssdimensionvalue.c @@ -19,370 +19,6 @@ #include "gtkcssdimensionvalueprivate.h" -#include "gtkcssenumvalueprivate.h" -#include "gtkstylepropertyprivate.h" - -#include "fallback-c89.c" - -struct _GtkCssValue { - GTK_CSS_VALUE_BASE - GtkCssUnit unit; - double value; -}; - -static void -gtk_css_value_dimension_free (GtkCssValue *value) -{ - g_slice_free (GtkCssValue, value); -} - -static double -get_base_font_size_px (guint property_id, - GtkStyleProvider *provider, - GtkCssStyle *style, - GtkCssStyle *parent_style) -{ - if (property_id == GTK_CSS_PROPERTY_FONT_SIZE) - { - if (parent_style) - return _gtk_css_number_value_get (parent_style->core->font_size, 100); - else - return gtk_css_font_size_get_default_px (provider, style); - } - - return _gtk_css_number_value_get (style->core->font_size, 100); -} - -static double -get_dpi (GtkCssStyle *style) -{ - return _gtk_css_number_value_get (style->core->dpi, 96); -} - -static GtkCssValue * -gtk_css_value_dimension_compute (GtkCssValue *number, - guint property_id, - GtkStyleProvider *provider, - GtkCssStyle *style, - GtkCssStyle *parent_style) -{ - switch (number->unit) - { - case GTK_CSS_PERCENT: - /* percentages for font sizes are computed, other percentages aren't */ - if (property_id == GTK_CSS_PROPERTY_FONT_SIZE) - return gtk_css_dimension_value_new (number->value / 100.0 * - get_base_font_size_px (property_id, provider, style, parent_style), - GTK_CSS_PX); - G_GNUC_FALLTHROUGH; - case GTK_CSS_NUMBER: - case GTK_CSS_PX: - case GTK_CSS_DEG: - case GTK_CSS_S: - return _gtk_css_value_ref (number); - case GTK_CSS_PT: - return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0, - GTK_CSS_PX); - case GTK_CSS_PC: - return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0 * 12.0, - GTK_CSS_PX); - case GTK_CSS_IN: - return gtk_css_dimension_value_new (number->value * get_dpi (style), - GTK_CSS_PX); - case GTK_CSS_CM: - return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.39370078740157477, - GTK_CSS_PX); - case GTK_CSS_MM: - return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.039370078740157477, - GTK_CSS_PX); - case GTK_CSS_EM: - return gtk_css_dimension_value_new (number->value * - get_base_font_size_px (property_id, provider, style, parent_style), - GTK_CSS_PX); - case GTK_CSS_EX: - /* for now we pretend ex is half of em */ - return gtk_css_dimension_value_new (number->value * 0.5 * - get_base_font_size_px (property_id, provider, style, parent_style), - GTK_CSS_PX); - case GTK_CSS_REM: - return gtk_css_dimension_value_new (number->value * - gtk_css_font_size_get_default_px (provider, style), - GTK_CSS_PX); - case GTK_CSS_RAD: - return gtk_css_dimension_value_new (number->value * 360.0 / (2 * G_PI), - GTK_CSS_DEG); - case GTK_CSS_GRAD: - return gtk_css_dimension_value_new (number->value * 360.0 / 400.0, - GTK_CSS_DEG); - case GTK_CSS_TURN: - return gtk_css_dimension_value_new (number->value * 360.0, - GTK_CSS_DEG); - case GTK_CSS_MS: - return gtk_css_dimension_value_new (number->value / 1000.0, - GTK_CSS_S); - default: - g_assert_not_reached(); - } -} - -static gboolean -gtk_css_value_dimension_equal (const GtkCssValue *number1, - const GtkCssValue *number2) -{ - return number1->unit == number2->unit && - number1->value == number2->value; -} - -static void -gtk_css_value_dimension_print (const GtkCssValue *number, - GString *string) -{ - char buf[G_ASCII_DTOSTR_BUF_SIZE]; - - const char *names[] = { - /* [GTK_CSS_NUMBER] = */ "", - /* [GTK_CSS_PERCENT] = */ "%", - /* [GTK_CSS_PX] = */ "px", - /* [GTK_CSS_PT] = */ "pt", - /* [GTK_CSS_EM] = */ "em", - /* [GTK_CSS_EX] = */ "ex", - /* [GTK_CSS_REM] = */ "rem", - /* [GTK_CSS_PC] = */ "pc", - /* [GTK_CSS_IN] = */ "in", - /* [GTK_CSS_CM] = */ "cm", - /* [GTK_CSS_MM] = */ "mm", - /* [GTK_CSS_RAD] = */ "rad", - /* [GTK_CSS_DEG] = */ "deg", - /* [GTK_CSS_GRAD] = */ "grad", - /* [GTK_CSS_TURN] = */ "turn", - /* [GTK_CSS_S] = */ "s", - /* [GTK_CSS_MS] = */ "ms", - }; - - if (isinf (number->value)) - g_string_append (string, "infinite"); - else - { - g_ascii_dtostr (buf, sizeof (buf), number->value); - g_string_append (string, buf); - if (number->value != 0.0) - g_string_append (string, names[number->unit]); - } -} - -static double -gtk_css_value_dimension_get (const GtkCssValue *value, - double one_hundred_percent) -{ - if (value->unit == GTK_CSS_PERCENT) - return value->value * one_hundred_percent / 100; - else - return value->value; -} - -static GtkCssDimension -gtk_css_value_dimension_get_dimension (const GtkCssValue *value) -{ - return gtk_css_unit_get_dimension (value->unit); -} - -static gboolean -gtk_css_value_dimension_has_percent (const GtkCssValue *value) -{ - return gtk_css_unit_get_dimension (value->unit) == GTK_CSS_DIMENSION_PERCENTAGE; -} - -static GtkCssValue * -gtk_css_value_dimension_multiply (GtkCssValue *value, - double factor) -{ - return gtk_css_dimension_value_new (value->value * factor, value->unit); -} - -static GtkCssValue * -gtk_css_value_dimension_try_add (GtkCssValue *value1, - GtkCssValue *value2) -{ - if (value1->unit != value2->unit) - return NULL; - - if (value1->value == 0) - return _gtk_css_value_ref (value2); - - if (value2->value == 0) - return _gtk_css_value_ref (value1); - - return gtk_css_dimension_value_new (value1->value + value2->value, value1->unit); -} - -static gint -gtk_css_value_dimension_get_calc_term_order (const GtkCssValue *value) -{ - /* note: the order is alphabetic */ - guint order_per_unit[] = { - /* [GTK_CSS_NUMBER] = */ 0, - /* [GTK_CSS_PERCENT] = */ 16, - /* [GTK_CSS_PX] = */ 11, - /* [GTK_CSS_PT] = */ 10, - /* [GTK_CSS_EM] = */ 3, - /* [GTK_CSS_EX] = */ 4, - /* [GTK_CSS_REM] = */ 13, - /* [GTK_CSS_PC] = */ 9, - /* [GTK_CSS_IN] = */ 6, - /* [GTK_CSS_CM] = */ 1, - /* [GTK_CSS_MM] = */ 7, - /* [GTK_CSS_RAD] = */ 12, - /* [GTK_CSS_DEG] = */ 2, - /* [GTK_CSS_GRAD] = */ 5, - /* [GTK_CSS_TURN] = */ 15, - /* [GTK_CSS_S] = */ 14, - /* [GTK_CSS_MS] = */ 8 - }; - - return 1000 + order_per_unit[value->unit]; -} - -static GtkCssValue * -gtk_css_value_dimension_transition (GtkCssValue *start, - GtkCssValue *end, - guint property_id, - double progress) -{ - if (start->unit == end->unit) - return gtk_css_dimension_value_new (start->value + (end->value - start->value) * progress, start->unit); - - return gtk_css_number_value_transition (start, end, property_id, progress); -} - -static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = { - { - "GtkCssDimensionValue", - gtk_css_value_dimension_free, - gtk_css_value_dimension_compute, - gtk_css_value_dimension_equal, - gtk_css_value_dimension_transition, - NULL, - NULL, - gtk_css_value_dimension_print - }, - gtk_css_value_dimension_get, - gtk_css_value_dimension_get_dimension, - gtk_css_value_dimension_has_percent, - gtk_css_value_dimension_multiply, - gtk_css_value_dimension_try_add, - gtk_css_value_dimension_get_calc_term_order -}; - -GtkCssValue * -gtk_css_dimension_value_new (double value, - GtkCssUnit unit) -{ - static GtkCssValue number_singletons[] = { - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 0 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 1 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 96 }, /* DPI default */ - }; - static GtkCssValue px_singletons[] = { - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 0 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 1 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 2 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 3 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 4 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 8 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 16 }, /* Icon size default */ - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 32 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 64 }, - }; - static GtkCssValue percent_singletons[] = { - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PERCENT, 0 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, FALSE, GTK_CSS_PERCENT, 50 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, FALSE, GTK_CSS_PERCENT, 100 }, - }; - static GtkCssValue second_singletons[] = { - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_S, 0 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_S, 1 }, - }; - static GtkCssValue deg_singletons[] = { - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 0 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 90 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 180 }, - { >K_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 270 }, - }; - GtkCssValue *result; - - switch ((guint)unit) - { - case GTK_CSS_NUMBER: - if (value == 0 || value == 1) - return _gtk_css_value_ref (&number_singletons[(int) value]); - - if (value == 96) - return _gtk_css_value_ref (&number_singletons[2]); - - break; - - case GTK_CSS_PX: - if (value == 0 || - value == 1 || - value == 2 || - value == 3 || - value == 4) - return _gtk_css_value_ref (&px_singletons[(int) value]); - if (value == 8) - return _gtk_css_value_ref (&px_singletons[5]); - if (value == 16) - return _gtk_css_value_ref (&px_singletons[6]); - if (value == 32) - return _gtk_css_value_ref (&px_singletons[7]); - if (value == 64) - return _gtk_css_value_ref (&px_singletons[8]); - - break; - - case GTK_CSS_PERCENT: - if (value == 0) - return _gtk_css_value_ref (&percent_singletons[0]); - if (value == 50) - return _gtk_css_value_ref (&percent_singletons[1]); - if (value == 100) - return _gtk_css_value_ref (&percent_singletons[2]); - - break; - - case GTK_CSS_S: - if (value == 0 || value == 1) - return _gtk_css_value_ref (&second_singletons[(int)value]); - - break; - - case GTK_CSS_DEG: - if (value == 0) - return _gtk_css_value_ref (°_singletons[0]); - if (value == 90) - return _gtk_css_value_ref (°_singletons[1]); - if (value == 180) - return _gtk_css_value_ref (°_singletons[2]); - if (value == 270) - return _gtk_css_value_ref (°_singletons[3]); - - break; - - default: - ; - } - - result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_DIMENSION.value_class); - result->unit = unit; - result->value = value; - result->is_computed = value == 0 || - unit == GTK_CSS_NUMBER || - unit == GTK_CSS_PX || - unit == GTK_CSS_DEG || - unit == GTK_CSS_S; - - return result; -} - GtkCssValue * gtk_css_dimension_value_parse (GtkCssParser *parser, GtkCssNumberParseFlags flags) @@ -495,15 +131,3 @@ gtk_css_dimension_value_parse (GtkCssParser *parser, return result; } - -gboolean -gtk_css_dimension_value_is_zero (const GtkCssValue *value) -{ - if (!value) - return TRUE; - - if (value->class != >K_CSS_VALUE_DIMENSION.value_class) - return FALSE; - - return value->value == 0; -} diff --git a/gtk/gtkcssdimensionvalueprivate.h b/gtk/gtkcssdimensionvalueprivate.h index fea2a919ef..71370d8768 100644 --- a/gtk/gtkcssdimensionvalueprivate.h +++ b/gtk/gtkcssdimensionvalueprivate.h @@ -24,14 +24,8 @@ G_BEGIN_DECLS -GtkCssValue * gtk_css_dimension_value_new (double value, - GtkCssUnit unit); - GtkCssValue * gtk_css_dimension_value_parse (GtkCssParser *parser, GtkCssNumberParseFlags flags); - -gboolean gtk_css_dimension_value_is_zero (const GtkCssValue *value) G_GNUC_PURE; - G_END_DECLS #endif /* __GTK_CSS_DIMENSION_VALUE_PRIVATE_H__ */ diff --git a/gtk/gtkcssimagecrossfade.c b/gtk/gtkcssimagecrossfade.c index 2d281b26cc..4ec2c3f0f1 100644 --- a/gtk/gtkcssimagecrossfade.c +++ b/gtk/gtkcssimagecrossfade.c @@ -294,7 +294,7 @@ parse_progress (GtkCssParser *parser, if (*progress > 1.0) { - gtk_css_parser_error_value (parser, "Percentages over 100%% are not allowed"); + gtk_css_parser_error_value (parser, "Percentages over 100%% are not allowed. Given value: %f", *progress); return FALSE; } diff --git a/gtk/gtkcssnumbervalue.c b/gtk/gtkcssnumbervalue.c index 625559580e..d63563783f 100644 --- a/gtk/gtkcssnumbervalue.c +++ b/gtk/gtkcssnumbervalue.c @@ -20,39 +20,633 @@ #include "gtkcssnumbervalueprivate.h" #include "gtkcsscalcvalueprivate.h" +#include "gtkcssenumvalueprivate.h" #include "gtkcssdimensionvalueprivate.h" +#include "gtkcssstyleprivate.h" #include "gtkprivate.h" +static GtkCssValue * gtk_css_calc_value_new (guint n_terms); +static GtkCssValue * gtk_css_calc_value_new_sum (GtkCssValue *a, + GtkCssValue *b); + +enum { + TYPE_CALC = 0, + TYPE_DIMENSION = 1, +}; + struct _GtkCssValue { GTK_CSS_VALUE_BASE + guint type : 1; /* Calc or dimension */ + union { + struct { + GtkCssUnit unit; + double value; + } dimension; + struct { + guint n_terms; + GtkCssValue *terms[1]; + } calc; + }; }; + +static GtkCssValue * +gtk_css_calc_value_new_from_array (GtkCssValue **values, + guint n_values) +{ + GtkCssValue *result; + + if (n_values > 1) + { + result = gtk_css_calc_value_new (n_values); + memcpy (result->calc.terms, values, n_values * sizeof (GtkCssValue *)); + } + else + { + result = values[0]; + } + + return result; +} + + +static void +gtk_css_value_number_free (GtkCssValue *value) +{ + g_slice_free (GtkCssValue, value); +} + +static double +get_dpi (GtkCssStyle *style) +{ + return _gtk_css_number_value_get (style->core->dpi, 96); +} + +static double +get_base_font_size_px (guint property_id, + GtkStyleProvider *provider, + GtkCssStyle *style, + GtkCssStyle *parent_style) +{ + if (property_id == GTK_CSS_PROPERTY_FONT_SIZE) + { + if (parent_style) + return _gtk_css_number_value_get (parent_style->core->font_size, 100); + else + return gtk_css_font_size_get_default_px (provider, style); + } + + return _gtk_css_number_value_get (style->core->font_size, 100); +} + +static GtkCssValue * +gtk_css_value_number_compute (GtkCssValue *number, + guint property_id, + GtkStyleProvider *provider, + GtkCssStyle *style, + GtkCssStyle *parent_style) +{ + double value; + + if (G_UNLIKELY (number->type == TYPE_CALC)) + { + const guint n_terms = number->calc.n_terms; + GtkCssValue *result; + gboolean changed = FALSE; + gsize i; + GtkCssValue **new_values; + + new_values = g_alloca (sizeof (GtkCssValue *) * n_terms); + + for (i = 0; i < n_terms; i++) + { + GtkCssValue *computed = _gtk_css_value_compute (number->calc.terms[i], + property_id, provider, style, + parent_style); + changed |= computed != number->calc.terms[i]; + new_values[i] = computed; + } + + if (changed) + { + result = gtk_css_calc_value_new_from_array (new_values, n_terms); + } + else + { + for (i = 0; i < n_terms; i++) + gtk_css_value_unref (new_values[i]); + + result = _gtk_css_value_ref (number); + } + + return result; + } + + g_assert (number->type == TYPE_DIMENSION); + + value = number->dimension.value; + switch (number->dimension.unit) + { + case GTK_CSS_PERCENT: + /* percentages for font sizes are computed, other percentages aren't */ + if (property_id == GTK_CSS_PROPERTY_FONT_SIZE) + return gtk_css_dimension_value_new (value / 100.0 * + get_base_font_size_px (property_id, provider, style, parent_style), + GTK_CSS_PX); + G_GNUC_FALLTHROUGH; + case GTK_CSS_NUMBER: + case GTK_CSS_PX: + case GTK_CSS_DEG: + case GTK_CSS_S: + return _gtk_css_value_ref (number); + case GTK_CSS_PT: + return gtk_css_dimension_value_new (value * get_dpi (style) / 72.0, + GTK_CSS_PX); + case GTK_CSS_PC: + return gtk_css_dimension_value_new (value * get_dpi (style) / 72.0 * 12.0, + GTK_CSS_PX); + case GTK_CSS_IN: + return gtk_css_dimension_value_new (value * get_dpi (style), + GTK_CSS_PX); + case GTK_CSS_CM: + return gtk_css_dimension_value_new (value * get_dpi (style) * 0.39370078740157477, + GTK_CSS_PX); + case GTK_CSS_MM: + return gtk_css_dimension_value_new (value * get_dpi (style) * 0.039370078740157477, + GTK_CSS_PX); + case GTK_CSS_EM: + return gtk_css_dimension_value_new (value * + get_base_font_size_px (property_id, provider, style, parent_style), + GTK_CSS_PX); + case GTK_CSS_EX: + /* for now we pretend ex is half of em */ + return gtk_css_dimension_value_new (value * 0.5 * + get_base_font_size_px (property_id, provider, style, parent_style), + GTK_CSS_PX); + case GTK_CSS_REM: + return gtk_css_dimension_value_new (value * + gtk_css_font_size_get_default_px (provider, style), + GTK_CSS_PX); + case GTK_CSS_RAD: + return gtk_css_dimension_value_new (value * 360.0 / (2 * G_PI), + GTK_CSS_DEG); + case GTK_CSS_GRAD: + return gtk_css_dimension_value_new (value * 360.0 / 400.0, + GTK_CSS_DEG); + case GTK_CSS_TURN: + return gtk_css_dimension_value_new (value * 360.0, + GTK_CSS_DEG); + case GTK_CSS_MS: + return gtk_css_dimension_value_new (value / 1000.0, + GTK_CSS_S); + default: + g_assert_not_reached(); + } +} + +static gboolean +gtk_css_value_number_equal (const GtkCssValue *val1, + const GtkCssValue *val2) +{ + guint i; + + if (val1->type != val2->type) + return FALSE; + + if (G_LIKELY (val1->type == TYPE_DIMENSION)) + { + return val1->dimension.unit == val2->dimension.unit && + val1->dimension.value == val2->dimension.value; + } + + g_assert (val1->type == TYPE_CALC); + + if (val1->calc.n_terms != val2->calc.n_terms) + return FALSE; + + for (i = 0; i < val1->calc.n_terms; i++) + { + if (!_gtk_css_value_equal (val1->calc.terms[i], val2->calc.terms[i])) + return FALSE; + } + + return TRUE; +} + +static void +gtk_css_value_number_print (const GtkCssValue *value, + GString *string) +{ + guint i; + + if (G_LIKELY (value->type == TYPE_DIMENSION)) + { + const char *names[] = { + /* [GTK_CSS_NUMBER] = */ "", + /* [GTK_CSS_PERCENT] = */ "%", + /* [GTK_CSS_PX] = */ "px", + /* [GTK_CSS_PT] = */ "pt", + /* [GTK_CSS_EM] = */ "em", + /* [GTK_CSS_EX] = */ "ex", + /* [GTK_CSS_REM] = */ "rem", + /* [GTK_CSS_PC] = */ "pc", + /* [GTK_CSS_IN] = */ "in", + /* [GTK_CSS_CM] = */ "cm", + /* [GTK_CSS_MM] = */ "mm", + /* [GTK_CSS_RAD] = */ "rad", + /* [GTK_CSS_DEG] = */ "deg", + /* [GTK_CSS_GRAD] = */ "grad", + /* [GTK_CSS_TURN] = */ "turn", + /* [GTK_CSS_S] = */ "s", + /* [GTK_CSS_MS] = */ "ms", + }; + char buf[G_ASCII_DTOSTR_BUF_SIZE]; + + if (isinf (value->dimension.value)) + g_string_append (string, "infinite"); + else + { + g_ascii_dtostr (buf, sizeof (buf), value->dimension.value); + g_string_append (string, buf); + if (value->dimension.value != 0.0) + g_string_append (string, names[value->dimension.unit]); + } + + return; + } + + g_assert (value->type == TYPE_CALC); + + g_string_append (string, "calc("); + _gtk_css_value_print (value->calc.terms[0], string); + + for (i = 1; i < value->calc.n_terms; i++) + { + g_string_append (string, " + "); + _gtk_css_value_print (value->calc.terms[i], string); + } + g_string_append (string, ")"); +} + +static GtkCssValue * +gtk_css_value_number_transition (GtkCssValue *start, + GtkCssValue *end, + guint property_id, + double progress) +{ + GtkCssValue *result, *mul_start, *mul_end; + + if (start == end) + return _gtk_css_value_ref (start); + + if (G_LIKELY (start->type == TYPE_DIMENSION && end->type == TYPE_DIMENSION)) + { + if (start->dimension.unit == end->dimension.unit) + { + const double start_value = start->dimension.value; + const double end_value = end->dimension.value; + return gtk_css_dimension_value_new (start_value + (end_value - start_value) * progress, + start->dimension.unit); + } + } + + mul_start = gtk_css_number_value_multiply (start, 1 - progress); + mul_end = gtk_css_number_value_multiply (end, progress); + + result = gtk_css_number_value_add (mul_start, mul_end); + + _gtk_css_value_unref (mul_start); + _gtk_css_value_unref (mul_end); + + return result; +} + +static const GtkCssValueClass GTK_CSS_VALUE_NUMBER = { + "GtkCssNumberValue", + gtk_css_value_number_free, + gtk_css_value_number_compute, + gtk_css_value_number_equal, + gtk_css_value_number_transition, + NULL, + NULL, + gtk_css_value_number_print +}; + +static gsize +gtk_css_value_calc_get_size (gsize n_terms) +{ + g_assert (n_terms > 0); + + return sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (n_terms - 1); +} + +static GtkCssValue * +gtk_css_calc_value_new (guint n_terms) +{ + GtkCssValue *result; + + result = _gtk_css_value_alloc (>K_CSS_VALUE_NUMBER, + gtk_css_value_calc_get_size (n_terms)); + result->type = TYPE_CALC; + result->calc.n_terms = n_terms; + + return result; +} + +GtkCssValue * +gtk_css_dimension_value_new (double value, + GtkCssUnit unit) +{ + static GtkCssValue number_singletons[] = { + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_NUMBER, 0 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_NUMBER, 1 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_NUMBER, 96 }} }, /* DPI default */ + }; + static GtkCssValue px_singletons[] = { + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 0 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 1 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 2 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 3 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 4 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 8 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 16 }} }, /* Icon size default */ + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 32 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 64 }} }, + }; + static GtkCssValue percent_singletons[] = { + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PERCENT, 0 }} }, + { >K_CSS_VALUE_NUMBER, 1, FALSE, TYPE_DIMENSION, {{ GTK_CSS_PERCENT, 50 }} }, + { >K_CSS_VALUE_NUMBER, 1, FALSE, TYPE_DIMENSION, {{ GTK_CSS_PERCENT, 100 }} }, + }; + static GtkCssValue second_singletons[] = { + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_S, 0 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_S, 1 }} }, + }; + static GtkCssValue deg_singletons[] = { + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 0 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 90 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 180 }} }, + { >K_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 270 }} }, + }; + GtkCssValue *result; + + switch ((guint)unit) + { + case GTK_CSS_NUMBER: + if (value == 0 || value == 1) + return _gtk_css_value_ref (&number_singletons[(int) value]); + + if (value == 96) + return _gtk_css_value_ref (&number_singletons[2]); + + break; + + case GTK_CSS_PX: + if (value == 0 || + value == 1 || + value == 2 || + value == 3 || + value == 4) + return _gtk_css_value_ref (&px_singletons[(int) value]); + if (value == 8) + return _gtk_css_value_ref (&px_singletons[5]); + if (value == 16) + return _gtk_css_value_ref (&px_singletons[6]); + if (value == 32) + return _gtk_css_value_ref (&px_singletons[7]); + if (value == 64) + return _gtk_css_value_ref (&px_singletons[8]); + + break; + + case GTK_CSS_PERCENT: + if (value == 0) + return _gtk_css_value_ref (&percent_singletons[0]); + if (value == 50) + return _gtk_css_value_ref (&percent_singletons[1]); + if (value == 100) + return _gtk_css_value_ref (&percent_singletons[2]); + + break; + + case GTK_CSS_S: + if (value == 0 || value == 1) + return _gtk_css_value_ref (&second_singletons[(int)value]); + + break; + + case GTK_CSS_DEG: + if (value == 0) + return _gtk_css_value_ref (°_singletons[0]); + if (value == 90) + return _gtk_css_value_ref (°_singletons[1]); + if (value == 180) + return _gtk_css_value_ref (°_singletons[2]); + if (value == 270) + return _gtk_css_value_ref (°_singletons[3]); + + break; + + default: + ; + } + + result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_NUMBER); + result->type = TYPE_DIMENSION; + result->dimension.unit = unit; + result->dimension.value = value; + result->is_computed = value == 0 || + unit == GTK_CSS_NUMBER || + unit == GTK_CSS_PX || + unit == GTK_CSS_DEG || + unit == GTK_CSS_S; + if (value == 5040) + g_critical ("%s: %f", __FUNCTION__, value); + return result; +} + +/* + * gtk_css_number_value_get_calc_term_order: + * @value: Value to compute order for + * + * Determines the position of @value when printed as part of a calc() + * expression. Values with lower numbers are printed first. Note that + * these numbers are arbitrary, so when adding new types of values to + * print, feel free to change them in implementations so that they + * match. + * + * Returns: Magic value determining placement when printing calc() + * expression. + */ +static int +gtk_css_number_value_get_calc_term_order (const GtkCssValue *value) +{ + if (G_LIKELY (value->type == TYPE_DIMENSION)) + { + /* note: the order is alphabetic */ + static const guint order_per_unit[] = { + /* [GTK_CSS_NUMBER] = */ 0, + /* [GTK_CSS_PERCENT] = */ 16, + /* [GTK_CSS_PX] = */ 11, + /* [GTK_CSS_PT] = */ 10, + /* [GTK_CSS_EM] = */ 3, + /* [GTK_CSS_EX] = */ 4, + /* [GTK_CSS_REM] = */ 13, + /* [GTK_CSS_PC] = */ 9, + /* [GTK_CSS_IN] = */ 6, + /* [GTK_CSS_CM] = */ 1, + /* [GTK_CSS_MM] = */ 7, + /* [GTK_CSS_RAD] = */ 12, + /* [GTK_CSS_DEG] = */ 2, + /* [GTK_CSS_GRAD] = */ 5, + /* [GTK_CSS_TURN] = */ 15, + /* [GTK_CSS_S] = */ 14, + /* [GTK_CSS_MS] = */ 8 + }; + return 1000 + order_per_unit[value->dimension.unit]; + } + + g_assert (value->type == TYPE_CALC); + + /* This should never be needed because calc() can't contain calc(), + * but eh... + */ + return 0; +} + +static void +gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value) +{ + gsize i; + gint calc_term_order; + + calc_term_order = gtk_css_number_value_get_calc_term_order (value); + + for (i = 0; i < array->len; i++) + { + GtkCssValue *sum = gtk_css_number_value_try_add (g_ptr_array_index (array, i), value); + + if (sum) + { + g_ptr_array_index (array, i) = sum; + _gtk_css_value_unref (value); + return; + } + else if (gtk_css_number_value_get_calc_term_order (g_ptr_array_index (array, i)) > calc_term_order) + { + g_ptr_array_insert (array, i, value); + return; + } + } + + g_ptr_array_add (array, value); +} + +static GtkCssValue * +gtk_css_calc_value_new_sum (GtkCssValue *value1, + GtkCssValue *value2) +{ + GPtrArray *array; + GtkCssValue *result; + gsize i; + + array = g_ptr_array_new (); + + if (value1->class == >K_CSS_VALUE_NUMBER && + value1->type == TYPE_CALC) + { + for (i = 0; i < value1->calc.n_terms; i++) + { + gtk_css_calc_array_add (array, _gtk_css_value_ref (value1->calc.terms[i])); + } + } + else + { + gtk_css_calc_array_add (array, _gtk_css_value_ref (value1)); + } + + if (value2->class == >K_CSS_VALUE_NUMBER && + value2->type == TYPE_CALC) + { + for (i = 0; i < value2->calc.n_terms; i++) + { + gtk_css_calc_array_add (array, _gtk_css_value_ref (value2->calc.terms[i])); + } + } + else + { + gtk_css_calc_array_add (array, _gtk_css_value_ref (value2)); + } + + result = gtk_css_calc_value_new_from_array ((GtkCssValue **)array->pdata, array->len); + g_ptr_array_free (array, TRUE); + + return result; +} + GtkCssDimension gtk_css_number_value_get_dimension (const GtkCssValue *value) { - GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; + GtkCssDimension dimension = GTK_CSS_DIMENSION_PERCENTAGE; + guint i; - return number_value_class->get_dimension (value); + if (G_LIKELY (value->type == TYPE_DIMENSION)) + return gtk_css_unit_get_dimension (value->dimension.unit); + + g_assert (value->type == TYPE_CALC); + + for (i = 0; i < value->calc.n_terms && dimension == GTK_CSS_DIMENSION_PERCENTAGE; i++) + { + dimension = gtk_css_number_value_get_dimension (value->calc.terms[i]); + if (dimension != GTK_CSS_DIMENSION_PERCENTAGE) + break; + } + + return dimension; } gboolean gtk_css_number_value_has_percent (const GtkCssValue *value) { - GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; + guint i; - return number_value_class->has_percent (value); + if (G_LIKELY (value->type == TYPE_DIMENSION)) + { + return gtk_css_unit_get_dimension (value->dimension.unit) == GTK_CSS_DIMENSION_PERCENTAGE; + } + + for (i = 0; i < value->calc.n_terms; i++) + { + if (gtk_css_number_value_has_percent (value->calc.terms[i])) + return TRUE; + } + + return FALSE; } GtkCssValue * gtk_css_number_value_multiply (GtkCssValue *value, double factor) { - GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; + GtkCssValue *result; + guint i; if (factor == 1) return _gtk_css_value_ref (value); - return number_value_class->multiply (value, factor); + if (G_LIKELY (value->type == TYPE_DIMENSION)) + { + return gtk_css_dimension_value_new (value->dimension.value * factor, + value->dimension.unit); + } + + g_assert (value->type == TYPE_CALC); + + result = gtk_css_calc_value_new (value->calc.n_terms); + for (i = 0; i < value->calc.n_terms; i++) + result->calc.terms[i] = gtk_css_number_value_multiply (value->calc.terms[i], factor); + + return result; } GtkCssValue * @@ -72,35 +666,27 @@ GtkCssValue * gtk_css_number_value_try_add (GtkCssValue *value1, GtkCssValue *value2) { - GtkCssNumberValueClass *number_value_class; - - if (value1->class != value2->class) + if (G_UNLIKELY (value1->type != value2->type)) return NULL; - number_value_class = (GtkCssNumberValueClass *) value1->class; + if (G_LIKELY (value1->type == TYPE_DIMENSION)) + { + if (value1->dimension.unit != value2->dimension.unit) + return NULL; - return number_value_class->try_add (value1, value2); -} + if (value1->dimension.value == 0) + return _gtk_css_value_ref (value2); -/* - * gtk_css_number_value_get_calc_term_order: - * @value: Value to compute order for - * - * Determines the position of @value when printed as part of a calc() - * expression. Values with lower numbers are printed first. Note that - * these numbers are arbitrary, so when adding new types of values to - * print, feel free to change them in implementations so that they - * match. - * - * Returns: Magic value determining placement when printing calc() - * expression. - */ -gint -gtk_css_number_value_get_calc_term_order (const GtkCssValue *value) -{ - GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; + if (value2->dimension.value == 0) + return _gtk_css_value_ref (value1); - return number_value_class->get_calc_term_order (value); + return gtk_css_dimension_value_new (value1->dimension.value + value2->dimension.value, + value1->dimension.unit); + } + + g_assert (value1->type == TYPE_CALC); + /* Not possible for calc() values */ + return NULL; } GtkCssValue * @@ -110,28 +696,6 @@ _gtk_css_number_value_new (double value, return gtk_css_dimension_value_new (value, unit); } -GtkCssValue * -gtk_css_number_value_transition (GtkCssValue *start, - GtkCssValue *end, - guint property_id, - double progress) -{ - GtkCssValue *result, *mul_start, *mul_end; - - if (start == end) - return _gtk_css_value_ref (start); - - mul_start = gtk_css_number_value_multiply (start, 1 - progress); - mul_end = gtk_css_number_value_multiply (end, progress); - - result = gtk_css_number_value_add (mul_start, mul_end); - - _gtk_css_value_unref (mul_start); - _gtk_css_value_unref (mul_end); - - return result; -} - gboolean gtk_css_number_value_can_parse (GtkCssParser *parser) { @@ -157,15 +721,40 @@ _gtk_css_number_value_parse (GtkCssParser *parser, } double -_gtk_css_number_value_get (const GtkCssValue *number, +_gtk_css_number_value_get (const GtkCssValue *value, double one_hundred_percent) { - GtkCssNumberValueClass *number_value_class; + double result; + guint i; - gtk_internal_return_val_if_fail (number != NULL, 0.0); + if (G_LIKELY (value->type == TYPE_DIMENSION)) + { + if (value->dimension.unit == GTK_CSS_PERCENT) + return value->dimension.value * one_hundred_percent / 100; + else + return value->dimension.value; + } - number_value_class = (GtkCssNumberValueClass *) number->class; + g_assert (value->type == TYPE_CALC); - return number_value_class->get (number, one_hundred_percent); + result = 0.0; + for (i = 0; i < value->calc.n_terms; i++) + result += _gtk_css_number_value_get (value->calc.terms[i], one_hundred_percent); + + return result; } +gboolean +gtk_css_dimension_value_is_zero (const GtkCssValue *value) +{ + if (!value) + return TRUE; + + if (value->class != >K_CSS_VALUE_NUMBER) + return FALSE; + + if (value->type != TYPE_DIMENSION) + return FALSE; + + return value->dimension.value == 0; +} diff --git a/gtk/gtkcssnumbervalueprivate.h b/gtk/gtkcssnumbervalueprivate.h index 040ba902da..bcac90e45e 100644 --- a/gtk/gtkcssnumbervalueprivate.h +++ b/gtk/gtkcssnumbervalueprivate.h @@ -35,28 +35,11 @@ typedef enum /*< skip >*/ { GTK_CSS_PARSE_TIME = (1 << 5) } GtkCssNumberParseFlags; -typedef struct _GtkCssNumberValueClass GtkCssNumberValueClass; - -struct _GtkCssNumberValueClass { - GtkCssValueClass value_class; - - double (* get) (const GtkCssValue *value, - double one_hundred_percent); - GtkCssDimension (* get_dimension) (const GtkCssValue *value); - gboolean (* has_percent) (const GtkCssValue *value); - GtkCssValue * (* multiply) (GtkCssValue *value, - double factor); - GtkCssValue * (* try_add) (GtkCssValue *value1, - GtkCssValue *value2); - gint (* get_calc_term_order) (const GtkCssValue *value); -}; +GtkCssValue * gtk_css_dimension_value_new (double value, + GtkCssUnit unit); GtkCssValue * _gtk_css_number_value_new (double value, GtkCssUnit unit); -GtkCssValue * gtk_css_number_value_transition (GtkCssValue *start, - GtkCssValue *end, - guint property_id, - double progress); gboolean gtk_css_number_value_can_parse (GtkCssParser *parser); GtkCssValue * _gtk_css_number_value_parse (GtkCssParser *parser, GtkCssNumberParseFlags flags); @@ -69,11 +52,10 @@ GtkCssValue * gtk_css_number_value_add (GtkCssValue *val GtkCssValue *value2); GtkCssValue * gtk_css_number_value_try_add (GtkCssValue *value1, GtkCssValue *value2); -gint gtk_css_number_value_get_calc_term_order (const GtkCssValue *value); - double _gtk_css_number_value_get (const GtkCssValue *number, double one_hundred_percent) G_GNUC_PURE; +gboolean gtk_css_dimension_value_is_zero (const GtkCssValue *value) G_GNUC_PURE; G_END_DECLS diff --git a/gtk/gtkcssvalue.c b/gtk/gtkcssvalue.c index ce6c3fac3b..b48f82a3c7 100644 --- a/gtk/gtkcssvalue.c +++ b/gtk/gtkcssvalue.c @@ -263,11 +263,6 @@ _gtk_css_value_transition (GtkCssValue *start, gtk_internal_return_val_if_fail (start != NULL, FALSE); gtk_internal_return_val_if_fail (end != NULL, FALSE); - /* We compare functions here instead of classes so that number - * values can all transition to each other */ - if (start->class->transition != end->class->transition) - return NULL; - if (progress == 0) return _gtk_css_value_ref (start); From 24608d5c239667b72336e94024ef8edd1533315c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 10:05:11 +0200 Subject: [PATCH 03/18] gtkarray: Fix a typo --- gtk/gtkarrayimplprivate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk/gtkarrayimplprivate.h b/gtk/gtkarrayimplprivate.h index 74c810a842..c1355205fd 100644 --- a/gtk/gtkarrayimplprivate.h +++ b/gtk/gtkarrayimplprivate.h @@ -4,7 +4,7 @@ /* This is a dumbed-down GPtrArray, which takes some stack * space to use. When using this, the general case should always - * be that the number of elements is lower than reversed_size. + * be that the number of elements is lower than reserved_size. * The GPtrArray should only be used in extreme cases. */ From 75cfe3c6aef18a64651c54307bf67b6831e0dafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 10:24:15 +0200 Subject: [PATCH 04/18] gtkarray: Create GPtrArray in insert() if we have to --- gtk/gtkarrayimplprivate.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gtk/gtkarrayimplprivate.h b/gtk/gtkarrayimplprivate.h index c1355205fd..8a669f2a40 100644 --- a/gtk/gtkarrayimplprivate.h +++ b/gtk/gtkarrayimplprivate.h @@ -88,6 +88,16 @@ gtk_array_insert (GtkArray *self, return; } + if (G_UNLIKELY (!self->ptr_array)) + { + guint i; + + self->ptr_array = g_ptr_array_new_full (self->reserved_size, NULL); + + for (i = 0; i < self->len; i++) + g_ptr_array_add (self->ptr_array, self->stack_space[i]); + } + g_assert (self->ptr_array); g_ptr_array_insert (self->ptr_array, index, element); self->len++; From f38bbb9bc28420df20b7bc217f86a86cd7e5e9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 10:25:05 +0200 Subject: [PATCH 05/18] gtkarray: memcpy() directly into the GPtrArray --- gtk/gtkarrayimplprivate.h | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/gtk/gtkarrayimplprivate.h b/gtk/gtkarrayimplprivate.h index 8a669f2a40..cd8051373d 100644 --- a/gtk/gtkarrayimplprivate.h +++ b/gtk/gtkarrayimplprivate.h @@ -55,13 +55,9 @@ gtk_array_add (GtkArray *self, /* Need to fall back to the GPtrArray */ if (G_UNLIKELY (!self->ptr_array)) { - guint i; - - self->ptr_array = g_ptr_array_new_full (self->reserved_size, NULL); - - /* Copy elements from stack space to GPtrArray */ - for (i = 0; i < self->len; i++) - g_ptr_array_add (self->ptr_array, self->stack_space[i]); + self->ptr_array = g_ptr_array_new_full (self->len + 1, NULL); + memcpy (self->ptr_array->pdata, self->stack_space, sizeof (void *) * self->len); + self->ptr_array->len = self->len; } g_ptr_array_add (self->ptr_array, element); @@ -90,12 +86,9 @@ gtk_array_insert (GtkArray *self, if (G_UNLIKELY (!self->ptr_array)) { - guint i; - - self->ptr_array = g_ptr_array_new_full (self->reserved_size, NULL); - - for (i = 0; i < self->len; i++) - g_ptr_array_add (self->ptr_array, self->stack_space[i]); + self->ptr_array = g_ptr_array_new_full (self->len + 1, NULL); + memcpy (self->ptr_array->pdata, self->stack_space, sizeof (void *) * self->len); + self->ptr_array->len = self->len; } g_assert (self->ptr_array); From e12c9de5dfd5b9ed0098650c516f4fed1653f423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 11:37:51 +0200 Subject: [PATCH 06/18] csstransiton: Save finished state Once a transtion is finished it can't change to unfinished again, so we don't have to consult the progress tracker all the time. --- gtk/gtkcsstransition.c | 10 +++++++--- gtk/gtkcsstransitionprivate.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gtk/gtkcsstransition.c b/gtk/gtkcsstransition.c index 23478b618b..62731a513d 100644 --- a/gtk/gtkcsstransition.c +++ b/gtk/gtkcsstransition.c @@ -42,6 +42,7 @@ gtk_css_transition_advance (GtkStyleAnimation *style_animation, gtk_progress_tracker_init_copy (&source->tracker, &transition->tracker); gtk_progress_tracker_advance_frame (&transition->tracker, timestamp); + transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; return GTK_STYLE_ANIMATION (transition); } @@ -55,8 +56,10 @@ gtk_css_transition_apply_values (GtkStyleAnimation *style_animation, double progress; GtkProgressState state; - end = gtk_css_animated_style_get_intrinsic_value (style, transition->property); + if (transition->finished) + return; + end = gtk_css_animated_style_get_intrinsic_value (style, transition->property); state = gtk_progress_tracker_get_state (&transition->tracker); if (state == GTK_PROGRESS_STATE_BEFORE) @@ -85,7 +88,7 @@ gtk_css_transition_is_finished (GtkStyleAnimation *animation) { GtkCssTransition *transition = GTK_CSS_TRANSITION (animation); - return gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; + return transition->finished; } static gboolean @@ -93,7 +96,7 @@ gtk_css_transition_is_static (GtkStyleAnimation *animation) { GtkCssTransition *transition = GTK_CSS_TRANSITION (animation); - return gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; + return transition->finished; } static void @@ -146,6 +149,7 @@ _gtk_css_transition_new (guint property, transition->ease = _gtk_css_value_ref (ease); gtk_progress_tracker_start (&transition->tracker, duration_us, delay_us, 1.0); gtk_progress_tracker_advance_frame (&transition->tracker, timestamp); + transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; return GTK_STYLE_ANIMATION (transition); } diff --git a/gtk/gtkcsstransitionprivate.h b/gtk/gtkcsstransitionprivate.h index 822a8246d9..6f722023a1 100644 --- a/gtk/gtkcsstransitionprivate.h +++ b/gtk/gtkcsstransitionprivate.h @@ -43,6 +43,7 @@ struct _GtkCssTransition GtkCssValue *start; GtkCssValue *ease; GtkProgressTracker tracker; + guint finished; }; struct _GtkCssTransitionClass From 06460ea50ca611a67c28f9e7ee1b4dba7b8f2aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 11:40:52 +0200 Subject: [PATCH 07/18] css: Drop a few dynamic type checks We hit these code paths a lot --- gtk/gtkcssanimatedstyle.c | 2 +- gtk/gtkcssstyle.c | 2 -- gtk/gtkcsstransition.c | 11 +++++------ gtk/gtkstyleanimation.c | 2 -- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/gtk/gtkcssanimatedstyle.c b/gtk/gtkcssanimatedstyle.c index d67bb9f191..c04f040b0b 100644 --- a/gtk/gtkcssanimatedstyle.c +++ b/gtk/gtkcssanimatedstyle.c @@ -53,7 +53,7 @@ gtk_css_animated_style_get_section (GtkCssStyle *style, static gboolean gtk_css_animated_style_is_static (GtkCssStyle *style) { - GtkCssAnimatedStyle *animated = GTK_CSS_ANIMATED_STYLE (style); + GtkCssAnimatedStyle *animated = (GtkCssAnimatedStyle *)style; guint i; for (i = 0; i < animated->n_animations; i ++) diff --git a/gtk/gtkcssstyle.c b/gtk/gtkcssstyle.c index b02c4dd394..8a15649b74 100644 --- a/gtk/gtkcssstyle.c +++ b/gtk/gtkcssstyle.c @@ -293,8 +293,6 @@ gtk_css_style_get_section (GtkCssStyle *style, gboolean gtk_css_style_is_static (GtkCssStyle *style) { - gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (style), TRUE); - return GTK_CSS_STYLE_GET_CLASS (style)->is_static (style); } diff --git a/gtk/gtkcsstransition.c b/gtk/gtkcsstransition.c index 62731a513d..bb872a0b17 100644 --- a/gtk/gtkcsstransition.c +++ b/gtk/gtkcsstransition.c @@ -30,8 +30,7 @@ static GtkStyleAnimation * gtk_css_transition_advance (GtkStyleAnimation *style_animation, gint64 timestamp) { - GtkCssTransition *source = GTK_CSS_TRANSITION (style_animation); - + GtkCssTransition *source = (GtkCssTransition *)style_animation; GtkCssTransition *transition; transition = g_object_new (GTK_TYPE_CSS_TRANSITION, NULL); @@ -44,14 +43,14 @@ gtk_css_transition_advance (GtkStyleAnimation *style_animation, gtk_progress_tracker_advance_frame (&transition->tracker, timestamp); transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; - return GTK_STYLE_ANIMATION (transition); + return (GtkStyleAnimation *)transition; } static void gtk_css_transition_apply_values (GtkStyleAnimation *style_animation, GtkCssAnimatedStyle *style) { - GtkCssTransition *transition = GTK_CSS_TRANSITION (style_animation); + GtkCssTransition *transition = (GtkCssTransition *)style_animation; GtkCssValue *value, *end; double progress; GtkProgressState state; @@ -86,7 +85,7 @@ gtk_css_transition_apply_values (GtkStyleAnimation *style_animation, static gboolean gtk_css_transition_is_finished (GtkStyleAnimation *animation) { - GtkCssTransition *transition = GTK_CSS_TRANSITION (animation); + GtkCssTransition *transition = (GtkCssTransition *)animation; return transition->finished; } @@ -94,7 +93,7 @@ gtk_css_transition_is_finished (GtkStyleAnimation *animation) static gboolean gtk_css_transition_is_static (GtkStyleAnimation *animation) { - GtkCssTransition *transition = GTK_CSS_TRANSITION (animation); + GtkCssTransition *transition = (GtkCssTransition *)animation; return transition->finished; } diff --git a/gtk/gtkstyleanimation.c b/gtk/gtkstyleanimation.c index 89f8319fba..754f09b0c0 100644 --- a/gtk/gtkstyleanimation.c +++ b/gtk/gtkstyleanimation.c @@ -117,8 +117,6 @@ _gtk_style_animation_is_static (GtkStyleAnimation *animation) { GtkStyleAnimationClass *klass; - g_return_val_if_fail (GTK_IS_STYLE_ANIMATION (animation), TRUE); - klass = GTK_STYLE_ANIMATION_GET_CLASS (animation); return klass->is_static (animation); From 57444f77f755423653b0da6e36a74695aa7e1c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 12:34:56 +0200 Subject: [PATCH 08/18] testtreeview: Properly annotate a switch fallthrough --- tests/testtreeview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testtreeview.c b/tests/testtreeview.c index a5648c6be9..0715c449f4 100644 --- a/tests/testtreeview.c +++ b/tests/testtreeview.c @@ -448,7 +448,7 @@ set_columns_type (GtkTreeView *tree_view, ColumnsType type) #endif - /* FALL THRU */ + G_GNUC_FALLTHROUGH; case COLUMNS_ONE: rend = gtk_cell_renderer_text_new (); From 1b10020b6e0853f92f75c7b9bae9d08acff2b5f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 6 May 2020 19:17:11 +0200 Subject: [PATCH 09/18] css: Make GtkStyleAnimation and subclasses non-objects Making them GObjects is unnecessary. This enables further optimizations down the road. The only place we use them in is gtkcssanimatedstyle.c after all. --- gtk/gtkcssanimatedstyle.c | 25 ++++++--- gtk/gtkcssanimation.c | 69 ++++++++++++------------- gtk/gtkcssanimationprivate.h | 8 +-- gtk/gtkcssdynamic.c | 40 ++++++++------- gtk/gtkcssdynamicprivate.h | 20 -------- gtk/gtkcsstransition.c | 92 +++++++++++++++++++--------------- gtk/gtkcsstransitionprivate.h | 21 +------- gtk/gtkstyleanimation.c | 91 +++++++++------------------------ gtk/gtkstyleanimationprivate.h | 17 +++---- 9 files changed, 157 insertions(+), 226 deletions(-) diff --git a/gtk/gtkcssanimatedstyle.c b/gtk/gtkcssanimatedstyle.c index c04f040b0b..bef4a9028c 100644 --- a/gtk/gtkcssanimatedstyle.c +++ b/gtk/gtkcssanimatedstyle.c @@ -81,7 +81,7 @@ gtk_css_animated_style_dispose (GObject *object) guint i; for (i = 0; i < style->n_animations; i ++) - g_object_unref (style->animations[i]); + gtk_style_animation_unref (style->animations[i]); style->n_animations = 0; g_free (style->animations); @@ -646,7 +646,7 @@ gtk_css_animated_style_find_transition (GtkCssAnimatedStyle *style, { GtkStyleAnimation *animation = style->animations[i]; - if (!GTK_IS_CSS_TRANSITION (animation)) + if (!_gtk_css_transition_is_transition (animation)) continue; if (_gtk_css_transition_get_property ((GtkCssTransition *)animation) == property_id) @@ -745,7 +745,7 @@ gtk_css_animated_style_find_animation (GtkStyleAnimation **animations, { GtkStyleAnimation *animation = animations[i]; - if (!GTK_IS_CSS_ANIMATION (animation)) + if (!_gtk_css_animation_is_animation (animation)) continue; if (g_str_equal (_gtk_css_animation_get_name ((GtkCssAnimation *)animation), name)) @@ -765,9 +765,19 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations, { GtkCssValue *durations, *delays, *timing_functions, *animation_names; GtkCssValue *iteration_counts, *directions, *play_states, *fill_modes; + gboolean source_is_animated; guint i; animation_names = base_style->animation->animation_name; + + if (_gtk_css_array_value_get_n_values (animation_names) == 1) + { + const char *name = _gtk_css_ident_value_get (_gtk_css_array_value_get_nth (animation_names, 0)); + + if (g_ascii_strcasecmp (name, "none") == 0) + return animations; + } + durations = base_style->animation->animation_duration; delays = base_style->animation->animation_delay; timing_functions = base_style->animation->animation_timing_function; @@ -775,6 +785,7 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations, directions = base_style->animation->animation_direction; play_states = base_style->animation->animation_play_state; fill_modes = base_style->animation->animation_fill_mode; + source_is_animated = GTK_IS_CSS_ANIMATED_STYLE (source); for (i = 0; i < _gtk_css_array_value_get_n_values (animation_names); i++) { @@ -792,14 +803,14 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations, if (animation) continue; - if (GTK_IS_CSS_ANIMATED_STYLE (source)) + if (source_is_animated) animation = gtk_css_animated_style_find_animation ((GtkStyleAnimation **)GTK_CSS_ANIMATED_STYLE (source)->animations, GTK_CSS_ANIMATED_STYLE (source)->n_animations, name); if (animation) { - animation = _gtk_css_animation_advance_with_play_state (GTK_CSS_ANIMATION (animation), + animation = _gtk_css_animation_advance_with_play_state ((GtkCssAnimation *)animation, timestamp, _gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i))); } @@ -825,7 +836,7 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations, } if (!animations) - animations = g_ptr_array_new (); + animations = g_ptr_array_sized_new (16); g_ptr_array_add (animations, animation); } @@ -928,7 +939,7 @@ gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source, continue; if (!animations) - animations = g_ptr_array_new (); + animations = g_ptr_array_sized_new (16); animation = _gtk_style_animation_advance (animation, timestamp); g_ptr_array_add (animations, animation); diff --git a/gtk/gtkcssanimation.c b/gtk/gtkcssanimation.c index 445b58d24d..076abd950a 100644 --- a/gtk/gtkcssanimation.c +++ b/gtk/gtkcssanimation.c @@ -26,8 +26,6 @@ #include -G_DEFINE_TYPE (GtkCssAnimation, _gtk_css_animation, GTK_TYPE_STYLE_ANIMATION) - static gboolean gtk_css_animation_is_executing (GtkCssAnimation *animation) { @@ -80,7 +78,7 @@ static GtkStyleAnimation * gtk_css_animation_advance (GtkStyleAnimation *style_animation, gint64 timestamp) { - GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation); + GtkCssAnimation *animation = (GtkCssAnimation *)style_animation; return _gtk_css_animation_advance_with_play_state (animation, timestamp, @@ -91,7 +89,7 @@ static void gtk_css_animation_apply_values (GtkStyleAnimation *style_animation, GtkCssAnimatedStyle *style) { - GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation); + GtkCssAnimation *animation = (GtkCssAnimation *)style_animation; double progress; guint i; @@ -125,7 +123,7 @@ gtk_css_animation_is_finished (GtkStyleAnimation *style_animation) static gboolean gtk_css_animation_is_static (GtkStyleAnimation *style_animation) { - GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation); + GtkCssAnimation *animation = (GtkCssAnimation *)style_animation; if (animation->play_state == GTK_CSS_PLAY_STATE_PAUSED) return TRUE; @@ -134,35 +132,26 @@ gtk_css_animation_is_static (GtkStyleAnimation *style_animation) } static void -gtk_css_animation_finalize (GObject *object) +gtk_css_animation_free (GtkStyleAnimation *animation) { - GtkCssAnimation *animation = GTK_CSS_ANIMATION (object); + GtkCssAnimation *self = (GtkCssAnimation *)animation; - g_free (animation->name); - _gtk_css_keyframes_unref (animation->keyframes); - _gtk_css_value_unref (animation->ease); + g_free (self->name); + _gtk_css_keyframes_unref (self->keyframes); + _gtk_css_value_unref (self->ease); - G_OBJECT_CLASS (_gtk_css_animation_parent_class)->finalize (object); + g_slice_free (GtkCssAnimation, self); } -static void -_gtk_css_animation_class_init (GtkCssAnimationClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkStyleAnimationClass *animation_class = GTK_STYLE_ANIMATION_CLASS (klass); +static const GtkStyleAnimationClass GTK_CSS_ANIMATION_CLASS = { + "GtkCssAnimation", + gtk_css_animation_free, + gtk_css_animation_is_finished, + gtk_css_animation_is_static, + gtk_css_animation_apply_values, + gtk_css_animation_advance, +}; - object_class->finalize = gtk_css_animation_finalize; - - animation_class->advance = gtk_css_animation_advance; - animation_class->apply_values = gtk_css_animation_apply_values; - animation_class->is_finished = gtk_css_animation_is_finished; - animation_class->is_static = gtk_css_animation_is_static; -} - -static void -_gtk_css_animation_init (GtkCssAnimation *animation) -{ -} GtkStyleAnimation * _gtk_css_animation_new (const char *name, @@ -183,7 +172,9 @@ _gtk_css_animation_new (const char *name, g_return_val_if_fail (ease != NULL, NULL); g_return_val_if_fail (iteration_count >= 0, NULL); - animation = g_object_new (GTK_TYPE_CSS_ANIMATION, NULL); + animation = g_slice_alloc (sizeof (GtkCssAnimation)); + animation->parent.class = >K_CSS_ANIMATION_CLASS; + animation->parent.ref_count = 1; animation->name = g_strdup (name); animation->keyframes = _gtk_css_keyframes_ref (keyframes); @@ -198,14 +189,12 @@ _gtk_css_animation_new (const char *name, else gtk_progress_tracker_advance_frame (&animation->tracker, timestamp); - return GTK_STYLE_ANIMATION (animation); + return (GtkStyleAnimation *)animation; } const char * _gtk_css_animation_get_name (GtkCssAnimation *animation) { - g_return_val_if_fail (GTK_IS_CSS_ANIMATION (animation), NULL); - return animation->name; } @@ -214,11 +203,9 @@ _gtk_css_animation_advance_with_play_state (GtkCssAnimation *source, gint64 timestamp, GtkCssPlayState play_state) { - GtkCssAnimation *animation; - - g_return_val_if_fail (GTK_IS_CSS_ANIMATION (source), NULL); - - animation = g_object_new (GTK_TYPE_CSS_ANIMATION, NULL); + GtkCssAnimation *animation = g_slice_alloc (sizeof (GtkCssAnimation)); + animation->parent.class = >K_CSS_ANIMATION_CLASS; + animation->parent.ref_count = 1; animation->name = g_strdup (source->name); animation->keyframes = _gtk_css_keyframes_ref (source->keyframes); @@ -233,5 +220,11 @@ _gtk_css_animation_advance_with_play_state (GtkCssAnimation *source, else gtk_progress_tracker_advance_frame (&animation->tracker, timestamp); - return GTK_STYLE_ANIMATION (animation); + return (GtkStyleAnimation *)animation; +} + +gboolean +_gtk_css_animation_is_animation (GtkStyleAnimation *animation) +{ + return animation->class == >K_CSS_ANIMATION_CLASS; } diff --git a/gtk/gtkcssanimationprivate.h b/gtk/gtkcssanimationprivate.h index 811cddfcce..ab47be8c9c 100644 --- a/gtk/gtkcssanimationprivate.h +++ b/gtk/gtkcssanimationprivate.h @@ -27,13 +27,6 @@ G_BEGIN_DECLS -#define GTK_TYPE_CSS_ANIMATION (_gtk_css_animation_get_type ()) -#define GTK_CSS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_ANIMATION, GtkCssAnimation)) -#define GTK_CSS_ANIMATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_ANIMATION, GtkCssAnimationClass)) -#define GTK_IS_CSS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_ANIMATION)) -#define GTK_IS_CSS_ANIMATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_ANIMATION)) -#define GTK_CSS_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_ANIMATION, GtkCssAnimationClass)) - typedef struct _GtkCssAnimation GtkCssAnimation; typedef struct _GtkCssAnimationClass GtkCssAnimationClass; @@ -73,6 +66,7 @@ GtkStyleAnimation * _gtk_css_animation_advance_with_play_state (GtkCssAnimat GtkCssPlayState play_state); const char * _gtk_css_animation_get_name (GtkCssAnimation *animation); +gboolean _gtk_css_animation_is_animation (GtkStyleAnimation *animation); G_END_DECLS diff --git a/gtk/gtkcssdynamic.c b/gtk/gtkcssdynamic.c index 89243b701c..5dc65101ab 100644 --- a/gtk/gtkcssdynamic.c +++ b/gtk/gtkcssdynamic.c @@ -20,10 +20,13 @@ #include "config.h" #include "gtkcssdynamicprivate.h" - #include "gtkprogresstrackerprivate.h" -G_DEFINE_TYPE (GtkCssDynamic, gtk_css_dynamic, GTK_TYPE_STYLE_ANIMATION) +struct _GtkCssDynamic +{ + GtkStyleAnimation parent; + gint64 timestamp; +}; static GtkStyleAnimation * gtk_css_dynamic_advance (GtkStyleAnimation *style_animation, @@ -36,13 +39,13 @@ static void gtk_css_dynamic_apply_values (GtkStyleAnimation *style_animation, GtkCssAnimatedStyle *style) { - GtkCssDynamic *dynamic = GTK_CSS_DYNAMIC (style_animation); + GtkCssDynamic *dynamic = (GtkCssDynamic *)style_animation; guint i; for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++) { GtkCssValue *value, *dynamic_value; - + value = gtk_css_style_get_value (GTK_CSS_STYLE (style), i); dynamic_value = gtk_css_value_get_dynamic_value (value, dynamic->timestamp); if (value != dynamic_value) @@ -65,30 +68,29 @@ gtk_css_dynamic_is_static (GtkStyleAnimation *style_animation) } static void -gtk_css_dynamic_class_init (GtkCssDynamicClass *klass) +gtk_css_dynamic_free (GtkStyleAnimation *animation) { - GtkStyleAnimationClass *animation_class = GTK_STYLE_ANIMATION_CLASS (klass); - - animation_class->advance = gtk_css_dynamic_advance; - animation_class->apply_values = gtk_css_dynamic_apply_values; - animation_class->is_finished = gtk_css_dynamic_is_finished; - animation_class->is_static = gtk_css_dynamic_is_static; + g_slice_free (GtkCssDynamic, (GtkCssDynamic *)animation); } -static void -gtk_css_dynamic_init (GtkCssDynamic *dynamic) -{ -} +static const GtkStyleAnimationClass GTK_CSS_DYNAMIC_CLASS = { + "GtkCssDynamic", + gtk_css_dynamic_free, + gtk_css_dynamic_is_finished, + gtk_css_dynamic_is_static, + gtk_css_dynamic_apply_values, + gtk_css_dynamic_advance, +}; GtkStyleAnimation * gtk_css_dynamic_new (gint64 timestamp) { - GtkCssDynamic *dynamic; - - dynamic = g_object_new (GTK_TYPE_CSS_DYNAMIC, NULL); + GtkCssDynamic *dynamic = g_slice_alloc (sizeof (GtkCssDynamic)); + dynamic->parent.class = >K_CSS_DYNAMIC_CLASS; + dynamic->parent.ref_count = 1; dynamic->timestamp = timestamp; - return GTK_STYLE_ANIMATION (dynamic); + return (GtkStyleAnimation *)dynamic; } diff --git a/gtk/gtkcssdynamicprivate.h b/gtk/gtkcssdynamicprivate.h index 5b91baa32c..8f356c265a 100644 --- a/gtk/gtkcssdynamicprivate.h +++ b/gtk/gtkcssdynamicprivate.h @@ -26,27 +26,7 @@ G_BEGIN_DECLS -#define GTK_TYPE_CSS_DYNAMIC (gtk_css_dynamic_get_type ()) -#define GTK_CSS_DYNAMIC(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_DYNAMIC, GtkCssDynamic)) -#define GTK_CSS_DYNAMIC_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_DYNAMIC, GtkCssDynamicClass)) -#define GTK_IS_CSS_DYNAMIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_DYNAMIC)) -#define GTK_IS_CSS_DYNAMIC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_DYNAMIC)) -#define GTK_CSS_DYNAMIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_DYNAMIC, GtkCssDynamicClass)) - typedef struct _GtkCssDynamic GtkCssDynamic; -typedef struct _GtkCssDynamicClass GtkCssDynamicClass; - -struct _GtkCssDynamic -{ - GtkStyleAnimation parent; - - gint64 timestamp; -}; - -struct _GtkCssDynamicClass -{ - GtkStyleAnimationClass parent_class; -}; GType gtk_css_dynamic_get_type (void) G_GNUC_CONST; diff --git a/gtk/gtkcsstransition.c b/gtk/gtkcsstransition.c index bb872a0b17..fee6d66d71 100644 --- a/gtk/gtkcsstransition.c +++ b/gtk/gtkcsstransition.c @@ -24,27 +24,22 @@ #include "gtkcsseasevalueprivate.h" #include "gtkprogresstrackerprivate.h" -G_DEFINE_TYPE (GtkCssTransition, _gtk_css_transition, GTK_TYPE_STYLE_ANIMATION) - -static GtkStyleAnimation * -gtk_css_transition_advance (GtkStyleAnimation *style_animation, - gint64 timestamp) +struct _GtkCssTransition { - GtkCssTransition *source = (GtkCssTransition *)style_animation; - GtkCssTransition *transition; + GtkStyleAnimation parent; - transition = g_object_new (GTK_TYPE_CSS_TRANSITION, NULL); + guint property; + GtkCssValue *start; + GtkCssValue *ease; + GtkProgressTracker tracker; + guint finished; +}; - transition->property = source->property; - transition->start = _gtk_css_value_ref (source->start); - transition->ease = _gtk_css_value_ref (source->ease); - gtk_progress_tracker_init_copy (&source->tracker, &transition->tracker); - gtk_progress_tracker_advance_frame (&transition->tracker, timestamp); - transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; +static GtkStyleAnimation * gtk_css_transition_advance (GtkStyleAnimation *style_animation, + gint64 timestamp); + - return (GtkStyleAnimation *)transition; -} static void gtk_css_transition_apply_values (GtkStyleAnimation *style_animation, @@ -99,35 +94,46 @@ gtk_css_transition_is_static (GtkStyleAnimation *animation) } static void -gtk_css_transition_finalize (GObject *object) +gtk_css_transition_free (GtkStyleAnimation *animation) { - GtkCssTransition *transition = GTK_CSS_TRANSITION (object); + GtkCssTransition *self = (GtkCssTransition *)animation; - _gtk_css_value_unref (transition->start); - _gtk_css_value_unref (transition->ease); + gtk_css_value_unref (self->start); + gtk_css_value_unref (self->ease); - G_OBJECT_CLASS (_gtk_css_transition_parent_class)->finalize (object); + g_slice_free (GtkCssTransition, self); } -static void -_gtk_css_transition_class_init (GtkCssTransitionClass *klass) +static const GtkStyleAnimationClass GTK_CSS_TRANSITION_CLASS = { + "GtkCssTransition", + gtk_css_transition_free, + gtk_css_transition_is_finished, + gtk_css_transition_is_static, + gtk_css_transition_apply_values, + gtk_css_transition_advance, +}; + +static GtkStyleAnimation * +gtk_css_transition_advance (GtkStyleAnimation *style_animation, + gint64 timestamp) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkStyleAnimationClass *animation_class = GTK_STYLE_ANIMATION_CLASS (klass); + GtkCssTransition *source = (GtkCssTransition *)style_animation; + GtkCssTransition *transition; - object_class->finalize = gtk_css_transition_finalize; + transition = g_slice_alloc (sizeof (GtkCssTransition)); + transition->parent.class = >K_CSS_TRANSITION_CLASS; + transition->parent.ref_count = 1; - animation_class->advance = gtk_css_transition_advance; - animation_class->apply_values = gtk_css_transition_apply_values; - animation_class->is_finished = gtk_css_transition_is_finished; - animation_class->is_static = gtk_css_transition_is_static; + transition->property = source->property; + transition->start = _gtk_css_value_ref (source->start); + transition->ease = _gtk_css_value_ref (source->ease); + + gtk_progress_tracker_init_copy (&source->tracker, &transition->tracker); + gtk_progress_tracker_advance_frame (&transition->tracker, timestamp); + transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; + + return (GtkStyleAnimation *)transition; } - -static void -_gtk_css_transition_init (GtkCssTransition *transition) -{ -} - GtkStyleAnimation * _gtk_css_transition_new (guint property, GtkCssValue *start, @@ -141,7 +147,9 @@ _gtk_css_transition_new (guint property, g_return_val_if_fail (start != NULL, NULL); g_return_val_if_fail (ease != NULL, NULL); - transition = g_object_new (GTK_TYPE_CSS_TRANSITION, NULL); + transition = g_slice_alloc (sizeof (GtkCssTransition)); + transition->parent.class = >K_CSS_TRANSITION_CLASS; + transition->parent.ref_count = 1; transition->property = property; transition->start = _gtk_css_value_ref (start); @@ -150,13 +158,17 @@ _gtk_css_transition_new (guint property, gtk_progress_tracker_advance_frame (&transition->tracker, timestamp); transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER; - return GTK_STYLE_ANIMATION (transition); + return (GtkStyleAnimation*)transition; } guint _gtk_css_transition_get_property (GtkCssTransition *transition) { - g_return_val_if_fail (GTK_IS_CSS_TRANSITION (transition), 0); - return transition->property; } + +gboolean +_gtk_css_transition_is_transition (GtkStyleAnimation *animation) +{ + return animation->class == >K_CSS_TRANSITION_CLASS; +} diff --git a/gtk/gtkcsstransitionprivate.h b/gtk/gtkcsstransitionprivate.h index 6f722023a1..f50f070c7e 100644 --- a/gtk/gtkcsstransitionprivate.h +++ b/gtk/gtkcsstransitionprivate.h @@ -25,26 +25,8 @@ G_BEGIN_DECLS -#define GTK_TYPE_CSS_TRANSITION (_gtk_css_transition_get_type ()) -#define GTK_CSS_TRANSITION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_TRANSITION, GtkCssTransition)) -#define GTK_CSS_TRANSITION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_TRANSITION, GtkCssTransitionClass)) -#define GTK_IS_CSS_TRANSITION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_TRANSITION)) -#define GTK_IS_CSS_TRANSITION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_TRANSITION)) -#define GTK_CSS_TRANSITION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_TRANSITION, GtkCssTransitionClass)) - -typedef struct _GtkCssTransition GtkCssTransition; typedef struct _GtkCssTransitionClass GtkCssTransitionClass; - -struct _GtkCssTransition -{ - GtkStyleAnimation parent; - - guint property; - GtkCssValue *start; - GtkCssValue *ease; - GtkProgressTracker tracker; - guint finished; -}; +typedef struct _GtkCssTransition GtkCssTransition; struct _GtkCssTransitionClass { @@ -61,6 +43,7 @@ GtkStyleAnimation * _gtk_css_transition_new (guint gint64 delay_us); guint _gtk_css_transition_get_property (GtkCssTransition *transition); +gboolean _gtk_css_transition_is_transition (GtkStyleAnimation *animation); G_END_DECLS diff --git a/gtk/gtkstyleanimation.c b/gtk/gtkstyleanimation.c index 754f09b0c0..0ad4667b7f 100644 --- a/gtk/gtkstyleanimation.c +++ b/gtk/gtkstyleanimation.c @@ -21,84 +21,47 @@ #include "gtkstyleanimationprivate.h" -G_DEFINE_ABSTRACT_TYPE (GtkStyleAnimation, _gtk_style_animation, G_TYPE_OBJECT) - -static GtkStyleAnimation * -gtk_style_animation_real_advance (GtkStyleAnimation *animation, - gint64 timestamp) -{ - return NULL; -} - -static void -gtk_style_animation_real_apply_values (GtkStyleAnimation *animation, - GtkCssAnimatedStyle *style) -{ -} - -static gboolean -gtk_style_animation_real_is_finished (GtkStyleAnimation *animation) -{ - return TRUE; -} - -static gboolean -gtk_style_animation_real_is_static (GtkStyleAnimation *animation) -{ - return FALSE; -} - -static void -_gtk_style_animation_class_init (GtkStyleAnimationClass *klass) -{ - klass->advance = gtk_style_animation_real_advance; - klass->apply_values = gtk_style_animation_real_apply_values; - klass->is_finished = gtk_style_animation_real_is_finished; - klass->is_static = gtk_style_animation_real_is_static; -} - -static void -_gtk_style_animation_init (GtkStyleAnimation *animation) -{ -} - GtkStyleAnimation * -_gtk_style_animation_advance (GtkStyleAnimation *animation, - gint64 timestamp) +_gtk_style_animation_advance (GtkStyleAnimation *animation, + gint64 timestamp) { - GtkStyleAnimationClass *klass; + g_assert (animation != NULL); - g_return_val_if_fail (GTK_IS_STYLE_ANIMATION (animation), NULL); - - klass = GTK_STYLE_ANIMATION_GET_CLASS (animation); - - return klass->advance (animation, timestamp); + return animation->class->advance (animation, timestamp); } void _gtk_style_animation_apply_values (GtkStyleAnimation *animation, GtkCssAnimatedStyle *style) { - GtkStyleAnimationClass *klass; - - g_return_if_fail (GTK_IS_STYLE_ANIMATION (animation)); - g_return_if_fail (GTK_IS_CSS_ANIMATED_STYLE (style)); - - klass = GTK_STYLE_ANIMATION_GET_CLASS (animation); - - klass->apply_values (animation, style); + animation->class->apply_values (animation, style); } gboolean _gtk_style_animation_is_finished (GtkStyleAnimation *animation) { - GtkStyleAnimationClass *klass; + return animation->class->is_finished (animation); +} - g_return_val_if_fail (GTK_IS_STYLE_ANIMATION (animation), TRUE); - klass = GTK_STYLE_ANIMATION_GET_CLASS (animation); +GtkStyleAnimation * +gtk_style_animation_ref (GtkStyleAnimation *animation) +{ + animation->ref_count++; + return animation; +} - return klass->is_finished (animation); +GtkStyleAnimation * +gtk_style_animation_unref (GtkStyleAnimation *animation) +{ + animation->ref_count--; + + if (animation->ref_count == 0) + { + animation->class->free (animation); + return NULL; + } + return animation; } /** @@ -115,9 +78,5 @@ _gtk_style_animation_is_finished (GtkStyleAnimation *animation) gboolean _gtk_style_animation_is_static (GtkStyleAnimation *animation) { - GtkStyleAnimationClass *klass; - - klass = GTK_STYLE_ANIMATION_GET_CLASS (animation); - - return klass->is_static (animation); + return animation->class->is_static (animation); } diff --git a/gtk/gtkstyleanimationprivate.h b/gtk/gtkstyleanimationprivate.h index dacb159e60..dbf8dbce40 100644 --- a/gtk/gtkstyleanimationprivate.h +++ b/gtk/gtkstyleanimationprivate.h @@ -24,25 +24,19 @@ G_BEGIN_DECLS -#define GTK_TYPE_STYLE_ANIMATION (_gtk_style_animation_get_type ()) -#define GTK_STYLE_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_STYLE_ANIMATION, GtkStyleAnimation)) -#define GTK_STYLE_ANIMATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_STYLE_ANIMATION, GtkStyleAnimationClass)) -#define GTK_IS_STYLE_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_STYLE_ANIMATION)) -#define GTK_IS_STYLE_ANIMATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_STYLE_ANIMATION)) -#define GTK_STYLE_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STYLE_ANIMATION, GtkStyleAnimationClass)) - typedef struct _GtkStyleAnimation GtkStyleAnimation; typedef struct _GtkStyleAnimationClass GtkStyleAnimationClass; struct _GtkStyleAnimation { - GObject parent; + const GtkStyleAnimationClass *class; + guint ref_count; }; struct _GtkStyleAnimationClass { - GObjectClass parent_class; - + const char *type_name; + void (* free) (GtkStyleAnimation *animation); gboolean (* is_finished) (GtkStyleAnimation *animation); gboolean (* is_static) (GtkStyleAnimation *animation); void (* apply_values) (GtkStyleAnimation *animation, @@ -60,6 +54,9 @@ void _gtk_style_animation_apply_values (GtkStyleAnimation gboolean _gtk_style_animation_is_finished (GtkStyleAnimation *animation); gboolean _gtk_style_animation_is_static (GtkStyleAnimation *animation); +GtkStyleAnimation * gtk_style_animation_ref (GtkStyleAnimation *animation); +GtkStyleAnimation * gtk_style_animation_unref (GtkStyleAnimation *animation); + G_END_DECLS From 343707e0a2142cb303f2f7b8e45c8e7c89f131ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 May 2020 08:19:52 +0200 Subject: [PATCH 10/18] stylecontext: Remove some unused private API --- gtk/gtkstylecontext.c | 36 ------------------------------------ gtk/gtkstylecontextprivate.h | 5 ----- 2 files changed, 41 deletions(-) diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index 8463b93c0f..c15acac6ed 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -471,42 +471,6 @@ gtk_style_context_remove_provider_for_display (GdkDisplay *display, _gtk_style_cascade_remove_provider (cascade, provider); } -/* - * gtk_style_context_set_id: - * @context: a #GtkStyleContext - * @id: (allow-none): the id to use or %NULL for none. - * - * Sets the CSS ID to be used when obtaining style information. - **/ -void -gtk_style_context_set_id (GtkStyleContext *context, - const char *id) -{ - GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context); - - g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); - - gtk_css_node_set_id (priv->cssnode, g_quark_from_string (id)); -} - -/* - * gtk_style_context_get_id: - * @context: a #GtkStyleContext - * - * Returns the CSS ID used when obtaining style information. - * - * Returns: (nullable): the ID or %NULL if no ID is set. - **/ -const char * -gtk_style_context_get_id (GtkStyleContext *context) -{ - GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context); - - g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL); - - return g_quark_to_string (gtk_css_node_get_id (priv->cssnode)); -} - /** * gtk_style_context_set_state: * @context: a #GtkStyleContext diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index c40442d498..580bb105c6 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -33,9 +33,6 @@ G_BEGIN_DECLS GtkStyleContext *gtk_style_context_new_for_node (GtkCssNode *node); GtkCssNode *gtk_style_context_get_node (GtkStyleContext *context); -void gtk_style_context_set_id (GtkStyleContext *context, - const char *id); -const char * gtk_style_context_get_id (GtkStyleContext *context); GtkStyleProvider * gtk_style_context_get_style_provider (GtkStyleContext *context); @@ -47,8 +44,6 @@ void gtk_style_context_save_to_node (GtkStyleContext *c GtkCssStyle * gtk_style_context_lookup_style (GtkStyleContext *context); GtkCssValue * _gtk_style_context_peek_property (GtkStyleContext *context, guint property_id); -gboolean _gtk_style_context_check_region_name (const gchar *str); - void _gtk_style_context_get_cursor_color (GtkStyleContext *context, GdkRGBA *primary_color, GdkRGBA *secondary_color); From 2455978c78da98d21de54a872ffd81fe31f572f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 May 2020 08:20:03 +0200 Subject: [PATCH 11/18] widget: Move {dis,}connect_frame_clock into their only caller Makes sense to have these only in (un)realize. --- gtk/gtkwidget.c | 63 ++++++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 15c775aa44..cacc247c63 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -3113,44 +3113,6 @@ gtk_widget_has_tick_callback (GtkWidget *widget) return priv->tick_callbacks != NULL; } -static void -gtk_widget_connect_frame_clock (GtkWidget *widget) -{ - GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - GdkFrameClock *frame_clock; - - frame_clock = gtk_widget_get_frame_clock (widget); - - if (priv->tick_callbacks != NULL && !priv->clock_tick_id) - { - priv->clock_tick_id = g_signal_connect (frame_clock, "update", - G_CALLBACK (gtk_widget_on_frame_clock_update), - widget); - gdk_frame_clock_begin_updating (frame_clock); - } - - gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE); -} - -static void -gtk_widget_disconnect_frame_clock (GtkWidget *widget) -{ - GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); - - gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE); - - if (priv->clock_tick_id) - { - GdkFrameClock *frame_clock; - - frame_clock = gtk_widget_get_frame_clock (widget); - - g_signal_handler_disconnect (frame_clock, priv->clock_tick_id); - priv->clock_tick_id = 0; - gdk_frame_clock_end_updating (frame_clock); - } -} - typedef struct _GtkSurfaceTransformChangedCallbackInfo GtkSurfaceTransformChangedCallbackInfo; struct _GtkSurfaceTransformChangedCallbackInfo @@ -7499,10 +7461,21 @@ static void gtk_widget_real_realize (GtkWidget *widget) { GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget); + GdkFrameClock *frame_clock; priv->realized = TRUE; - gtk_widget_connect_frame_clock (widget); + /* Connect frame clock */ + frame_clock = gtk_widget_get_frame_clock (widget); + if (priv->tick_callbacks != NULL && !priv->clock_tick_id) + { + priv->clock_tick_id = g_signal_connect (frame_clock, "update", + G_CALLBACK (gtk_widget_on_frame_clock_update), + widget); + gdk_frame_clock_begin_updating (frame_clock); + } + + gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE); } /***************************************** @@ -7528,7 +7501,17 @@ gtk_widget_real_unrealize (GtkWidget *widget) gtk_widget_forall (widget, (GtkCallback)gtk_widget_unrealize, NULL); - gtk_widget_disconnect_frame_clock (widget); + /* Disconnect frame clock */ + gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE); + + if (priv->clock_tick_id) + { + GdkFrameClock *frame_clock = gtk_widget_get_frame_clock (widget); + + g_signal_handler_disconnect (frame_clock, priv->clock_tick_id); + priv->clock_tick_id = 0; + gdk_frame_clock_end_updating (frame_clock); + } priv->realized = FALSE; } From cbbbf44dd43ca608709846cca3a5e2dac92429c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 May 2020 08:40:09 +0200 Subject: [PATCH 12/18] cellrenderertoggle: Replace save_named with a css node --- gtk/gtkcellrenderertoggle.c | 58 ++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/gtk/gtkcellrenderertoggle.c b/gtk/gtkcellrenderertoggle.c index fca10951d3..19e84adc63 100644 --- a/gtk/gtkcellrenderertoggle.c +++ b/gtk/gtkcellrenderertoggle.c @@ -26,6 +26,7 @@ #include "gtkrendericonprivate.h" #include "gtksnapshot.h" #include "gtkstylecontextprivate.h" +#include "gtkwidgetprivate.h" #include "gtktreeprivate.h" #include "a11y/gtkbooleancellaccessible.h" @@ -111,6 +112,7 @@ struct _GtkCellRendererTogglePrivate guint activatable : 1; guint inconsistent : 1; guint radio : 1; + GtkCssNode *cssnode; }; @@ -126,12 +128,26 @@ gtk_cell_renderer_toggle_init (GtkCellRendererToggle *celltoggle) priv->active = FALSE; priv->radio = FALSE; + priv->cssnode = gtk_css_node_new (); + gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("check")); + g_object_set (celltoggle, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL); gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (celltoggle), 2, 2); priv->inconsistent = FALSE; } +static void +gtk_cell_renderer_toggle_dispose (GObject *object) +{ + GtkCellRendererToggle *celltoggle = GTK_CELL_RENDERER_TOGGLE (object); + GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (celltoggle); + + g_clear_object (&priv->cssnode); + + G_OBJECT_CLASS (gtk_cell_renderer_toggle_parent_class)->dispose (object); +} + static void gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class) { @@ -140,6 +156,7 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class) object_class->get_property = gtk_cell_renderer_toggle_get_property; object_class->set_property = gtk_cell_renderer_toggle_set_property; + object_class->dispose = gtk_cell_renderer_toggle_dispose; cell_class->get_size = gtk_cell_renderer_toggle_get_size; cell_class->snapshot = gtk_cell_renderer_toggle_snapshot; @@ -268,7 +285,7 @@ gtk_cell_renderer_toggle_set_property (GObject *object, case PROP_RADIO: if (priv->radio != g_value_get_boolean (value)) { - priv->radio = g_value_get_boolean (value); + gtk_cell_renderer_toggle_set_radio (celltoggle, g_value_get_boolean (value)); g_object_notify_by_pspec (object, pspec); } break; @@ -298,23 +315,32 @@ gtk_cell_renderer_toggle_new (void) } static GtkStyleContext * -gtk_cell_renderer_toggle_save_context (GtkCellRenderer *cell, - GtkWidget *widget) +gtk_cell_renderer_toggle_save_context (GtkCellRendererToggle *cell, + GtkWidget *widget) { - GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (GTK_CELL_RENDERER_TOGGLE (cell)); - + GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (cell); GtkStyleContext *context; context = gtk_widget_get_style_context (widget); - if (priv->radio) - gtk_style_context_save_named (context, "radio"); - else - gtk_style_context_save_named (context, "check"); + gtk_css_node_set_parent (priv->cssnode, gtk_widget_get_css_node (widget)); + gtk_style_context_save_to_node (context, priv->cssnode); return context; } - + +static GtkStyleContext * +gtk_cell_renderer_toggle_restore_context (GtkCellRendererToggle *cell, + GtkStyleContext *context) +{ + GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (cell); + + gtk_style_context_restore (context); + gtk_css_node_set_parent (priv->cssnode, NULL); + + return context; +} + static int calc_indicator_size (GtkStyleContext *context) { @@ -339,7 +365,7 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell, gtk_cell_renderer_get_padding (cell, &xpad, &ypad); - context = gtk_cell_renderer_toggle_save_context (cell, widget); + context = gtk_cell_renderer_toggle_save_context (GTK_CELL_RENDERER_TOGGLE (cell), widget); gtk_style_context_get_padding (context, &padding); gtk_style_context_get_border (context, &border); @@ -347,7 +373,7 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell, calc_width += xpad * 2 + padding.left + padding.right + border.left + border.right; calc_height += ypad * 2 + padding.top + padding.bottom + border.top + border.bottom; - gtk_style_context_restore (context); + gtk_cell_renderer_toggle_restore_context (GTK_CELL_RENDERER_TOGGLE (cell), context); if (width) *width = calc_width; @@ -426,7 +452,7 @@ gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell, cell_area->width, cell_area->height )); - context = gtk_cell_renderer_toggle_save_context (cell, widget); + context = gtk_cell_renderer_toggle_save_context (celltoggle, widget); gtk_style_context_set_state (context, state); gtk_snapshot_render_background (snapshot, context, @@ -448,7 +474,7 @@ gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell, width - padding.left - padding.right - border.left - border.right, height - padding.top - padding.bottom - border.top - border.bottom); - gtk_style_context_restore (context); + gtk_cell_renderer_toggle_restore_context (celltoggle, context); gtk_snapshot_pop (snapshot); } @@ -495,6 +521,10 @@ gtk_cell_renderer_toggle_set_radio (GtkCellRendererToggle *toggle, g_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle)); priv->radio = radio; + if (radio) + gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("radio")); + else + gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("check")); } /** From bcdd6d54250941aac9ee19195f9f2ea74084a510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 May 2020 09:01:50 +0200 Subject: [PATCH 13/18] printunixdialog: Use two "paper" css nodes Instead of save_named'ing to a temporary "paper" node. --- gtk/gtkprintunixdialog.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/gtk/gtkprintunixdialog.c b/gtk/gtkprintunixdialog.c index 90ba3c5f50..9357c35f6b 100644 --- a/gtk/gtkprintunixdialog.c +++ b/gtk/gtkprintunixdialog.c @@ -377,6 +377,8 @@ struct _GtkPrintUnixDialog gchar *format_for_printer; gint current_page; + GtkCssNode *collate_paper_node; + GtkCssNode *page_layout_paper_node; }; struct _GtkPrintUnixDialogClass @@ -799,6 +801,18 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) gtk_css_node_set_name (gtk_widget_get_css_node (dialog->collate_image), g_quark_from_static_string ("drawing")); gtk_css_node_set_name (gtk_widget_get_css_node (dialog->page_layout_preview), g_quark_from_static_string ("drawing")); + + dialog->collate_paper_node = gtk_css_node_new(); + gtk_css_node_set_name (dialog->collate_paper_node, g_quark_from_static_string ("paper")); + gtk_css_node_set_parent (dialog->collate_paper_node, + gtk_widget_get_css_node (dialog->collate_image)); + g_object_unref (dialog->collate_paper_node); + + dialog->page_layout_paper_node = gtk_css_node_new(); + gtk_css_node_set_name (dialog->page_layout_paper_node, g_quark_from_static_string ("paper")); + gtk_css_node_set_parent (dialog->page_layout_paper_node, + gtk_widget_get_css_node (dialog->page_layout_preview)); + g_object_unref (dialog->page_layout_paper_node); } static void @@ -2183,7 +2197,8 @@ update_collate_icon (GtkToggleButton *toggle_button, } static void -paint_page (GtkWidget *widget, +paint_page (GtkPrintUnixDialog *dialog, + GtkWidget *widget, cairo_t *cr, gint x, gint y, @@ -2200,7 +2215,7 @@ paint_page (GtkWidget *widget, text_y = 21; context = gtk_widget_get_style_context (widget); - gtk_style_context_save_named (context, "paper"); + gtk_style_context_save_to_node (context, dialog->collate_paper_node); gtk_render_background (context, cr, x, y, width, height); gtk_render_frame (context, cr, x, y, width, height); @@ -2259,16 +2274,16 @@ draw_collate (GtkDrawingArea *da, if (copies == 1) { - paint_page (widget, cr, x1 + p1, y, reverse ? "1" : "2", text_x); - paint_page (widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x); + paint_page (dialog, widget, cr, x1 + p1, y, reverse ? "1" : "2", text_x); + paint_page (dialog, widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x); } else { - paint_page (widget, cr, x1 + p1, y, collate == reverse ? "1" : "2", text_x); - paint_page (widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x); + paint_page (dialog, widget, cr, x1 + p1, y, collate == reverse ? "1" : "2", text_x); + paint_page (dialog, widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x); - paint_page (widget, cr, x2 + p1, y, reverse ? "1" : "2", text_x); - paint_page (widget, cr, x2 + p2, y + 10, collate == reverse ? "2" : "1", text_x); + paint_page (dialog, widget, cr, x2 + p1, y, reverse ? "1" : "2", text_x); + paint_page (dialog, widget, cr, x2 + p2, y + 10, collate == reverse ? "2" : "1", text_x); } } @@ -2733,7 +2748,7 @@ draw_page (GtkDrawingArea *da, } context = gtk_widget_get_style_context (widget); - gtk_style_context_save_named (context, "paper"); + gtk_style_context_save_to_node (context, dialog->page_layout_paper_node); gtk_style_context_get_color (context, &color); pos_x = (width - w) / 2; @@ -2843,6 +2858,7 @@ draw_page (GtkDrawingArea *da, break; } + cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha); if (horizontal) for (y = start_y; y != end_y + dy; y += dy) { From 6566fdc1e32a9a59c9d5b6563fce09cfde9876be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 May 2020 09:07:43 +0200 Subject: [PATCH 14/18] scrolledwindwo: Add a permanent junction node Use that instead of save_named'ing a junction node. --- gtk/gtkscrolledwindow.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 24bdd5a063..6f6af32a83 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -246,6 +246,7 @@ typedef struct GtkCssNode *overshoot_node[4]; GtkCssNode *undershoot_node[4]; + GtkCssNode *junction_node; Indicator hindicator; Indicator vindicator; @@ -1839,7 +1840,7 @@ gtk_scrolled_window_snapshot_scrollbars_junction (GtkScrolledWindow *scrolled_wi junction_rect.height = hscr_allocation.height; context = gtk_widget_get_style_context (widget); - gtk_style_context_save_named (context, "junction"); + gtk_style_context_save_to_node (context, priv->junction_node); gtk_snapshot_render_background (snapshot, context, junction_rect.x, junction_rect.y, @@ -2050,6 +2051,12 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window) gtk_scrolled_window_update_use_indicators (scrolled_window); + priv->junction_node = gtk_css_node_new (); + gtk_css_node_set_name (priv->junction_node, g_quark_from_static_string ("junction")); + gtk_css_node_set_parent (priv->junction_node, widget_node); + gtk_css_node_set_state (priv->junction_node, gtk_css_node_get_state (widget_node)); + g_object_unref (priv->junction_node); + controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES | GTK_EVENT_CONTROLLER_SCROLL_KINETIC); g_signal_connect (controller, "scroll-begin", From 343d294bfbb9b966a54f5ace8054ead5051c3297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 May 2020 09:10:01 +0200 Subject: [PATCH 15/18] stylecontext: Remove _save_named Now unused. --- gtk/gtkstylecontext.c | 39 ++++++++++++++---------------------- gtk/gtkstylecontextprivate.h | 2 -- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index c15acac6ed..7c40e4a055 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -591,29 +591,6 @@ gtk_style_context_save_to_node (GtkStyleContext *context, priv->cssnode = g_object_ref (node); } -void -gtk_style_context_save_named (GtkStyleContext *context, - const char *name) -{ - GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context); - GtkCssNode *cssnode; - - /* Make sure we have the style existing. It is the - * parent of the new saved node after all. - */ - if (!gtk_style_context_is_saved (context)) - gtk_style_context_lookup_style (context); - - cssnode = gtk_css_transient_node_new (priv->cssnode); - gtk_css_node_set_parent (cssnode, gtk_style_context_get_root (context)); - if (name) - gtk_css_node_set_name (cssnode, g_quark_from_string (name)); - - gtk_style_context_save_to_node (context, cssnode); - - g_object_unref (cssnode); -} - /** * gtk_style_context_save: * @context: a #GtkStyleContext @@ -629,9 +606,23 @@ gtk_style_context_save_named (GtkStyleContext *context, void gtk_style_context_save (GtkStyleContext *context) { + GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context); + GtkCssNode *cssnode; + g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); - gtk_style_context_save_named (context, NULL); + + /* Make sure we have the style existing. It is the + * parent of the new saved node after all. + */ + if (!gtk_style_context_is_saved (context)) + gtk_style_context_lookup_style (context); + + cssnode = gtk_css_transient_node_new (priv->cssnode); + gtk_css_node_set_parent (cssnode, gtk_style_context_get_root (context)); + gtk_style_context_save_to_node (context, cssnode); + + g_object_unref (cssnode); } /** diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index 580bb105c6..b902bb5b99 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -36,8 +36,6 @@ GtkCssNode *gtk_style_context_get_node (GtkStyleContext *c GtkStyleProvider * gtk_style_context_get_style_provider (GtkStyleContext *context); -void gtk_style_context_save_named (GtkStyleContext *context, - const char *name); void gtk_style_context_save_to_node (GtkStyleContext *context, GtkCssNode *node); From d015b1b29eb377656d461fd20453b6f6a56f6de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 May 2020 19:00:30 +0200 Subject: [PATCH 16/18] scrolledwindow: Always keep the main child first Otherwise we can't pick the scrollbars, which are allocated behind it. --- gtk/gtkscrolledwindow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 6f6af32a83..a778502245 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -4213,7 +4213,7 @@ gtk_scrolled_window_set_child (GtkScrolledWindow *scrolled_window, } priv->child = scrollable_child; - gtk_widget_set_parent (scrollable_child, GTK_WIDGET (scrolled_window)); + gtk_widget_insert_after (scrollable_child, GTK_WIDGET (scrolled_window), NULL); g_object_set (scrollable_child, "hadjustment", hadj, From b98ad549c2826ee254bfb9dbb2e23cd65079cdfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 10 May 2020 09:07:30 +0200 Subject: [PATCH 17/18] gl renderer: Only destroy shader programs with ids > 0 We may return -1 as an error return value. --- gsk/gl/gskglrenderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index c1fa55c2dd..ac8680ba0f 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -2573,7 +2573,7 @@ gsk_gl_renderer_programs_unref (GskGLRendererPrograms *programs) { for (i = 0; i < GL_N_PROGRAMS; i ++) { - if (programs->programs[i].id != 0) + if (programs->programs[i].id > 0) glDeleteProgram (programs->programs[i].id); gsk_transform_unref (programs->state[i].modelview); } From 52ae384bfdfa17c7211dbc103287d4fd580e790f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sun, 10 May 2020 09:20:53 +0200 Subject: [PATCH 18/18] gl shaders: unify frag coord handling --- gsk/resources/glsl/border.glsl | 8 +++--- gsk/resources/glsl/inset_shadow.glsl | 9 +++---- gsk/resources/glsl/linear_gradient.glsl | 10 +------ gsk/resources/glsl/outset_shadow.glsl | 7 ++--- gsk/resources/glsl/preamble.fs.glsl | 27 ++++++++++++++----- .../glsl/unblurred_outset_shadow.glsl | 9 +++---- 6 files changed, 32 insertions(+), 38 deletions(-) diff --git a/gsk/resources/glsl/border.glsl b/gsk/resources/glsl/border.glsl index 812d365431..894843cc50 100644 --- a/gsk/resources/glsl/border.glsl +++ b/gsk/resources/glsl/border.glsl @@ -32,12 +32,10 @@ _IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline; _IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline; void main() { - vec4 f = gl_FragCoord; - f.x += u_viewport.x; - f.y = (u_viewport.y + u_viewport.w) - f.y; + vec2 frag = get_frag_coord(); - float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) - - rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy), + float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), frag) - + rounded_rect_coverage(decode_rect(transformed_inside_outline), frag), 0.0, 1.0); setOutputColor(final_color * alpha); diff --git a/gsk/resources/glsl/inset_shadow.glsl b/gsk/resources/glsl/inset_shadow.glsl index b3ba05a41f..238540c731 100644 --- a/gsk/resources/glsl/inset_shadow.glsl +++ b/gsk/resources/glsl/inset_shadow.glsl @@ -33,13 +33,10 @@ _IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline; _IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline; void main() { - vec4 f = gl_FragCoord; + vec2 frag = get_frag_coord(); - f.x += u_viewport.x; - f.y = (u_viewport.y + u_viewport.w) - f.y; - - float alpha = clamp (rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) - - rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy), + float alpha = clamp (rounded_rect_coverage(decode_rect(transformed_outside_outline), frag) - + rounded_rect_coverage(decode_rect(transformed_inside_outline), frag), 0.0, 1.0); setOutputColor(final_color * alpha); diff --git a/gsk/resources/glsl/linear_gradient.glsl b/gsk/resources/glsl/linear_gradient.glsl index 6814eed53f..cffe39294d 100644 --- a/gsk/resources/glsl/linear_gradient.glsl +++ b/gsk/resources/glsl/linear_gradient.glsl @@ -47,17 +47,9 @@ _IN_ float gradientLength; _IN_ vec4 color_stops[8]; _IN_ float color_offsets[8]; - -vec4 fragCoord() { - vec4 f = gl_FragCoord; - f.x += u_viewport.x; - f.y = (u_viewport.y + u_viewport.w) - f.y; - return f; -} - void main() { // Position relative to startPoint - vec2 pos = fragCoord().xy - startPoint; + vec2 pos = get_frag_coord() - startPoint; // Current pixel, projected onto the line between the start point and the end point // The projection will be relative to the start point! diff --git a/gsk/resources/glsl/outset_shadow.glsl b/gsk/resources/glsl/outset_shadow.glsl index 4111ddcea8..40ef45f648 100644 --- a/gsk/resources/glsl/outset_shadow.glsl +++ b/gsk/resources/glsl/outset_shadow.glsl @@ -25,13 +25,10 @@ _IN_ vec4 final_color; _IN_ _ROUNDED_RECT_UNIFORM_ transformed_outline; void main() { - vec4 f = gl_FragCoord; - - f.x += u_viewport.x; - f.y = (u_viewport.y + u_viewport.w) - f.y; + vec2 frag = get_frag_coord(); float alpha = Texture(u_source, vUv).a; - alpha *= (1.0 - clamp(rounded_rect_coverage(decode_rect(transformed_outline), f.xy), 0.0, 1.0)); + alpha *= (1.0 - clamp(rounded_rect_coverage(decode_rect(transformed_outline), frag), 0.0, 1.0)); vec4 color = final_color * alpha; diff --git a/gsk/resources/glsl/preamble.fs.glsl b/gsk/resources/glsl/preamble.fs.glsl index 5107470e00..cadbaf1331 100644 --- a/gsk/resources/glsl/preamble.fs.glsl +++ b/gsk/resources/glsl/preamble.fs.glsl @@ -84,19 +84,32 @@ vec4 Texture(sampler2D sampler, vec2 texCoords) { #endif } +#ifdef GSK_GL3 +layout(origin_upper_left) in vec4 gl_FragCoord; +#endif + +vec2 get_frag_coord() { + vec2 fc = gl_FragCoord.xy; + +#ifdef GSK_GL3 + fc += u_viewport.xy; +#else + fc.x += u_viewport.x; + fc.y = (u_viewport.y + u_viewport.w) - fc.y; +#endif + + return fc; +} + void setOutputColor(vec4 color) { - vec4 f = gl_FragCoord; - - f.x += u_viewport.x; - f.y = (u_viewport.y + u_viewport.w) - f.y; - + vec2 f = get_frag_coord(); // We do *NOT* transform the clip rect here since we already // need to do that on the CPU. #if defined(GSK_GLES) || defined(GSK_LEGACY) - gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy); + gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f); #else - outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy); + outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f); #endif /*outputColor = color;*/ } diff --git a/gsk/resources/glsl/unblurred_outset_shadow.glsl b/gsk/resources/glsl/unblurred_outset_shadow.glsl index 77c02be8e1..419605e092 100644 --- a/gsk/resources/glsl/unblurred_outset_shadow.glsl +++ b/gsk/resources/glsl/unblurred_outset_shadow.glsl @@ -33,13 +33,10 @@ _IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline; _IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline; void main() { - vec4 f = gl_FragCoord; + vec2 frag = get_frag_coord(); - f.x += u_viewport.x; - f.y = (u_viewport.y + u_viewport.w) - f.y; - - float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) - - rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy), + float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), frag) - + rounded_rect_coverage(decode_rect(transformed_inside_outline), frag), 0.0, 1.0); setOutputColor(final_color * alpha);