mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-02 17:00:19 +00:00
shadow: Rewrite to store contents as values
This commit is contained in:
parent
7bdcba189e
commit
b8ccda4140
@ -21,6 +21,7 @@
|
||||
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssrgbavalueprivate.h"
|
||||
#include "gtkstylecontextprivate.h"
|
||||
#include "gtksymboliccolorprivate.h"
|
||||
@ -31,10 +32,10 @@ struct _GtkCssValue {
|
||||
GTK_CSS_VALUE_BASE
|
||||
guint inset :1;
|
||||
|
||||
gint16 hoffset;
|
||||
gint16 voffset;
|
||||
gint16 radius;
|
||||
gint16 spread;
|
||||
GtkCssValue *hoffset;
|
||||
GtkCssValue *voffset;
|
||||
GtkCssValue *radius;
|
||||
GtkCssValue *spread;
|
||||
|
||||
GtkCssValue *color;
|
||||
};
|
||||
@ -42,6 +43,10 @@ struct _GtkCssValue {
|
||||
static void
|
||||
gtk_css_value_shadow_free (GtkCssValue *shadow)
|
||||
{
|
||||
_gtk_css_value_unref (shadow->hoffset);
|
||||
_gtk_css_value_unref (shadow->voffset);
|
||||
_gtk_css_value_unref (shadow->radius);
|
||||
_gtk_css_value_unref (shadow->spread);
|
||||
_gtk_css_value_unref (shadow->color);
|
||||
|
||||
g_slice_free (GtkCssValue, shadow);
|
||||
@ -67,20 +72,28 @@ static void
|
||||
gtk_css_value_shadow_print (const GtkCssValue *shadow,
|
||||
GString *string)
|
||||
{
|
||||
if (shadow->inset)
|
||||
g_string_append (string, "inset ");
|
||||
_gtk_css_value_print (shadow->hoffset, string);
|
||||
g_string_append_c (string, ' ');
|
||||
_gtk_css_value_print (shadow->voffset, string);
|
||||
g_string_append_c (string, ' ');
|
||||
if (_gtk_css_number_value_get (shadow->radius, 100) != 0 ||
|
||||
_gtk_css_number_value_get (shadow->spread, 100) != 0)
|
||||
{
|
||||
_gtk_css_value_print (shadow->radius, string);
|
||||
g_string_append_c (string, ' ');
|
||||
}
|
||||
|
||||
g_string_append_printf (string, "%d %d ",
|
||||
(gint) shadow->hoffset,
|
||||
(gint) shadow->voffset);
|
||||
|
||||
if (shadow->radius != 0)
|
||||
g_string_append_printf (string, "%d ", (gint) shadow->radius);
|
||||
|
||||
if (shadow->spread != 0)
|
||||
g_string_append_printf (string, "%d ", (gint) shadow->spread);
|
||||
if (_gtk_css_number_value_get (shadow->spread, 100) != 0)
|
||||
{
|
||||
_gtk_css_value_print (shadow->spread, string);
|
||||
g_string_append_c (string, ' ');
|
||||
}
|
||||
|
||||
_gtk_css_value_print (shadow->color, string);
|
||||
|
||||
if (shadow->inset)
|
||||
g_string_append (string, " inset");
|
||||
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_SHADOW = {
|
||||
@ -91,11 +104,11 @@ static const GtkCssValueClass GTK_CSS_VALUE_SHADOW = {
|
||||
};
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_shadow_value_new (gdouble hoffset,
|
||||
gdouble voffset,
|
||||
gdouble radius,
|
||||
gdouble spread,
|
||||
gboolean inset,
|
||||
gtk_css_shadow_value_new (GtkCssValue *hoffset,
|
||||
GtkCssValue *voffset,
|
||||
GtkCssValue *radius,
|
||||
GtkCssValue *spread,
|
||||
gboolean inset,
|
||||
GtkCssValue *color)
|
||||
{
|
||||
GtkCssValue *retval;
|
||||
@ -112,72 +125,119 @@ gtk_css_shadow_value_new (gdouble hoffset,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
value_is_done_parsing (GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_parser_is_eof (parser) ||
|
||||
_gtk_css_parser_begins_with (parser, ',') ||
|
||||
_gtk_css_parser_begins_with (parser, ';') ||
|
||||
_gtk_css_parser_begins_with (parser, '}');
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_shadow_value_parse (GtkCssParser *parser)
|
||||
{
|
||||
gboolean have_inset, have_color, have_lengths;
|
||||
gdouble hoffset, voffset, blur, spread;
|
||||
GtkSymbolicColor *color;
|
||||
enum {
|
||||
HOFFSET,
|
||||
VOFFSET,
|
||||
RADIUS,
|
||||
SPREAD,
|
||||
COLOR,
|
||||
N_VALUES
|
||||
};
|
||||
GtkCssValue *values[N_VALUES] = { NULL, };
|
||||
gboolean inset;
|
||||
guint i;
|
||||
|
||||
have_inset = have_lengths = have_color = FALSE;
|
||||
inset = _gtk_css_parser_try (parser, "inset", TRUE);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
do
|
||||
{
|
||||
if (values[HOFFSET] == NULL &&
|
||||
_gtk_css_parser_has_number (parser))
|
||||
{
|
||||
values[HOFFSET] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH
|
||||
| GTK_CSS_NUMBER_AS_PIXELS);
|
||||
if (values[HOFFSET] == NULL)
|
||||
goto fail;
|
||||
|
||||
values[VOFFSET] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH
|
||||
| GTK_CSS_NUMBER_AS_PIXELS);
|
||||
if (values[VOFFSET] == NULL)
|
||||
goto fail;
|
||||
|
||||
if (_gtk_css_parser_has_number (parser))
|
||||
{
|
||||
values[RADIUS] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH
|
||||
| GTK_CSS_POSITIVE_ONLY
|
||||
| GTK_CSS_NUMBER_AS_PIXELS);
|
||||
if (values[RADIUS] == NULL)
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
values[RADIUS] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
|
||||
|
||||
if (_gtk_css_parser_has_number (parser))
|
||||
{
|
||||
values[SPREAD] = _gtk_css_number_value_parse (parser,
|
||||
GTK_CSS_PARSE_LENGTH
|
||||
| GTK_CSS_NUMBER_AS_PIXELS);
|
||||
if (values[SPREAD] == NULL)
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
values[SPREAD] = _gtk_css_number_value_new (0.0, GTK_CSS_PX);
|
||||
}
|
||||
else if (!inset && _gtk_css_parser_try (parser, "inset", TRUE))
|
||||
{
|
||||
if (values[HOFFSET] == NULL)
|
||||
goto fail;
|
||||
inset = TRUE;
|
||||
break;
|
||||
}
|
||||
else if (values[COLOR] == NULL)
|
||||
{
|
||||
GtkSymbolicColor *symbolic;
|
||||
|
||||
if (_gtk_css_parser_try (parser, "currentcolor", TRUE))
|
||||
symbolic = gtk_symbolic_color_ref (_gtk_symbolic_color_get_current_color ());
|
||||
else
|
||||
symbolic = _gtk_css_parser_read_symbolic_color (parser);
|
||||
if (symbolic == NULL)
|
||||
goto fail;
|
||||
|
||||
values[COLOR] = _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 */
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
while (values[HOFFSET] == NULL || !value_is_done_parsing (parser));
|
||||
|
||||
if (values[COLOR] == NULL)
|
||||
values[COLOR] = _gtk_css_value_new_take_symbolic_color (
|
||||
gtk_symbolic_color_ref (
|
||||
_gtk_symbolic_color_get_current_color ()));
|
||||
|
||||
return gtk_css_shadow_value_new (values[HOFFSET], values[VOFFSET],
|
||||
values[RADIUS], values[SPREAD],
|
||||
inset, values[COLOR]);
|
||||
|
||||
fail:
|
||||
for (i = 0; i < N_VALUES; i++)
|
||||
{
|
||||
if (!have_inset &&
|
||||
_gtk_css_parser_try (parser, "inset", TRUE))
|
||||
{
|
||||
have_inset = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!have_lengths &&
|
||||
_gtk_css_parser_try_double (parser, &hoffset))
|
||||
{
|
||||
have_lengths = TRUE;
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &voffset))
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Horizontal and vertical offsets are required");
|
||||
if (have_color)
|
||||
gtk_symbolic_color_unref (color);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &blur))
|
||||
blur = 0;
|
||||
|
||||
if (!_gtk_css_parser_try_double (parser, &spread))
|
||||
spread = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!have_color)
|
||||
{
|
||||
have_color = TRUE;
|
||||
|
||||
/* XXX: the color is optional and UA-defined if it's missing,
|
||||
* but it doesn't really make sense for us...
|
||||
*/
|
||||
color = _gtk_css_parser_read_symbolic_color (parser);
|
||||
|
||||
if (color == NULL)
|
||||
return NULL;
|
||||
}
|
||||
if (values[i])
|
||||
_gtk_css_value_unref (values[i]);
|
||||
}
|
||||
|
||||
if (!have_color || !have_lengths)
|
||||
{
|
||||
_gtk_css_parser_error (parser, "Must specify at least color and offsets");
|
||||
if (have_color)
|
||||
gtk_symbolic_color_unref (color);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gtk_css_shadow_value_new (hoffset, voffset,
|
||||
blur, spread, have_inset,
|
||||
_gtk_css_value_new_take_symbolic_color (color));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
@ -193,8 +253,11 @@ _gtk_css_shadow_value_compute (GtkCssValue *shadow,
|
||||
context,
|
||||
FALSE);
|
||||
|
||||
return gtk_css_shadow_value_new (shadow->hoffset, shadow->voffset,
|
||||
shadow->radius, shadow->spread, shadow->inset,
|
||||
return gtk_css_shadow_value_new (_gtk_css_number_value_compute (shadow->hoffset, context),
|
||||
_gtk_css_number_value_compute (shadow->voffset, context),
|
||||
_gtk_css_number_value_compute (shadow->radius, context),
|
||||
_gtk_css_number_value_compute (shadow->spread, context),
|
||||
shadow->inset,
|
||||
color);
|
||||
}
|
||||
|
||||
@ -210,11 +273,15 @@ _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_rel_move_to (cr, shadow->hoffset, shadow->voffset);
|
||||
cairo_rel_move_to (cr,
|
||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
_gtk_css_number_value_get (shadow->voffset, 0));
|
||||
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
||||
_gtk_pango_fill_layout (cr, layout);
|
||||
|
||||
cairo_rel_move_to (cr, -shadow->hoffset, -shadow->voffset);
|
||||
cairo_rel_move_to (cr,
|
||||
- _gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
- _gtk_css_number_value_get (shadow->voffset, 0));
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
@ -230,7 +297,9 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
|
||||
pattern = cairo_pattern_reference (cairo_get_source (cr));
|
||||
gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
|
||||
|
||||
cairo_translate (cr, shadow->hoffset, shadow->voffset);
|
||||
cairo_translate (cr,
|
||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
_gtk_css_number_value_get (shadow->voffset, 0));
|
||||
cairo_mask (cr, pattern);
|
||||
|
||||
cairo_restore (cr);
|
||||
@ -247,7 +316,9 @@ _gtk_css_shadow_value_paint_spinner (const GtkCssValue *shadow,
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_translate (cr, shadow->hoffset, shadow->voffset);
|
||||
cairo_translate (cr,
|
||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
_gtk_css_number_value_get (shadow->voffset, 0));
|
||||
_gtk_theming_engine_paint_spinner (cr,
|
||||
radius, progress,
|
||||
_gtk_css_rgba_value_get_rgba (shadow->color));
|
||||
@ -261,6 +332,7 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
|
||||
const GtkRoundedBox *padding_box)
|
||||
{
|
||||
GtkRoundedBox box;
|
||||
double spread;
|
||||
|
||||
g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
|
||||
|
||||
@ -271,10 +343,11 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
|
||||
cairo_clip (cr);
|
||||
|
||||
box = *padding_box;
|
||||
_gtk_rounded_box_move (&box, shadow->hoffset, shadow->voffset);
|
||||
_gtk_rounded_box_shrink (&box,
|
||||
shadow->spread, shadow->spread,
|
||||
shadow->spread, shadow->spread);
|
||||
_gtk_rounded_box_move (&box,
|
||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
_gtk_css_number_value_get (shadow->voffset, 0));
|
||||
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||
_gtk_rounded_box_shrink (&box, spread, spread, spread, spread);
|
||||
|
||||
_gtk_rounded_box_path (&box, cr);
|
||||
_gtk_rounded_box_clip_path (padding_box, cr);
|
||||
|
Loading…
Reference in New Issue
Block a user