css: Add a way to resolve css images

This will be needed to separate out computed and used values
for css image values.
This commit is contained in:
Matthias Clasen 2024-05-19 18:41:59 -04:00
parent 5de0ebab26
commit e027843cb0
11 changed files with 469 additions and 75 deletions

View File

@ -120,6 +120,20 @@ gtk_css_image_real_is_computed (GtkCssImage *image)
return FALSE;
}
static gboolean
gtk_css_image_real_contains_current_color (GtkCssImage *image)
{
return FALSE;
}
static GtkCssImage *
gtk_css_image_real_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
return g_object_ref (image);
}
static void
_gtk_css_image_class_init (GtkCssImageClass *klass)
{
@ -133,6 +147,8 @@ _gtk_css_image_class_init (GtkCssImageClass *klass)
klass->is_dynamic = gtk_css_image_real_is_dynamic;
klass->get_dynamic_image = gtk_css_image_real_get_dynamic_image;
klass->is_computed = gtk_css_image_real_is_computed;
klass->contains_current_color = gtk_css_image_real_contains_current_color;
klass->resolve = gtk_css_image_real_resolve;
}
static void
@ -239,11 +255,11 @@ _gtk_css_image_equal (GtkCssImage *image1,
return klass->equal (image1, image2);
}
void
_gtk_css_image_draw (GtkCssImage *image,
cairo_t *cr,
double width,
double height)
static void
gtk_css_image_draw (GtkCssImage *image,
cairo_t *cr,
double width,
double height)
{
GtkSnapshot *snapshot;
GskRenderNode *node;
@ -497,7 +513,7 @@ _gtk_css_image_get_surface (GtkCssImage *image,
surface_height);
cr = cairo_create (result);
_gtk_css_image_draw (image, cr, surface_width, surface_height);
gtk_css_image_draw (image, cr, surface_width, surface_height);
cairo_destroy (cr);
return result;
@ -588,3 +604,21 @@ gtk_css_image_is_computed (GtkCssImage *image)
return klass->is_computed (image);
}
gboolean
gtk_css_image_contains_current_color (GtkCssImage *image)
{
GtkCssImageClass *klass = GTK_CSS_IMAGE_GET_CLASS (image);
return klass->contains_current_color (image);
}
GtkCssImage *
gtk_css_image_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
GtkCssImageClass *klass = GTK_CSS_IMAGE_GET_CLASS (image);
return klass->resolve (image, context, current_color);
}

View File

@ -363,7 +363,7 @@ gtk_css_image_conic_compute (GtkCssImage *image,
copy->hue_interp = self->hue_interp;
copy->n_stops = self->n_stops;
copy->color_stops = g_malloc (sizeof (GtkCssImageConicColorStop) * copy->n_stops);
copy->color_stops = g_new (GtkCssImageConicColorStop, self->n_stops);
for (i = 0; i < self->n_stops; i++)
{
const GtkCssImageConicColorStop *stop = &self->color_stops[i];
@ -544,6 +544,54 @@ gtk_css_image_conic_is_computed (GtkCssImage *image)
return computed;
}
static gboolean
gtk_css_image_conic_contains_current_color (GtkCssImage *image)
{
GtkCssImageConic *self = GTK_CSS_IMAGE_CONIC (image);
for (guint i = 0; i < self->n_stops; i ++)
{
const GtkCssImageConicColorStop *stop = &self->color_stops[i];
if (gtk_css_value_contains_current_color (stop->color))
return TRUE;
}
return FALSE;
}
static GtkCssImage *
gtk_css_image_conic_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
GtkCssImageConic *self = GTK_CSS_IMAGE_CONIC (image);
GtkCssImageConic *resolved;
if (!gtk_css_image_conic_contains_current_color (image))
return g_object_ref (image);
resolved = g_object_new (GTK_TYPE_CSS_IMAGE_CONIC, NULL);
resolved->center = gtk_css_value_ref (self->center);
resolved->rotation = gtk_css_value_ref (self->rotation);
resolved->n_stops = self->n_stops;
resolved->color_stops = g_new (GtkCssImageConicColorStop, self->n_stops);
for (guint i = 0; i < self->n_stops; i++)
{
if (self->color_stops[i].offset)
resolved->color_stops[i].offset = gtk_css_value_ref (self->color_stops[i].offset);
else
resolved->color_stops[i].offset = NULL;
resolved->color_stops[i].color = gtk_css_color_value_resolve (self->color_stops[i].color, context, current_color);
}
return GTK_CSS_IMAGE (resolved);
}
static void
gtk_css_image_conic_class_init (GtkCssImageConicClass *klass)
{
@ -557,6 +605,8 @@ gtk_css_image_conic_class_init (GtkCssImageConicClass *klass)
image_class->equal = gtk_css_image_conic_equal;
image_class->transition = gtk_css_image_conic_transition;
image_class->is_computed = gtk_css_image_conic_is_computed;
image_class->contains_current_color = gtk_css_image_conic_contains_current_color;
image_class->resolve = gtk_css_image_conic_resolve;
object_class->dispose = gtk_css_image_conic_dispose;
}

