cssvalue: Add a custom value for repeats

In particular, that's background-repeat and border-image-repeat.

Also, fix up the border-image shorthand to allow any order.
This commit is contained in:
Benjamin Otte 2012-04-04 11:44:57 +02:00
parent 5377169ef3
commit f785f7177c
15 changed files with 453 additions and 282 deletions

View File

@ -445,6 +445,7 @@ gtk_private_h_sources = \
gtkcssparserprivate.h \
gtkcsspositionvalueprivate.h \
gtkcssproviderprivate.h \
gtkcssrepeatvalueprivate.h \
gtkcssrgbavalueprivate.h \
gtkcsssectionprivate.h \
gtkcssselectorprivate.h \
@ -656,6 +657,7 @@ gtk_base_c_sources = \
gtkcssparser.c \
gtkcsspositionvalue.c \
gtkcssprovider.c \
gtkcssrepeatvalue.c \
gtkcssrgbavalue.c \
gtkcsssection.c \
gtkcssselector.c \

View File

@ -26,6 +26,7 @@
#include "gtkborderimageprivate.h"
#include "gtkcssimagevalueprivate.h"
#include "gtkcssrepeatvalueprivate.h"
#include "gtkstylepropertiesprivate.h"
#include "gtkthemingengineprivate.h"
@ -54,7 +55,7 @@ _gtk_border_image_init (GtkBorderImage *image,
else
image->has_width = FALSE;
image->repeat = *_gtk_css_value_get_border_image_repeat (_gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT));
image->repeat = _gtk_theming_engine_peek_property (engine, GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT);
return TRUE;
}
@ -91,8 +92,8 @@ gtk_border_image_render_slice (cairo_t *cr,
double y,
double width,
double height,
GtkCssBorderRepeatStyle hrepeat,
GtkCssBorderRepeatStyle vrepeat)
GtkCssRepeatStyle hrepeat,
GtkCssRepeatStyle vrepeat)
{
double hscale, vscale;
double xstep, ystep;
@ -299,8 +300,8 @@ _gtk_border_image_render (GtkBorderImage *image,
vertical_border[v].offset,
horizontal_border[h].size,
vertical_border[v].size,
h == 1 ? image->repeat.hrepeat : GTK_CSS_REPEAT_STYLE_STRETCH,
v == 1 ? image->repeat.vrepeat : GTK_CSS_REPEAT_STYLE_STRETCH);
h == 1 ? _gtk_css_border_repeat_value_get_x (image->repeat) : GTK_CSS_REPEAT_STYLE_STRETCH,
v == 1 ? _gtk_css_border_repeat_value_get_y (image->repeat) : GTK_CSS_REPEAT_STYLE_STRETCH);
cairo_surface_destroy (slice);
}

View File

