css: Convert border-radius to GtkCssNumber

We can do % now, wohoo!
This commit is contained in:
Benjamin Otte 2012-01-15 06:26:08 +01:00
parent 82c2dad178
commit a63ff72406
8 changed files with 105 additions and 71 deletions

View File

@ -133,13 +133,15 @@ parse_border_radius (GtkCssShorthandProperty *shorthand,
for (i = 0; i < G_N_ELEMENTS (borders); i++) for (i = 0; i < G_N_ELEMENTS (borders); i++)
{ {
if (!_gtk_css_parser_try_double (parser, &borders[i].horizontal)) if (!_gtk_css_parser_has_number (parser))
break; break;
if (borders[i].horizontal < 0) if (!_gtk_css_parser_read_number (parser,
{ &borders[i].horizontal,
_gtk_css_parser_error (parser, "Border radius values cannot be negative"); GTK_CSS_POSITIVE_ONLY
return FALSE; | GTK_CSS_PARSE_PERCENT
} | GTK_CSS_NUMBER_AS_PIXELS
| GTK_CSS_PARSE_LENGTH))
return FALSE;
} }
if (i == 0) if (i == 0)
@ -157,13 +159,15 @@ parse_border_radius (GtkCssShorthandProperty *shorthand,
{ {
for (i = 0; i < G_N_ELEMENTS (borders); i++) for (i = 0; i < G_N_ELEMENTS (borders); i++)
{ {
if (!_gtk_css_parser_try_double (parser, &borders[i].vertical)) if (!_gtk_css_parser_has_number (parser))
break; break;
if (borders[i].vertical < 0) if (!_gtk_css_parser_read_number (parser,
{ &borders[i].vertical,
_gtk_css_parser_error (parser, "Border radius values cannot be negative"); GTK_CSS_POSITIVE_ONLY
return FALSE; | GTK_CSS_PARSE_PERCENT
} | GTK_CSS_NUMBER_AS_PIXELS
| GTK_CSS_PARSE_LENGTH))
return FALSE;
} }
if (i == 0) if (i == 0)
@ -638,7 +642,8 @@ unpack_border_radius (GtkCssShorthandProperty *shorthand,
GValue v = G_VALUE_INIT; GValue v = G_VALUE_INIT;
guint i; guint i;
border.horizontal = border.vertical = g_value_get_int (value); _gtk_css_number_init (&border.horizontal, g_value_get_int (value), GTK_CSS_PX);
border.vertical = border.horizontal;
g_value_init (&v, GTK_TYPE_CSS_BORDER_CORNER_RADIUS); g_value_init (&v, GTK_TYPE_CSS_BORDER_CORNER_RADIUS);
g_value_set_boxed (&v, &border); g_value_set_boxed (&v, &border);
@ -664,7 +669,7 @@ pack_border_radius (GtkCssShorthandProperty *shorthand,
{ {
top_left = g_value_get_boxed (v); top_left = g_value_get_boxed (v);
if (top_left) if (top_left)
g_value_set_int (value, top_left->horizontal); g_value_set_int (value, top_left->horizontal.value);
} }
} }

View File

@ -100,16 +100,6 @@ gtk_css_style_property_register (const char * name,
/*** HELPERS ***/ /*** HELPERS ***/
static void
string_append_double (GString *string,
double d)
{
char buf[G_ASCII_DTOSTR_BUF_SIZE];
g_ascii_dtostr (buf, sizeof (buf), d);
g_string_append (string, buf);
}
static void static void
string_append_string (GString *str, string_append_string (GString *str,
const char *string) const char *string)
@ -333,25 +323,26 @@ border_corner_radius_value_parse (GtkCssStyleProperty *property,
{ {
GtkCssBorderCornerRadius corner; GtkCssBorderCornerRadius corner;
if (!_gtk_css_parser_try_double (parser, &corner.horizontal)) if (!_gtk_css_parser_read_number (parser,
{ &corner.horizontal,
_gtk_css_parser_error (parser, "Expected a number"); GTK_CSS_POSITIVE_ONLY
return FALSE; | GTK_CSS_PARSE_PERCENT
} | GTK_CSS_NUMBER_AS_PIXELS
else if (corner.horizontal < 0) | GTK_CSS_PARSE_LENGTH))
goto negative; return FALSE;
if (!_gtk_css_parser_try_double (parser, &corner.vertical)) if (!_gtk_css_parser_has_number (parser))
corner.vertical = corner.horizontal; corner.vertical = corner.horizontal;
else if (corner.vertical < 0) else if (!_gtk_css_parser_read_number (parser,
goto negative; &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); g_value_set_boxed (value, &corner);
return TRUE; return TRUE;
negative:
_gtk_css_parser_error (parser, "Border radius values cannot be negative");
return FALSE;
} }
static void static void
@ -363,17 +354,12 @@ border_corner_radius_value_print (GtkCssStyleProperty *property,
corner = g_value_get_boxed (value); corner = g_value_get_boxed (value);
if (corner == NULL) _gtk_css_number_print (&corner->horizontal, string);
{
g_string_append (string, "none");
return;
}
string_append_double (string, corner->horizontal); if (!_gtk_css_number_equal (&corner->horizontal, &corner->vertical))
if (corner->horizontal != corner->vertical)
{ {
g_string_append_c (string, ' '); g_string_append_c (string, ' ');
string_append_double (string, corner->vertical); _gtk_css_number_print (&corner->vertical, string);
} }
} }
@ -558,7 +544,7 @@ _gtk_css_style_property_init_properties (void)
char *default_font_family[] = { "Sans", NULL }; char *default_font_family[] = { "Sans", NULL };
GtkCssNumber number; GtkCssNumber number;
GtkSymbolicColor *symbolic; GtkSymbolicColor *symbolic;
GtkCssBorderCornerRadius no_corner_radius = { 0, }; 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 }; GtkBorder border_of_ones = { 1, 1, 1, 1 };
GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH }; GtkCssBorderImageRepeat border_image_repeat = { GTK_CSS_REPEAT_STYLE_STRETCH, GTK_CSS_REPEAT_STYLE_STRETCH };

View File

@ -45,6 +45,24 @@ _gtk_css_number_init (GtkCssNumber *number,
number->unit = unit; number->unit = unit;
} }
gboolean
_gtk_css_number_equal (const GtkCssNumber *one,
const GtkCssNumber *two)
{
return one->unit == two->unit &&
one->value == two->value;
}
double
_gtk_css_number_get (const GtkCssNumber *number,
double one_hundred_percent)
{
if (number->unit == GTK_CSS_PERCENT)
return number->value * one_hundred_percent * 0.01;
else
return number->value;
}
void void
_gtk_css_number_compute (GtkCssNumber *dest, _gtk_css_number_compute (GtkCssNumber *dest,
const GtkCssNumber *src, const GtkCssNumber *src,

View File

@ -104,8 +104,8 @@ struct _GtkCssNumber {
}; };
struct _GtkCssBorderCornerRadius { struct _GtkCssBorderCornerRadius {
double horizontal; GtkCssNumber horizontal;
double vertical; GtkCssNumber vertical;
}; };
struct _GtkCssBorderImageRepeat { struct _GtkCssBorderImageRepeat {
@ -125,6 +125,10 @@ GType _gtk_css_number_get_type (void);
void _gtk_css_number_init (GtkCssNumber *number, void _gtk_css_number_init (GtkCssNumber *number,
double value, double value,
GtkCssUnit unit); GtkCssUnit unit);
gboolean _gtk_css_number_equal (const GtkCssNumber *one,
const GtkCssNumber *two);
double _gtk_css_number_get (const GtkCssNumber *number,
double one_hundred_percent);
void _gtk_css_number_compute (GtkCssNumber *dest, void _gtk_css_number_compute (GtkCssNumber *dest,
const GtkCssNumber *src, const GtkCssNumber *src,
GtkStyleContext *context); GtkStyleContext *context);

View File

@ -94,13 +94,33 @@ _gtk_rounded_box_apply_border_radius (GtkRoundedBox *box,
NULL); NULL);
if (corner[GTK_CSS_TOP_LEFT] && (junction & GTK_JUNCTION_CORNER_TOPLEFT) == 0) if (corner[GTK_CSS_TOP_LEFT] && (junction & GTK_JUNCTION_CORNER_TOPLEFT) == 0)
box->corner[GTK_CSS_TOP_LEFT] = *corner[GTK_CSS_TOP_LEFT]; {
box->corner[GTK_CSS_TOP_LEFT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_TOP_LEFT]->horizontal,
box->box.width);
box->corner[GTK_CSS_TOP_LEFT].vertical = _gtk_css_number_get (&corner[GTK_CSS_TOP_LEFT]->vertical,
box->box.height);
}
if (corner[GTK_CSS_TOP_RIGHT] && (junction & GTK_JUNCTION_CORNER_TOPRIGHT) == 0) if (corner[GTK_CSS_TOP_RIGHT] && (junction & GTK_JUNCTION_CORNER_TOPRIGHT) == 0)
box->corner[GTK_CSS_TOP_RIGHT] = *corner[GTK_CSS_TOP_RIGHT]; {
box->corner[GTK_CSS_TOP_RIGHT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_TOP_RIGHT]->horizontal,
box->box.width);
box->corner[GTK_CSS_TOP_RIGHT].vertical = _gtk_css_number_get (&corner[GTK_CSS_TOP_RIGHT]->vertical,
box->box.height);
}
if (corner[GTK_CSS_BOTTOM_RIGHT] && (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT) == 0) if (corner[GTK_CSS_BOTTOM_RIGHT] && (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT) == 0)
box->corner[GTK_CSS_BOTTOM_RIGHT] = *corner[GTK_CSS_BOTTOM_RIGHT]; {
box->corner[GTK_CSS_BOTTOM_RIGHT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_RIGHT]->horizontal,
box->box.width);
box->corner[GTK_CSS_BOTTOM_RIGHT].vertical = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_RIGHT]->vertical,
box->box.height);
}
if (corner[GTK_CSS_BOTTOM_LEFT] && (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT) == 0) if (corner[GTK_CSS_BOTTOM_LEFT] && (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT) == 0)
box->corner[GTK_CSS_BOTTOM_LEFT] = *corner[GTK_CSS_BOTTOM_LEFT]; {
box->corner[GTK_CSS_BOTTOM_LEFT].horizontal = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_LEFT]->horizontal,
box->box.width);
box->corner[GTK_CSS_BOTTOM_LEFT].vertical = _gtk_css_number_get (&corner[GTK_CSS_BOTTOM_LEFT]->vertical,
box->box.height);
}
gtk_rounded_box_clamp_border_radius (box); gtk_rounded_box_clamp_border_radius (box);
@ -109,9 +129,9 @@ _gtk_rounded_box_apply_border_radius (GtkRoundedBox *box,
} }
static void static void
gtk_css_border_radius_grow (GtkCssBorderCornerRadius *corner, gtk_css_border_radius_grow (GtkRoundedBoxCorner *corner,
double horizontal, double horizontal,
double vertical) double vertical)
{ {
corner->horizontal += horizontal; corner->horizontal += horizontal;
corner->vertical += vertical; corner->vertical += vertical;

View File

@ -30,11 +30,17 @@
G_BEGIN_DECLS G_BEGIN_DECLS
typedef struct _GtkRoundedBox GtkRoundedBox; typedef struct _GtkRoundedBox GtkRoundedBox;
typedef struct _GtkRoundedBoxCorner GtkRoundedBoxCorner;
struct _GtkRoundedBoxCorner {
double horizontal;
double vertical;
};
struct _GtkRoundedBox { struct _GtkRoundedBox {
/*< private >*/ /*< private >*/
cairo_rectangle_t box; cairo_rectangle_t box;
GtkCssBorderCornerRadius corner[4]; GtkRoundedBoxCorner corner[4];
}; };
void _gtk_rounded_box_init_rect (GtkRoundedBox *box, void _gtk_rounded_box_init_rect (GtkRoundedBox *box,

View File

@ -2378,14 +2378,9 @@ _gtk_style_context_get_number (GtkStyleContext *context,
double one_hundred_percent) double one_hundred_percent)
{ {
const GValue *value; const GValue *value;
const GtkCssNumber *number;
value = _gtk_style_context_peek_property (context, property_name); value = _gtk_style_context_peek_property (context, property_name);
number = g_value_get_boxed (value); return _gtk_css_number_get (g_value_get_boxed (value), one_hundred_percent);
if (number->unit == GTK_CSS_PERCENT)
return number->value * one_hundred_percent * 0.01;
else
return number->value;
} }
const GValue * const GValue *

View File

@ -2223,10 +2223,10 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
wc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0); wc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
hc = border_width; hc = border_width;
if (xy0_gap < top_left_radius->horizontal) if (xy0_gap < _gtk_css_number_get (&top_left_radius->horizontal, width))
junction |= GTK_JUNCTION_CORNER_TOPLEFT; junction |= GTK_JUNCTION_CORNER_TOPLEFT;
if (xy1_gap > width - top_right_radius->horizontal) if (xy1_gap > width - _gtk_css_number_get (&top_right_radius->horizontal, width))
junction |= GTK_JUNCTION_CORNER_TOPRIGHT; junction |= GTK_JUNCTION_CORNER_TOPRIGHT;
break; break;
case GTK_POS_BOTTOM: case GTK_POS_BOTTOM:
@ -2235,10 +2235,10 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
wc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0); wc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
hc = border_width; hc = border_width;
if (xy0_gap < bottom_left_radius->horizontal) if (xy0_gap < _gtk_css_number_get (&bottom_left_radius->horizontal, width))
junction |= GTK_JUNCTION_CORNER_BOTTOMLEFT; junction |= GTK_JUNCTION_CORNER_BOTTOMLEFT;
if (xy1_gap > width - bottom_right_radius->horizontal) if (xy1_gap > width - _gtk_css_number_get (&bottom_right_radius->horizontal, width))
junction |= GTK_JUNCTION_CORNER_BOTTOMRIGHT; junction |= GTK_JUNCTION_CORNER_BOTTOMRIGHT;
break; break;
@ -2248,10 +2248,10 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
wc = border_width; wc = border_width;
hc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0); hc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
if (xy0_gap < top_left_radius->vertical) if (xy0_gap < _gtk_css_number_get (&top_left_radius->vertical, height))
junction |= GTK_JUNCTION_CORNER_TOPLEFT; junction |= GTK_JUNCTION_CORNER_TOPLEFT;
if (xy1_gap > height - bottom_left_radius->vertical) if (xy1_gap > height - _gtk_css_number_get (&bottom_left_radius->vertical, height))
junction |= GTK_JUNCTION_CORNER_BOTTOMLEFT; junction |= GTK_JUNCTION_CORNER_BOTTOMLEFT;
break; break;
@ -2261,10 +2261,10 @@ gtk_theming_engine_render_frame_gap (GtkThemingEngine *engine,
wc = border_width; wc = border_width;
hc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0); hc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
if (xy0_gap < top_right_radius->vertical) if (xy0_gap < _gtk_css_number_get (&top_right_radius->vertical, height))
junction |= GTK_JUNCTION_CORNER_TOPRIGHT; junction |= GTK_JUNCTION_CORNER_TOPRIGHT;
if (xy1_gap > height - bottom_right_radius->vertical) if (xy1_gap > height - _gtk_css_number_get (&bottom_right_radius->vertical, height))
junction |= GTK_JUNCTION_CORNER_BOTTOMRIGHT; junction |= GTK_JUNCTION_CORNER_BOTTOMRIGHT;
break; break;