View File

@ -72,7 +72,10 @@ gtk_css_image_fallback_snapshot (GtkCssImage *image,
{
if (fallback->color)
{
const GdkRGBA *color = gtk_css_color_value_get_rgba (fallback->color);
const GdkRGBA *color;
color = gtk_css_color_value_get_rgba (fallback->color);
if (!gdk_rgba_is_clear (color))
gtk_snapshot_append_color (snapshot, color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
@ -301,6 +304,70 @@ gtk_css_image_fallback_is_computed (GtkCssImage *image)
return TRUE;
}
static gboolean
gtk_css_image_fallback_contains_current_color (GtkCssImage *image)
{
GtkCssImageFallback *fallback = GTK_CSS_IMAGE_FALLBACK (image);
if (fallback->used < 0)
{
guint i;
if (fallback->color && !fallback->images)
return gtk_css_value_contains_current_color (fallback->color);
for (i = 0; i < fallback->n_images; i++)
{
if (gtk_css_image_contains_current_color (fallback->images[i]))
return TRUE;
}
}
return FALSE;
}
static GtkCssImage *
gtk_css_image_fallback_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
GtkCssImageFallback *fallback = GTK_CSS_IMAGE_FALLBACK (image);
GtkCssImageFallback *resolved;
int i;
if (fallback->used < 0)
{
GtkCssValue *resolved_color = NULL;
if (fallback->color)
resolved_color = gtk_css_color_value_resolve (fallback->color, context, current_color);
/* image($color) that didn't change */
if (resolved_color && !fallback->images && resolved_color == fallback->color)
return g_object_ref (image);
resolved = g_object_new (_gtk_css_image_fallback_get_type (), NULL);
resolved->n_images = fallback->n_images;
resolved->images = g_new (GtkCssImage *, fallback->n_images);
for (i = 0; i < fallback->n_images; i++)
{
resolved->images[i] = g_object_ref (fallback->images[i]);
if (gtk_css_image_is_invalid (resolved->images[i]))
continue;
if (resolved->used < 0)
resolved->used = i;
}
resolved->color = resolved_color;
return GTK_CSS_IMAGE (resolved);
}
else
return GTK_CSS_IMAGE (g_object_ref (image));
}
static void
_gtk_css_image_fallback_class_init (GtkCssImageFallbackClass *klass)
{
@ -316,6 +383,8 @@ _gtk_css_image_fallback_class_init (GtkCssImageFallbackClass *klass)
image_class->print = gtk_css_image_fallback_print;
image_class->equal = gtk_css_image_fallback_equal;
image_class->is_computed = gtk_css_image_fallback_is_computed;
image_class->contains_current_color = gtk_css_image_fallback_contains_current_color;
image_class->resolve = gtk_css_image_fallback_resolve;
object_class->dispose = gtk_css_image_fallback_dispose;
}

View File

@ -29,6 +29,8 @@
#include "gtkstyleproviderprivate.h"
#include "gtksymbolicpaintable.h"
#include "gtkiconthemeprivate.h"
#include "gtkcsscolorvalueprivate.h"
#include "gtkcsspalettevalueprivate.h"
G_DEFINE_TYPE (GtkCssImageIconTheme, _gtk_css_image_icon_theme, GTK_TYPE_CSS_IMAGE)
@ -50,6 +52,7 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
double icon_width, icon_height;
int size;
double x, y;
GdkRGBA colors[4];
size = floor (MIN (width, height));
if (size <= 0)
@ -89,11 +92,15 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (x, y));
}
for (guint i = 0; i < 4; i++)
colors[i] = *gtk_css_color_value_get_rgba (icon_theme->colors[i]);
gtk_symbolic_paintable_snapshot_symbolic (GTK_SYMBOLIC_PAINTABLE (icon),
snapshot,
icon_width,
icon_height,
icon_theme->colors,
colors,
G_N_ELEMENTS (icon_theme->colors));
if (x != 0 || y != 0)
gtk_snapshot_restore (snapshot);
@ -146,6 +153,7 @@ gtk_css_image_icon_theme_compute (GtkCssImage *image,
GtkCssImageIconTheme *copy;
GtkSettings *settings;
GdkDisplay *display;
const char *names[4] = { NULL, "success", "warning", "error" };
copy = g_object_new (GTK_TYPE_CSS_IMAGE_ICON_THEME, NULL);
copy->name = g_strdup (icon_theme->name);
@ -154,7 +162,18 @@ gtk_css_image_icon_theme_compute (GtkCssImage *image,
copy->icon_theme = gtk_icon_theme_get_for_display (display);
copy->serial = gtk_icon_theme_get_serial (copy->icon_theme);
copy->scale = gtk_style_provider_get_scale (context->provider);
gtk_css_style_lookup_symbolic_colors (context->style, copy->colors);
for (guint i = 0; i < 4; i++)
{
GtkCssValue *color = NULL;
if (names[i])
color = gtk_css_palette_value_get_color (context->style->core->icon_palette, names[i]);
if (color)
copy->colors[i] = gtk_css_value_ref (color);
else
copy->colors[i] = gtk_css_value_ref (context->style->core->color);
}
return GTK_CSS_IMAGE (copy);
}
@ -180,10 +199,52 @@ gtk_css_image_icon_theme_dispose (GObject *object)
icon_theme->name = NULL;
g_clear_object (&icon_theme->cached_icon);
g_clear_pointer (&icon_theme->colors[0], gtk_css_value_unref);
g_clear_pointer (&icon_theme->colors[1], gtk_css_value_unref);
g_clear_pointer (&icon_theme->colors[2], gtk_css_value_unref);
g_clear_pointer (&icon_theme->colors[3], gtk_css_value_unref);
G_OBJECT_CLASS (_gtk_css_image_icon_theme_parent_class)->dispose (object);
}
static gboolean
gtk_css_image_icon_theme_contains_current_color (GtkCssImage *image)
{
GtkCssImageIconTheme *icon_theme = GTK_CSS_IMAGE_ICON_THEME (image);
for (guint i = 0; i < 4; i++)
{
if (!icon_theme->colors[i] ||
gtk_css_value_contains_current_color (icon_theme->colors[i]))
return TRUE;
}
return FALSE;
}
static GtkCssImage *
gtk_css_image_icon_theme_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current)
{
GtkCssImageIconTheme *icon_theme = GTK_CSS_IMAGE_ICON_THEME (image);
GtkCssImageIconTheme *copy;
if (!gtk_css_image_icon_theme_contains_current_color (image))
return g_object_ref (image);
copy = g_object_new (GTK_TYPE_CSS_IMAGE_ICON_THEME, NULL);
copy->name = g_strdup (icon_theme->name);
copy->icon_theme = icon_theme->icon_theme;
copy->serial = icon_theme->serial;
copy->scale = icon_theme->scale;
for (guint i = 0; i < 4; i++)
copy->colors[i] = gtk_css_color_value_resolve (icon_theme->colors[i], context, current);
return GTK_CSS_IMAGE (copy);
}
static void
_gtk_css_image_icon_theme_class_init (GtkCssImageIconThemeClass *klass)
{
@ -196,7 +257,8 @@ _gtk_css_image_icon_theme_class_init (GtkCssImageIconThemeClass *klass)
image_class->print = gtk_css_image_icon_theme_print;
image_class->compute = gtk_css_image_icon_theme_compute;
image_class->equal = gtk_css_image_icon_theme_equal;
image_class->contains_current_color = gtk_css_image_icon_theme_contains_current_color;
image_class->resolve = gtk_css_image_icon_theme_resolve;
object_class->dispose = gtk_css_image_icon_theme_dispose;
}