@ -24,8 +24,8 @@
#include "gtkborder.h"
#include "gtkcssimageprivate.h"
#include "gtkcssvalueprivate.h"
#include "gtkthemingengine.h"
#include "gtkcsstypesprivate.h"
G_BEGIN_DECLS
@ -37,7 +37,7 @@ struct _GtkBorderImage {
GtkBorder slice;
gboolean has_width;
GtkBorder width;
GtkCssBorderImageRepeat repeat;
GtkCssValue *repeat;
};
gboolean _gtk_border_image_init (GtkBorderImage *image,

View File

@ -120,12 +120,6 @@ gtk_css_value_position_print (const GtkCssValue *position,
g_string_append (string, "center ");
_gtk_css_value_print (position->y, string);
}
_gtk_css_value_print (position->x, string);
if (!_gtk_css_value_equal (position->x, position->y))
{
g_string_append_c (string, ' ');
_gtk_css_value_print (position->y, string);
}
done:
for (i = 0; i < G_N_ELEMENTS (values); i++)

299
gtk/gtkcssrepeatvalue.c Normal file
View File

@ -0,0 +1,299 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2011 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 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 "gtkcssrepeatvalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
GtkCssRepeatStyle x;
GtkCssRepeatStyle y;
};
static void
gtk_css_value_repeat_free (GtkCssValue *value)
{
g_slice_free (GtkCssValue, value);
}
static gboolean
gtk_css_value_repeat_equal (const GtkCssValue *repeat1,
const GtkCssValue *repeat2)
{
return repeat1->x == repeat2->x
&& repeat1->y == repeat2->y;
}
static GtkCssValue *
gtk_css_value_repeat_transition (GtkCssValue *start,
GtkCssValue *end,
double progress)
{
return NULL;
}
static void
gtk_css_value_background_repeat_print (const GtkCssValue *repeat,
GString *string)
{
static const char *names[] = {
"no-repeat",
"repeat",
"round",
"space"
};
if (repeat->x == repeat->y)
{
g_string_append (string, names[repeat->x]);
}
else if (repeat->x == GTK_CSS_REPEAT_STYLE_REPEAT &&
repeat->y == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
{
g_string_append (string, "repeat-x");
}
else if (repeat->x == GTK_CSS_REPEAT_STYLE_NO_REPEAT &&
repeat->y == GTK_CSS_REPEAT_STYLE_REPEAT)
{
g_string_append (string, "repeat-y");
}
else
{
g_string_append (string, names[repeat->x]);
g_string_append_c (string, ' ');
g_string_append (string, names[repeat->y]);
}
}
static void
gtk_css_value_border_repeat_print (const GtkCssValue *repeat,
GString *string)
{
static const char *names[] = {
"stretch",
"repeat",
"round",
"space"
};
g_string_append (string, names[repeat->x]);
if (repeat->x != repeat->y)
{
g_string_append_c (string, ' ');
g_string_append (string, names[repeat->y]);
}
}
static const GtkCssValueClass GTK_CSS_VALUE_BACKGROUND_REPEAT = {
gtk_css_value_repeat_free,
gtk_css_value_repeat_equal,
gtk_css_value_repeat_transition,
gtk_css_value_background_repeat_print
};
static const GtkCssValueClass GTK_CSS_VALUE_BORDER_REPEAT = {
gtk_css_value_repeat_free,
gtk_css_value_repeat_equal,
gtk_css_value_repeat_transition,
gtk_css_value_border_repeat_print
};
/* BACKGROUND REPEAT */
static struct {
const char *name;
GtkCssValue values[4];
} background_repeat_values[4] = {
{ "no-repeat",
{ { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_SPACE }
} },
{ "repeat",
{ { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_SPACE }
} },
{ "round",
{ { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_NO_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_SPACE }
} },
{ "space",
{ { &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_NO_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BACKGROUND_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_SPACE }
} }
};
GtkCssValue *
_gtk_css_background_repeat_value_new (GtkCssRepeatStyle x,
GtkCssRepeatStyle y)
{
return _gtk_css_value_ref (&background_repeat_values[x].values[y]);
}
static gboolean
_gtk_css_background_repeat_style_try (GtkCssParser *parser,
GtkCssRepeatStyle *result)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (background_repeat_values); i++)
{
if (_gtk_css_parser_try (parser, background_repeat_values[i].name, TRUE))
{
*result = i;
return TRUE;
}
}
return FALSE;
}
GtkCssValue *
_gtk_css_background_repeat_value_try_parse (GtkCssParser *parser)
{
GtkCssRepeatStyle x, y;
g_return_val_if_fail (parser != NULL, NULL);
if (_gtk_css_parser_try (parser, "repeat-x", TRUE))
return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
if (_gtk_css_parser_try (parser, "repeat-y", TRUE))
return _gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_NO_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT);
if (!_gtk_css_background_repeat_style_try (parser, &x))
return NULL;
if (!_gtk_css_background_repeat_style_try (parser, &y))
y = x;
return _gtk_css_background_repeat_value_new (x, y);
}
GtkCssRepeatStyle
_gtk_css_background_repeat_value_get_x (const GtkCssValue *repeat)
{
g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BACKGROUND_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
return repeat->x;
}
GtkCssRepeatStyle
_gtk_css_background_repeat_value_get_y (const GtkCssValue *repeat)
{
g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BACKGROUND_REPEAT, GTK_CSS_REPEAT_STYLE_NO_REPEAT);
return repeat->y;
}
/* BORDER IMAGE REPEAT */
static struct {
const char *name;
GtkCssValue values[4];
} border_repeat_values[4] = {
{ "stretch",
{ { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_SPACE }
} },
{ "repeat",
{ { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_STRETCH },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_REPEAT, GTK_CSS_REPEAT_STYLE_SPACE }
} },
{ "round",
{ { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_STRETCH },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_ROUND, GTK_CSS_REPEAT_STYLE_SPACE }
} },
{ "space",
{ { &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_STRETCH },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_REPEAT },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_ROUND },
{ &GTK_CSS_VALUE_BORDER_REPEAT, 1, GTK_CSS_REPEAT_STYLE_SPACE, GTK_CSS_REPEAT_STYLE_SPACE }
} }
};
GtkCssValue *
_gtk_css_border_repeat_value_new (GtkCssRepeatStyle x,
GtkCssRepeatStyle y)
{
return _gtk_css_value_ref (&border_repeat_values[x].values[y]);
}
static gboolean
_gtk_css_border_repeat_style_try (GtkCssParser *parser,
GtkCssRepeatStyle *result)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (border_repeat_values); i++)
{
if (_gtk_css_parser_try (parser, border_repeat_values[i].name, TRUE))
{
*result = i;
return TRUE;
}
}
return FALSE;
}
GtkCssValue *
_gtk_css_border_repeat_value_try_parse (GtkCssParser *parser)
{
GtkCssRepeatStyle x, y;
g_return_val_if_fail (parser != NULL, NULL);
if (!_gtk_css_border_repeat_style_try (parser, &x))
return NULL;
if (!_gtk_css_border_repeat_style_try (parser, &y))
y = x;
return _gtk_css_border_repeat_value_new (x, y);
}
GtkCssRepeatStyle
_gtk_css_border_repeat_value_get_x (const GtkCssValue *repeat)
{
g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BORDER_REPEAT, GTK_CSS_REPEAT_STYLE_STRETCH);
return repeat->x;
}
GtkCssRepeatStyle
_gtk_css_border_repeat_value_get_y (const GtkCssValue *repeat)
{
g_return_val_if_fail (repeat->class == &GTK_CSS_VALUE_BORDER_REPEAT, GTK_CSS_REPEAT_STYLE_STRETCH);
return repeat->y;
}

