diff options
author | Alexander Larsson <alexl@redhat.com> | 2013-06-27 18:29:38 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2013-07-03 14:39:25 +0200 |
commit | 48ff7d026eeb3931bff607787c743bd756c8710a (patch) | |
tree | 362a5115d6d9bfbcbd9d7eabef72bc3db35a3a04 | |
parent | af2c40bd54149237cd4ab998b5515167018fdc47 (diff) | |
download | gtk+-48ff7d026eeb3931bff607787c743bd756c8710a.tar.gz |
CSS: Add -gtk-scaled(image1,image2,...) support for hidpi assets
-rw-r--r-- | gtk/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/gtkcssimage.c | 2 | ||||
-rw-r--r-- | gtk/gtkcssimagescaled.c | 205 | ||||
-rw-r--r-- | gtk/gtkcssimagescaledprivate.h | 55 |
4 files changed, 264 insertions, 0 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index f5fc3d1a69..1fdb26cd21 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -449,6 +449,7 @@ gtk_private_h_sources = \ gtkcssimageprivate.h \ gtkcssimagesurfaceprivate.h \ gtkcssimageurlprivate.h \ + gtkcssimagescaledprivate.h \ gtkcssimagevalueprivate.h \ gtkcssimagewin32private.h \ gtkcssinheritvalueprivate.h \ @@ -683,6 +684,7 @@ gtk_base_c_sources = \ gtkcssimagelinear.c \ gtkcssimagesurface.c \ gtkcssimageurl.c \ + gtkcssimagescaled.c \ gtkcssimagevalue.c \ gtkcssimagewin32.c \ gtkcssinheritvalue.c \ diff --git a/gtk/gtkcssimage.c b/gtk/gtkcssimage.c index d1c1df72bb..a79b3e1398 100644 --- a/gtk/gtkcssimage.c +++ b/gtk/gtkcssimage.c @@ -28,6 +28,7 @@ #include "gtk/gtkcssimagegradientprivate.h" #include "gtk/gtkcssimagelinearprivate.h" #include "gtk/gtkcssimageurlprivate.h" +#include "gtk/gtkcssimagescaledprivate.h" #include "gtk/gtkcssimagewin32private.h" G_DEFINE_ABSTRACT_TYPE (GtkCssImage, _gtk_css_image, G_TYPE_OBJECT) @@ -419,6 +420,7 @@ gtk_css_image_get_parser_type (GtkCssParser *parser) } image_types[] = { { "url", _gtk_css_image_url_get_type }, { "-gtk-gradient", _gtk_css_image_gradient_get_type }, + { "-gtk-scaled", _gtk_css_image_scaled_get_type }, { "-gtk-win32-theme-part", _gtk_css_image_win32_get_type }, { "linear-gradient", _gtk_css_image_linear_get_type }, { "repeating-linear-gradient", _gtk_css_image_linear_get_type }, diff --git a/gtk/gtkcssimagescaled.c b/gtk/gtkcssimagescaled.c new file mode 100644 index 0000000000..125e53e7df --- /dev/null +++ b/gtk/gtkcssimagescaled.c @@ -0,0 +1,205 @@ +/* + * Copyright © 2013 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: Alexander Larsson <alexl@gnome.org> + */ + +#include "config.h" + +#include "gtkcssimagescaledprivate.h" + +G_DEFINE_TYPE (GtkCssImageScaled, _gtk_css_image_scaled, GTK_TYPE_CSS_IMAGE) + +static int +gtk_css_image_scaled_get_width (GtkCssImage *image) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image); + + return _gtk_css_image_get_width (scaled->images[scaled->scale - 1]) / scaled->scale; +} + +static int +gtk_css_image_scaled_get_height (GtkCssImage *image) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image); + + return _gtk_css_image_get_height (scaled->images[scaled->scale - 1]) / scaled->scale; +} + +static double +gtk_css_image_scaled_get_aspect_ratio (GtkCssImage *image) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image); + + return _gtk_css_image_get_aspect_ratio (scaled->images[scaled->scale - 1]); +} + +static void +gtk_css_image_scaled_draw (GtkCssImage *image, + cairo_t *cr, + double width, + double height) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image); + + _gtk_css_image_draw (scaled->images[scaled->scale - 1], cr, width, height); +} + +static void +gtk_css_image_scaled_print (GtkCssImage *image, + GString *string) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image); + int i; + + g_string_append (string, "-gtk-scaled("); + for (i = 0; i < scaled->n_images; i++) + { + _gtk_css_image_print (scaled->images[i], string); + if (i != scaled->n_images - 1) + g_string_append (string, ","); + } + g_string_append (string, ")"); +} + +static void +gtk_css_image_scaled_dispose (GObject *object) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (object); + int i; + + for (i = 0; i < scaled->n_images; i++) + g_object_unref (scaled->images[i]); + g_free (scaled->images); + scaled->images = NULL; + + G_OBJECT_CLASS (_gtk_css_image_scaled_parent_class)->dispose (object); +} + + +static GtkCssImage * +gtk_css_image_scaled_compute (GtkCssImage *image, + guint property_id, + GtkStyleProviderPrivate *provider, + int scale, + GtkCssComputedValues *values, + GtkCssComputedValues *parent_values, + GtkCssDependencies *dependencies) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image); + GtkCssImageScaled *copy; + int i; + + scale = MAX(MIN (scale, scaled->n_images), 1); + + if (scaled->scale == scale) + return g_object_ref (scaled); + else + { + copy = g_object_new (_gtk_css_image_scaled_get_type (), NULL); + copy->scale = scale; + copy->n_images = scaled->n_images; + copy->images = g_new (GtkCssImage *, scaled->n_images); + for (i = 0; i < scaled->n_images; i++) + { + if (i == scale - 1) + copy->images[i] = _gtk_css_image_compute (scaled->images[i], + property_id, + provider, + scale, + values, + parent_values, + dependencies); + else + copy->images[i] = g_object_ref (scaled->images[i]); + } + + return GTK_CSS_IMAGE (copy); + } +} + +static gboolean +gtk_css_image_scaled_parse (GtkCssImage *image, + GtkCssParser *parser) +{ + GtkCssImageScaled *scaled = GTK_CSS_IMAGE_SCALED (image); + GPtrArray *images; + GtkCssImage *child; + + if (!_gtk_css_parser_try (parser, "-gtk-scaled", TRUE)) + { + _gtk_css_parser_error (parser, "'-gtk-scaled'"); + return FALSE; + } + + if (!_gtk_css_parser_try (parser, "(", TRUE)) + { + _gtk_css_parser_error (parser, + "Expected '(' after '-gtk-scaled'"); + return FALSE; + } + + images = g_ptr_array_new_with_free_func (g_object_unref); + + do + { + child = _gtk_css_image_new_parse (parser); + if (child == NULL) + { + g_ptr_array_free (images, TRUE); + return FALSE; + } + g_ptr_array_add (images, child); + + } + while ( _gtk_css_parser_try (parser, ",", TRUE)); + + if (!_gtk_css_parser_try (parser, ")", TRUE)) + { + g_ptr_array_free (images, TRUE); + _gtk_css_parser_error (parser, + "Expected ')' at end of '-gtk-scaled'"); + return FALSE; + } + + scaled->n_images = images->len; + scaled->images = (GtkCssImage **) g_ptr_array_free (images, FALSE); + + return TRUE; +} + +static void +_gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass) +{ + GtkCssImageClass *image_class = GTK_CSS_IMAGE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + image_class->get_width = gtk_css_image_scaled_get_width; + image_class->get_height = gtk_css_image_scaled_get_height; + image_class->get_aspect_ratio = gtk_css_image_scaled_get_aspect_ratio; + image_class->draw = gtk_css_image_scaled_draw; + image_class->parse = gtk_css_image_scaled_parse; + image_class->compute = gtk_css_image_scaled_compute; + image_class->print = gtk_css_image_scaled_print; + + object_class->dispose = gtk_css_image_scaled_dispose; +} + +static void +_gtk_css_image_scaled_init (GtkCssImageScaled *image_scaled) +{ + image_scaled->scale = 1; +} diff --git a/gtk/gtkcssimagescaledprivate.h b/gtk/gtkcssimagescaledprivate.h new file mode 100644 index 0000000000..ec1b6697c8 --- /dev/null +++ b/gtk/gtkcssimagescaledprivate.h @@ -0,0 +1,55 @@ +/* + * Copyright © 2013 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: Alexander Larsson <alexl@gnome.org> + */ + +#ifndef __GTK_CSS_IMAGE_SCALED_PRIVATE_H__ +#define __GTK_CSS_IMAGE_SCALED_PRIVATE_H__ + +#include "gtk/gtkcssimageprivate.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_CSS_IMAGE_SCALED (_gtk_css_image_scaled_get_type ()) +#define GTK_CSS_IMAGE_SCALED(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_IMAGE_SCALED, GtkCssImageScaled)) +#define GTK_CSS_IMAGE_SCALED_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_IMAGE_SCALED, GtkCssImageScaledClass)) +#define GTK_IS_CSS_IMAGE_SCALED(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_IMAGE_SCALED)) +#define GTK_IS_CSS_IMAGE_SCALED_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_IMAGE_SCALED)) +#define GTK_CSS_IMAGE_SCALED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_IMAGE_SCALED, GtkCssImageScaledClass)) + +typedef struct _GtkCssImageScaled GtkCssImageScaled; +typedef struct _GtkCssImageScaledClass GtkCssImageScaledClass; + +struct _GtkCssImageScaled +{ + GtkCssImage parent; + + int scale; + GtkCssImage **images; + int n_images; +}; + +struct _GtkCssImageScaledClass +{ + GtkCssImageClass parent_class; +}; + +GType _gtk_css_image_scaled_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GTK_CSS_IMAGE_SCALED_PRIVATE_H__ */ |