forked from AuroraMiddleware/gtk
Remove GtkCssShadowsValue
Previously, we wrapped all GtkCssShadowValues in a GtkCssShadowsValue, even if it was just one shadow. This causes an unnecessary bloat in css values. Make each GtkCssShadowValue able to handle multiple shadows instead, and use gtk_css_shadow_value* API everywhere.
This commit is contained in:
parent
a3769eb0e5
commit
45455f1bdb
@ -1,390 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* Author: Cosimo Cecchi <cosimoc@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 "gtkcssshadowsvalueprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct _GtkCssValue {
|
||||
GTK_CSS_VALUE_BASE
|
||||
guint len;
|
||||
GtkCssValue *values[1];
|
||||
};
|
||||
|
||||
static GtkCssValue * gtk_css_shadows_value_new (GtkCssValue **values,
|
||||
guint len);
|
||||
|
||||
static void
|
||||
gtk_css_value_shadows_free (GtkCssValue *value)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < value->len; i++)
|
||||
{
|
||||
_gtk_css_value_unref (value->values[i]);
|
||||
}
|
||||
|
||||
g_slice_free1 (sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (value->len - 1), value);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_shadows_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GtkCssValue *result, *tmp;
|
||||
guint i, j;
|
||||
|
||||
if (value->len == 0)
|
||||
return _gtk_css_value_ref (value);
|
||||
|
||||
result = NULL;
|
||||
for (i = 0; i < value->len; i++)
|
||||
{
|
||||
tmp = _gtk_css_value_compute (value->values[i], property_id, provider, style, parent_style);
|
||||
|
||||
if (result)
|
||||
{
|
||||
result->values[i] = tmp;
|
||||
}
|
||||
else if (tmp != value->values[i])
|
||||
{
|
||||
result = gtk_css_shadows_value_new (value->values, value->len);
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
_gtk_css_value_ref (result->values[j]);
|
||||
}
|
||||
result->values[i] = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_css_value_unref (tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (result != NULL)
|
||||
return result;
|
||||
else
|
||||
return _gtk_css_value_ref (value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_value_shadows_equal (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
{
|
||||
guint i;
|
||||
|
||||
/* XXX: Should we fill up here? */
|
||||
if (value1->len != value2->len)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < value1->len; i++)
|
||||
{
|
||||
if (!_gtk_css_value_equal (value1->values[i],
|
||||
value2->values[i]))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_shadows_transition (GtkCssValue *start,
|
||||
GtkCssValue *end,
|
||||
guint property_id,
|
||||
double progress)
|
||||
{
|
||||
guint i, len;
|
||||
GtkCssValue **values;
|
||||
|
||||
/* catches the important case of 2 none values */
|
||||
if (start == end)
|
||||
return _gtk_css_value_ref (start);
|
||||
|
||||
if (start->len > end->len)
|
||||
len = start->len;
|
||||
else
|
||||
len = end->len;
|
||||
|
||||
values = g_newa (GtkCssValue *, len);
|
||||
|
||||
for (i = 0; i < MIN (start->len, end->len); i++)
|
||||
{
|
||||
values[i] = _gtk_css_value_transition (start->values[i], end->values[i], property_id, progress);
|
||||
if (values[i] == NULL)
|
||||
{
|
||||
while (i--)
|
||||
_gtk_css_value_unref (values[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (start->len > end->len)
|
||||
{
|
||||
for (; i < len; i++)
|
||||
{
|
||||
GtkCssValue *fill = _gtk_css_shadow_value_new_for_transition (start->values[i]);
|
||||
values[i] = _gtk_css_value_transition (start->values[i], fill, property_id, progress);
|
||||
_gtk_css_value_unref (fill);
|
||||
|
||||
if (values[i] == NULL)
|
||||
{
|
||||
while (i--)
|
||||
_gtk_css_value_unref (values[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; i < len; i++)
|
||||
{
|
||||
GtkCssValue *fill = _gtk_css_shadow_value_new_for_transition (end->values[i]);
|
||||
values[i] = _gtk_css_value_transition (fill, end->values[i], property_id, progress);
|
||||
_gtk_css_value_unref (fill);
|
||||
|
||||
if (values[i] == NULL)
|
||||
{
|
||||
while (i--)
|
||||
_gtk_css_value_unref (values[i]);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return gtk_css_shadows_value_new (values, len);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_value_shadows_print (const GtkCssValue *value,
|
||||
GString *string)
|
||||
{
|
||||
guint i;
|
||||
|
||||
if (value->len == 0)
|
||||
{
|
||||
g_string_append (string, "none");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < value->len; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
g_string_append (string, ", ");
|
||||
_gtk_css_value_print (value->values[i], string);
|
||||
}
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_SHADOWS = {
|
||||
"GtkCssShadowsValue",
|
||||
gtk_css_value_shadows_free,
|
||||
gtk_css_value_shadows_compute,
|
||||
gtk_css_value_shadows_equal,
|
||||
gtk_css_value_shadows_transition,
|
||||
NULL,
|
||||
NULL,
|
||||
gtk_css_value_shadows_print
|
||||
};
|
||||
|
||||
static GtkCssValue none_singleton = { >K_CSS_VALUE_SHADOWS, 1, TRUE, 0, { NULL } };
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_shadows_value_new_none (void)
|
||||
{
|
||||
return _gtk_css_value_ref (&none_singleton);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_shadows_value_new (GtkCssValue **values,
|
||||
guint len)
|
||||
{
|
||||
GtkCssValue *result;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (values != NULL, NULL);
|
||||
g_return_val_if_fail (len > 0, NULL);
|
||||
|
||||
result = _gtk_css_value_alloc (>K_CSS_VALUE_SHADOWS, sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (len - 1));
|
||||
result->len = len;
|
||||
memcpy (&result->values[0], values, sizeof (GtkCssValue *) * len);
|
||||
|
||||
result->is_computed = TRUE;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (!gtk_css_value_is_computed (values[i]))
|
||||
{
|
||||
result->is_computed = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_shadows_value_parse (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode)
|
||||
{
|
||||
GtkCssValue *value, *result;
|
||||
GPtrArray *values;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
return _gtk_css_shadows_value_new_none ();
|
||||
|
||||
values = g_ptr_array_new ();
|
||||
|
||||
do {
|
||||
value = _gtk_css_shadow_value_parse (parser, box_shadow_mode);
|
||||
|
||||
if (value == NULL)
|
||||
{
|
||||
g_ptr_array_set_free_func (values, (GDestroyNotify) _gtk_css_value_unref);
|
||||
g_ptr_array_free (values, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_ptr_array_add (values, value);
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
result = gtk_css_shadows_value_new ((GtkCssValue **) values->pdata, values->len);
|
||||
g_ptr_array_free (values, TRUE);
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_shadows_value_is_none (const GtkCssValue *shadows)
|
||||
{
|
||||
g_return_val_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS, TRUE);
|
||||
|
||||
return shadows->len == 0;
|
||||
}
|
||||
|
||||
gsize
|
||||
gtk_css_shadows_value_get_n_shadows (const GtkCssValue *shadows)
|
||||
{
|
||||
return shadows->len;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_shadows_value_get_shadows (const GtkCssValue *shadows,
|
||||
GskShadow *out_shadows)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < shadows->len; i++)
|
||||
gtk_css_shadow_value_get_shadow (shadows->values[i], &out_shadows[i]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_shadows_value_snapshot_outset (const GtkCssValue *shadows,
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect*border_box)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
|
||||
|
||||
for (i = 0; i < shadows->len; i++)
|
||||
{
|
||||
if (_gtk_css_shadow_value_get_inset (shadows->values[i]))
|
||||
continue;
|
||||
|
||||
gtk_css_shadow_value_snapshot_outset (shadows->values[i], snapshot, border_box);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_shadows_value_snapshot_inset (const GtkCssValue *shadows,
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect*padding_box)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
|
||||
|
||||
for (i = 0; i < shadows->len; i++)
|
||||
{
|
||||
if (!_gtk_css_shadow_value_get_inset (shadows->values[i]))
|
||||
continue;
|
||||
|
||||
gtk_css_shadow_value_snapshot_inset (shadows->values[i], snapshot, padding_box);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
|
||||
GtkBorder *border)
|
||||
{
|
||||
guint i;
|
||||
GtkBorder b = { 0 }, sb;
|
||||
const GtkCssValue *shadow;
|
||||
|
||||
g_return_if_fail (shadows->class == >K_CSS_VALUE_SHADOWS);
|
||||
|
||||
for (i = 0; i < shadows->len; i++)
|
||||
{
|
||||
shadow = shadows->values[i];
|
||||
|
||||
if (_gtk_css_shadow_value_get_inset (shadow))
|
||||
continue;
|
||||
|
||||
gtk_css_shadow_value_get_extents (shadow, &sb);
|
||||
|
||||
b.top = MAX (b.top, sb.top);
|
||||
b.right = MAX (b.right, sb.right);
|
||||
b.bottom = MAX (b.bottom, sb.bottom);
|
||||
b.left = MAX (b.left, sb.left);
|
||||
}
|
||||
|
||||
*border = b;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_shadows_value_push_snapshot (const GtkCssValue *value,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
gboolean need_shadow = FALSE;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < value->len; i++)
|
||||
{
|
||||
if (!gtk_css_shadow_value_is_clear (value->values[i]))
|
||||
{
|
||||
need_shadow = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_shadow)
|
||||
{
|
||||
GskShadow *shadows = g_newa (GskShadow, value->len);
|
||||
gtk_css_shadows_value_get_shadows (value, shadows);
|
||||
gtk_snapshot_push_shadow (snapshot, shadows, value->len);
|
||||
}
|
||||
|
||||
return need_shadow;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2011 Red Hat, Inc.
|
||||
*
|
||||
* Author: Cosimo Cecchi <cosimoc@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/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_SHADOWS_VALUE_H__
|
||||
#define __GTK_CSS_SHADOWS_VALUE_H__
|
||||
|
||||
#include <cairo.h>
|
||||
#include <pango/pango.h>
|
||||
|
||||
#include "gtkborder.h"
|
||||
#include "gtktypes.h"
|
||||
#include "gtkcssparserprivate.h"
|
||||
#include "gtkcssvalueprivate.h"
|
||||
#include "gtkroundedboxprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkCssValue * _gtk_css_shadows_value_new_none (void);
|
||||
GtkCssValue * _gtk_css_shadows_value_parse (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode);
|
||||
|
||||
gboolean _gtk_css_shadows_value_is_none (const GtkCssValue *shadows);
|
||||
|
||||
gsize gtk_css_shadows_value_get_n_shadows (const GtkCssValue *shadows);
|
||||
|
||||
void gtk_css_shadows_value_get_shadows (const GtkCssValue *shadows,
|
||||
GskShadow *out_shadows);
|
||||
|
||||
void gtk_css_shadows_value_snapshot_outset (const GtkCssValue *shadows,
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect *border_box);
|
||||
void gtk_css_shadows_value_snapshot_inset (const GtkCssValue *shadows,
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect *padding_box);
|
||||
|
||||
void _gtk_css_shadows_value_get_extents (const GtkCssValue *shadows,
|
||||
GtkBorder *border);
|
||||
gboolean gtk_css_shadows_value_push_snapshot (const GtkCssValue *shadows,
|
||||
GtkSnapshot *snapshot);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_SHADOWS_VALUE_H__ */
|
@ -33,80 +33,133 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
struct _GtkCssValue {
|
||||
GTK_CSS_VALUE_BASE
|
||||
typedef struct {
|
||||
guint inset :1;
|
||||
|
||||
GtkCssValue *hoffset;
|
||||
GtkCssValue *voffset;
|
||||
GtkCssValue *radius;
|
||||
GtkCssValue *spread;
|
||||
|
||||
GtkCssValue *color;
|
||||
} ShadowValue;
|
||||
|
||||
struct _GtkCssValue {
|
||||
GTK_CSS_VALUE_BASE
|
||||
guint n_shadows;
|
||||
ShadowValue shadows[1];
|
||||
};
|
||||
|
||||
static GtkCssValue * gtk_css_shadow_value_new (GtkCssValue *hoffset,
|
||||
GtkCssValue *voffset,
|
||||
GtkCssValue *radius,
|
||||
GtkCssValue *spread,
|
||||
gboolean inset,
|
||||
GtkCssValue *color);
|
||||
static GtkCssValue * gtk_css_shadow_value_new (ShadowValue *shadows,
|
||||
guint n_shadows);
|
||||
|
||||
static void
|
||||
gtk_css_value_shadow_free (GtkCssValue *shadow)
|
||||
shadow_value_for_transition (ShadowValue *result,
|
||||
gboolean inset)
|
||||
{
|
||||
result->inset = inset;
|
||||
result->hoffset = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
result->voffset = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
result->radius = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
result->spread = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
result->color = gtk_css_color_value_new_transparent ();
|
||||
}
|
||||
|
||||
static void
|
||||
shadow_value_unref (const ShadowValue *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->radius);
|
||||
_gtk_css_value_unref (shadow->color);
|
||||
}
|
||||
|
||||
g_slice_free (GtkCssValue, shadow);
|
||||
static gboolean
|
||||
shadow_value_transition (const ShadowValue *start,
|
||||
const ShadowValue *end,
|
||||
guint property_id,
|
||||
double progress,
|
||||
ShadowValue *result)
|
||||
|
||||
{
|
||||
if (start->inset != end->inset)
|
||||
return FALSE;
|
||||
|
||||
result->inset = start->inset;
|
||||
result->hoffset = _gtk_css_value_transition (start->hoffset, end->hoffset, property_id, progress);
|
||||
result->voffset = _gtk_css_value_transition (start->voffset, end->voffset, property_id, progress);
|
||||
result->radius = _gtk_css_value_transition (start->radius, end->radius, property_id, progress);
|
||||
result->spread = _gtk_css_value_transition (start->spread, end->spread, property_id, progress);
|
||||
result->color = _gtk_css_value_transition (start->color, end->color, property_id, progress);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_value_shadow_free (GtkCssValue *value)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < value->n_shadows; i ++)
|
||||
{
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
shadow_value_unref (shadow);
|
||||
}
|
||||
|
||||
g_slice_free1 (sizeof (GtkCssValue) + sizeof (ShadowValue) * (value->n_shadows - 1), value);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_value_shadow_compute (GtkCssValue *shadow,
|
||||
gtk_css_value_shadow_compute (GtkCssValue *value,
|
||||
guint property_id,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GtkCssValue *hoffset, *voffset, *radius, *spread, *color;
|
||||
guint i;
|
||||
ShadowValue *shadows;
|
||||
|
||||
hoffset = _gtk_css_value_compute (shadow->hoffset, property_id, provider, style, parent_style);
|
||||
voffset = _gtk_css_value_compute (shadow->voffset, property_id, provider, style, parent_style);
|
||||
radius = _gtk_css_value_compute (shadow->radius, property_id, provider, style, parent_style);
|
||||
spread = _gtk_css_value_compute (shadow->spread, property_id, provider, style, parent_style),
|
||||
color = _gtk_css_value_compute (shadow->color, property_id, provider, style, parent_style);
|
||||
shadows = g_alloca (sizeof (ShadowValue) * value->n_shadows);
|
||||
|
||||
if (hoffset == shadow->hoffset &&
|
||||
voffset == shadow->voffset &&
|
||||
radius == shadow->radius &&
|
||||
spread == shadow->spread &&
|
||||
color == shadow->color)
|
||||
for (i = 0; i < value->n_shadows; i++)
|
||||
{
|
||||
_gtk_css_value_unref (hoffset);
|
||||
_gtk_css_value_unref (voffset);
|
||||
_gtk_css_value_unref (radius);
|
||||
_gtk_css_value_unref (spread);
|
||||
_gtk_css_value_unref (color);
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
return _gtk_css_value_ref (shadow);
|
||||
shadows[i].hoffset = _gtk_css_value_compute (shadow->hoffset, property_id, provider, style, parent_style);
|
||||
shadows[i].voffset = _gtk_css_value_compute (shadow->voffset, property_id, provider, style, parent_style);
|
||||
shadows[i].radius = _gtk_css_value_compute (shadow->radius, property_id, provider, style, parent_style);
|
||||
shadows[i].spread = _gtk_css_value_compute (shadow->spread, property_id, provider, style, parent_style),
|
||||
shadows[i].color = _gtk_css_value_compute (shadow->color, property_id, provider, style, parent_style);
|
||||
}
|
||||
|
||||
return gtk_css_shadow_value_new (hoffset, voffset, radius, spread, shadow->inset, color);
|
||||
return gtk_css_shadow_value_new (shadows, value->n_shadows);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_value_shadow_equal (const GtkCssValue *shadow1,
|
||||
const GtkCssValue *shadow2)
|
||||
gtk_css_value_shadow_equal (const GtkCssValue *value1,
|
||||
const GtkCssValue *value2)
|
||||
{
|
||||
return shadow1->inset == shadow2->inset
|
||||
&& _gtk_css_value_equal (shadow1->hoffset, shadow2->hoffset)
|
||||
&& _gtk_css_value_equal (shadow1->voffset, shadow2->voffset)
|
||||
&& _gtk_css_value_equal (shadow1->radius, shadow2->radius)
|
||||
&& _gtk_css_value_equal (shadow1->spread, shadow2->spread)
|
||||
&& _gtk_css_value_equal (shadow1->color, shadow2->color);
|
||||
guint i;
|
||||
|
||||
if (value1->n_shadows != value2->n_shadows)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < value1->n_shadows; i++)
|
||||
{
|
||||
const ShadowValue *shadow1 = &value1->shadows[i];
|
||||
const ShadowValue *shadow2 = &value2->shadows[i];
|
||||
|
||||
if (shadow1->inset != shadow2->inset ||
|
||||
_gtk_css_value_equal (shadow1->hoffset, shadow2->hoffset) ||
|
||||
_gtk_css_value_equal (shadow1->voffset, shadow2->voffset) ||
|
||||
_gtk_css_value_equal (shadow1->radius, shadow2->radius) ||
|
||||
_gtk_css_value_equal (shadow1->spread, shadow2->spread) ||
|
||||
_gtk_css_value_equal (shadow1->color, shadow2->color))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
@ -115,43 +168,112 @@ gtk_css_value_shadow_transition (GtkCssValue *start,
|
||||
guint property_id,
|
||||
double progress)
|
||||
{
|
||||
if (start->inset != end->inset)
|
||||
|
||||
guint i, len;
|
||||
ShadowValue *shadows;
|
||||
|
||||
if (start->n_shadows != end->n_shadows)
|
||||
return NULL;
|
||||
|
||||
return gtk_css_shadow_value_new (_gtk_css_value_transition (start->hoffset, end->hoffset, property_id, progress),
|
||||
_gtk_css_value_transition (start->voffset, end->voffset, property_id, progress),
|
||||
_gtk_css_value_transition (start->radius, end->radius, property_id, progress),
|
||||
_gtk_css_value_transition (start->spread, end->spread, property_id, progress),
|
||||
start->inset,
|
||||
_gtk_css_value_transition (start->color, end->color, property_id, progress));
|
||||
if (start->n_shadows > end->n_shadows)
|
||||
len = start->n_shadows;
|
||||
else
|
||||
len = end->n_shadows;
|
||||
|
||||
shadows = g_newa (ShadowValue, len);
|
||||
|
||||
for (i = 0; i < MIN (start->n_shadows, end->n_shadows); i++)
|
||||
{
|
||||
if (!shadow_value_transition (&start->shadows[i], &end->shadows[i],
|
||||
property_id, progress,
|
||||
&shadows[i]))
|
||||
{
|
||||
while (i--)
|
||||
shadow_value_unref (&shadows[i]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (start->n_shadows > end->n_shadows)
|
||||
{
|
||||
for (; i < len; i++)
|
||||
{
|
||||
ShadowValue fill;
|
||||
|
||||
shadow_value_for_transition (&fill, start->shadows[i].inset);
|
||||
if (!shadow_value_transition (&start->shadows[i], &fill, property_id, progress, &shadows[i]))
|
||||
{
|
||||
while (i--)
|
||||
shadow_value_unref (&shadows[i]);
|
||||
shadow_value_unref (&fill);
|
||||
return NULL;
|
||||
}
|
||||
shadow_value_unref (&fill);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; i < len; i++)
|
||||
{
|
||||
ShadowValue fill;
|
||||
|
||||
shadow_value_for_transition (&fill, end->shadows[i].inset);
|
||||
if (!shadow_value_transition (&fill, &end->shadows[i], property_id, progress, &shadows[i]))
|
||||
{
|
||||
while (i--)
|
||||
shadow_value_unref (&shadows[i]);
|
||||
shadow_value_unref (&fill);
|
||||
return NULL;
|
||||
}
|
||||
shadow_value_unref (&fill);
|
||||
}
|
||||
}
|
||||
|
||||
return gtk_css_shadow_value_new (shadows, len);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_value_shadow_print (const GtkCssValue *shadow,
|
||||
gtk_css_value_shadow_print (const GtkCssValue *value,
|
||||
GString *string)
|
||||
{
|
||||
_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)
|
||||
guint i;
|
||||
|
||||
if (value->n_shadows == 0)
|
||||
{
|
||||
_gtk_css_value_print (shadow->radius, string);
|
||||
g_string_append_c (string, ' ');
|
||||
g_string_append (string, "none");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_gtk_css_number_value_get (shadow->spread, 100) != 0)
|
||||
for (i = 0; i < value->n_shadows; i ++)
|
||||
{
|
||||
_gtk_css_value_print (shadow->spread, string);
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
if (i > 0)
|
||||
g_string_append (string, ", ");
|
||||
|
||||
_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, ' ');
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
_gtk_css_value_print (shadow->color, string);
|
||||
|
||||
if (shadow->inset)
|
||||
g_string_append (string, " inset");
|
||||
|
||||
}
|
||||
|
||||
static const GtkCssValueClass GTK_CSS_VALUE_SHADOW = {
|
||||
@ -165,56 +287,46 @@ static const GtkCssValueClass GTK_CSS_VALUE_SHADOW = {
|
||||
gtk_css_value_shadow_print
|
||||
};
|
||||
|
||||
static GtkCssValue *
|
||||
gtk_css_shadow_value_new (GtkCssValue *hoffset,
|
||||
GtkCssValue *voffset,
|
||||
GtkCssValue *radius,
|
||||
GtkCssValue *spread,
|
||||
gboolean inset,
|
||||
GtkCssValue *color)
|
||||
{
|
||||
GtkCssValue *retval;
|
||||
|
||||
retval = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_SHADOW);
|
||||
|
||||
retval->hoffset = hoffset;
|
||||
retval->voffset = voffset;
|
||||
retval->radius = radius;
|
||||
retval->spread = spread;
|
||||
retval->inset = inset;
|
||||
retval->color = color;
|
||||
retval->is_computed = gtk_css_value_is_computed (hoffset) &&
|
||||
gtk_css_value_is_computed (voffset) &&
|
||||
gtk_css_value_is_computed (radius) &&
|
||||
gtk_css_value_is_computed (spread) &&
|
||||
gtk_css_value_is_computed (color);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static GtkCssValue transition_inset_singleton = { >K_CSS_VALUE_SHADOW, 1, TRUE, .inset = TRUE };
|
||||
static GtkCssValue transition_outset_singleton = { >K_CSS_VALUE_SHADOW, 1, TRUE, .inset = FALSE };
|
||||
static GtkCssValue none_singleton = { >K_CSS_VALUE_SHADOW, 1, TRUE, 0 };
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_shadow_value_new_for_transition (GtkCssValue *target)
|
||||
gtk_css_shadow_value_new_none (void)
|
||||
{
|
||||
GtkCssValue *result;
|
||||
return _gtk_css_value_ref (&none_singleton);
|
||||
}
|
||||
|
||||
g_return_val_if_fail (target->class == >K_CSS_VALUE_SHADOW, NULL);
|
||||
static GtkCssValue *
|
||||
gtk_css_shadow_value_new (ShadowValue *shadows,
|
||||
guint n_shadows)
|
||||
{
|
||||
GtkCssValue *retval;
|
||||
guint i;
|
||||
|
||||
if (target->inset)
|
||||
result = &transition_inset_singleton;
|
||||
else
|
||||
result = &transition_outset_singleton;
|
||||
if (n_shadows == 0)
|
||||
return gtk_css_shadow_value_new_none ();
|
||||
|
||||
if (G_UNLIKELY (!result->hoffset))
|
||||
retval = _gtk_css_value_alloc (>K_CSS_VALUE_SHADOW, sizeof (GtkCssValue) + sizeof (ShadowValue) * (n_shadows - 1));
|
||||
retval->n_shadows = n_shadows;
|
||||
|
||||
memcpy (retval->shadows, shadows, sizeof (ShadowValue) * n_shadows);
|
||||
|
||||
retval->is_computed = TRUE;
|
||||
for (i = 0; i < n_shadows; i++)
|
||||
{
|
||||
result->hoffset = result->voffset = result->spread = result->radius = _gtk_css_number_value_new (0, GTK_CSS_PX);
|
||||
result->color = gtk_css_color_value_new_transparent ();
|
||||
const ShadowValue *shadow = &retval->shadows[i];
|
||||
|
||||
if (!gtk_css_value_is_computed (shadow->hoffset) ||
|
||||
!gtk_css_value_is_computed (shadow->voffset) ||
|
||||
!gtk_css_value_is_computed (shadow->spread) ||
|
||||
!gtk_css_value_is_computed (shadow->radius) ||
|
||||
!gtk_css_value_is_computed (shadow->color))
|
||||
{
|
||||
retval->is_computed = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _gtk_css_value_ref (result);
|
||||
return retval;
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -306,9 +418,10 @@ parse_color (GtkCssParser *parser,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GtkCssValue *
|
||||
_gtk_css_shadow_value_parse (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode)
|
||||
static gboolean
|
||||
_gtk_css_shadow_value_parse_one (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode,
|
||||
ShadowValue *result)
|
||||
{
|
||||
GtkCssValue *values[N_VALUES] = { NULL, };
|
||||
GtkCssValue *color = NULL;
|
||||
@ -333,9 +446,14 @@ _gtk_css_shadow_value_parse (GtkCssParser *parser,
|
||||
if (color == NULL)
|
||||
color = _gtk_css_color_value_new_current_color ();
|
||||
|
||||
return gtk_css_shadow_value_new (values[HOFFSET], values[VOFFSET],
|
||||
values[RADIUS], values[SPREAD],
|
||||
inset, color);
|
||||
result->hoffset = values[HOFFSET];
|
||||
result->voffset = values[VOFFSET];
|
||||
result->spread = values[SPREAD];
|
||||
result->radius = values[RADIUS];
|
||||
result->color = color;
|
||||
result->inset = inset;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < N_VALUES; i++)
|
||||
@ -344,149 +462,250 @@ fail:
|
||||
}
|
||||
g_clear_pointer (&color, gtk_css_value_unref);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define MAX_SHADOWS 64
|
||||
GtkCssValue *
|
||||
_gtk_css_shadow_value_parse (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode)
|
||||
{
|
||||
ShadowValue shadows[MAX_SHADOWS];
|
||||
int n_shadows = 0;
|
||||
int i;
|
||||
|
||||
if (gtk_css_parser_try_ident (parser, "none"))
|
||||
return gtk_css_shadow_value_new_none ();
|
||||
|
||||
do {
|
||||
if (_gtk_css_shadow_value_parse_one (parser, box_shadow_mode, &shadows[n_shadows]))
|
||||
n_shadows++;
|
||||
|
||||
if (n_shadows > MAX_SHADOWS)
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Not more than 64 shadows supported");
|
||||
goto fail;
|
||||
}
|
||||
} while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
|
||||
|
||||
return gtk_css_shadow_value_new (shadows, n_shadows);
|
||||
|
||||
fail:
|
||||
for (i = 0; i < n_shadows; i++)
|
||||
{
|
||||
const ShadowValue *shadow = &shadows[i];
|
||||
|
||||
shadow_value_unref (shadow);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_css_shadow_value_get_inset (const GtkCssValue *shadow)
|
||||
{
|
||||
g_return_val_if_fail (shadow->class == >K_CSS_VALUE_SHADOW, FALSE);
|
||||
|
||||
return shadow->inset;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_shadow_value_get_extents (const GtkCssValue *shadow,
|
||||
gtk_css_shadow_value_get_extents (const GtkCssValue *value,
|
||||
GtkBorder *border)
|
||||
{
|
||||
gdouble hoffset, voffset, spread, radius, clip_radius;
|
||||
guint i;
|
||||
|
||||
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||
radius = _gtk_css_number_value_get (shadow->radius, 0);
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (radius);
|
||||
hoffset = _gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
voffset = _gtk_css_number_value_get (shadow->voffset, 0);
|
||||
memset (border, 0, sizeof (GtkBorder));
|
||||
|
||||
border->top = MAX (0, ceil (clip_radius + spread - voffset));
|
||||
border->right = MAX (0, ceil (clip_radius + spread + hoffset));
|
||||
border->bottom = MAX (0, ceil (clip_radius + spread + voffset));
|
||||
border->left = MAX (0, ceil (clip_radius + spread - hoffset));
|
||||
for (i = 0; i < value->n_shadows; i ++)
|
||||
{
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
double hoffset, voffset, spread, radius, clip_radius;
|
||||
|
||||
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||
radius = _gtk_css_number_value_get (shadow->radius, 0);
|
||||
clip_radius = gsk_cairo_blur_compute_pixels (radius);
|
||||
hoffset = _gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
voffset = _gtk_css_number_value_get (shadow->voffset, 0);
|
||||
|
||||
border->top = MAX (border->top, ceil (clip_radius + spread - voffset));
|
||||
border->right = MAX (border->right, ceil (clip_radius + spread + hoffset));
|
||||
border->bottom = MAX (border->bottom, ceil (clip_radius + spread + voffset));
|
||||
border->left = MAX (border->left, ceil (clip_radius + spread - hoffset));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_shadow_value_get_shadow (const GtkCssValue *value,
|
||||
GskShadow *shadow)
|
||||
{
|
||||
shadow->color = *gtk_css_color_value_get_rgba (value->color);
|
||||
shadow->dx = _gtk_css_number_value_get (value->hoffset, 0);
|
||||
shadow->dy = _gtk_css_number_value_get (value->voffset, 0);
|
||||
shadow->radius = _gtk_css_number_value_get (value->radius, 0);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow,
|
||||
gtk_css_shadow_value_snapshot_outset (const GtkCssValue *value,
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect *border_box)
|
||||
{
|
||||
g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
|
||||
guint i;
|
||||
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color)))
|
||||
return;
|
||||
g_return_if_fail (value->class == >K_CSS_VALUE_SHADOW);
|
||||
|
||||
gtk_snapshot_append_outset_shadow (snapshot,
|
||||
border_box,
|
||||
gtk_css_color_value_get_rgba (shadow->color),
|
||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
_gtk_css_number_value_get (shadow->voffset, 0),
|
||||
_gtk_css_number_value_get (shadow->spread, 0),
|
||||
_gtk_css_number_value_get (shadow->radius, 0));
|
||||
for (i = 0; i < value->n_shadows; i ++)
|
||||
{
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
if (shadow->inset)
|
||||
continue;
|
||||
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color)))
|
||||
continue;
|
||||
|
||||
gtk_snapshot_append_outset_shadow (snapshot,
|
||||
border_box,
|
||||
gtk_css_color_value_get_rgba (shadow->color),
|
||||
_gtk_css_number_value_get (shadow->hoffset, 0),
|
||||
_gtk_css_number_value_get (shadow->voffset, 0),
|
||||
_gtk_css_number_value_get (shadow->spread, 0),
|
||||
_gtk_css_number_value_get (shadow->radius, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow,
|
||||
gtk_css_shadow_value_snapshot_inset (const GtkCssValue *value,
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect *padding_box)
|
||||
{
|
||||
guint i;
|
||||
double dx, dy, spread, radius;
|
||||
const GdkRGBA *color;
|
||||
|
||||
g_return_if_fail (shadow->class == >K_CSS_VALUE_SHADOW);
|
||||
g_return_if_fail (value->class == >K_CSS_VALUE_SHADOW);
|
||||
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color)))
|
||||
return;
|
||||
|
||||
dx = _gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
dy = _gtk_css_number_value_get (shadow->voffset, 0);
|
||||
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||
radius = _gtk_css_number_value_get (shadow->radius, 0);
|
||||
color = gtk_css_color_value_get_rgba (shadow->color);
|
||||
|
||||
/* These are trivial to do with a color node */
|
||||
if (spread == 0 && radius == 0 &&
|
||||
gsk_rounded_rect_is_rectilinear (padding_box))
|
||||
for (i = 0; i < value->n_shadows; i ++)
|
||||
{
|
||||
const graphene_rect_t *padding_bounds = &padding_box->bounds;
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
if (dx > 0)
|
||||
{
|
||||
const float y = dy > 0 ? dy : 0;
|
||||
if (!shadow->inset)
|
||||
continue;
|
||||
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x,
|
||||
padding_bounds->origin.y + y,
|
||||
dx,
|
||||
padding_bounds->size.height - ABS (dy)
|
||||
));
|
||||
}
|
||||
else if (dx < 0)
|
||||
{
|
||||
const float y = dy > 0 ? dy : 0;
|
||||
/* We don't need to draw invisible shadows */
|
||||
if (gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color)))
|
||||
continue;
|
||||
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x + padding_bounds->size.width + dx,
|
||||
padding_bounds->origin.y + y,
|
||||
- dx,
|
||||
padding_bounds->size.height - ABS (dy)
|
||||
));
|
||||
}
|
||||
dx = _gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
dy = _gtk_css_number_value_get (shadow->voffset, 0);
|
||||
spread = _gtk_css_number_value_get (shadow->spread, 0);
|
||||
radius = _gtk_css_number_value_get (shadow->radius, 0);
|
||||
color = gtk_css_color_value_get_rgba (shadow->color);
|
||||
|
||||
if (dy > 0)
|
||||
/* These are trivial to do with a color node */
|
||||
if (spread == 0 && radius == 0 &&
|
||||
gsk_rounded_rect_is_rectilinear (padding_box))
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x,
|
||||
padding_bounds->origin.y,
|
||||
padding_bounds->size.width,
|
||||
dy
|
||||
));
|
||||
const graphene_rect_t *padding_bounds = &padding_box->bounds;
|
||||
|
||||
if (dx > 0)
|
||||
{
|
||||
const float y = dy > 0 ? dy : 0;
|
||||
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x,
|
||||
padding_bounds->origin.y + y,
|
||||
dx,
|
||||
padding_bounds->size.height - ABS (dy)
|
||||
));
|
||||
}
|
||||
else if (dx < 0)
|
||||
{
|
||||
const float y = dy > 0 ? dy : 0;
|
||||
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x + padding_bounds->size.width + dx,
|
||||
padding_bounds->origin.y + y,
|
||||
- dx,
|
||||
padding_bounds->size.height - ABS (dy)
|
||||
));
|
||||
}
|
||||
|
||||
if (dy > 0)
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x,
|
||||
padding_bounds->origin.y,
|
||||
padding_bounds->size.width,
|
||||
dy
|
||||
));
|
||||
}
|
||||
else if (dy < 0)
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x,
|
||||
padding_bounds->origin.y + padding_bounds->size.height + dy,
|
||||
padding_bounds->size.width,
|
||||
- dy
|
||||
));
|
||||
}
|
||||
}
|
||||
else if (dy < 0)
|
||||
else
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot, color,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
padding_bounds->origin.x,
|
||||
padding_bounds->origin.y + padding_bounds->size.height + dy,
|
||||
padding_bounds->size.width,
|
||||
- dy
|
||||
));
|
||||
gtk_snapshot_append_inset_shadow (snapshot,
|
||||
padding_box,
|
||||
color,
|
||||
dx, dy, spread, radius);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_snapshot_append_inset_shadow (snapshot,
|
||||
padding_box,
|
||||
color,
|
||||
dx, dy, spread, radius);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_shadow_value_is_clear (const GtkCssValue *shadow)
|
||||
gtk_css_shadow_value_is_clear (const GtkCssValue *value)
|
||||
{
|
||||
return gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color));
|
||||
guint i;
|
||||
|
||||
if (!value)
|
||||
return TRUE;
|
||||
|
||||
for (i = 0; i < value->n_shadows; i++)
|
||||
{
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
if (!gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_shadow_value_is_none (const GtkCssValue *shadow)
|
||||
{
|
||||
return !shadow || shadow->n_shadows == 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_css_shadow_value_push_snapshot (const GtkCssValue *value,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
gboolean need_shadow = FALSE;
|
||||
guint i;
|
||||
|
||||
/* TODO: We can save this as a flag once and then reuse it */
|
||||
for (i = 0; i < value->n_shadows; i++)
|
||||
{
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
if (!gdk_rgba_is_clear (gtk_css_color_value_get_rgba (shadow->color)))
|
||||
{
|
||||
need_shadow = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_shadow)
|
||||
{
|
||||
GskShadow *shadows = g_newa (GskShadow, value->n_shadows);
|
||||
|
||||
for (i = 0; i < value->n_shadows; i++)
|
||||
{
|
||||
const ShadowValue *shadow = &value->shadows[i];
|
||||
|
||||
shadows[i].dx = _gtk_css_number_value_get (shadow->hoffset, 0);
|
||||
shadows[i].dy = _gtk_css_number_value_get (shadow->voffset, 0);
|
||||
shadows[i].color = *gtk_css_color_value_get_rgba (shadow->color);
|
||||
shadows[i].radius = _gtk_css_number_value_get (shadow->radius, 0);
|
||||
}
|
||||
|
||||
gtk_snapshot_push_shadow (snapshot, shadows, value->n_shadows);
|
||||
}
|
||||
|
||||
return need_shadow;
|
||||
}
|
||||
|
@ -28,21 +28,17 @@
|
||||
#include "gtkcssparserprivate.h"
|
||||
#include "gtkcssvalueprivate.h"
|
||||
#include "gtkroundedboxprivate.h"
|
||||
#include "gtksnapshot.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkCssValue * _gtk_css_shadow_value_new_for_transition (GtkCssValue *target);
|
||||
GtkCssValue * gtk_css_shadow_value_new_none (void);
|
||||
|
||||
GtkCssValue * _gtk_css_shadow_value_parse (GtkCssParser *parser,
|
||||
gboolean box_shadow_mode);
|
||||
|
||||
gboolean _gtk_css_shadow_value_get_inset (const GtkCssValue *shadow);
|
||||
|
||||
void gtk_css_shadow_value_get_extents (const GtkCssValue *shadow,
|
||||
GtkBorder *border);
|
||||
void gtk_css_shadow_value_get_shadow (const GtkCssValue *value,
|
||||
GskShadow *shadow);
|
||||
|
||||
void gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow,
|
||||
GtkSnapshot *snapshot,
|
||||
const GskRoundedRect *border_box);
|
||||
@ -51,6 +47,10 @@ void gtk_css_shadow_value_snapshot_inset (const GtkCssValue
|
||||
const GskRoundedRect *padding_box);
|
||||
|
||||
gboolean gtk_css_shadow_value_is_clear (const GtkCssValue *shadow);
|
||||
gboolean gtk_css_shadow_value_is_none (const GtkCssValue *shadow);
|
||||
|
||||
gboolean gtk_css_shadow_value_push_snapshot (const GtkCssValue *value,
|
||||
GtkSnapshot *snapshot);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include "gtkcsspalettevalueprivate.h"
|
||||
#include "gtkcsspositionvalueprivate.h"
|
||||
#include "gtkcssrepeatvalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
#include "gtkcssstringvalueprivate.h"
|
||||
#include "gtkcsstransformvalueprivate.h"
|
||||
#include "gtkcssfontvariationsvalueprivate.h"
|
||||
@ -619,14 +619,14 @@ static GtkCssValue *
|
||||
box_shadow_value_parse (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_shadows_value_parse (parser, TRUE);
|
||||
return _gtk_css_shadow_value_parse (parser, TRUE);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
shadow_value_parse (GtkCssStyleProperty *property,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
return _gtk_css_shadows_value_parse (parser, FALSE);
|
||||
return _gtk_css_shadow_value_parse (parser, FALSE);
|
||||
}
|
||||
|
||||
static GtkCssValue *
|
||||
@ -1110,7 +1110,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_AFFECTS_TEXT_CONTENT,
|
||||
shadow_value_parse,
|
||||
NULL,
|
||||
_gtk_css_shadows_value_new_none ());
|
||||
gtk_css_shadow_value_new_none ());
|
||||
|
||||
gtk_css_style_property_register ("box-shadow",
|
||||
GTK_CSS_PROPERTY_BOX_SHADOW,
|
||||
@ -1119,7 +1119,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_AFFECTS_BACKGROUND,
|
||||
box_shadow_value_parse,
|
||||
NULL,
|
||||
_gtk_css_shadows_value_new_none ());
|
||||
gtk_css_shadow_value_new_none ());
|
||||
|
||||
gtk_css_style_property_register ("margin-top",
|
||||
GTK_CSS_PROPERTY_MARGIN_TOP,
|
||||
@ -1518,7 +1518,7 @@ _gtk_css_style_property_init_properties (void)
|
||||
GTK_CSS_AFFECTS_ICON | GTK_CSS_AFFECTS_SYMBOLIC_ICON,
|
||||
shadow_value_parse,
|
||||
NULL,
|
||||
_gtk_css_shadows_value_new_none ());
|
||||
gtk_css_shadow_value_new_none ());
|
||||
gtk_css_style_property_register ("-gtk-icon-style",
|
||||
GTK_CSS_PROPERTY_ICON_STYLE,
|
||||
G_TYPE_NONE,
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "gtkbuildable.h"
|
||||
#include "gtkbuilderprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkeventcontrollermotion.h"
|
||||
#include "gtkgesturedrag.h"
|
||||
|
@ -28,7 +28,6 @@
|
||||
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkgizmoprivate.h"
|
||||
#include "gtkintl.h"
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "gtkcssimagevalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
#include "gtkcsstransformvalueprivate.h"
|
||||
#include "gtkhslaprivate.h"
|
||||
#include "gtkrendericonprivate.h"
|
||||
@ -232,7 +232,7 @@ gtk_render_background_get_clip (GtkStyleContext *context,
|
||||
{
|
||||
GtkBorder shadow;
|
||||
|
||||
_gtk_css_shadows_value_get_extents (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BOX_SHADOW), &shadow);
|
||||
gtk_css_shadow_value_get_extents (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BOX_SHADOW), &shadow);
|
||||
|
||||
out_clip->x = floor (x) - shadow.left;
|
||||
out_clip->y = floor (y) - shadow.top;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "gtkcssenumvalueprivate.h"
|
||||
#include "gtkcssimagevalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
#include "gtkcsspositionvalueprivate.h"
|
||||
#include "gtkcssrepeatvalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
@ -285,14 +285,14 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
if (gdk_rgba_is_clear (bg_color) &&
|
||||
_gtk_css_array_value_get_n_values (background_image) == 1 &&
|
||||
_gtk_css_image_value_get_image (_gtk_css_array_value_get_nth (background_image, 0)) == NULL &&
|
||||
_gtk_css_shadows_value_is_none (box_shadow))
|
||||
gtk_css_shadow_value_is_none (box_shadow))
|
||||
return;
|
||||
|
||||
gtk_snapshot_push_debug (snapshot, "CSS background");
|
||||
|
||||
gtk_css_shadows_value_snapshot_outset (box_shadow,
|
||||
snapshot,
|
||||
gtk_css_boxes_get_border_box (boxes));
|
||||
gtk_css_shadow_value_snapshot_outset (box_shadow,
|
||||
snapshot,
|
||||
gtk_css_boxes_get_border_box (boxes));
|
||||
|
||||
blend_modes = gtk_css_style_get_value (boxes->style, GTK_CSS_PROPERTY_BACKGROUND_BLEND_MODE);
|
||||
number_of_layers = _gtk_css_array_value_get_n_values (background_image);
|
||||
@ -323,9 +323,9 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_css_shadows_value_snapshot_inset (box_shadow,
|
||||
snapshot,
|
||||
gtk_css_boxes_get_padding_box (boxes));
|
||||
gtk_css_shadow_value_snapshot_inset (box_shadow,
|
||||
snapshot,
|
||||
gtk_css_boxes_get_padding_box (boxes));
|
||||
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include "gtkcssfiltervalueprivate.h"
|
||||
#include "gtkcssimagevalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
#include "gtkcssstyleprivate.h"
|
||||
#include "gtkcsstransformvalueprivate.h"
|
||||
#include "gtkiconthemeprivate.h"
|
||||
@ -63,7 +63,7 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style,
|
||||
|
||||
gtk_css_filter_value_push_snapshot (filter_value, snapshot);
|
||||
|
||||
has_shadow = gtk_css_shadows_value_push_snapshot (shadows_value, snapshot);
|
||||
has_shadow = gtk_css_shadow_value_push_snapshot (shadows_value, snapshot);
|
||||
|
||||
if (transform == NULL)
|
||||
{
|
||||
@ -119,7 +119,7 @@ gtk_css_style_snapshot_icon_paintable (GtkCssStyle *style,
|
||||
|
||||
gtk_css_filter_value_push_snapshot (filter_value, snapshot);
|
||||
|
||||
has_shadow = gtk_css_shadows_value_push_snapshot (shadows_value, snapshot);
|
||||
has_shadow = gtk_css_shadow_value_push_snapshot (shadows_value, snapshot);
|
||||
|
||||
if (recolor)
|
||||
{
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "gtksnapshotprivate.h"
|
||||
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkrenderborderprivate.h"
|
||||
@ -1735,7 +1735,7 @@ gtk_snapshot_render_layout (GtkSnapshot *snapshot,
|
||||
fg_color = gtk_css_color_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR));
|
||||
|
||||
shadows_value = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_SHADOW);
|
||||
has_shadow = gtk_css_shadows_value_push_snapshot (shadows_value, snapshot);
|
||||
has_shadow = gtk_css_shadow_value_push_snapshot (shadows_value, snapshot);
|
||||
|
||||
gtk_snapshot_append_layout (snapshot, layout, fg_color);
|
||||
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "gtkcsstransformvalueprivate.h"
|
||||
#include "gtkcssfontvariationsvalueprivate.h"
|
||||
#include "gtkcssnumbervalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkcsswidgetnodeprivate.h"
|
||||
#include "gtkdebug.h"
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "gtkcsscornervalueprivate.h"
|
||||
#include "gtkcssiconthemevalueprivate.h"
|
||||
#include "gtkcsscolorvalueprivate.h"
|
||||
#include "gtkcssshadowsvalueprivate.h"
|
||||
#include "gtkcssshadowvalueprivate.h"
|
||||
#include "gtkcssstylepropertyprivate.h"
|
||||
#include "gtkdragdest.h"
|
||||
#include "gtkeventcontrollerkey.h"
|
||||
@ -5322,7 +5322,7 @@ get_shadow_width (GtkWindow *window,
|
||||
|
||||
/* Calculate the size of the drop shadows ... */
|
||||
shadows = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BOX_SHADOW);
|
||||
_gtk_css_shadows_value_get_extents (shadows, &border);
|
||||
gtk_css_shadow_value_get_extents (shadows, &border);
|
||||
|
||||
if (priv->type != GTK_WINDOW_POPUP)
|
||||
{
|
||||
|
@ -83,7 +83,6 @@ gtk_private_sources = files([
|
||||
'gtkcsspositionvalue.c',
|
||||
'gtkcssrepeatvalue.c',
|
||||
'gtkcssselector.c',
|
||||
'gtkcssshadowsvalue.c',
|
||||
'gtkcssshadowvalue.c',
|
||||
'gtkcssshorthandproperty.c',
|
||||
'gtkcssshorthandpropertyimpl.c',
|
||||
|
Loading…
Reference in New Issue
Block a user