Compare commits
2 Commits
quick-keyb
...
filter-ima
Author | SHA1 | Date | |
---|---|---|---|
|
3ff7c86b65 | ||
|
79a0f183ec |
@@ -80,6 +80,31 @@ and in some cases a number as arguments.
|
||||
|
||||
## Images
|
||||
|
||||
CSS allows to specify images in various forms, the most simple one being
|
||||
a url for an image file. Beyond that, images can be specified as
|
||||
|
||||
`linear-gradient(Angle, ColorStops)`
|
||||
`repeating-linear-gradient(Angle, ColorStops)`
|
||||
: creates a linear gradient.
|
||||
|
||||
`radial-gradient(Shape, ColorStops)`
|
||||
`repeating-radial-gradient(Shape, ColorStops)`
|
||||
: creates a radial gradient.
|
||||
|
||||
`conic-gradient(Angle, ColorStops)`
|
||||
: creates a conic gradient.
|
||||
|
||||
`cross-fade(Percentage Image,…)`
|
||||
: combines two or more images.
|
||||
|
||||
`image(Image,… Color)`
|
||||
: falls back to the first valid image, or to a solid color.
|
||||
|
||||
`filter(Image, Filters)`
|
||||
: applies filters to an image.
|
||||
|
||||
For more details, see [CSS Image Level 4](https://www.w3.org/TR/css-images-4/).
|
||||
|
||||
GTK extends the CSS syntax for images and also uses it for specifying icons.
|
||||
To load a themed icon, use
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "gtk/gtkcssimageurlprivate.h"
|
||||
#include "gtk/gtkcssimagescaledprivate.h"
|
||||
#include "gtk/gtkcssimagerecolorprivate.h"
|
||||
#include "gtk/gtkcssimagefilterprivate.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GtkCssImage, _gtk_css_image, G_TYPE_OBJECT)
|
||||
|
||||
@@ -524,6 +525,7 @@ gtk_css_image_get_parser_type (GtkCssParser *parser)
|
||||
{ "repeating-radial-gradient", _gtk_css_image_radial_get_type },
|
||||
{ "conic-gradient", gtk_css_image_conic_get_type },
|
||||
{ "cross-fade", gtk_css_image_cross_fade_get_type },
|
||||
{ "filter", gtk_css_image_filter_get_type },
|
||||
{ "image", _gtk_css_image_fallback_get_type }
|
||||
};
|
||||
guint i;
|
||||
|
216
gtk/gtkcssimagefilter.c
Normal file
216
gtk/gtkcssimagefilter.c
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat Inc.
|
||||
*
|
||||
* 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.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gtkcssimagefilterprivate.h"
|
||||
|
||||
#include "gtkcssfiltervalueprivate.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkCssImageFilter, gtk_css_image_filter, GTK_TYPE_CSS_IMAGE)
|
||||
|
||||
static int
|
||||
gtk_css_image_filter_get_width (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
return _gtk_css_image_get_width (self->image);
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_css_image_filter_get_height (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
return _gtk_css_image_get_height (self->image);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_filter_equal (GtkCssImage *image1,
|
||||
GtkCssImage *image2)
|
||||
{
|
||||
GtkCssImageFilter *filter1 = GTK_CSS_IMAGE_FILTER (image1);
|
||||
GtkCssImageFilter *filter2 = GTK_CSS_IMAGE_FILTER (image2);
|
||||
|
||||
return _gtk_css_image_equal (filter1->image, filter2->image) &&
|
||||
_gtk_css_value_equal (filter1->filter, filter2->filter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_filter_is_dynamic (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
return gtk_css_image_is_dynamic (self->image);
|
||||
}
|
||||
|
||||
static GtkCssImage *
|
||||
gtk_css_image_filter_get_dynamic_image (GtkCssImage *image,
|
||||
gint64 monotonic_time)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
return gtk_css_image_filter_new (gtk_css_image_get_dynamic_image (self->image, monotonic_time),
|
||||
self->filter);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_filter_snapshot (GtkCssImage *image,
|
||||
GtkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
gtk_css_filter_value_push_snapshot (self->filter, snapshot);
|
||||
gtk_css_image_snapshot (self->image, snapshot, width, height);
|
||||
gtk_css_filter_value_pop_snapshot (self->filter, snapshot);
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_css_image_filter_parse_arg (GtkCssParser *parser,
|
||||
guint arg,
|
||||
gpointer data)
|
||||
{
|
||||
GtkCssImageFilter *self = data;
|
||||
|
||||
switch (arg)
|
||||
{
|
||||
case 0:
|
||||
self->image = _gtk_css_image_new_parse (parser);
|
||||
if (self->image == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case 1:
|
||||
self->filter = gtk_css_filter_value_parse (parser);
|
||||
if (self->filter == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_filter_parse (GtkCssImage *image,
|
||||
GtkCssParser *parser)
|
||||
{
|
||||
if (!gtk_css_parser_has_function (parser, "filter"))
|
||||
{
|
||||
gtk_css_parser_error_syntax (parser, "Expected 'filter('");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return gtk_css_parser_consume_function (parser, 2, 2, gtk_css_image_filter_parse_arg, image);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_filter_print (GtkCssImage *image,
|
||||
GString *string)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
g_string_append (string, "filter(");
|
||||
_gtk_css_image_print (self->image, string);
|
||||
g_string_append (string, ",");
|
||||
_gtk_css_value_print (self->filter, string);
|
||||
g_string_append (string, ")");
|
||||
}
|
||||
|
||||
static GtkCssImage *
|
||||
gtk_css_image_filter_compute (GtkCssImage *image,
|
||||
guint property_id,
|
||||
GtkStyleProvider *provider,
|
||||
GtkCssStyle *style,
|
||||
GtkCssStyle *parent_style)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
return gtk_css_image_filter_new (_gtk_css_image_compute (self->image, property_id, provider, style, parent_style),
|
||||
_gtk_css_value_compute (self->filter, property_id, provider, style, parent_style));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_filter_dispose (GObject *object)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (object);
|
||||
|
||||
g_clear_object (&self->image);
|
||||
g_clear_pointer (&self->filter, _gtk_css_value_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_css_image_filter_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_image_filter_is_computed (GtkCssImage *image)
|
||||
{
|
||||
GtkCssImageFilter *self = GTK_CSS_IMAGE_FILTER (image);
|
||||
|
||||
return gtk_css_image_is_computed (self->image) &&
|
||||
gtk_css_value_is_computed (self->filter);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_filter_class_init (GtkCssImageFilterClass *klass)
|
||||
{
|
||||
GtkCssImageClass *image_class = GTK_CSS_IMAGE_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
image_class->get_width = gtk_css_image_filter_get_width;
|
||||
image_class->get_height = gtk_css_image_filter_get_height;
|
||||
image_class->compute = gtk_css_image_filter_compute;
|
||||
image_class->equal = gtk_css_image_filter_equal;
|
||||
image_class->snapshot = gtk_css_image_filter_snapshot;
|
||||
image_class->is_dynamic = gtk_css_image_filter_is_dynamic;
|
||||
image_class->get_dynamic_image = gtk_css_image_filter_get_dynamic_image;
|
||||
image_class->parse = gtk_css_image_filter_parse;
|
||||
image_class->print = gtk_css_image_filter_print;
|
||||
image_class->is_computed = gtk_css_image_filter_is_computed;
|
||||
|
||||
object_class->dispose = gtk_css_image_filter_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_image_filter_init (GtkCssImageFilter *self)
|
||||
{
|
||||
}
|
||||
|
||||
GtkCssImage *
|
||||
gtk_css_image_filter_new (GtkCssImage *image,
|
||||
GtkCssValue *filter)
|
||||
{
|
||||
GtkCssImageFilter *self;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_CSS_IMAGE (image), NULL);
|
||||
|
||||
self = g_object_new (GTK_TYPE_CSS_IMAGE_FILTER, NULL);
|
||||
|
||||
self->image = g_object_ref (image);
|
||||
self->filter = gtk_css_value_ref (filter);
|
||||
|
||||
return GTK_CSS_IMAGE (self);
|
||||
}
|
||||
|
58
gtk/gtkcssimagefilterprivate.h
Normal file
58
gtk/gtkcssimagefilterprivate.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright © 2021 Red Hat Inc.
|
||||
*
|
||||
* 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.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_CSS_IMAGE_FILTER_PRIVATE_H__
|
||||
#define __GTK_CSS_IMAGE_FILTER_PRIVATE_H__
|
||||
|
||||
#include "gtk/gtkcssimageprivate.h"
|
||||
#include "gtk/gtkcssvalueprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CSS_IMAGE_FILTER (gtk_css_image_filter_get_type ())
|
||||
#define GTK_CSS_IMAGE_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_IMAGE_FILTER, GtkCssImageFilter))
|
||||
#define GTK_CSS_IMAGE_FILTER_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_IMAGE_FILTER, GtkCssImageFilterClass))
|
||||
#define GTK_IS_CSS_IMAGE_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_IMAGE_FILTER))
|
||||
#define GTK_IS_CSS_IMAGE_FILTER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_IMAGE_FILTER))
|
||||
#define GTK_CSS_IMAGE_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_IMAGE_FILTER, GtkCssImageFilterClass))
|
||||
|
||||
typedef struct _GtkCssImageFilter GtkCssImageFilter;
|
||||
typedef struct _GtkCssImageFilterClass GtkCssImageFilterClass;
|
||||
|
||||
struct _GtkCssImageFilter
|
||||
{
|
||||
GtkCssImage parent;
|
||||
|
||||
GtkCssImage *image;
|
||||
GtkCssValue *filter;
|
||||
};
|
||||
|
||||
struct _GtkCssImageFilterClass
|
||||
{
|
||||
GtkCssImageClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_css_image_filter_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkCssImage * gtk_css_image_filter_new (GtkCssImage *image,
|
||||
GtkCssValue *filter);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_CSS_IMAGE_FILTER_PRIVATE_H__ */
|
@@ -66,6 +66,7 @@ gtk_private_sources = files([
|
||||
'gtkcssimageconic.c',
|
||||
'gtkcssimagecrossfade.c',
|
||||
'gtkcssimagefallback.c',
|
||||
'gtkcssimagefilter.c',
|
||||
'gtkcssimageicontheme.c',
|
||||
'gtkcssimageinvalid.c',
|
||||
'gtkcssimagelinear.c',
|
||||
|
@@ -74,3 +74,11 @@ r {
|
||||
s {
|
||||
background-image: -gtk-scaled(-gtk-icontheme("object-select-symbolic"),linear-gradient(yellow, blue));
|
||||
}
|
||||
|
||||
t {
|
||||
background-image: cross-fade(10% image(red), 20% image(yellow), linear-gradient(blue, black));
|
||||
}
|
||||
|
||||
u {
|
||||
background-image: filter(url("test.png"), grayscale(100%) invert(50%));
|
||||
}
|
||||
|
@@ -73,3 +73,11 @@ r {
|
||||
s {
|
||||
background-image: -gtk-scaled(-gtk-icontheme("object-select-symbolic"),1,linear-gradient(rgb(255,255,0), rgb(0,0,255)),2);
|
||||
}
|
||||
|
||||
t {
|
||||
background-image: cross-fade(10% image(rgb(255,0,0)), 20% image(rgb(255,255,0)), linear-gradient(rgb(0,0,255), rgb(0,0,0)));
|
||||
}
|
||||
|
||||
u {
|
||||
background-image: filter(none /* FIXME */,grayscale(100%) invert(50%));
|
||||
}
|
||||
|
Reference in New Issue
Block a user