View File

@ -0,0 +1,50 @@
/*
* 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: Alexander Larsson <alexl@gnome.org>
*/
#ifndef __GTK_CSS_REPEAT_VALUE_PRIVATE_H__
#define __GTK_CSS_REPEAT_VALUE_PRIVATE_H__
#include "gtkcssparserprivate.h"
#include "gtkcssvalueprivate.h"
G_BEGIN_DECLS
typedef enum {
GTK_CSS_REPEAT_STYLE_NO_REPEAT,
GTK_CSS_REPEAT_STYLE_STRETCH = GTK_CSS_REPEAT_STYLE_NO_REPEAT,
GTK_CSS_REPEAT_STYLE_REPEAT,
GTK_CSS_REPEAT_STYLE_ROUND,
GTK_CSS_REPEAT_STYLE_SPACE
} GtkCssRepeatStyle;
GtkCssValue * _gtk_css_background_repeat_value_new (GtkCssRepeatStyle x,
GtkCssRepeatStyle y);
GtkCssValue * _gtk_css_background_repeat_value_try_parse (GtkCssParser *parser);
GtkCssRepeatStyle _gtk_css_background_repeat_value_get_x (const GtkCssValue *repeat);
GtkCssRepeatStyle _gtk_css_background_repeat_value_get_y (const GtkCssValue *repeat);
GtkCssValue * _gtk_css_border_repeat_value_new (GtkCssRepeatStyle x,
GtkCssRepeatStyle y);
GtkCssValue * _gtk_css_border_repeat_value_try_parse (GtkCssParser *parser);
GtkCssRepeatStyle _gtk_css_border_repeat_value_get_x (const GtkCssValue *repeat);
GtkCssRepeatStyle _gtk_css_border_repeat_value_get_y (const GtkCssValue *repeat);
G_END_DECLS
#endif /* __GTK_CSS_REPEAT_VALUE_PRIVATE_H__ */

View File