View File

@ -39,7 +39,7 @@ struct _GtkCssImageIconTheme
GtkCssImage parent;
GtkIconTheme *icon_theme;
GdkRGBA colors[4];
GtkCssValue *colors[4];
int serial;
int scale;
char *name;

View File

@ -134,10 +134,10 @@ gtk_css_image_linear_compute_start_point (double angle_in_degrees,
}
static void
gtk_css_image_linear_snapshot (GtkCssImage *image,
GtkSnapshot *snapshot,
double width,
double height)
gtk_css_image_linear_snapshot (GtkCssImage *image,
GtkSnapshot *snapshot,
double width,
double height)
{
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
GskColorStop *stops;
@ -188,12 +188,16 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
if (start == end)
{
/* repeating gradients with all color stops sharing the same offset
* get the color of the last color stop */
/* Repeating gradients with all color stops sharing the same offset
* get the color of the last color stop
*/
const GtkCssImageLinearColorStop *stop = &linear->color_stops[linear->n_stops - 1];
const GdkRGBA *color;
color = gtk_css_color_value_get_rgba (stop->color);
gtk_snapshot_append_color (snapshot,
gtk_css_color_value_get_rgba (stop->color),
color,
&GRAPHENE_RECT_INIT (0, 0, width, height));
return;
}
@ -236,8 +240,9 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
offset += step;
stops[last].offset = (offset - start) / (end - start);
stops[last].color = *gtk_css_color_value_get_rgba (stop->color);
stops[last].offset = (offset - start) / (end - start);
}
offset = pos;
@ -742,6 +747,57 @@ gtk_css_image_linear_is_computed (GtkCssImage *image)
return computed;
}
static gboolean
gtk_css_image_linear_contains_current_color (GtkCssImage *image)
{
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
for (guint i = 0; i < linear->n_stops; i ++)
{
const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
if (gtk_css_value_contains_current_color (stop->color))
return TRUE;
}
return FALSE;
}
static GtkCssImage *
gtk_css_image_linear_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
GtkCssImageLinear *copy;
guint i;
copy = g_object_new (GTK_TYPE_CSS_IMAGE_LINEAR, NULL);
copy->repeating = linear->repeating;
copy->side = linear->side;
if (linear->angle)
copy->angle = gtk_css_value_ref (linear->angle);
copy->n_stops = linear->n_stops;
copy->color_stops = g_new (GtkCssImageLinearColorStop, copy->n_stops);
for (i = 0; i < linear->n_stops; i++)
{
const GtkCssImageLinearColorStop *stop = &linear->color_stops[i];
GtkCssImageLinearColorStop *scopy = &copy->color_stops[i];
scopy->color = gtk_css_color_value_resolve (stop->color, context, current_color);
if (stop->offset)
scopy->offset = gtk_css_value_ref (stop->offset);
else
scopy->offset = NULL;
}
return GTK_CSS_IMAGE (copy);
}
static void
_gtk_css_image_linear_class_init (GtkCssImageLinearClass *klass)
{
@ -755,6 +811,8 @@ _gtk_css_image_linear_class_init (GtkCssImageLinearClass *klass)
image_class->equal = gtk_css_image_linear_equal;
image_class->transition = gtk_css_image_linear_transition;
image_class->is_computed = gtk_css_image_linear_is_computed;
image_class->contains_current_color = gtk_css_image_linear_contains_current_color;
image_class->resolve = gtk_css_image_linear_resolve;
object_class->dispose = gtk_css_image_linear_dispose;
}

