gtk2/gtk/gtkcssstaticstyle.c
Matthias Clasen b378f566d7 Compute style change based on values structs
We can save some time here by comparing struct by
struct and avoiding individual values comparisons
as much as possible.
2020-01-29 11:07:32 +01:00

1119 lines
44 KiB
C

/*
* Copyright © 2012 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gtkcssstaticstyleprivate.h"
#include "gtkcssanimationprivate.h"
#include "gtkcssarrayvalueprivate.h"
#include "gtkcssenumvalueprivate.h"
#include "gtkcssinheritvalueprivate.h"
#include "gtkcssinitialvalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssshorthandpropertyprivate.h"
#include "gtkcssstringvalueprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkcsstransitionprivate.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "gtksettings.h"
#include "gtkstyleanimationprivate.h"
#include "gtkstylepropertyprivate.h"
#include "gtkstyleproviderprivate.h"
#include "gtkcssdimensionvalueprivate.h"
static void gtk_css_static_style_compute_value (GtkCssStaticStyle *style,
GtkStyleProvider *provider,
GtkCssStyle *parent_style,
guint id,
GtkCssValue *specified,
GtkCssSection *section);
static int core_props[] = {
GTK_CSS_PROPERTY_COLOR,
GTK_CSS_PROPERTY_DPI,
GTK_CSS_PROPERTY_FONT_SIZE,
GTK_CSS_PROPERTY_ICON_THEME,
GTK_CSS_PROPERTY_ICON_PALETTE
};
static int background_props[] = {
GTK_CSS_PROPERTY_BACKGROUND_COLOR,
GTK_CSS_PROPERTY_BOX_SHADOW,
GTK_CSS_PROPERTY_BACKGROUND_CLIP,
GTK_CSS_PROPERTY_BACKGROUND_ORIGIN,
GTK_CSS_PROPERTY_BACKGROUND_SIZE,
GTK_CSS_PROPERTY_BACKGROUND_POSITION,
GTK_CSS_PROPERTY_BACKGROUND_REPEAT,
GTK_CSS_PROPERTY_BACKGROUND_IMAGE,
GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE
};
static int border_props[] = {
GTK_CSS_PROPERTY_BORDER_TOP_STYLE,
GTK_CSS_PROPERTY_BORDER_TOP_WIDTH,
GTK_CSS_PROPERTY_BORDER_LEFT_STYLE,
GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH,
GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE,
GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE,
GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH,
GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS,
GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS,
GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS,
GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS,
GTK_CSS_PROPERTY_BORDER_TOP_COLOR,
GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR,
GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR,
GTK_CSS_PROPERTY_BORDER_LEFT_COLOR,
GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE,
GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT,
GTK_CSS_PROPERTY_BORDER_IMAGE_SLICE,
GTK_CSS_PROPERTY_BORDER_IMAGE_WIDTH
};
static int icon_props[] = {
GTK_CSS_PROPERTY_ICON_SIZE,
GTK_CSS_PROPERTY_ICON_SHADOW,
GTK_CSS_PROPERTY_ICON_STYLE,
};
static int outline_props[] = {
GTK_CSS_PROPERTY_OUTLINE_STYLE,
GTK_CSS_PROPERTY_OUTLINE_WIDTH,
GTK_CSS_PROPERTY_OUTLINE_OFFSET,
GTK_CSS_PROPERTY_OUTLINE_TOP_LEFT_RADIUS,
GTK_CSS_PROPERTY_OUTLINE_TOP_RIGHT_RADIUS,
GTK_CSS_PROPERTY_OUTLINE_BOTTOM_RIGHT_RADIUS,
GTK_CSS_PROPERTY_OUTLINE_BOTTOM_LEFT_RADIUS,
GTK_CSS_PROPERTY_OUTLINE_COLOR,
};
static int font_props[] = {
GTK_CSS_PROPERTY_FONT_FAMILY,
GTK_CSS_PROPERTY_FONT_STYLE,
GTK_CSS_PROPERTY_FONT_WEIGHT,
GTK_CSS_PROPERTY_FONT_STRETCH,
GTK_CSS_PROPERTY_LETTER_SPACING,
GTK_CSS_PROPERTY_TEXT_SHADOW,
GTK_CSS_PROPERTY_CARET_COLOR,
GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR,
GTK_CSS_PROPERTY_FONT_FEATURE_SETTINGS,
GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS,
};
static int font_variant_props[] = {
GTK_CSS_PROPERTY_TEXT_DECORATION_LINE,
GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR,
GTK_CSS_PROPERTY_TEXT_DECORATION_STYLE,
GTK_CSS_PROPERTY_FONT_KERNING,
GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES,
GTK_CSS_PROPERTY_FONT_VARIANT_POSITION,
GTK_CSS_PROPERTY_FONT_VARIANT_CAPS,
GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC,
GTK_CSS_PROPERTY_FONT_VARIANT_ALTERNATES,
GTK_CSS_PROPERTY_FONT_VARIANT_EAST_ASIAN,
};
static int animation_props[] = {
GTK_CSS_PROPERTY_ANIMATION_NAME,
GTK_CSS_PROPERTY_ANIMATION_DURATION,
GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION,
GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT,
GTK_CSS_PROPERTY_ANIMATION_DIRECTION,
GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE,
GTK_CSS_PROPERTY_ANIMATION_DELAY,
GTK_CSS_PROPERTY_ANIMATION_FILL_MODE,
};
static int transition_props[] = {
GTK_CSS_PROPERTY_TRANSITION_PROPERTY,
GTK_CSS_PROPERTY_TRANSITION_DURATION,
GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION,
GTK_CSS_PROPERTY_TRANSITION_DELAY,
};
static int size_props[] = {
GTK_CSS_PROPERTY_MARGIN_TOP,
GTK_CSS_PROPERTY_MARGIN_LEFT,
GTK_CSS_PROPERTY_MARGIN_BOTTOM,
GTK_CSS_PROPERTY_MARGIN_RIGHT,
GTK_CSS_PROPERTY_PADDING_TOP,
GTK_CSS_PROPERTY_PADDING_LEFT,
GTK_CSS_PROPERTY_PADDING_BOTTOM,
GTK_CSS_PROPERTY_PADDING_RIGHT,
GTK_CSS_PROPERTY_BORDER_SPACING,
GTK_CSS_PROPERTY_MIN_WIDTH,
GTK_CSS_PROPERTY_MIN_HEIGHT,
};
static int other_props[] = {
GTK_CSS_PROPERTY_ICON_SOURCE,
GTK_CSS_PROPERTY_ICON_TRANSFORM,
GTK_CSS_PROPERTY_ICON_FILTER,
GTK_CSS_PROPERTY_TRANSFORM,
GTK_CSS_PROPERTY_OPACITY,
GTK_CSS_PROPERTY_FILTER,
};
#define DEFINE_VALUES(ENUM, TYPE, NAME) \
void \
gtk_css_## NAME ## _values_compute_changes_and_affects (GtkCssStyle *style1, \
GtkCssStyle *style2, \
GtkBitmask **changes, \
GtkCssAffects *affects) \
{ \
GtkCssValues *g1 = (GtkCssValues *)style1->NAME; \
GtkCssValues *g2 = (GtkCssValues *)style2->NAME; \
int i; \
for (i = 0; i < G_N_ELEMENTS (NAME ## _props); i++) \
{ \
GtkCssValue *v1 = g1->values[i] ? g1->values[i] : style1->core->color; \
GtkCssValue *v2 = g2->values[i] ? g2->values[i] : style2->core->color; \
if (!_gtk_css_value_equal (v1, v2)) \
{ \
guint id = NAME ## _props[i]; \
*changes = _gtk_bitmask_set (*changes, id, TRUE); \
*affects |= _gtk_css_style_property_get_affects (_gtk_css_style_property_lookup_by_id (id)); \
} \
} \
} \
\
static inline void \
gtk_css_ ## NAME ## _values_new_compute (GtkCssStaticStyle *sstyle, \
GtkStyleProvider *provider, \
GtkCssStyle *parent_style, \
GtkCssLookup *lookup) \
{ \
GtkCssStyle *style = (GtkCssStyle *)sstyle; \
int i; \
\
style->NAME = (GtkCss ## TYPE ## Values *)gtk_css_values_new (GTK_CSS_ ## ENUM ## _VALUES); \
\
for (i = 0; i < G_N_ELEMENTS (NAME ## _props); i++) \
{ \
guint id = NAME ## _props[i]; \
gtk_css_static_style_compute_value (sstyle, \
provider, \
parent_style, \
id, \
lookup->values[id].value, \
lookup->values[id].section); \
} \
} \
static GtkBitmask * gtk_css_ ## NAME ## _values_mask; \
static GtkCssValues * gtk_css_ ## NAME ## _initial_values; \
\
static GtkCssValues * gtk_css_ ## NAME ## _create_initial_values (void); \
\
static void \
gtk_css_ ## NAME ## _values_init (void) \
{ \
int i; \
gtk_css_ ## NAME ## _values_mask = _gtk_bitmask_new (); \
for (i = 0; i < G_N_ELEMENTS(NAME ## _props); i++) \
{ \
guint id = NAME ## _props[i]; \
gtk_css_ ## NAME ## _values_mask = _gtk_bitmask_set (gtk_css_ ## NAME ## _values_mask, id, TRUE); \
} \
\
gtk_css_ ## NAME ## _initial_values = gtk_css_ ## NAME ## _create_initial_values (); \
} \
\
static inline gboolean \
gtk_css_ ## NAME ## _values_unset (const GtkCssLookup *lookup) \
{ \
const GtkBitmask *set_values = _gtk_css_lookup_get_set_values (lookup); \
return !_gtk_bitmask_intersects (set_values, gtk_css_ ## NAME ## _values_mask); \
}
DEFINE_VALUES (CORE, Core, core)
DEFINE_VALUES (BACKGROUND, Background, background)
DEFINE_VALUES (BORDER, Border, border)
DEFINE_VALUES (ICON, Icon, icon)
DEFINE_VALUES (OUTLINE, Outline, outline)
DEFINE_VALUES (FONT, Font, font)
DEFINE_VALUES (FONT_VARIANT, FontVariant, font_variant)
DEFINE_VALUES (ANIMATION, Animation, animation)
DEFINE_VALUES (TRANSITION, Transition, transition)
DEFINE_VALUES (SIZE, Size, size)
DEFINE_VALUES (OTHER, Other, other)
#define VERIFY_MASK(NAME) \
{ \
GtkBitmask *copy; \
copy = _gtk_bitmask_intersect (_gtk_bitmask_copy (gtk_css_ ## NAME ## _values_mask), all); \
g_assert (_gtk_bitmask_equals (copy, gtk_css_ ## NAME ## _values_mask)); \
_gtk_bitmask_free (copy); \
} \
all = _gtk_bitmask_subtract (all, gtk_css_ ## NAME ## _values_mask);
/* Verify that every style property is present in one group, and none
* is present in more than one group.
*/
static void
verify_style_groups (void)
{
GtkBitmask *all;
guint id;
all = _gtk_bitmask_new ();
for (id = 0; id < GTK_CSS_PROPERTY_N_PROPERTIES; id++)
all = _gtk_bitmask_set (all, id, TRUE);
VERIFY_MASK (core);
VERIFY_MASK (background);
VERIFY_MASK (border);
VERIFY_MASK (icon);
VERIFY_MASK (outline);
VERIFY_MASK (font);
VERIFY_MASK (font_variant);
VERIFY_MASK (animation);
VERIFY_MASK (transition);
VERIFY_MASK (size);
VERIFY_MASK (other);
g_assert (_gtk_bitmask_is_empty (all));
_gtk_bitmask_free (all);
}
#undef VERIFY_MASK
G_DEFINE_TYPE (GtkCssStaticStyle, gtk_css_static_style, GTK_TYPE_CSS_STYLE)
static GtkCssSection *
gtk_css_static_style_get_section (GtkCssStyle *style,
guint id)
{
GtkCssStaticStyle *sstyle = GTK_CSS_STATIC_STYLE (style);
if (sstyle->sections == NULL ||
id >= sstyle->sections->len)
return NULL;
return g_ptr_array_index (sstyle->sections, id);
}
static void
gtk_css_static_style_dispose (GObject *object)
{
GtkCssStaticStyle *style = GTK_CSS_STATIC_STYLE (object);
if (style->sections)
{
g_ptr_array_unref (style->sections);
style->sections = NULL;
}
G_OBJECT_CLASS (gtk_css_static_style_parent_class)->dispose (object);
}
static GtkCssStaticStyle *
gtk_css_static_style_get_static_style (GtkCssStyle *style)
{
return (GtkCssStaticStyle *)style;
}
static void
gtk_css_static_style_class_init (GtkCssStaticStyleClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkCssStyleClass *style_class = GTK_CSS_STYLE_CLASS (klass);
object_class->dispose = gtk_css_static_style_dispose;
style_class->get_section = gtk_css_static_style_get_section;
style_class->get_static_style = gtk_css_static_style_get_static_style;
gtk_css_core_values_init ();
gtk_css_background_values_init ();
gtk_css_border_values_init ();
gtk_css_icon_values_init ();
gtk_css_outline_values_init ();
gtk_css_font_values_init ();
gtk_css_font_variant_values_init ();
gtk_css_animation_values_init ();
gtk_css_transition_values_init ();
gtk_css_size_values_init ();
gtk_css_other_values_init ();
verify_style_groups ();
}
static void
gtk_css_static_style_init (GtkCssStaticStyle *style)
{
}
static void
maybe_unref_section (gpointer section)
{
if (section)
gtk_css_section_unref (section);
}
static inline void
gtk_css_take_value (GtkCssValue **variable,
GtkCssValue *value)
{
if (*variable)
gtk_css_value_unref (*variable);
*variable = value;
}
static void
gtk_css_static_style_set_value (GtkCssStaticStyle *sstyle,
guint id,
GtkCssValue *value,
GtkCssSection *section)
{
GtkCssStyle *style = (GtkCssStyle *)sstyle;
switch (id)
{
case GTK_CSS_PROPERTY_COLOR:
gtk_css_take_value (&style->core->color, value);
break;
case GTK_CSS_PROPERTY_DPI:
gtk_css_take_value (&style->core->dpi, value);
break;
case GTK_CSS_PROPERTY_FONT_SIZE:
gtk_css_take_value (&style->core->font_size, value);
break;
case GTK_CSS_PROPERTY_ICON_THEME:
gtk_css_take_value (&style->core->icon_theme, value);
break;
case GTK_CSS_PROPERTY_ICON_PALETTE:
gtk_css_take_value (&style->core->icon_palette, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_COLOR:
gtk_css_take_value (&style->background->background_color, value);
break;
case GTK_CSS_PROPERTY_FONT_FAMILY:
gtk_css_take_value (&style->font->font_family, value);
break;
case GTK_CSS_PROPERTY_FONT_STYLE:
gtk_css_take_value (&style->font->font_style, value);
break;
case GTK_CSS_PROPERTY_FONT_WEIGHT:
gtk_css_take_value (&style->font->font_weight, value);
break;
case GTK_CSS_PROPERTY_FONT_STRETCH:
gtk_css_take_value (&style->font->font_stretch, value);
break;
case GTK_CSS_PROPERTY_LETTER_SPACING:
gtk_css_take_value (&style->font->letter_spacing, value);
break;
case GTK_CSS_PROPERTY_TEXT_DECORATION_LINE:
gtk_css_take_value (&style->font_variant->text_decoration_line, value);
break;
case GTK_CSS_PROPERTY_TEXT_DECORATION_COLOR:
gtk_css_take_value (&style->font_variant->text_decoration_color, value);
break;
case GTK_CSS_PROPERTY_TEXT_DECORATION_STYLE:
gtk_css_take_value (&style->font_variant->text_decoration_style, value);
break;
case GTK_CSS_PROPERTY_FONT_KERNING:
gtk_css_take_value (&style->font_variant->font_kerning, value);
break;
case GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES:
gtk_css_take_value (&style->font_variant->font_variant_ligatures, value);
break;
case GTK_CSS_PROPERTY_FONT_VARIANT_POSITION:
gtk_css_take_value (&style->font_variant->font_variant_position, value);
break;
case GTK_CSS_PROPERTY_FONT_VARIANT_CAPS:
gtk_css_take_value (&style->font_variant->font_variant_caps, value);
break;
case GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC:
gtk_css_take_value (&style->font_variant->font_variant_numeric, value);
break;
case GTK_CSS_PROPERTY_FONT_VARIANT_ALTERNATES:
gtk_css_take_value (&style->font_variant->font_variant_alternates, value);
break;
case GTK_CSS_PROPERTY_FONT_VARIANT_EAST_ASIAN:
gtk_css_take_value (&style->font_variant->font_variant_east_asian, value);
break;
case GTK_CSS_PROPERTY_TEXT_SHADOW:
gtk_css_take_value (&style->font->text_shadow, value);
break;
case GTK_CSS_PROPERTY_BOX_SHADOW:
gtk_css_take_value (&style->background->box_shadow, value);
break;
case GTK_CSS_PROPERTY_MARGIN_TOP:
gtk_css_take_value (&style->size->margin_top, value);
break;
case GTK_CSS_PROPERTY_MARGIN_LEFT:
gtk_css_take_value (&style->size->margin_left, value);
break;
case GTK_CSS_PROPERTY_MARGIN_BOTTOM:
gtk_css_take_value (&style->size->margin_bottom, value);
break;
case GTK_CSS_PROPERTY_MARGIN_RIGHT:
gtk_css_take_value (&style->size->margin_right, value);
break;
case GTK_CSS_PROPERTY_PADDING_TOP:
gtk_css_take_value (&style->size->padding_top, value);
break;
case GTK_CSS_PROPERTY_PADDING_LEFT:
gtk_css_take_value (&style->size->padding_left, value);
break;
case GTK_CSS_PROPERTY_PADDING_BOTTOM:
gtk_css_take_value (&style->size->padding_bottom, value);
break;
case GTK_CSS_PROPERTY_PADDING_RIGHT:
gtk_css_take_value (&style->size->padding_right, value);
break;
case GTK_CSS_PROPERTY_BORDER_TOP_STYLE:
gtk_css_take_value (&style->border->border_top_style, value);
break;
case GTK_CSS_PROPERTY_BORDER_TOP_WIDTH:
gtk_css_take_value (&style->border->border_top_width, value);
break;
case GTK_CSS_PROPERTY_BORDER_LEFT_STYLE:
gtk_css_take_value (&style->border->border_left_style, value);
break;
case GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH:
gtk_css_take_value (&style->border->border_left_width, value);
break;
case GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE:
gtk_css_take_value (&style->border->border_bottom_style, value);
break;
case GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH:
gtk_css_take_value (&style->border->border_bottom_width, value);
break;
case GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE:
gtk_css_take_value (&style->border->border_right_style, value);
break;
case GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH:
gtk_css_take_value (&style->border->border_right_width, value);
break;
case GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS:
gtk_css_take_value (&style->border->border_top_left_radius, value);
break;
case GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS:
gtk_css_take_value (&style->border->border_top_right_radius, value);
break;
case GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS:
gtk_css_take_value (&style->border->border_bottom_right_radius, value);
break;
case GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS:
gtk_css_take_value (&style->border->border_bottom_left_radius, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_STYLE:
gtk_css_take_value (&style->outline->outline_style, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_WIDTH:
gtk_css_take_value (&style->outline->outline_width, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_OFFSET:
gtk_css_take_value (&style->outline->outline_offset, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_TOP_LEFT_RADIUS:
gtk_css_take_value (&style->outline->outline_top_left_radius, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_TOP_RIGHT_RADIUS:
gtk_css_take_value (&style->outline->outline_top_right_radius, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_BOTTOM_RIGHT_RADIUS:
gtk_css_take_value (&style->outline->outline_bottom_right_radius, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_BOTTOM_LEFT_RADIUS:
gtk_css_take_value (&style->outline->outline_bottom_left_radius, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_CLIP:
gtk_css_take_value (&style->background->background_clip, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_ORIGIN:
gtk_css_take_value (&style->background->background_origin, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_SIZE:
gtk_css_take_value (&style->background->background_size, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_POSITION:
gtk_css_take_value (&style->background->background_position, value);
break;
case GTK_CSS_PROPERTY_BORDER_TOP_COLOR:
gtk_css_take_value (&style->border->border_top_color, value);
break;
case GTK_CSS_PROPERTY_BORDER_RIGHT_COLOR:
gtk_css_take_value (&style->border->border_right_color, value);
break;
case GTK_CSS_PROPERTY_BORDER_BOTTOM_COLOR:
gtk_css_take_value (&style->border->border_bottom_color, value);
break;
case GTK_CSS_PROPERTY_BORDER_LEFT_COLOR:
gtk_css_take_value (&style->border->border_left_color, value);
break;
case GTK_CSS_PROPERTY_OUTLINE_COLOR:
gtk_css_take_value (&style->outline->outline_color, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_REPEAT:
gtk_css_take_value (&style->background->background_repeat, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_IMAGE:
gtk_css_take_value (&style->background->background_image, value);
break;
case GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE:
gtk_css_take_value (&style->background->background_blend_mode, value);
break;
case GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE:
gtk_css_take_value (&style->border->border_image_source, value);
break;
case GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT:
gtk_css_take_value (&style->border->border_image_repeat, value);
break;
case GTK_CSS_PROPERTY_BORDER_IMAGE_SLICE:
gtk_css_take_value (&style->border->border_image_slice, value);
break;
case GTK_CSS_PROPERTY_BORDER_IMAGE_WIDTH:
gtk_css_take_value (&style->border->border_image_width, value);
break;
case GTK_CSS_PROPERTY_ICON_SOURCE:
gtk_css_take_value (&style->other->icon_source, value);
break;
case GTK_CSS_PROPERTY_ICON_SIZE:
gtk_css_take_value (&style->icon->icon_size, value);
break;
case GTK_CSS_PROPERTY_ICON_SHADOW:
gtk_css_take_value (&style->icon->icon_shadow, value);
break;
case GTK_CSS_PROPERTY_ICON_STYLE:
gtk_css_take_value (&style->icon->icon_style, value);
break;
case GTK_CSS_PROPERTY_ICON_TRANSFORM:
gtk_css_take_value (&style->other->icon_transform, value);
break;
case GTK_CSS_PROPERTY_ICON_FILTER:
gtk_css_take_value (&style->other->icon_filter, value);
break;
case GTK_CSS_PROPERTY_BORDER_SPACING:
gtk_css_take_value (&style->size->border_spacing, value);
break;
case GTK_CSS_PROPERTY_TRANSFORM:
gtk_css_take_value (&style->other->transform, value);
break;
case GTK_CSS_PROPERTY_MIN_WIDTH:
gtk_css_take_value (&style->size->min_width, value);
break;
case GTK_CSS_PROPERTY_MIN_HEIGHT:
gtk_css_take_value (&style->size->min_height, value);
break;
case GTK_CSS_PROPERTY_TRANSITION_PROPERTY:
gtk_css_take_value (&style->transition->transition_property, value);
break;
case GTK_CSS_PROPERTY_TRANSITION_DURATION:
gtk_css_take_value (&style->transition->transition_duration, value);
break;
case GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION:
gtk_css_take_value (&style->transition->transition_timing_function, value);
break;
case GTK_CSS_PROPERTY_TRANSITION_DELAY:
gtk_css_take_value (&style->transition->transition_delay, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_NAME:
gtk_css_take_value (&style->animation->animation_name, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_DURATION:
gtk_css_take_value (&style->animation->animation_duration, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION:
gtk_css_take_value (&style->animation->animation_timing_function, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT:
gtk_css_take_value (&style->animation->animation_iteration_count, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_DIRECTION:
gtk_css_take_value (&style->animation->animation_direction, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE:
gtk_css_take_value (&style->animation->animation_play_state, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_DELAY:
gtk_css_take_value (&style->animation->animation_delay, value);
break;
case GTK_CSS_PROPERTY_ANIMATION_FILL_MODE:
gtk_css_take_value (&style->animation->animation_fill_mode, value);
break;
case GTK_CSS_PROPERTY_OPACITY:
gtk_css_take_value (&style->other->opacity, value);
break;
case GTK_CSS_PROPERTY_FILTER:
gtk_css_take_value (&style->other->filter, value);
break;
case GTK_CSS_PROPERTY_CARET_COLOR:
gtk_css_take_value (&style->font->caret_color, value);
break;
case GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR:
gtk_css_take_value (&style->font->secondary_caret_color, value);
break;
case GTK_CSS_PROPERTY_FONT_FEATURE_SETTINGS:
gtk_css_take_value (&style->font->font_feature_settings, value);
break;
case GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS:
gtk_css_take_value (&style->font->font_variation_settings, value);
break;
default:
g_assert_not_reached ();
break;
}
if (sstyle->sections && sstyle->sections->len > id && g_ptr_array_index (sstyle->sections, id))
{
gtk_css_section_unref (g_ptr_array_index (sstyle->sections, id));
g_ptr_array_index (sstyle->sections, id) = NULL;
}
if (section)
{
if (sstyle->sections == NULL)
sstyle->sections = g_ptr_array_new_with_free_func (maybe_unref_section);
if (sstyle->sections->len <= id)
g_ptr_array_set_size (sstyle->sections, id + 1);
g_ptr_array_index (sstyle->sections, id) = gtk_css_section_ref (section);
}
}
static GtkCssStyle *default_style;
static void
clear_default_style (gpointer data)
{
g_set_object (&default_style, NULL);
}
GtkCssStyle *
gtk_css_static_style_get_default (void)
{
/* FIXME: This really depends on the screen, but we don't have
* a screen at hand when we call this function, and in practice,
* the default style is always replaced by something else
* before we use it.
*/
if (default_style == NULL)
{
GtkCountingBloomFilter filter = GTK_COUNTING_BLOOM_FILTER_INIT;
GtkSettings *settings;
settings = gtk_settings_get_default ();
default_style = gtk_css_static_style_new_compute (GTK_STYLE_PROVIDER (settings),
&filter,
NULL,
0);
g_object_set_data_full (G_OBJECT (settings), I_("gtk-default-style"),
default_style, clear_default_style);
}
return default_style;
}
static GtkCssValues *
gtk_css_core_create_initial_values (void)
{
return NULL;
}
static GtkCssValues *
gtk_css_background_create_initial_values (void)
{
GtkCssBackgroundValues *values;
values = (GtkCssBackgroundValues *)gtk_css_values_new (GTK_CSS_BACKGROUND_VALUES);
values->background_color = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_COLOR, NULL, NULL, NULL);
values->box_shadow = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BOX_SHADOW, NULL, NULL, NULL);
values->background_clip = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_CLIP, NULL, NULL, NULL);
values->background_origin = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_ORIGIN, NULL, NULL, NULL);
values->background_size = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_SIZE, NULL, NULL, NULL);
values->background_position = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_POSITION, NULL, NULL, NULL);
values->background_repeat = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_REPEAT, NULL, NULL, NULL);
values->background_image = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_IMAGE, NULL, NULL, NULL);
values->background_blend_mode = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE, NULL, NULL, NULL);
return (GtkCssValues *)values;
}
static GtkCssValues *
gtk_css_border_create_initial_values (void)
{
GtkCssBorderValues *values;
values = (GtkCssBorderValues *)gtk_css_values_new (GTK_CSS_BORDER_VALUES);
values->border_top_style = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_TOP_STYLE, NULL, NULL, NULL);
values->border_top_width = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_TOP_WIDTH, NULL, NULL, NULL);
values->border_left_style = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_LEFT_STYLE, NULL, NULL, NULL);
values->border_left_width = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH, NULL, NULL, NULL);
values->border_bottom_style = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE, NULL, NULL, NULL);
values->border_bottom_width = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH, NULL, NULL, NULL);
values->border_right_style = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE, NULL, NULL, NULL);
values->border_right_width = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH, NULL, NULL, NULL);
values->border_top_left_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_TOP_LEFT_RADIUS, NULL, NULL, NULL);
values->border_top_right_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_TOP_RIGHT_RADIUS, NULL, NULL, NULL);
values->border_bottom_left_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS, NULL, NULL, NULL);
values->border_bottom_right_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS, NULL, NULL, NULL);
values->border_top_color = NULL;
values->border_right_color = NULL;
values->border_bottom_color = NULL;
values->border_left_color = NULL;
values->border_image_source = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_IMAGE_SOURCE, NULL, NULL, NULL);
values->border_image_repeat = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT, NULL, NULL, NULL);
values->border_image_slice = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_IMAGE_SLICE, NULL, NULL, NULL);
values->border_image_width = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_IMAGE_WIDTH, NULL, NULL, NULL);
return (GtkCssValues *)values;
}
static GtkCssValues *
gtk_css_outline_create_initial_values (void)
{
GtkCssOutlineValues *values;
values = (GtkCssOutlineValues *)gtk_css_values_new (GTK_CSS_OUTLINE_VALUES);
values->outline_style = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OUTLINE_STYLE, NULL, NULL, NULL);
values->outline_width = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OUTLINE_WIDTH, NULL, NULL, NULL);
values->outline_offset = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OUTLINE_OFFSET, NULL, NULL, NULL);
values->outline_top_left_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OUTLINE_TOP_LEFT_RADIUS, NULL, NULL, NULL);
values->outline_top_right_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OUTLINE_TOP_RIGHT_RADIUS, NULL, NULL, NULL);
values->outline_bottom_right_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OUTLINE_BOTTOM_RIGHT_RADIUS, NULL, NULL, NULL);
values->outline_bottom_left_radius = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OUTLINE_BOTTOM_LEFT_RADIUS, NULL, NULL, NULL);
values->outline_color = NULL;
return (GtkCssValues *)values;
}
static GtkCssValues *
gtk_css_icon_create_initial_values (void)
{
return NULL;
}
static GtkCssValues *
gtk_css_font_create_initial_values (void)
{
return NULL;
}
static GtkCssValues *
gtk_css_font_variant_create_initial_values (void)
{
GtkCssFontVariantValues *values;
values = (GtkCssFontVariantValues *)gtk_css_values_new (GTK_CSS_FONT_VARIANT_VALUES);
values->text_decoration_line = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_TEXT_DECORATION_LINE, NULL, NULL, NULL);
values->text_decoration_color = NULL;
values->text_decoration_style = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_TEXT_DECORATION_STYLE, NULL, NULL, NULL);
values->font_kerning = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FONT_KERNING, NULL, NULL, NULL);
values->font_variant_ligatures = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FONT_VARIANT_LIGATURES, NULL, NULL, NULL);
values->font_variant_position = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FONT_VARIANT_POSITION, NULL, NULL, NULL);
values->font_variant_caps = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FONT_VARIANT_CAPS, NULL, NULL, NULL);
values->font_variant_numeric = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FONT_VARIANT_NUMERIC, NULL, NULL, NULL);
values->font_variant_alternates = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FONT_VARIANT_ALTERNATES, NULL, NULL, NULL);
values->font_variant_east_asian = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FONT_VARIANT_EAST_ASIAN, NULL, NULL, NULL);
return (GtkCssValues *)values;
}
static GtkCssValues *
gtk_css_animation_create_initial_values (void)
{
GtkCssAnimationValues *values;
values = (GtkCssAnimationValues *)gtk_css_values_new (GTK_CSS_ANIMATION_VALUES);
values->animation_name = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_NAME, NULL, NULL, NULL);
values->animation_duration = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_DURATION, NULL, NULL, NULL);
values->animation_timing_function = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_TIMING_FUNCTION, NULL, NULL, NULL);
values->animation_iteration_count = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_ITERATION_COUNT, NULL, NULL, NULL);
values->animation_direction = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_DIRECTION, NULL, NULL, NULL);
values->animation_play_state = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_PLAY_STATE, NULL, NULL, NULL);
values->animation_delay = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_DELAY, NULL, NULL, NULL);
values->animation_fill_mode = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ANIMATION_FILL_MODE, NULL, NULL, NULL);
return (GtkCssValues *)values;
}
static GtkCssValues *
gtk_css_transition_create_initial_values (void)
{
GtkCssTransitionValues *values;
values = (GtkCssTransitionValues *)gtk_css_values_new (GTK_CSS_TRANSITION_VALUES);
values->transition_property = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_TRANSITION_PROPERTY, NULL, NULL, NULL);
values->transition_duration = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_TRANSITION_DURATION, NULL, NULL, NULL);
values->transition_timing_function = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_TRANSITION_TIMING_FUNCTION, NULL, NULL, NULL);
values->transition_delay = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_TRANSITION_DELAY, NULL, NULL, NULL);
return (GtkCssValues *)values;
}
static GtkCssValues *
gtk_css_size_create_initial_values (void)
{
GtkCssSizeValues *values;
values = (GtkCssSizeValues *)gtk_css_values_new (GTK_CSS_SIZE_VALUES);
values->margin_top = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_MARGIN_TOP, NULL, NULL, NULL);
values->margin_left = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_MARGIN_LEFT, NULL, NULL, NULL);
values->margin_bottom = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_MARGIN_BOTTOM, NULL, NULL, NULL);
values->margin_right = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_MARGIN_RIGHT, NULL, NULL, NULL);
values->padding_top = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_PADDING_TOP, NULL, NULL, NULL);
values->padding_left = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_PADDING_LEFT, NULL, NULL, NULL);
values->padding_bottom = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_PADDING_BOTTOM, NULL, NULL, NULL);
values->padding_right = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_PADDING_RIGHT, NULL, NULL, NULL);
values->border_spacing = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_BORDER_SPACING, NULL, NULL, NULL);
values->min_width = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_MIN_WIDTH, NULL, NULL, NULL);
values->min_height = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_MIN_HEIGHT, NULL, NULL, NULL);
return (GtkCssValues *)values;
}
static GtkCssValues *
gtk_css_other_create_initial_values (void)
{
GtkCssOtherValues *values;
values = (GtkCssOtherValues *)gtk_css_values_new (GTK_CSS_OTHER_VALUES);
values->icon_source = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ICON_SOURCE, NULL, NULL, NULL);
values->icon_transform = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ICON_TRANSFORM, NULL, NULL, NULL);
values->icon_filter = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_ICON_FILTER, NULL, NULL, NULL);
values->transform = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_TRANSFORM, NULL, NULL, NULL);
values->opacity = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_OPACITY, NULL, NULL, NULL);
values->filter = _gtk_css_initial_value_new_compute (GTK_CSS_PROPERTY_FILTER, NULL, NULL, NULL);
return (GtkCssValues *)values;
}
static void
gtk_css_lookup_resolve (GtkCssLookup *lookup,
GtkStyleProvider *provider,
GtkCssStaticStyle *sstyle,
GtkCssStyle *parent_style)
{
GtkCssStyle *style = (GtkCssStyle *)sstyle;
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));
if (_gtk_bitmask_is_empty (_gtk_css_lookup_get_set_values (lookup)))
{
style->background = (GtkCssBackgroundValues *)gtk_css_values_ref (gtk_css_background_initial_values);
style->border = (GtkCssBorderValues *)gtk_css_values_ref (gtk_css_border_initial_values);
style->outline = (GtkCssOutlineValues *)gtk_css_values_ref (gtk_css_outline_initial_values);
style->font_variant = (GtkCssFontVariantValues *)gtk_css_values_ref (gtk_css_font_variant_initial_values);
style->animation = (GtkCssAnimationValues *)gtk_css_values_ref (gtk_css_animation_initial_values);
style->transition = (GtkCssTransitionValues *)gtk_css_values_ref (gtk_css_transition_initial_values);
style->size = (GtkCssSizeValues *)gtk_css_values_ref (gtk_css_size_initial_values);
style->other = (GtkCssOtherValues *)gtk_css_values_ref (gtk_css_other_initial_values);
if (parent_style)
{
style->core = (GtkCssCoreValues *)gtk_css_values_ref ((GtkCssValues *)parent_style->core);
style->icon = (GtkCssIconValues *)gtk_css_values_ref ((GtkCssValues *)parent_style->icon);
style->font = (GtkCssFontValues *)gtk_css_values_ref ((GtkCssValues *)parent_style->font);
}
else
{
gtk_css_core_values_new_compute (sstyle, provider, parent_style, lookup);
gtk_css_icon_values_new_compute (sstyle, provider, parent_style, lookup);
gtk_css_font_values_new_compute (sstyle, provider, parent_style, lookup);
}
return;
}
if (parent_style && gtk_css_core_values_unset (lookup))
style->core = (GtkCssCoreValues *)gtk_css_values_ref ((GtkCssValues *)parent_style->core);
else
gtk_css_core_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_background_values_unset (lookup))
style->background = (GtkCssBackgroundValues *)gtk_css_values_ref (gtk_css_background_initial_values);
else
gtk_css_background_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_border_values_unset (lookup))
style->border = (GtkCssBorderValues *)gtk_css_values_ref (gtk_css_border_initial_values);
else
gtk_css_border_values_new_compute (sstyle, provider, parent_style, lookup);
if (parent_style && gtk_css_icon_values_unset (lookup))
style->icon = (GtkCssIconValues *)gtk_css_values_ref ((GtkCssValues *)parent_style->icon);
else
gtk_css_icon_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_outline_values_unset (lookup))
style->outline = (GtkCssOutlineValues *)gtk_css_values_ref (gtk_css_outline_initial_values);
else
gtk_css_outline_values_new_compute (sstyle, provider, parent_style, lookup);
if (parent_style && gtk_css_font_values_unset (lookup))
style->font = (GtkCssFontValues *)gtk_css_values_ref ((GtkCssValues *)parent_style->font);
else
gtk_css_font_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_font_variant_values_unset (lookup))
style->font_variant = (GtkCssFontVariantValues *)gtk_css_values_ref (gtk_css_font_variant_initial_values);
else
gtk_css_font_variant_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_animation_values_unset (lookup))
style->animation = (GtkCssAnimationValues *)gtk_css_values_ref (gtk_css_animation_initial_values);
else
gtk_css_animation_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_transition_values_unset (lookup))
style->transition = (GtkCssTransitionValues *)gtk_css_values_ref (gtk_css_transition_initial_values);
else
gtk_css_transition_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_size_values_unset (lookup))
style->size = (GtkCssSizeValues *)gtk_css_values_ref (gtk_css_size_initial_values);
else
gtk_css_size_values_new_compute (sstyle, provider, parent_style, lookup);
if (gtk_css_other_values_unset (lookup))
style->other = (GtkCssOtherValues *)gtk_css_values_ref (gtk_css_other_initial_values);
else
gtk_css_other_values_new_compute (sstyle, provider, parent_style, lookup);
}
GtkCssStyle *
gtk_css_static_style_new_compute (GtkStyleProvider *provider,
const GtkCountingBloomFilter *filter,
GtkCssNode *node,
GtkCssChange change)
{
GtkCssStaticStyle *result;
GtkCssLookup lookup;
GtkCssNode *parent;
_gtk_css_lookup_init (&lookup);
if (node)
gtk_style_provider_lookup (provider,
filter,
node,
&lookup,
change == 0 ? &change : NULL);
result = g_object_new (GTK_TYPE_CSS_STATIC_STYLE, NULL);
result->change = change;
if (node)
parent = gtk_css_node_get_parent (node);
else
parent = NULL;
gtk_css_lookup_resolve (&lookup,
provider,
result,
parent ? gtk_css_node_get_style (parent) : NULL);
_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);
static 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)
{
g_return_val_if_fail (GTK_IS_CSS_STATIC_STYLE (style), GTK_CSS_CHANGE_ANY);
return style->change;
}