summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkcsslookup.c38
-rw-r--r--gtk/gtkcsslookupprivate.h5
-rw-r--r--gtk/gtkcssstaticstyle.c215
-rw-r--r--gtk/gtkcssstaticstyleprivate.h8
-rw-r--r--gtk/gtkcssstylepropertyimpl.c6
-rw-r--r--gtk/gtkcssstylepropertyprivate.h7
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);