[StThemeNode] Add text-shadow property

Reorganize the existing code which parses the -st-shadow property
to allow parsing different shadow properties and add support for
the text-shadow property.

https://bugzilla.gnome.org/show_bug.cgi?id=624384
This commit is contained in:
Florian Müllner 2010-07-24 16:56:50 +02:00
parent e942444630
commit 29781b2e5c
3 changed files with 138 additions and 51 deletions

View File

@ -47,6 +47,7 @@ struct _StThemeNode {
char *background_image; char *background_image;
StBorderImage *border_image; StBorderImage *border_image;
StShadow *shadow; StShadow *shadow;
StShadow *text_shadow;
GType element_type; GType element_type;
char *element_id; char *element_id;
@ -66,6 +67,7 @@ struct _StThemeNode {
guint foreground_computed : 1; guint foreground_computed : 1;
guint border_image_computed : 1; guint border_image_computed : 1;
guint shadow_computed : 1; guint shadow_computed : 1;
guint text_shadow_computed : 1;
guint link_type : 2; guint link_type : 2;
/* Graphics state */ /* Graphics state */

View File

@ -103,6 +103,12 @@ st_theme_node_finalize (GObject *object)
node->shadow = NULL; node->shadow = NULL;
} }
if (node->text_shadow)
{
st_shadow_unref (node->text_shadow);
node->text_shadow = NULL;
}
if (node->background_image) if (node->background_image)
g_free (node->background_image); g_free (node->background_image);
@ -2452,6 +2458,72 @@ st_theme_node_get_vertical_padding (StThemeNode *node)
return padding; return padding;
} }
static void
parse_shadow_property (StThemeNode *node,
CRDeclaration *decl,
ClutterColor *color,
gdouble *xoffset,
gdouble *yoffset,
gdouble *blur,
gdouble *spread)
{
/* Set value for width/color/blur in any order */
CRTerm *term;
int n_offsets = 0;
/* default values */
color->red = 0x0; color->green = 0x0; color->blue = 0x0; color->alpha = 0xff;
*xoffset = 0.;
*yoffset = 0.;
*blur = 0.;
*spread = 0.;
for (term = decl->value; term; term = term->next)
{
GetFromTermResult result;
if (term->type == TERM_NUMBER)
{
gdouble value;
gdouble multiplier;
multiplier = (term->unary_op == MINUS_UOP) ? -1. : 1.;
result = get_length_from_term (node, term, FALSE, &value);
if (result != VALUE_NOT_FOUND)
{
switch (n_offsets++)
{
case 0:
*xoffset = multiplier * value;
break;
case 1:
*yoffset = multiplier * value;
break;
case 2:
if (multiplier < 0)
g_warning ("Negative blur values are "
"not allowed");
*blur = value;
break;
case 3:
if (multiplier < 0)
g_warning ("Negative spread values are "
"not allowed");
*spread = value;
break;
}
continue;
}
}
result = get_color_from_term (node, term, color);
if (result != VALUE_NOT_FOUND)
{
continue;
}
}
}
/** /**
* st_theme_node_get_shadow: * st_theme_node_get_shadow:
* @node: a #StThemeNode * @node: a #StThemeNode
@ -2480,59 +2552,15 @@ st_theme_node_get_shadow (StThemeNode *node)
if (strcmp (decl->property->stryng->str, "-st-shadow") == 0) if (strcmp (decl->property->stryng->str, "-st-shadow") == 0)
{ {
/* Set value for width/color/blur in any order */ ClutterColor color;
CRTerm *term; gdouble xoffset;
ClutterColor color = { 0x0, 0x0, 0x0, 0xff }; gdouble yoffset;
gdouble xoffset = 0.; gdouble blur;
gdouble yoffset = 0.; gdouble spread;
gdouble blur = 0.;
gdouble spread = 0.;
int n_offsets = 0;
for (term = decl->value; term; term = term->next) parse_shadow_property (node, decl,
{ &color, &xoffset, &yoffset, &blur, &spread);
GetFromTermResult result;
if (term->type == TERM_NUMBER)
{
gdouble value;
gdouble multiplier;
multiplier = (term->unary_op == MINUS_UOP) ? -1. : 1.;
result = get_length_from_term (node, term, FALSE, &value);
if (result != VALUE_NOT_FOUND)
{
switch (n_offsets++)
{
case 0:
xoffset = multiplier * value;
break;
case 1:
yoffset = multiplier * value;
break;
case 2:
if (multiplier < 0)
g_warning ("Negative blur values are "
"not allowed");
blur = value;
break;
case 3:
if (multiplier < 0)
g_warning ("Negative spread values are "
"not allowed");
spread = value;
break;
}
continue;
}
}
result = get_color_from_term (node, term, &color);
if (result != VALUE_NOT_FOUND)
{
continue;
}
}
node->shadow = st_shadow_new (&color, node->shadow = st_shadow_new (&color,
xoffset, yoffset, xoffset, yoffset,
blur, spread); blur, spread);
@ -2543,6 +2571,62 @@ st_theme_node_get_shadow (StThemeNode *node)
return NULL; return NULL;
} }
/**
* st_theme_node_get_text_shadow:
* @node: a #StThemeNode
*
* Gets the value for the text-shadow style property
*
* Return value: (transfer none): the node's text-shadow, or %NULL
* if node has no text-shadow
*/
StShadow *
st_theme_node_get_text_shadow (StThemeNode *node)
{
StShadow *result = NULL;
int i;
if (node->text_shadow_computed)
return node->text_shadow;
ensure_properties (node);
for (i = node->n_properties - 1; i >= 0; i--)
{
CRDeclaration *decl = node->properties[i];
if (strcmp (decl->property->stryng->str, "text-shadow") == 0)
{
ClutterColor color;
gdouble xoffset;
gdouble yoffset;
gdouble blur;
gdouble spread;
parse_shadow_property (node, decl,
&color, &xoffset, &yoffset, &blur, &spread);
result = st_shadow_new (&color,
xoffset, yoffset,
blur, spread);
break;
}
}
if (!result && node->parent_node)
{
result = st_theme_node_get_text_shadow (node->parent_node);
if (result)
st_shadow_ref (result);
}
node->text_shadow = result;
node->text_shadow_computed = TRUE;
return result;
}
static float static float
get_width_inc (StThemeNode *node) get_width_inc (StThemeNode *node)
{ {

View File

@ -167,6 +167,7 @@ const PangoFontDescription *st_theme_node_get_font (StThemeNode *node);
StBorderImage *st_theme_node_get_border_image (StThemeNode *node); StBorderImage *st_theme_node_get_border_image (StThemeNode *node);
StShadow *st_theme_node_get_shadow (StThemeNode *node); StShadow *st_theme_node_get_shadow (StThemeNode *node);
StShadow *st_theme_node_get_text_shadow (StThemeNode *node);
/* Helpers for get_preferred_width()/get_preferred_height() ClutterActor vfuncs */ /* Helpers for get_preferred_width()/get_preferred_height() ClutterActor vfuncs */
void st_theme_node_adjust_for_height (StThemeNode *node, void st_theme_node_adjust_for_height (StThemeNode *node,