View File

@ -91,6 +91,10 @@ struct _GtkCssImageClass
void (* print) (GtkCssImage *image,
GString *string);
gboolean (* is_computed) (GtkCssImage *image);
gboolean (* contains_current_color) (GtkCssImage *image);
GtkCssImage *( * resolve) (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color);
};
GType _gtk_css_image_get_type (void) G_GNUC_CONST;
@ -112,10 +116,6 @@ GtkCssImage * _gtk_css_image_transition (GtkCssImage *
guint property_id,
double progress);
void _gtk_css_image_draw (GtkCssImage *image,
cairo_t *cr,
double width,
double height);
void gtk_css_image_snapshot (GtkCssImage *image,
GtkSnapshot *snapshot,
double width,
@ -142,6 +142,11 @@ cairo_surface_t *
int surface_height);
gboolean gtk_css_image_is_computed (GtkCssImage *image) G_GNUC_PURE;
gboolean gtk_css_image_contains_current_color (GtkCssImage *image) G_GNUC_PURE;
GtkCssImage * gtk_css_image_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color);
G_END_DECLS

View File

@ -748,6 +748,63 @@ gtk_css_image_radial_is_computed (GtkCssImage *image)
return computed;
}
static gboolean
gtk_css_image_radial_contains_current_color (GtkCssImage *image)
{
GtkCssImageRadial *radial = GTK_CSS_IMAGE_RADIAL (image);
for (guint i = 0; i < radial->n_stops; i ++)
{
const GtkCssImageRadialColorStop *stop = &radial->color_stops[i];
if (gtk_css_value_contains_current_color (stop->color))
return TRUE;
}
return FALSE;
}
static GtkCssImage *
gtk_css_image_radial_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
GtkCssImageRadial *radial = GTK_CSS_IMAGE_RADIAL (image);
GtkCssImageRadial *copy;
copy = g_object_new (GTK_TYPE_CSS_IMAGE_RADIAL, NULL);
copy->repeating = radial->repeating;
copy->circle = radial->circle;
copy->size = radial->size;
copy->position = gtk_css_value_ref (radial->position);
if (radial->sizes[0])
copy->sizes[0] = gtk_css_value_ref (radial->sizes[0]);
if (radial->sizes[1])
copy->sizes[1] = gtk_css_value_ref (radial->sizes[1]);
copy->n_stops = radial->n_stops;
copy->color_stops = g_new (GtkCssImageRadialColorStop, copy->n_stops);
for (guint i = 0; i < radial->n_stops; i++)
{
const GtkCssImageRadialColorStop *stop = &radial->color_stops[i];
GtkCssImageRadialColorStop *scopy = &copy->color_stops[i];
scopy->color = gtk_css_color_value_resolve (stop->color, context, current_color);
if (stop->offset)
scopy->offset = gtk_css_value_ref (stop->offset);
else
scopy->offset = NULL;
}
return GTK_CSS_IMAGE (copy);
}
static void
_gtk_css_image_radial_class_init (GtkCssImageRadialClass *klass)
{
@ -761,6 +818,8 @@ _gtk_css_image_radial_class_init (GtkCssImageRadialClass *klass)
image_class->transition = gtk_css_image_radial_transition;
image_class->equal = gtk_css_image_radial_equal;
image_class->is_computed = gtk_css_image_radial_is_computed;
image_class->contains_current_color = gtk_css_image_radial_contains_current_color;
image_class->resolve = gtk_css_image_radial_resolve;
object_class->dispose = gtk_css_image_radial_dispose;
}

