diff options
-rw-r--r-- | gtk/gtkcsslookup.c | 38 | ||||
-rw-r--r-- | gtk/gtkcsslookupprivate.h | 5 | ||||
-rw-r--r-- | gtk/gtkcssstaticstyle.c | 215 | ||||
-rw-r--r-- | gtk/gtkcssstaticstyleprivate.h | 8 | ||||
-rw-r--r-- | gtk/gtkcssstylepropertyimpl.c | 6 | ||||
-rw-r--r-- | gtk/gtkcssstylepropertyprivate.h | 7 |
6 files changed, 131 insertions, 148 deletions
diff --git a/gtk/gtkcsslookup.c b/gtk/gtkcsslookup.c index cfe5bfc5c5..3869840f59 100644 --- a/gtk/gtkcsslookup.c +++ b/gtk/gtkcsslookup.c @@ -76,40 +76,6 @@ _gtk_css_lookup_set (GtkCssLookup *lookup, lookup->values[id].value = value; lookup->values[id].section = section; lookup->n_set_values ++; -} - -/** - * _gtk_css_lookup_resolve: - * @lookup: the lookup - * @context: the context the values are resolved for - * @values: a new #GtkCssStyle to be filled with the new properties - * - * Resolves the current lookup into a styleproperties object. This is done - * by converting from the “winning declaration” to the “computed value”. - * - * XXX: This bypasses the notion of “specified value”. If this ever becomes - * an issue, go fix it. - **/ -void -_gtk_css_lookup_resolve (GtkCssLookup *lookup, - GtkStyleProvider *provider, - GtkCssStaticStyle *style, - GtkCssStyle *parent_style) -{ - guint i; - - gtk_internal_return_if_fail (lookup != NULL); - gtk_internal_return_if_fail (GTK_IS_STYLE_PROVIDER (provider)); - gtk_internal_return_if_fail (GTK_IS_CSS_STATIC_STYLE (style)); - gtk_internal_return_if_fail (parent_style == NULL || GTK_IS_CSS_STYLE (parent_style)); - - for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++) - { - gtk_css_static_style_compute_value (style, - provider, - parent_style, - i, - lookup->values[i].value, - lookup->values[i].section); - } + if (section) + lookup->has_section = TRUE; } diff --git a/gtk/gtkcsslookupprivate.h b/gtk/gtkcsslookupprivate.h index 34acd504c3..3e9915d4d4 100644 --- a/gtk/gtkcsslookupprivate.h +++ b/gtk/gtkcsslookupprivate.h @@ -37,6 +37,7 @@ typedef struct { struct _GtkCssLookup { guint n_set_values; + gboolean has_section; GtkCssLookupValue values[GTK_CSS_PROPERTY_N_PROPERTIES]; }; @@ -49,10 +50,6 @@ void _gtk_css_lookup_set (GtkCssLookup guint id, GtkCssSection *section, GtkCssValue *value); -void _gtk_css_lookup_resolve (GtkCssLookup *lookup, - GtkStyleProvider *provider, - GtkCssStaticStyle *style, - GtkCssStyle *parent_style); G_END_DECLS diff --git a/gtk/gtkcssstaticstyle.c b/gtk/gtkcssstaticstyle.c index 0c6b8da04b..f99f9efbc6 100644 --- a/gtk/gtkcssstaticstyle.c +++ b/gtk/gtkcssstaticstyle.c @@ -115,34 +115,6 @@ maybe_unref_section (gpointer section) gtk_css_section_unref (section); } -static void -gtk_css_static_style_set_value (GtkCssStaticStyle *style, - guint id, - GtkCssValue *value, - GtkCssSection *section) -{ - if (style->values[id]) - _gtk_css_value_unref (style->values[id]); - - style->values[id] = value; - - if (style->sections && style->sections->len > id && g_ptr_array_index (style->sections, id)) - { - gtk_css_section_unref (g_ptr_array_index (style->sections, id)); - g_ptr_array_index (style->sections, id) = NULL; - } - - if (section) - { - if (style->sections == NULL) - style->sections = g_ptr_array_new_with_free_func (maybe_unref_section); - if (style->sections->len <= id) - g_ptr_array_set_size (style->sections, id + 1); - - g_ptr_array_index (style->sections, id) = gtk_css_section_ref (section); - } -} - static GtkCssStyle *default_style; static void @@ -175,6 +147,120 @@ gtk_css_static_style_get_default (void) return default_style; } +G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_TOP_STYLE == GTK_CSS_PROPERTY_BORDER_TOP_WIDTH - 1); +G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE == GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH - 1); +G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE == GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH - 1); +G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_LEFT_STYLE == GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH - 1); +G_STATIC_ASSERT (GTK_CSS_PROPERTY_OUTLINE_STYLE == GTK_CSS_PROPERTY_OUTLINE_WIDTH - 1); + +static inline gboolean +is_border_style_special_case (guint id) +{ + switch (id) + { + case GTK_CSS_PROPERTY_BORDER_TOP_STYLE: + case GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE: + case GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE: + case GTK_CSS_PROPERTY_BORDER_LEFT_STYLE: + case GTK_CSS_PROPERTY_OUTLINE_STYLE: + return TRUE; + default: + return FALSE; + } +} + +static void +gtk_css_static_style_compute_values (GtkCssStaticStyle *style, + GtkStyleProvider *provider, + GtkCssStyle *parent_style, + GtkCssLookup *lookup) +{ + GtkCssLookupValue *values = lookup->values; + guint id; + GtkCssValue **parent_values; + guint border_prop[] = { + GTK_CSS_PROPERTY_BORDER_TOP_STYLE, + GTK_CSS_PROPERTY_BORDER_LEFT_STYLE, + GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE, + GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE, + GTK_CSS_PROPERTY_OUTLINE_STYLE, + 0 + }; + int b = 0; + + if (GTK_IS_CSS_STATIC_STYLE (parent_style)) + parent_values = GTK_CSS_STATIC_STYLE (parent_style)->values; + else + parent_values = NULL; + + for (id = 0; id < GTK_CSS_PROPERTY_N_PROPERTIES; id++) + { + GtkCssValue *specified = values[id].value; + + /* http://www.w3.org/TR/css3-cascade/#cascade + * Then, for every element, the value for each property can be found + * by following this pseudo-algorithm: + * 1) Identify all declarations that apply to the element + */ + if (specified) + { + style->values[id] = _gtk_css_value_compute (specified, id, provider, (GtkCssStyle *)style, parent_style); + + /* special case according to http://dev.w3.org/csswg/css-backgrounds/#the-border-width */ + if (id == border_prop[b]) + { + b++; + /* We have them ordered in gtkcssstylepropertyimpl.c accordingly, so the + * border styles are computed before the border widths. + * Note that we rely on ..._WIDTH == ..._STYLE + 1 here. + */ + GtkBorderStyle border_style = _gtk_css_border_style_value_get (style->values[id]); + if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) + { + id++; + style->values[id] = gtk_css_dimension_value_new (0, GTK_CSS_NUMBER); + } + } + } + else if (parent_values && gtk_css_style_property_is_inherit (id)) + { + style->values[id] = _gtk_css_value_ref (parent_values[id]); + + /* the border properties are not inherit, so no need to check the special case here */ + } + else if (parent_style && gtk_css_style_property_is_inherit (id)) + { + style->values[id] = _gtk_css_value_ref (gtk_css_style_get_value (parent_style, id)); + + /* the border properties are not inherit, so no need to check the special case here */ + } + else + { + style->values[id] = _gtk_css_initial_value_new_compute (id, provider, (GtkCssStyle *)style, parent_style); + + /* special case according to http://dev.w3.org/csswg/css-backgrounds/#the-border-width */ + if (id == border_prop[b]) + { + b++; + /* no need to check the value. The initial value of the border-style properties is none */ + id++; + style->values[id] = gtk_css_dimension_value_new (0, GTK_CSS_NUMBER); + } + } + } + + if (lookup->has_section) + { + style->sections = g_ptr_array_new_full (GTK_CSS_PROPERTY_N_PROPERTIES, maybe_unref_section); + for (id = 0; id < GTK_CSS_PROPERTY_N_PROPERTIES; id++) + { + GtkCssSection *section = values[id].section; + if (section) + g_ptr_array_index (style->sections, id) = gtk_css_section_ref (section); + } + } +} + GtkCssStyle * gtk_css_static_style_new_compute (GtkStyleProvider *provider, const GtkCssMatcher *matcher, @@ -196,84 +282,13 @@ gtk_css_static_style_new_compute (GtkStyleProvider *provider, result->change = change; - _gtk_css_lookup_resolve (&lookup, - provider, - result, - parent); + gtk_css_static_style_compute_values (result, provider, parent, &lookup); _gtk_css_lookup_destroy (&lookup); return GTK_CSS_STYLE (result); } -G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_TOP_STYLE == GTK_CSS_PROPERTY_BORDER_TOP_WIDTH - 1); -G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE == GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH - 1); -G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE == GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH - 1); -G_STATIC_ASSERT (GTK_CSS_PROPERTY_BORDER_LEFT_STYLE == GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH - 1); -G_STATIC_ASSERT (GTK_CSS_PROPERTY_OUTLINE_STYLE == GTK_CSS_PROPERTY_OUTLINE_WIDTH - 1); - -void -gtk_css_static_style_compute_value (GtkCssStaticStyle *style, - GtkStyleProvider *provider, - GtkCssStyle *parent_style, - guint id, - GtkCssValue *specified, - GtkCssSection *section) -{ - GtkCssValue *value; - GtkBorderStyle border_style; - - gtk_internal_return_if_fail (id < GTK_CSS_PROPERTY_N_PROPERTIES); - - /* special case according to http://dev.w3.org/csswg/css-backgrounds/#the-border-width */ - switch (id) - { - /* We have them ordered in gtkcssstylepropertyimpl.c accordingly, so the - * border styles are already computed when we compute the border widths. - * - * Note that we rely on ..._STYLE == ..._WIDTH - 1 here. - */ - case GTK_CSS_PROPERTY_BORDER_TOP_WIDTH: - case GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH: - case GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH: - case GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH: - case GTK_CSS_PROPERTY_OUTLINE_WIDTH: - border_style = _gtk_css_border_style_value_get (gtk_css_style_get_value ((GtkCssStyle *)style, id - 1)); - if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) - { - gtk_css_static_style_set_value (style, id, gtk_css_dimension_value_new (0, GTK_CSS_NUMBER), section); - return; - } - break; - - default: - /* Go ahead */ - break; - } - - - /* http://www.w3.org/TR/css3-cascade/#cascade - * Then, for every element, the value for each property can be found - * by following this pseudo-algorithm: - * 1) Identify all declarations that apply to the element - */ - if (specified) - { - value = _gtk_css_value_compute (specified, id, provider, (GtkCssStyle *)style, parent_style); - } - else if (parent_style && _gtk_css_style_property_is_inherit (_gtk_css_style_property_lookup_by_id (id))) - { - /* Just take the style from the parent */ - value = _gtk_css_value_ref (gtk_css_style_get_value (parent_style, id)); - } - else - { - value = _gtk_css_initial_value_new_compute (id, provider, (GtkCssStyle *)style, parent_style); - } - - gtk_css_static_style_set_value (style, id, value, section); -} - GtkCssChange gtk_css_static_style_get_change (GtkCssStaticStyle *style) { diff --git a/gtk/gtkcssstaticstyleprivate.h b/gtk/gtkcssstaticstyleprivate.h index 81c97bbdc0..b01c0dbaed 100644 --- a/gtk/gtkcssstaticstyleprivate.h +++ b/gtk/gtkcssstaticstyleprivate.h @@ -56,14 +56,6 @@ GtkCssStyle * gtk_css_static_style_new_compute (GtkStyleProvide const GtkCssMatcher *matcher, GtkCssStyle *parent, GtkCssChange change); - -void gtk_css_static_style_compute_value (GtkCssStaticStyle *style, - GtkStyleProvider *provider, - GtkCssStyle *parent_style, - guint id, - GtkCssValue *specified, - GtkCssSection *section); - GtkCssChange gtk_css_static_style_get_change (GtkCssStaticStyle *style); G_END_DECLS diff --git a/gtk/gtkcssstylepropertyimpl.c b/gtk/gtkcssstylepropertyimpl.c index ce076944d5..2b346d4a26 100644 --- a/gtk/gtkcssstylepropertyimpl.c +++ b/gtk/gtkcssstylepropertyimpl.c @@ -66,6 +66,8 @@ typedef enum { GTK_STYLE_PROPERTY_ANIMATED = (1 << 1), } GtkStylePropertyFlags; +gboolean inherit_properties[ GTK_CSS_PROPERTY_N_PROPERTIES]; + static void gtk_css_style_property_register (const char * name, guint expected_id, @@ -96,6 +98,8 @@ gtk_css_style_property_register (const char * name, _gtk_css_value_unref (initial_value); + inherit_properties[expected_id] = (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE; + g_assert (_gtk_css_style_property_get_id (node) == expected_id); } @@ -924,6 +928,7 @@ icon_theme_value_parse (GtkCssStyleProperty *property, G_STATIC_ASSERT (GTK_CSS_PROPERTY_COLOR == 0); G_STATIC_ASSERT (GTK_CSS_PROPERTY_DPI < GTK_CSS_PROPERTY_FONT_SIZE); + void _gtk_css_style_property_init_properties (void) { @@ -1720,4 +1725,5 @@ _gtk_css_style_property_init_properties (void) parse_font_variation_settings, NULL, gtk_css_font_variations_value_new_default ()); + } diff --git a/gtk/gtkcssstylepropertyprivate.h b/gtk/gtkcssstylepropertyprivate.h index 005ada4e70..f089c09995 100644 --- a/gtk/gtkcssstylepropertyprivate.h +++ b/gtk/gtkcssstylepropertyprivate.h @@ -80,6 +80,13 @@ void _gtk_css_style_property_print_value (GtkCssStyleProp GtkCssValue *value, GString *string); +extern gboolean inherit_properties[]; + +inline gboolean gtk_css_style_property_is_inherit (uint id) +{ + return inherit_properties[id]; +} + /* XXX - find a better place for these */ GtkCssValue * gtk_css_font_family_value_parse (GtkCssParser *parser); GtkCssValue * gtk_css_font_size_value_parse (GtkCssParser *parser); |