@ -30,6 +30,7 @@
#include "gtkcssimageprivate.h"
#include "gtkcssimagevalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssrepeatvalueprivate.h"
#include "gtkcssstringvalueprivate.h"
#include "gtkcssstylefuncsprivate.h"
#include "gtkcsstypesprivate.h"
@ -277,45 +278,58 @@ parse_border_image (GtkCssShorthandProperty *shorthand,
GtkCssParser *parser,
GFile *base)
{
GValue value = G_VALUE_INIT;
GtkCssImage *image;
if (_gtk_css_parser_try (parser, "none", TRUE))
image = NULL;
else
do
{
image = _gtk_css_image_new_parse (parser, base);
if (!image)
return FALSE;
if (values[0] == NULL &&
(_gtk_css_parser_has_prefix (parser, "none") ||
_gtk_css_image_can_parse (parser)))
{
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;
}
values[0] = _gtk_css_image_value_new (image);
}
else if (values[3] == NULL &&
(values[3] = _gtk_css_border_repeat_value_try_parse (parser)))
{
/* please move along */
}
else if (values[1] == NULL)
{
GValue value = G_VALUE_INIT;
g_value_init (&value, GTK_TYPE_BORDER);
if (!_gtk_css_style_parse_value (&value, parser, base))
return FALSE;
values[1] = _gtk_css_value_new_from_gvalue (&value);
g_value_unset (&value);
if (_gtk_css_parser_try (parser, "/", TRUE))
{
g_value_init (&value, GTK_TYPE_BORDER);
if (!_gtk_css_style_parse_value (&value, parser, base))
return FALSE;
values[2] = _gtk_css_value_new_from_gvalue (&value);
g_value_unset (&value);
}
}
else
{
/* We parsed everything and there's still stuff left?
* Pretend we didn't notice and let the normal code produce
* a 'junk at end of value' error */
break;
}
}
values[0] = _gtk_css_image_value_new (image);
if (value_is_done_parsing (parser))
return TRUE;
g_value_init (&value, GTK_TYPE_BORDER);
if (!_gtk_css_style_parse_value (&value, parser, base))
return FALSE;
values[1] = _gtk_css_value_new_from_gvalue (&value);
g_value_unset (&value);
if (_gtk_css_parser_try (parser, "/", TRUE))
{
g_value_init (&value, GTK_TYPE_BORDER);
if (!_gtk_css_style_parse_value (&value, parser, base))
return FALSE;
values[2] = _gtk_css_value_new_from_gvalue (&value);
g_value_unset (&value);
}
if (value_is_done_parsing (parser))
return TRUE;
g_value_init (&value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
if (!_gtk_css_style_parse_value (&value, parser, base))
return FALSE;
values[3] = _gtk_css_value_new_from_gvalue (&value);
g_value_unset (&value);
while (!value_is_done_parsing (parser));
return TRUE;
}
@ -353,13 +367,6 @@ parse_border_side (GtkCssShorthandProperty *shorthand,
values[2] = _gtk_css_value_new_take_symbolic_color (symbolic);
}
else
{
/* We parsed everything and there's still stuff left?
* Pretend we didn't notice and let the normal code produce
* a 'junk at end of value' error */
break;
}
}
while (!value_is_done_parsing (parser));
@ -474,8 +481,6 @@ parse_background (GtkCssShorthandProperty *shorthand,
GtkCssParser *parser,
GFile *base)
{
int enum_value;
do
{
/* the image part */
@ -497,27 +502,9 @@ parse_background (GtkCssShorthandProperty *shorthand,
values[0] = _gtk_css_image_value_new (image);
}
else if (values[1] == NULL &&
_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &enum_value))
(values[1] = _gtk_css_background_repeat_value_try_parse (parser)))
{
if (enum_value <= GTK_CSS_BACKGROUND_REPEAT_MASK)
{
int vertical;
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 for border-repeat");
return FALSE;
}
else
enum_value |= vertical << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
}
else
enum_value |= enum_value << GTK_CSS_BACKGROUND_REPEAT_SHIFT;
}
values[1] = _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT, enum_value);
/* nothing to do here */
}
else if ((values[2] == NULL || values[3] == NULL) &&
(values[3] = _gtk_css_area_value_try_parse (parser)))

View File