View File

@ -55,43 +55,13 @@ gtk_css_image_recolor_dispose (GObject *object)
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (object);
g_clear_pointer (&recolor->palette, gtk_css_value_unref);
g_clear_pointer (&recolor->color, gtk_css_value_unref);
g_clear_object (&recolor->file);
g_clear_object (&recolor->texture);
G_OBJECT_CLASS (_gtk_css_image_recolor_parent_class)->dispose (object);
}
static void
lookup_symbolic_colors (GtkCssStyle *style,
GtkCssValue *palette,
GdkRGBA *color_out,
GdkRGBA *success_out,
GdkRGBA *warning_out,
GdkRGBA *error_out)
{
GtkCssValue *lookup;
*color_out = *gtk_css_color_value_get_rgba (style->core->color);
lookup = gtk_css_palette_value_get_color (palette, "success");
if (lookup)
*success_out = *gtk_css_color_value_get_rgba (lookup);
else
*success_out = *color_out;
lookup = gtk_css_palette_value_get_color (palette, "warning");
if (lookup)
*warning_out = *gtk_css_color_value_get_rgba (lookup);
else
*warning_out = *color_out;
lookup = gtk_css_palette_value_get_color (palette, "error");
if (lookup)
*error_out = *gtk_css_color_value_get_rgba (lookup);
else
*error_out = *color_out;
}
static void
gtk_css_image_recolor_load_texture (GtkCssImageRecolor *recolor,
GError **error)
@ -127,21 +97,22 @@ gtk_css_image_recolor_load_texture (GtkCssImageRecolor *recolor,
}
static GtkCssImage *
gtk_css_image_recolor_load (GtkCssImageRecolor *recolor,
GtkCssStyle *style,
GtkCssValue *palette,
int scale,
GError **gerror)
gtk_css_image_recolor_load (GtkCssImageRecolor *recolor,
GtkCssComputeContext *context,
GtkCssValue *palette,
int scale,
GError **gerror)
{
GError *local_error = NULL;
GtkCssImageRecolor *image;
image = g_object_new (GTK_TYPE_CSS_IMAGE_RECOLOR, NULL);
lookup_symbolic_colors (style, palette, &image->color, &image->success, &image->warning, &image->error);
gtk_css_image_recolor_load_texture (recolor, &local_error);
image->file = g_object_ref (recolor->file);
image->palette = gtk_css_value_ref (palette);
image->color = gtk_css_value_ref (context->style->core->color);
gtk_css_image_recolor_load_texture (recolor, &local_error);
if (recolor->texture)
image->texture = g_object_ref (recolor->texture);
@ -172,16 +143,34 @@ gtk_css_image_recolor_snapshot (GtkCssImage *image,
double height)
{
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
const GdkRGBA *fg = &recolor->color;
const GdkRGBA *sc = &recolor->success;
const GdkRGBA *wc = &recolor->warning;
const GdkRGBA *ec = &recolor->error;
const GdkRGBA *fg, *sc, *wc, *ec;
const GtkCssValue *color;
graphene_matrix_t matrix;
graphene_vec4_t offset;
if (recolor->texture == NULL)
return;
fg = gtk_css_color_value_get_rgba (recolor->color);
color = gtk_css_palette_value_get_color (recolor->palette, "success");
if (color)
sc = gtk_css_color_value_get_rgba (color);
else
sc = fg;
color = gtk_css_palette_value_get_color (recolor->palette, "warning");
if (color)
wc = gtk_css_color_value_get_rgba (color);
else
wc = fg;
color = gtk_css_palette_value_get_color (recolor->palette, "error");
if (color)
ec = gtk_css_color_value_get_rgba (color);
else
ec = fg;
graphene_matrix_init_from_float (&matrix,
(float[16]) {
sc->red - fg->red, sc->green - fg->green, sc->blue - fg->blue, 0,
@ -218,7 +207,7 @@ gtk_css_image_recolor_compute (GtkCssImage *image,
else
palette = gtk_css_value_ref (context->style->core->icon_palette);
img = gtk_css_image_recolor_load (recolor, context->style, palette, scale, &error);
img = gtk_css_image_recolor_load (recolor, context, palette, scale, &error);
if (error)
{
@ -267,7 +256,7 @@ gtk_css_image_recolor_parse_arg (GtkCssParser *parser,
static gboolean
gtk_css_image_recolor_parse (GtkCssImage *image,
GtkCssParser *parser)
GtkCssParser *parser)
{
if (!gtk_css_parser_has_function (parser, "-gtk-recolor"))
{
@ -309,8 +298,38 @@ gtk_css_image_recolor_is_computed (GtkCssImage *image)
{
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
return recolor->texture &&
(!recolor->palette || gtk_css_value_is_computed (recolor->palette));
return recolor->texture && gtk_css_value_is_computed (recolor->palette);
}
static gboolean
gtk_css_image_recolor_contains_current_color (GtkCssImage *image)
{
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
if (!recolor->palette || !recolor->color)
return TRUE;
return gtk_css_value_contains_current_color (recolor->palette) ||
gtk_css_value_contains_current_color (recolor->color);
}
static GtkCssImage *
gtk_css_image_recolor_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
GtkCssImageRecolor *img;
img = g_object_new (GTK_TYPE_CSS_IMAGE_RECOLOR, NULL);
img->palette = gtk_css_palette_value_resolve (recolor->palette, context, current_color);
img->color = gtk_css_color_value_resolve (recolor->color, context, current_color);
img->file = g_object_ref (recolor->file);
if (recolor->texture)
img->texture = g_object_ref (recolor->texture);
return GTK_CSS_IMAGE (img);
}
static void
@ -326,6 +345,8 @@ _gtk_css_image_recolor_class_init (GtkCssImageRecolorClass *klass)
image_class->parse = gtk_css_image_recolor_parse;
image_class->print = gtk_css_image_recolor_print;
image_class->is_computed = gtk_css_image_recolor_is_computed;
image_class->contains_current_color = gtk_css_image_recolor_contains_current_color;
image_class->resolve = gtk_css_image_recolor_resolve;
object_class->dispose = gtk_css_image_recolor_dispose;
}

View File

@ -39,12 +39,9 @@ struct _GtkCssImageRecolor
GtkCssImage parent;
GFile *file;
GtkCssValue *color;
GtkCssValue *palette;
GdkTexture *texture;
GdkRGBA color;
GdkRGBA success;
GdkRGBA warning;
GdkRGBA error;
};
struct _GtkCssImageRecolorClass

View File

@ -208,6 +208,43 @@ gtk_css_image_scaled_is_computed (GtkCssImage *image)
gtk_css_image_is_computed (self->images[0]);
}
static gboolean
gtk_css_image_scaled_contains_current_color (GtkCssImage *image)
{
GtkCssImageScaled *self = GTK_CSS_IMAGE_SCALED (image);
for (guint i = 0; i < self->n_images; i++)
{
if (gtk_css_image_contains_current_color (self->images[i]))
return TRUE;
}
return FALSE;
}
static GtkCssImage *
gtk_css_image_scaled_resolve (GtkCssImage *image,
GtkCssComputeContext *context,
GtkCssValue *current_color)
{
GtkCssImageScaled *self = GTK_CSS_IMAGE_SCALED (image);
GtkCssImageScaled *res;
res = g_object_new (GTK_TYPE_CSS_IMAGE_SCALED, NULL);
res->n_images = self->n_images;
res->images = g_new (GtkCssImage *, self->n_images);
res->scales = g_new (int, self->n_images);
for (guint i = 0; i < self->n_images; i++)
{
res->images[i] = gtk_css_image_resolve (self->images[i], context, current_color);
res->scales[i] = self->scales[i];
}
return GTK_CSS_IMAGE (res);
}
static void
_gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass)
{
@ -222,6 +259,8 @@ _gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass)
image_class->compute = gtk_css_image_scaled_compute;
image_class->print = gtk_css_image_scaled_print;
image_class->is_computed = gtk_css_image_scaled_is_computed;
image_class->contains_current_color = gtk_css_image_scaled_contains_current_color;
image_class->resolve = gtk_css_image_scaled_resolve;
object_class->dispose = gtk_css_image_scaled_dispose;
}