gtk2/gtk/gtkcssstylepropertyimpl.c
2012-02-27 17:06:11 +00:00

1187 lines
47 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* GTK - The GIMP Toolkit
* Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
*
* 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 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/>.
*/
#include "config.h"
#include "gtkstylepropertyprivate.h"
#include <gobject/gvaluecollector.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <cairo-gobject.h>
#include <math.h>
#include "gtkcssparserprivate.h"
#include "gtkcssstylefuncsprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkcsstypesprivate.h"
#include "gtkintl.h"
#include "gtkprivatetypebuiltins.h"
#include "gtkstylepropertiesprivate.h"
/* this is in case round() is not provided by the compiler,
* such as in the case of C89 compilers, like MSVC
*/
#include "fallback-c89.c"
/* the actual parsers we have */
#include "gtkanimationdescription.h"
#include "gtkbindings.h"
#include "gtkcssimageprivate.h"
#include "gtkgradient.h"
#include "gtkshadowprivate.h"
#include "gtksymboliccolorprivate.h"
#include "gtkthemingengine.h"
#include "gtktypebuiltins.h"
#include "gtkwin32themeprivate.h"
/*** REGISTRATION ***/
static void
gtk_css_style_property_register (const char * name,
GType specified_type,
GType computed_type,
GType value_type,
GtkStylePropertyFlags flags,
GtkCssStylePropertyParseFunc parse_value,
GtkCssStylePropertyPrintFunc print_value,
GtkCssStylePropertyComputeFunc compute_value,
...)
{
GtkCssStyleProperty *node;
GValue initial_value = G_VALUE_INIT;
char *error = NULL;
va_list args;
va_start (args, compute_value);
G_VALUE_COLLECT_INIT (&initial_value, specified_type,
args, 0, &error);
if (error)
{
g_error ("property `%s' initial value is broken: %s", name, error);
g_value_unset (&initial_value);
return;
}
va_end (args);
node = g_object_new (GTK_TYPE_CSS_STYLE_PROPERTY,
"value-type", value_type,
"computed-type", computed_type,
"inherit", (flags & GTK_STYLE_PROPERTY_INHERIT) ? TRUE : FALSE,
"initial-value", &initial_value,
"name", name,
NULL);
if (parse_value)
node->parse_value = parse_value;
if (print_value)
node->print_value = print_value;
if (compute_value)
node->compute_value = compute_value;
g_value_unset (&initial_value);
}
/*** HELPERS ***/
static void
string_append_string (GString *str,
const char *string)
{
gsize len;
g_string_append_c (str, '"');
do {
len = strcspn (string, "\"\n\r\f");
g_string_append (str, string);
string += len;
switch (*string)
{
case '\0':
break;
case '\n':
g_string_append (str, "\\A ");
break;
case '\r':
g_string_append (str, "\\D ");
break;
case '\f':
g_string_append (str, "\\C ");
break;
case '\"':
g_string_append (str, "\\\"");
break;
default:
g_assert_not_reached ();
break;
}
} while (*string);
g_string_append_c (str, '"');
}
/*** IMPLEMENTATIONS ***/
static void
color_compute (GtkCssStyleProperty *property,
GValue *computed,
GtkStyleContext *context,
const GValue *specified)
{
GtkSymbolicColor *symbolic = g_value_get_boxed (specified);
GdkRGBA rgba;
if (symbolic == _gtk_symbolic_color_get_current_color ())
{
/* The computed value of the currentColor keyword is the computed
* value of the color property. If the currentColor keyword is
* set on the color property itself, it is treated as color: inherit.
*/
if (g_str_equal (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (property)), "color"))
{
GtkStyleContext *parent = gtk_style_context_get_parent (context);
if (parent)
g_value_copy (_gtk_style_context_peek_property (parent, "color"), computed);
else
_gtk_css_style_compute_value (computed,
context,
_gtk_css_style_property_get_initial_value (property));
}
else
{
g_value_copy (_gtk_style_context_peek_property (context, "color"), computed);
}
}
else if (_gtk_style_context_resolve_color (context,
symbolic,
&rgba))
{
g_value_set_boxed (computed, &rgba);
}
else
{
color_compute (property,
computed,
context,
_gtk_css_style_property_get_initial_value (property));
}
}
static gboolean
font_family_parse (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GPtrArray *names;
char *name;
/* We don't special case generic families. Pango should do
* that for us */
names = g_ptr_array_new ();
do {
name = _gtk_css_parser_try_ident (parser, TRUE);
if (name)
{
GString *string = g_string_new (name);
g_free (name);
while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
{
g_string_append_c (string, ' ');
g_string_append (string, name);
g_free (name);
}
name = g_string_free (string, FALSE);
}
else
{
name = _gtk_css_parser_read_string (parser);
if (name == NULL)
{
g_ptr_array_free (names, TRUE);
return FALSE;
}
}
g_ptr_array_add (names, name);
} while (_gtk_css_parser_try (parser, ",", TRUE));
/* NULL-terminate array */
g_ptr_array_add (names, NULL);
g_value_set_boxed (value, g_ptr_array_free (names, FALSE));
return TRUE;
}
static void
font_family_value_print (GtkCssStyleProperty *property,
const GValue *value,
GString *string)
{
const char **names = g_value_get_boxed (value);
if (names == NULL || *names == NULL)
{
g_string_append (string, "none");
return;
}
string_append_string (string, *names);
names++;
while (*names)
{
g_string_append (string, ", ");
string_append_string (string, *names);
names++;
}
}
static gboolean
bindings_value_parse (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GPtrArray *array;
GtkBindingSet *binding_set;
char *name;
array = g_ptr_array_new ();
do {
name = _gtk_css_parser_try_ident (parser, TRUE);
if (name == NULL)
{
_gtk_css_parser_error (parser, "Not a valid binding name");
g_ptr_array_free (array, TRUE);
return FALSE;
}
binding_set = gtk_binding_set_find (name);
if (!binding_set)
{
_gtk_css_parser_error (parser, "No binding set named '%s'", name);
g_free (name);
continue;
}
g_ptr_array_add (array, binding_set);
g_free (name);
}
while (_gtk_css_parser_try (parser, ",", TRUE));
g_value_take_boxed (value, array);
return TRUE;
}
static void
bindings_value_print (GtkCssStyleProperty *property,
const GValue *value,
GString *string)
{
GPtrArray *array;
guint i;
array = g_value_get_boxed (value);
for (i = 0; i < array->len; i++)
{
GtkBindingSet *binding_set = g_ptr_array_index (array, i);
if (i > 0)
g_string_append (string, ", ");
g_string_append (string, binding_set->set_name);
}
}
static gboolean
border_corner_radius_value_parse (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GtkCssBorderCornerRadius corner;
if (!_gtk_css_parser_read_number (parser,
&corner.horizontal,
GTK_CSS_POSITIVE_ONLY
| GTK_CSS_PARSE_PERCENT
| GTK_CSS_NUMBER_AS_PIXELS
| GTK_CSS_PARSE_LENGTH))
return FALSE;
if (!_gtk_css_parser_has_number (parser))
corner.vertical = corner.horizontal;
else if (!_gtk_css_parser_read_number (parser,
&corner.vertical,
GTK_CSS_POSITIVE_ONLY
| GTK_CSS_PARSE_PERCENT
| GTK_CSS_NUMBER_AS_PIXELS
| GTK_CSS_PARSE_LENGTH))
return FALSE;
g_value_set_boxed (value, &corner);
return TRUE;
}
static void
border_corner_radius_value_print (GtkCssStyleProperty *property,
const GValue *value,
GString *string)
{
GtkCssBorderCornerRadius *corner;
corner = g_value_get_boxed (value);
_gtk_css_number_print (&corner->horizontal, string);
if (!_gtk_css_number_equal (&corner->horizontal, &corner->vertical))
{
g_string_append_c (string, ' ');
_gtk_css_number_print (&corner->vertical, string);
}
}
static gboolean
css_image_value_parse (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GtkCssImage *image;
if (_gtk_css_parser_try (parser, "none", TRUE))
image = NULL;
else
{
image = _gtk_css_image_new_parse (parser, base);
if (image == NULL)
return FALSE;
}
g_value_take_object (value, image);
return TRUE;
}
static void
css_image_value_print (GtkCssStyleProperty *property,
const GValue *value,
GString *string)
{
GtkCssImage *image = g_value_get_object (value);
if (image)
_gtk_css_image_print (image, string);
else
g_string_append (string, "none");
}
static void
css_image_value_compute (GtkCssStyleProperty *property,
GValue *computed,
GtkStyleContext *context,
const GValue *specified)
{
GtkCssImage *image = g_value_get_object (specified);
if (image)
image = _gtk_css_image_compute (image, context);
g_value_take_object (computed, image);
}
static gboolean
parse_margin (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GtkCssNumber number;
if (!_gtk_css_parser_read_number (parser,
&number,
GTK_CSS_NUMBER_AS_PIXELS
| GTK_CSS_PARSE_LENGTH))
return FALSE;
g_value_set_boxed (value, &number);
return TRUE;
}
static void
compute_margin (GtkCssStyleProperty *property,
GValue *computed,
GtkStyleContext *context,
const GValue *specified)
{
GtkCssNumber number;
_gtk_css_number_compute (&number,
g_value_get_boxed (specified),
context);
g_value_set_boxed (computed, &number);
}
static gboolean
parse_padding (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GtkCssNumber number;
if (!_gtk_css_parser_read_number (parser,
&number,
GTK_CSS_POSITIVE_ONLY
| GTK_CSS_NUMBER_AS_PIXELS
| GTK_CSS_PARSE_LENGTH))
return FALSE;
g_value_set_boxed (value, &number);
return TRUE;
}
static void
compute_padding (GtkCssStyleProperty *property,
GValue *computed,
GtkStyleContext *context,
const GValue *specified)
{
GtkCssNumber number;
_gtk_css_number_compute (&number,
g_value_get_boxed (specified),
context);
g_value_set_boxed (computed, &number);
}
static gboolean
parse_border_width (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GtkCssNumber number;
if (!_gtk_css_parser_read_number (parser,
&number,
GTK_CSS_POSITIVE_ONLY
| GTK_CSS_NUMBER_AS_PIXELS
| GTK_CSS_PARSE_LENGTH))
return FALSE;
g_value_set_boxed (value, &number);
return TRUE;
}
static void
compute_border_width (GtkCssStyleProperty *property,
GValue *computed,
GtkStyleContext *context,
const GValue *specified)
{
GtkCssStyleProperty *style;
GtkBorderStyle border_style;
GtkCssNumber number;
/* The -1 is magic that is only true because we register the style
* properties directly after the width properties.
*/
style = _gtk_css_style_property_lookup_by_id (_gtk_css_style_property_get_id (property) - 1);
border_style = g_value_get_enum (_gtk_style_context_peek_property (context, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (style))));
if (border_style == GTK_BORDER_STYLE_NONE ||
border_style == GTK_BORDER_STYLE_HIDDEN)
{
g_value_set_int (computed, 0);
return;
}
_gtk_css_number_compute (&number,
g_value_get_boxed (specified),
context);
g_value_set_int (computed, round (number.value));
}
static gboolean
background_repeat_value_parse (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
int repeat, vertical;
if (!_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &repeat))
{
_gtk_css_parser_error (parser, "Not a valid value");
return FALSE;
}
if (repeat <= GTK_CSS_BACKGROUND_REPEAT_MASK)
{
if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &vertical))
{
if (vertical >= GTK_CSS_BACKGROUND_REPEAT_MASK)
{
_gtk_css_parser_error (parser, "Not a valid 2nd value");
return FALSE;
}
else
repeat |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
}
else
repeat |= repeat << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
}
g_value_set_enum (value, repeat);
return TRUE;
}
static void
background_repeat_value_print (GtkCssStyleProperty *property,
const GValue *value,
GString *string)
{
GEnumClass *enum_class;
GEnumValue *enum_value;
GtkCssBackgroundRepeat repeat;
repeat = g_value_get_enum (value);
enum_class = g_type_class_ref (GTK_TYPE_CSS_BACKGROUND_REPEAT);
enum_value = g_enum_get_value (enum_class, repeat);
/* only triggers for 'repeat-x' and 'repeat-y' */
if (enum_value)
g_string_append (string, enum_value->value_nick);
else
{
enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_HORIZONTAL (repeat));
g_string_append (string, enum_value->value_nick);
if (GTK_CSS_BACKGROUND_HORIZONTAL (repeat) != GTK_CSS_BACKGROUND_VERTICAL (repeat))
{
enum_value = g_enum_get_value (enum_class, GTK_CSS_BACKGROUND_VERTICAL (repeat));
g_string_append (string, " ");
g_string_append (string, enum_value->value_nick);
}
}
g_type_class_unref (enum_class);
}
static gboolean
background_size_parse (GtkCssStyleProperty *property,
GValue *value,
GtkCssParser *parser,
GFile *base)
{
GtkCssBackgroundSize size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE};
if (_gtk_css_parser_try (parser, "cover", TRUE))
size.cover = TRUE;
else if (_gtk_css_parser_try (parser, "contain", TRUE))
size.contain = TRUE;
else
{
if (_gtk_css_parser_try (parser, "auto", TRUE))
_gtk_css_number_init (&size.width, 0, GTK_CSS_PX);
else if (!_gtk_css_parser_read_number (parser,
&size.width,
GTK_CSS_POSITIVE_ONLY
| GTK_CSS_PARSE_PERCENT
| GTK_CSS_PARSE_LENGTH))
return FALSE;
if (_gtk_css_parser_try (parser, "auto", TRUE))
_gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
else if (_gtk_css_parser_has_number (parser))
{
if (!_gtk_css_parser_read_number (parser,
&size.height,
GTK_CSS_POSITIVE_ONLY
| GTK_CSS_PARSE_PERCENT
| GTK_CSS_PARSE_LENGTH))
return FALSE;
}
else
_gtk_css_number_init (&size.height, 0, GTK_CSS_PX);
}
g_value_set_boxed (value, &size);
return TRUE;
}
static void
background_size_print (GtkCssStyleProperty *property,
const GValue *value,
GString *string)
{
GtkCssBackgroundSize *size = g_value_get_boxed (value);
if (size->cover)
g_string_append (string, "cover");
else if (size->contain)
g_string_append (string, "contain");
else
{
if (size->width.value == 0)
g_string_append (string, "auto");
else
_gtk_css_number_print (&size->width, string);
if (size->height.value != 0)
{
g_string_append (string, " ");
_gtk_css_number_print (&size->height, string);
}
}
}
static void
background_size_compute (GtkCssStyleProperty *property,
GValue *computed,
GtkStyleContext *context,
const GValue *specified)
{
GtkCssBackgroundSize *ssize = g_value_get_boxed (specified);
GtkCssBackgroundSize csize;
csize.cover = ssize->cover;
csize.contain = ssize->contain;
_gtk_css_number_compute (&csize.width,
&ssize->width,
context);
_gtk_css_number_compute (&csize.height,
&ssize->height,
context);
g_value_set_boxed (computed, &csize);
}
/*** REGISTRATION ***/
static GtkSymbolicColor *
gtk_symbolic_color_new_rgba (double red,
double green,
double blue,
double alpha)
{
GdkRGBA rgba = { red, green, blue, alpha };
return gtk_symbolic_color_new_literal (&rgba);
}
void
_gtk_css_style_property_init_properties (void)
{
char *default_font_family[] = { "Sans", NULL };
GtkCssNumber number;
GtkSymbolicColor *symbolic;
GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
GtkCssBorderCornerRadius no_corner_radius = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX) };
GtkBorder border_of_ones = { 1, 1, 1, 1 };
GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };
/* Initialize "color" and "font-size" first,
* so that when computing values later they are
* done first. That way, 'currentColor' and font
* sizes in em can be looked up properly */
symbolic = gtk_symbolic_color_new_rgba (1, 1, 1, 1);
gtk_css_style_property_register ("color",
GTK_TYPE_SYMBOLIC_COLOR,
GDK_TYPE_RGBA,
GDK_TYPE_RGBA,
GTK_STYLE_PROPERTY_INHERIT,
NULL,
NULL,
color_compute,
symbolic);
gtk_symbolic_color_unref (symbolic);
gtk_css_style_property_register ("font-size",
G_TYPE_DOUBLE,
G_TYPE_DOUBLE,
G_TYPE_DOUBLE,
GTK_STYLE_PROPERTY_INHERIT,
NULL,
NULL,
NULL,
10.0);
/* properties that aren't referenced when computing values
* start here */
symbolic = gtk_symbolic_color_new_rgba (0, 0, 0, 0);
gtk_css_style_property_register ("background-color",
GTK_TYPE_SYMBOLIC_COLOR,
GDK_TYPE_RGBA,
GDK_TYPE_RGBA,
0,
NULL,
NULL,
color_compute,
symbolic);
gtk_symbolic_color_unref (symbolic);
gtk_css_style_property_register ("font-family",
G_TYPE_STRV,
G_TYPE_STRV,
G_TYPE_STRV,
GTK_STYLE_PROPERTY_INHERIT,
font_family_parse,
font_family_value_print,
NULL,
default_font_family);
gtk_css_style_property_register ("font-style",
PANGO_TYPE_STYLE,
PANGO_TYPE_STYLE,
PANGO_TYPE_STYLE,
GTK_STYLE_PROPERTY_INHERIT,
NULL,
NULL,
NULL,
PANGO_STYLE_NORMAL);
gtk_css_style_property_register ("font-variant",
PANGO_TYPE_VARIANT,
PANGO_TYPE_VARIANT,
PANGO_TYPE_VARIANT,
GTK_STYLE_PROPERTY_INHERIT,
NULL,
NULL,
NULL,
PANGO_VARIANT_NORMAL);
/* xxx: need to parse this properly, ie parse the numbers */
gtk_css_style_property_register ("font-weight",
PANGO_TYPE_WEIGHT,
PANGO_TYPE_WEIGHT,
PANGO_TYPE_WEIGHT,
GTK_STYLE_PROPERTY_INHERIT,
NULL,
NULL,
NULL,
PANGO_WEIGHT_NORMAL);
gtk_css_style_property_register ("text-shadow",
GTK_TYPE_SHADOW,
GTK_TYPE_SHADOW,
GTK_TYPE_SHADOW,
GTK_STYLE_PROPERTY_INHERIT,
NULL,
NULL,
NULL,
NULL);
gtk_css_style_property_register ("icon-shadow",
GTK_TYPE_SHADOW,
GTK_TYPE_SHADOW,
GTK_TYPE_SHADOW,
GTK_STYLE_PROPERTY_INHERIT,
NULL,
NULL,
NULL,
NULL);
gtk_css_style_property_register ("box-shadow",
GTK_TYPE_SHADOW,
GTK_TYPE_SHADOW,
GTK_TYPE_SHADOW,
0,
NULL,
NULL,
NULL,
NULL);
_gtk_css_number_init (&number, 0, GTK_CSS_PX);
gtk_css_style_property_register ("margin-top",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_margin,
NULL,
compute_margin,
&number);
gtk_css_style_property_register ("margin-left",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_margin,
NULL,
compute_margin,
&number);
gtk_css_style_property_register ("margin-bottom",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_margin,
NULL,
compute_margin,
&number);
gtk_css_style_property_register ("margin-right",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_margin,
NULL,
compute_margin,
&number);
gtk_css_style_property_register ("padding-top",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_padding,
NULL,
compute_padding,
&number);
gtk_css_style_property_register ("padding-left",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_padding,
NULL,
compute_padding,
&number);
gtk_css_style_property_register ("padding-bottom",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_padding,
NULL,
compute_padding,
&number);
gtk_css_style_property_register ("padding-right",
GTK_TYPE_CSS_NUMBER,
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
0,
parse_padding,
NULL,
compute_padding,
&number);
/* IMPORTANT: compute_border_width() requires that the border-width
* properties be immeditaly followed by the border-style properties
*/
gtk_css_style_property_register ("border-top-style",
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
0,
NULL,
NULL,
NULL,
GTK_BORDER_STYLE_NONE);
gtk_css_style_property_register ("border-top-width",
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
G_TYPE_INT,
0,
parse_border_width,
NULL,
compute_border_width,
&number);
gtk_css_style_property_register ("border-left-style",
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
0,
NULL,
NULL,
NULL,
GTK_BORDER_STYLE_NONE);
gtk_css_style_property_register ("border-left-width",
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
G_TYPE_INT,
0,
parse_border_width,
NULL,
compute_border_width,
&number);
gtk_css_style_property_register ("border-bottom-style",
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
0,
NULL,
NULL,
NULL,
GTK_BORDER_STYLE_NONE);
gtk_css_style_property_register ("border-bottom-width",
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
G_TYPE_INT,
0,
parse_border_width,
NULL,
compute_border_width,
&number);
gtk_css_style_property_register ("border-right-style",
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
0,
NULL,
NULL,
NULL,
GTK_BORDER_STYLE_NONE);
gtk_css_style_property_register ("border-right-width",
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
G_TYPE_INT,
0,
parse_border_width,
NULL,
compute_border_width,
&number);
gtk_css_style_property_register ("border-top-left-radius",
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
0,
border_corner_radius_value_parse,
border_corner_radius_value_print,
NULL,
&no_corner_radius);
gtk_css_style_property_register ("border-top-right-radius",
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
0,
border_corner_radius_value_parse,
border_corner_radius_value_print,
NULL,
&no_corner_radius);
gtk_css_style_property_register ("border-bottom-right-radius",
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
0,
border_corner_radius_value_parse,
border_corner_radius_value_print,
NULL,
&no_corner_radius);
gtk_css_style_property_register ("border-bottom-left-radius",
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
GTK_TYPE_CSS_BORDER_CORNER_RADIUS,
0,
border_corner_radius_value_parse,
border_corner_radius_value_print,
NULL,
&no_corner_radius);
gtk_css_style_property_register ("outline-style",
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
GTK_TYPE_BORDER_STYLE,
0,
NULL,
NULL,
NULL,
GTK_BORDER_STYLE_NONE);
gtk_css_style_property_register ("outline-width",
GTK_TYPE_CSS_NUMBER,
G_TYPE_INT,
G_TYPE_INT,
0,
parse_border_width,
NULL,
compute_border_width,
&number);
gtk_css_style_property_register ("outline-offset",
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_INT,
0,
NULL,
NULL,
NULL,
0);
gtk_css_style_property_register ("background-clip",
GTK_TYPE_CSS_AREA,
GTK_TYPE_CSS_AREA,
GTK_TYPE_CSS_AREA,
0,
NULL,
NULL,
NULL,
GTK_CSS_AREA_BORDER_BOX);
gtk_css_style_property_register ("background-origin",
GTK_TYPE_CSS_AREA,
GTK_TYPE_CSS_AREA,
GTK_TYPE_CSS_AREA,
0,
NULL,
NULL,
NULL,
GTK_CSS_AREA_PADDING_BOX);
gtk_css_style_property_register ("background-size",
GTK_TYPE_CSS_BACKGROUND_SIZE,
GTK_TYPE_CSS_BACKGROUND_SIZE,
G_TYPE_NONE,
0,
background_size_parse,
background_size_print,
background_size_compute,
&default_background_size);
gtk_css_style_property_register ("border-top-color",
GTK_TYPE_SYMBOLIC_COLOR,
GDK_TYPE_RGBA,
GDK_TYPE_RGBA,
0,
NULL,
NULL,
color_compute,
_gtk_symbolic_color_get_current_color ());
gtk_css_style_property_register ("border-right-color",
GTK_TYPE_SYMBOLIC_COLOR,
GDK_TYPE_RGBA,
GDK_TYPE_RGBA,
0,
NULL,
NULL,
color_compute,
_gtk_symbolic_color_get_current_color ());
gtk_css_style_property_register ("border-bottom-color",
GTK_TYPE_SYMBOLIC_COLOR,
GDK_TYPE_RGBA,
GDK_TYPE_RGBA,
0,
NULL,
NULL,
color_compute,
_gtk_symbolic_color_get_current_color ());
gtk_css_style_property_register ("border-left-color",
GTK_TYPE_SYMBOLIC_COLOR,
GDK_TYPE_RGBA,
GDK_TYPE_RGBA,
0,
NULL,
NULL,
color_compute,
_gtk_symbolic_color_get_current_color ());
gtk_css_style_property_register ("outline-color",
GTK_TYPE_SYMBOLIC_COLOR,
GDK_TYPE_RGBA,
GDK_TYPE_RGBA,
0,
NULL,
NULL,
color_compute,
_gtk_symbolic_color_get_current_color ());
gtk_css_style_property_register ("background-repeat",
GTK_TYPE_CSS_BACKGROUND_REPEAT,
GTK_TYPE_CSS_BACKGROUND_REPEAT,
GTK_TYPE_CSS_BACKGROUND_REPEAT,
0,
background_repeat_value_parse,
background_repeat_value_print,
NULL,
GTK_CSS_BACKGROUND_REPEAT | (GTK_CSS_BACKGROUND_REPEAT << GTK_CSS_BACKGROUND_REPEAT_SHIFT));
gtk_css_style_property_register ("background-image",
GTK_TYPE_CSS_IMAGE,
GTK_TYPE_CSS_IMAGE,
CAIRO_GOBJECT_TYPE_PATTERN,
0,
css_image_value_parse,
css_image_value_print,
css_image_value_compute,
NULL);
gtk_css_style_property_register ("border-image-source",
GTK_TYPE_CSS_IMAGE,
GTK_TYPE_CSS_IMAGE,
CAIRO_GOBJECT_TYPE_PATTERN,
0,
css_image_value_parse,
css_image_value_print,
css_image_value_compute,
NULL);
gtk_css_style_property_register ("border-image-repeat",
GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
0,
NULL,
NULL,
NULL,
&border_image_repeat);
/* XXX: The initial value is wrong, it should be 100% */
gtk_css_style_property_register ("border-image-slice",
GTK_TYPE_BORDER,
GTK_TYPE_BORDER,
GTK_TYPE_BORDER,
0,
NULL,
NULL,
NULL,
&border_of_ones);
gtk_css_style_property_register ("border-image-width",
GTK_TYPE_BORDER,
GTK_TYPE_BORDER,
GTK_TYPE_BORDER,
0,
NULL,
NULL,
NULL,
NULL);
gtk_css_style_property_register ("engine",
GTK_TYPE_THEMING_ENGINE,
GTK_TYPE_THEMING_ENGINE,
GTK_TYPE_THEMING_ENGINE,
0,
NULL,
NULL,
NULL,
gtk_theming_engine_load (NULL));
gtk_css_style_property_register ("transition",
GTK_TYPE_ANIMATION_DESCRIPTION,
GTK_TYPE_ANIMATION_DESCRIPTION,
GTK_TYPE_ANIMATION_DESCRIPTION,
0,
NULL,
NULL,
NULL,
NULL);
/* Private property holding the binding sets */
gtk_css_style_property_register ("gtk-key-bindings",
G_TYPE_PTR_ARRAY,
G_TYPE_PTR_ARRAY,
G_TYPE_PTR_ARRAY,
0,
bindings_value_parse,
bindings_value_print,
NULL,
NULL);
}