@ -887,52 +887,6 @@ pattern_value_compute (GtkStyleContext *context,
return _gtk_css_value_ref (specified);
}
static gboolean
border_image_repeat_value_parse (GtkCssParser *parser,
GFile *file,
GValue *value)
{
GtkCssBorderImageRepeat image_repeat;
GtkCssBorderRepeatStyle styles[2];
gint i, v;
for (i = 0; i < 2; i++)
{
if (_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, &v))
styles[i] = v;
else if (i == 0)
{
styles[1] = styles[0] = GTK_CSS_REPEAT_STYLE_STRETCH;
break;
}
else
styles[i] = styles[0];
}
image_repeat.hrepeat = styles[0];
image_repeat.vrepeat = styles[1];
g_value_set_boxed (value, &image_repeat);
return TRUE;
}
static void
border_image_repeat_value_print (const GValue *value,
GString *string)
{
GtkCssBorderImageRepeat *image_repeat;
image_repeat = g_value_get_boxed (value);
enum_print (image_repeat->hrepeat, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, string);
if (image_repeat->hrepeat != image_repeat->vrepeat)
{
g_string_append (string, " ");
enum_print (image_repeat->vrepeat, GTK_TYPE_CSS_BORDER_REPEAT_STYLE, string);
}
}
static gboolean
enum_value_parse (GtkCssParser *parser,
GFile *base,
@ -1100,10 +1054,6 @@ gtk_css_style_funcs_init (void)
pattern_value_parse,
pattern_value_print,
pattern_value_compute);
register_conversion_function (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
border_image_repeat_value_parse,
border_image_repeat_value_print,
NULL);
register_conversion_function (G_TYPE_ENUM,
enum_value_parse,
enum_value_print,

View File

@ -50,6 +50,7 @@
#include "gtkcssenumvalueprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcsspositionvalueprivate.h"
#include "gtkcssrepeatvalueprivate.h"
#include "gtkcssrgbavalueprivate.h"
#include "gtkcssshadowsvalueprivate.h"
#include "gtkcssstringvalueprivate.h"
@ -665,20 +666,15 @@ border_image_repeat_parse (GtkCssStyleProperty *property,
GtkCssParser *parser,
GFile *base)
{
GValue value = G_VALUE_INIT;
GtkCssValue *result;
GtkCssValue *value = _gtk_css_border_repeat_value_try_parse (parser);
g_value_init (&value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
if (!_gtk_css_style_parse_value (&value, parser, base))
if (value == NULL)
{
g_value_unset (&value);
_gtk_css_parser_error (parser, "Not a valid value");
return NULL;
}
result = _gtk_css_value_new_from_gvalue (&value);
g_value_unset (&value);
return result;
return value;
}
static GtkCssValue *
@ -886,63 +882,15 @@ background_repeat_value_parse (GtkCssStyleProperty *property,
GtkCssParser *parser,
GFile *base)
{
int repeat, vertical;
GtkCssValue *value = _gtk_css_background_repeat_value_try_parse (parser);
if (!_gtk_css_parser_try_enum (parser, GTK_TYPE_CSS_BACKGROUND_REPEAT, &repeat))
if (value == NULL)
{
_gtk_css_parser_error (parser, "Not a valid value");
return FALSE;
return NULL;
}
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;
}
return _gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT, repeat);
}
static void
background_repeat_value_print (GtkCssStyleProperty *property,
const GtkCssValue *value,
GString *string)
{
GEnumClass *enum_class;
GEnumValue *enum_value;
GtkCssBackgroundRepeat repeat;
repeat = _gtk_css_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);
return value;
}
static GtkCssValue *
@ -1067,7 +1015,6 @@ _gtk_css_style_property_init_properties (void)
{
GtkCssBackgroundSize default_background_size = { GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), GTK_CSS_NUMBER_INIT (0, GTK_CSS_PX), FALSE, FALSE };
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
@ -1571,17 +1518,16 @@ _gtk_css_style_property_init_properties (void)
gtk_css_style_property_register ("background-repeat",
GTK_CSS_PROPERTY_BACKGROUND_REPEAT,
GTK_TYPE_CSS_BACKGROUND_REPEAT,
G_TYPE_NONE,
0,
background_repeat_value_parse,
background_repeat_value_print,
NULL,
query_simple,
assign_simple,
NULL,
_gtk_css_value_new_from_enum (GTK_TYPE_CSS_BACKGROUND_REPEAT,
GTK_CSS_BACKGROUND_REPEAT |
(GTK_CSS_BACKGROUND_REPEAT << GTK_CSS_BACKGROUND_REPEAT_SHIFT)));
NULL,
NULL,
NULL,
_gtk_css_background_repeat_value_new (GTK_CSS_REPEAT_STYLE_REPEAT,
GTK_CSS_REPEAT_STYLE_REPEAT));
gtk_css_style_property_register ("background-image",
GTK_CSS_PROPERTY_BACKGROUND_IMAGE,
CAIRO_GOBJECT_TYPE_PATTERN,
@ -1607,15 +1553,16 @@ _gtk_css_style_property_init_properties (void)
_gtk_css_image_value_new (NULL));
gtk_css_style_property_register ("border-image-repeat",
GTK_CSS_PROPERTY_BORDER_IMAGE_REPEAT,
GTK_TYPE_CSS_BORDER_IMAGE_REPEAT,
G_TYPE_NONE,
0,
border_image_repeat_parse,
NULL,
NULL,
query_simple,
assign_simple,
NULL,
_gtk_css_value_new_from_border_image_repeat (&border_image_repeat));
NULL,
NULL,
_gtk_css_border_repeat_value_new (GTK_CSS_REPEAT_STYLE_STRETCH,
GTK_CSS_REPEAT_STYLE_STRETCH));
/* XXX: The initial value is wrong, it should be 100% */
gtk_css_style_property_register ("border-image-slice",

View File

@ -33,7 +33,6 @@ type_name ## _copy (const TypeName *foo) \
G_DEFINE_BOXED_TYPE (TypeName, type_name, type_name ## _copy, g_free)
DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBackgroundSize, _gtk_css_background_size)
DEFINE_BOXED_TYPE_WITH_COPY_FUNC (GtkCssBorderImageRepeat, _gtk_css_border_image_repeat)
typedef struct _GtkCssChangeTranslation GtkCssChangeTranslation;
struct _GtkCssChangeTranslation {

View File

@ -114,33 +114,6 @@ enum { /*< skip >*/
GTK_CSS_PROPERTY_N_PROPERTIES
};
/* We encode horizontal and vertical repeat in one enum value.
* This eases parsing and storage, but you need to be aware that
* you have to "unpack" this value.
*/
#define GTK_CSS_BACKGROUND_REPEAT_SHIFT (8)
#define GTK_CSS_BACKGROUND_REPEAT_MASK ((1 << GTK_CSS_BACKGROUND_REPEAT_SHIFT) - 1)
#define GTK_CSS_BACKGROUND_HORIZONTAL(repeat) ((repeat) & GTK_CSS_BACKGROUND_REPEAT_MASK)
#define GTK_CSS_BACKGROUND_VERTICAL(repeat) (((repeat) >> GTK_CSS_BACKGROUND_REPEAT_SHIFT) & GTK_CSS_BACKGROUND_REPEAT_MASK)
typedef enum /*< enum >*/
{
GTK_CSS_BACKGROUND_INVALID, /*< skip >*/
GTK_CSS_BACKGROUND_REPEAT, /* start at one so we know if a value has been set */
GTK_CSS_BACKGROUND_SPACE,
GTK_CSS_BACKGROUND_ROUND,
GTK_CSS_BACKGROUND_NO_REPEAT,
/* need to hardcode the numer or glib-mkenums makes us into a flags type */
GTK_CSS_BACKGROUND_REPEAT_X = 1025,
GTK_CSS_BACKGROUND_REPEAT_Y = 260
} GtkCssBackgroundRepeat;
typedef enum {
GTK_CSS_REPEAT_STYLE_STRETCH,
GTK_CSS_REPEAT_STYLE_REPEAT,
GTK_CSS_REPEAT_STYLE_ROUND,
GTK_CSS_REPEAT_STYLE_SPACE
} GtkCssBorderRepeatStyle;
typedef enum /*< skip >*/ {
GTK_CSS_AREA_BORDER_BOX,
GTK_CSS_AREA_PADDING_BOX,
@ -188,7 +161,6 @@ typedef enum /*< skip >*/ {
typedef struct _GtkCssNumber GtkCssNumber;
typedef struct _GtkCssBackgroundSize GtkCssBackgroundSize;
typedef struct _GtkCssBorderImageRepeat GtkCssBorderImageRepeat;
struct _GtkCssNumber {
gdouble value;
@ -202,16 +174,9 @@ struct _GtkCssBackgroundSize {
guint contain :1;
};
struct _GtkCssBorderImageRepeat {
GtkCssBorderRepeatStyle vrepeat;
GtkCssBorderRepeatStyle hrepeat;
};
#define GTK_TYPE_CSS_BACKGROUND_SIZE _gtk_css_background_size_get_type ()
#define GTK_TYPE_CSS_BORDER_IMAGE_REPEAT _gtk_css_border_image_repeat_get_type ()
GType _gtk_css_background_size_get_type (void);
GType _gtk_css_border_image_repeat_get_type (void);
GtkCssChange _gtk_css_change_for_sibling (GtkCssChange match);
GtkCssChange _gtk_css_change_for_child (GtkCssChange match);

View File

@ -289,17 +289,6 @@ _gtk_css_value_new_from_background_size (const GtkCssBackgroundSize *v)
return value;
}
GtkCssValue *
_gtk_css_value_new_from_border_image_repeat (const GtkCssBorderImageRepeat *v)
{
GtkCssValue *value;
value = gtk_css_value_new (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT);
value->u.ptr = g_boxed_copy0 (GTK_TYPE_CSS_BORDER_IMAGE_REPEAT, v);
return value;
}
GtkCssValue *
_gtk_css_value_new_from_border_style (GtkBorderStyle style)
{
@ -532,13 +521,6 @@ _gtk_css_value_get_background_size (const GtkCssValue *value)
return value->u.ptr;
}
const GtkCssBorderImageRepeat *
_gtk_css_value_get_border_image_repeat (const GtkCssValue *value)
{
g_return_val_if_fail (_gtk_css_value_holds (value, GTK_TYPE_CSS_BORDER_IMAGE_REPEAT), NULL);
return value->u.ptr;
}
GtkGradient *
_gtk_css_value_get_gradient (const GtkCssValue *value)
{

View File

@ -89,7 +89,6 @@ GtkCssValue *_gtk_css_value_new_take_symbolic_color (GtkSymbolicColor
GtkCssValue *_gtk_css_value_new_take_pattern (cairo_pattern_t *v);
GtkCssValue *_gtk_css_value_new_take_binding_sets (GPtrArray *array);
GtkCssValue *_gtk_css_value_new_from_background_size (const GtkCssBackgroundSize *v);
GtkCssValue *_gtk_css_value_new_from_border_image_repeat (const GtkCssBorderImageRepeat *v);
void _gtk_css_value_init_gvalue (const GtkCssValue *value,
GValue *g_value);
@ -101,7 +100,6 @@ gpointer _gtk_css_value_get_boxed (const
const char ** _gtk_css_value_get_strv (const GtkCssValue *value);
GtkSymbolicColor *_gtk_css_value_get_symbolic_color (const GtkCssValue *value);
const GtkCssBackgroundSize *_gtk_css_value_get_background_size (const GtkCssValue *value);
const GtkCssBorderImageRepeat *_gtk_css_value_get_border_image_repeat (const GtkCssValue *value);
GtkGradient *_gtk_css_value_get_gradient (const GtkCssValue *value);
G_END_DECLS

View File

@ -23,6 +23,7 @@
#include <gobject/gvaluecollector.h>
#include "gtkstylecontextprivate.h"
#include "gtkcssenginevalueprivate.h"
#include "gtkcssrgbavalueprivate.h"
#include "gtkstylepropertiesprivate.h"
#include "gtktypebuiltins.h"
@ -974,7 +975,6 @@ style_data_lookup (GtkStyleContext *context)
{
GtkStyleContextPrivate *priv;
GtkStyleInfo *info;
GtkCssValue *v;
priv = context->priv;
info = priv->info_stack->data;
@ -1006,11 +1006,9 @@ style_data_lookup (GtkStyleContext *context)
if (priv->theming_engine)
g_object_unref (priv->theming_engine);
v = _gtk_css_computed_values_get_value (info->data->store, GTK_CSS_PROPERTY_ENGINE);
if (v)
priv->theming_engine = _gtk_css_value_dup_object (v);
else
priv->theming_engine = g_object_ref (gtk_theming_engine_load (NULL));
priv->theming_engine = g_object_ref (
_gtk_css_engine_value_get_engine (
_gtk_css_computed_values_get_value (info->data->store, GTK_CSS_PROPERTY_ENGINE)));
return info->data;
}

View File

@ -28,6 +28,7 @@
#include "gtkcssimagevalueprivate.h"
#include "gtkcssshadowsvalueprivate.h"
#include "gtkcsspositionvalueprivate.h"
#include "gtkcssrepeatvalueprivate.h"
#include "gtkcsstypesprivate.h"
#include "gtkthemingengineprivate.h"
@ -160,19 +161,17 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
&& bg->image_rect.width > 0
&& bg->image_rect.height > 0)
{
GtkCssBackgroundRepeat hrepeat, vrepeat;
const GtkCssBackgroundSize *size;
const GtkCssValue *pos;
const GtkCssValue *pos, *repeat;
double image_width, image_height;
double width, height;
GtkCssRepeatStyle hrepeat, vrepeat;
size = _gtk_css_value_get_background_size (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_SIZE));
pos = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_POSITION);
gtk_style_context_get (bg->context, bg->flags,
"background-repeat", &hrepeat,
NULL);
vrepeat = GTK_CSS_BACKGROUND_VERTICAL (hrepeat);
hrepeat = GTK_CSS_BACKGROUND_HORIZONTAL (hrepeat);
repeat = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_REPEAT);
hrepeat = _gtk_css_background_repeat_value_get_x (repeat);
vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
width = bg->image_rect.width;
height = bg->image_rect.height;
@ -193,13 +192,13 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
/* optimization */
if (image_width == width)
hrepeat = GTK_CSS_BACKGROUND_NO_REPEAT;
hrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
if (image_height == height)
vrepeat = GTK_CSS_BACKGROUND_NO_REPEAT;
vrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
cairo_translate (cr, bg->image_rect.x, bg->image_rect.y);
if (hrepeat == GTK_CSS_BACKGROUND_NO_REPEAT && vrepeat == GTK_CSS_BACKGROUND_NO_REPEAT)
if (hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT && vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT)
{
cairo_translate (cr,
_gtk_css_position_value_get_x (pos, width - image_width),
@ -229,24 +228,24 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
* a third step: that other dimension is scaled so that the original
* aspect ratio is restored.
*/
if (hrepeat == GTK_CSS_BACKGROUND_ROUND)
if (hrepeat == GTK_CSS_REPEAT_STYLE_ROUND)
{
double n = round (width / image_width);
n = MAX (1, n);
if (vrepeat != GTK_CSS_BACKGROUND_ROUND
if (vrepeat != GTK_CSS_REPEAT_STYLE_ROUND
/* && vsize == auto (it is by default) */)
image_height *= width / (image_width * n);
image_width = width / n;
}
if (vrepeat == GTK_CSS_BACKGROUND_ROUND)
if (vrepeat == GTK_CSS_REPEAT_STYLE_ROUND)
{
double n = round (height / image_height);
n = MAX (1, n);
if (hrepeat != GTK_CSS_BACKGROUND_ROUND
if (hrepeat != GTK_CSS_REPEAT_STYLE_ROUND
/* && hsize == auto (it is by default) */)
image_width *= height / (image_height * n);
image_height = height / n;
@ -254,7 +253,7 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
/* if hrepeat or vrepeat is 'space', we create a somewhat larger surface
* to store the extra space. */
if (hrepeat == GTK_CSS_BACKGROUND_SPACE)
if (hrepeat == GTK_CSS_REPEAT_STYLE_SPACE)
{
double n = floor (width / image_width);
surface_width = n ? round (width / n) : 0;
@ -262,7 +261,7 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
else
surface_width = round (image_width);
if (vrepeat == GTK_CSS_BACKGROUND_SPACE)
if (vrepeat == GTK_CSS_REPEAT_STYLE_SPACE)
{
double n = floor (height / image_height);
surface_height = n ? round (height / n) : 0;
@ -288,8 +287,8 @@ _gtk_theming_background_paint (GtkThemingBackground *bg,
cairo_rectangle (cr,
0, 0,
hrepeat == GTK_CSS_BACKGROUND_NO_REPEAT ? image_width : width,
vrepeat == GTK_CSS_BACKGROUND_NO_REPEAT ? image_height : height);
hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT ? image_width : width,
vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT ? image_height : height);
cairo_fill (cr);
}
}