diff options
author | Matthias Clasen <mclasen@redhat.com> | 2023-05-16 22:00:08 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2023-05-16 22:00:08 -0400 |
commit | c2ba1d69a1b1bd04571db0e0813e85c4ee6a14ef (patch) | |
tree | 30a7ab535ffe1317799444032bee877ac93948fd /gtk/gdkpixbufutils.c | |
parent | 847739aed7cf6f6cf5f745fdef0a976980089ea9 (diff) | |
download | gtk+-c2ba1d69a1b1bd04571db0e0813e85c4ee6a14ef.tar.gz |
Rename pixbuf utils to texture utils
That is what this is now.
Diffstat (limited to 'gtk/gdkpixbufutils.c')
-rw-r--r-- | gtk/gdkpixbufutils.c | 739 |
1 files changed, 0 insertions, 739 deletions
diff --git a/gtk/gdkpixbufutils.c b/gtk/gdkpixbufutils.c deleted file mode 100644 index b96282c94d..0000000000 --- a/gtk/gdkpixbufutils.c +++ /dev/null @@ -1,739 +0,0 @@ -/* Copyright (C) 2016 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 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 <gdk/gdk.h> -#include "gdkpixbufutilsprivate.h" -#include "gtkscalerprivate.h" - -#include "gdk/gdktextureprivate.h" - -/* {{{ Pixbuf helpers */ - -static GdkPixbuf * -load_from_stream (GdkPixbufLoader *loader, - GInputStream *stream, - GCancellable *cancellable, - GError **error) -{ - GdkPixbuf *pixbuf; - gssize n_read; - guchar buffer[65536]; - gboolean res; - - res = TRUE; - while (1) - { - n_read = g_input_stream_read (stream, buffer, sizeof (buffer), cancellable, error); - if (n_read < 0) - { - res = FALSE; - error = NULL; /* Ignore further errors */ - break; - } - - if (n_read == 0) - break; - - if (!gdk_pixbuf_loader_write (loader, buffer, n_read, error)) - { - res = FALSE; - error = NULL; - break; - } - } - - if (!gdk_pixbuf_loader_close (loader, error)) - { - res = FALSE; - error = NULL; - } - - pixbuf = NULL; - - if (res) - { - pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - if (pixbuf) - g_object_ref (pixbuf); - } - - return pixbuf; -} - -static void -size_prepared_cb (GdkPixbufLoader *loader, - int width, - int height, - gpointer data) -{ - double *scale = data; - - width = MAX (*scale * width, 1); - height = MAX (*scale * height, 1); - - gdk_pixbuf_loader_set_size (loader, width, height); -} - -/* Like gdk_pixbuf_new_from_stream_at_scale, but - * load the image at its original size times the - * given scale. - */ -static GdkPixbuf * -_gdk_pixbuf_new_from_stream_scaled (GInputStream *stream, - double scale, - GCancellable *cancellable, - GError **error) -{ - GdkPixbufLoader *loader; - GdkPixbuf *pixbuf; - - loader = gdk_pixbuf_loader_new (); - - if (scale != 0) - g_signal_connect (loader, "size-prepared", - G_CALLBACK (size_prepared_cb), &scale); - - pixbuf = load_from_stream (loader, stream, cancellable, error); - - g_object_unref (loader); - - return pixbuf; -} - -static void -size_prepared_cb2 (GdkPixbufLoader *loader, - int width, - int height, - gpointer data) -{ - int *scales = data; - - if (scales[2]) /* keep same aspect ratio as original, while fitting in given size */ - { - double aspect = (double) height / width; - - /* First use given width and calculate size */ - width = scales[0]; - height = scales[0] * aspect; - - /* Check if it fits given height, otherwise scale down */ - if (height > scales[1]) - { - width *= (double) scales[1] / height; - height = scales[1]; - } - } - else - { - width = scales[0]; - height = scales[1]; - } - - gdk_pixbuf_loader_set_size (loader, width, height); -} - -static GdkPixbuf * -_gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream, - int width, - int height, - gboolean aspect, - GCancellable *cancellable, - GError **error) -{ - GdkPixbufLoader *loader; - GdkPixbuf *pixbuf; - int scales[3]; - - loader = gdk_pixbuf_loader_new (); - - scales[0] = width; - scales[1] = height; - scales[2] = aspect; - g_signal_connect (loader, "size-prepared", - G_CALLBACK (size_prepared_cb2), scales); - - pixbuf = load_from_stream (loader, stream, cancellable, error); - - g_object_unref (loader); - - return pixbuf; -} - -static GdkPixbuf * -_gdk_pixbuf_new_from_resource_at_scale (const char *resource_path, - int width, - int height, - gboolean preserve_aspect, - GError **error) -{ - GInputStream *stream; - GdkPixbuf *pixbuf; - - stream = g_resources_open_stream (resource_path, 0, error); - if (stream == NULL) - return NULL; - - pixbuf = _gdk_pixbuf_new_from_stream_at_scale (stream, width, height, preserve_aspect, NULL, error); - g_object_unref (stream); - - return pixbuf; -} - -/* }}} */ -/* {{{ Symbolic processing */ - -static GdkPixbuf * -load_symbolic_svg (const char *escaped_file_data, - int width, - int height, - const char *icon_width_str, - const char *icon_height_str, - const char *fg_string, - const char *success_color_string, - const char *warning_color_string, - const char *error_color_string, - GError **error) -{ - GInputStream *stream; - GdkPixbuf *pixbuf; - char *data; - - data = g_strconcat ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" - "<svg version=\"1.1\"\n" - " xmlns=\"http://www.w3.org/2000/svg\"\n" - " xmlns:xi=\"http://www.w3.org/2001/XInclude\"\n" - " width=\"", icon_width_str, "\"\n" - " height=\"", icon_height_str, "\">\n" - " <style type=\"text/css\">\n" - " rect,circle,path {\n" - " fill: ", fg_string," !important;\n" - " }\n" - " .warning {\n" - " fill: ", warning_color_string, " !important;\n" - " }\n" - " .error {\n" - " fill: ", error_color_string ," !important;\n" - " }\n" - " .success {\n" - " fill: ", success_color_string, " !important;\n" - " }\n" - " </style>\n" - " <xi:include href=\"data:text/xml;base64,", escaped_file_data, "\"/>\n" - "</svg>", - NULL); - - stream = g_memory_input_stream_new_from_data (data, -1, g_free); - pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, width, height, TRUE, NULL, error); - g_object_unref (stream); - - return pixbuf; -} - -static void -extract_plane (GdkPixbuf *src, - GdkPixbuf *dst, - int from_plane, - int to_plane) -{ - guchar *src_data, *dst_data; - int width, height; - gsize src_stride, dst_stride; - guchar *src_row, *dst_row; - int x, y; - - width = gdk_pixbuf_get_width (src); - height = gdk_pixbuf_get_height (src); - - g_assert (width <= gdk_pixbuf_get_width (dst)); - g_assert (height <= gdk_pixbuf_get_height (dst)); - - src_stride = gdk_pixbuf_get_rowstride (src); - src_data = gdk_pixbuf_get_pixels (src); - - dst_data = gdk_pixbuf_get_pixels (dst); - dst_stride = gdk_pixbuf_get_rowstride (dst); - - for (y = 0; y < height; y++) - { - src_row = src_data + src_stride * y; - dst_row = dst_data + dst_stride * y; - for (x = 0; x < width; x++) - { - dst_row[to_plane] = src_row[from_plane]; - src_row += 4; - dst_row += 4; - } - } -} - -GdkPixbuf * -gtk_make_symbolic_pixbuf_from_data (const char *file_data, - gsize file_len, - int width, - int height, - double scale, - const char *debug_output_basename, - GError **error) - -{ - const char *r_string = "rgb(255,0,0)"; - const char *g_string = "rgb(0,255,0)"; - char *icon_width_str; - char *icon_height_str; - GdkPixbuf *loaded; - GdkPixbuf *pixbuf = NULL; - int plane; - int icon_width, icon_height; - char *escaped_file_data; - - /* Fetch size from the original icon */ - GInputStream *stream = g_memory_input_stream_new_from_data (file_data, file_len, NULL); - GdkPixbuf *reference = gdk_pixbuf_new_from_stream (stream, NULL, error); - - g_object_unref (stream); - - if (!reference) - return NULL; - - icon_width = gdk_pixbuf_get_width (reference); - icon_height = gdk_pixbuf_get_height (reference); - g_object_unref (reference); - - escaped_file_data = g_base64_encode ((guchar *) file_data, file_len); - icon_width_str = g_strdup_printf ("%d", icon_width); - icon_height_str = g_strdup_printf ("%d", icon_height); - - if (width == 0) - width = icon_width * scale; - if (height == 0) - height = icon_height * scale; - - for (plane = 0; plane < 3; plane++) - { - /* Here we render the svg with all colors solid, this should - * always make the alpha channel the same and it should match - * the final alpha channel for all possible renderings. We - * Just use it as-is for final alpha. - * - * For the 3 non-fg colors, we render once each with that - * color as red, and every other color as green. The resulting - * red will describe the amount of that color is in the - * opaque part of the color. We store these as the rgb - * channels, with the color of the fg being implicitly - * the "rest", as all color fractions should add up to 1. - */ - loaded = load_symbolic_svg (escaped_file_data, width, height, - icon_width_str, - icon_height_str, - g_string, - plane == 0 ? r_string : g_string, - plane == 1 ? r_string : g_string, - plane == 2 ? r_string : g_string, - error); - if (loaded == NULL) - goto out; - - if (debug_output_basename) - { - char *filename; - - filename = g_strdup_printf ("%s.debug%d.png", debug_output_basename, plane); - g_print ("Writing %s\n", filename); - gdk_pixbuf_save (loaded, filename, "png", NULL, NULL); - g_free (filename); - } - - if (pixbuf == NULL) - { - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, - gdk_pixbuf_get_width (loaded), - gdk_pixbuf_get_height (loaded)); - gdk_pixbuf_fill (pixbuf, 0); - } - - if (plane == 0) - extract_plane (loaded, pixbuf, 3, 3); - - extract_plane (loaded, pixbuf, 0, plane); - - g_object_unref (loaded); - } - - g_free (escaped_file_data); - -out: - g_free (icon_width_str); - g_free (icon_height_str); - - return pixbuf; -} - -static GdkPixbuf * -make_symbolic_pixbuf_from_resource (const char *path, - int width, - int height, - double scale, - GError **error) -{ - GBytes *bytes; - const char *data; - gsize size; - GdkPixbuf *pixbuf; - - bytes = g_resources_lookup_data (path, G_RESOURCE_LOOKUP_FLAGS_NONE, error); - if (bytes == NULL) - return NULL; - - data = g_bytes_get_data (bytes, &size); - - pixbuf = gtk_make_symbolic_pixbuf_from_data (data, size, width, height, scale, NULL, error); - - g_bytes_unref (bytes); - - return pixbuf; -} - -static GdkPixbuf * -make_symbolic_pixbuf_from_path (const char *path, - int width, - int height, - double scale, - GError **error) -{ - char *data; - gsize size; - GdkPixbuf *pixbuf; - - if (!g_file_get_contents (path, &data, &size, error)) - return NULL; - - pixbuf = gtk_make_symbolic_pixbuf_from_data (data, size, width, height, scale, NULL, error); - - g_free (data); - - return pixbuf; -} - -static GdkPixbuf * -make_symbolic_pixbuf_from_file (GFile *file, - int width, - int height, - double scale, - GError **error) -{ - char *data; - gsize size; - GdkPixbuf *pixbuf; - - if (!g_file_load_contents (file, NULL, &data, &size, NULL, error)) - return NULL; - - pixbuf = gtk_make_symbolic_pixbuf_from_data (data, size, width, height, scale, NULL, error); - - g_free (data); - - return pixbuf; -} - -/* }}} */ -/* {{{ Texture API */ - -GdkTexture * -gdk_texture_new_from_stream_at_scale (GInputStream *stream, - int width, - int height, - gboolean aspect, - GCancellable *cancellable, - GError **error) -{ - GdkPixbuf *pixbuf; - GdkTexture *texture = NULL; - - pixbuf = _gdk_pixbuf_new_from_stream_at_scale (stream, width, height, aspect, cancellable, error); - if (pixbuf) - { - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - } - - return texture; -} - -GdkTexture * -gdk_texture_new_from_stream (GInputStream *stream, - GCancellable *cancellable, - GError **error) -{ - GdkPixbuf *pixbuf; - GdkTexture *texture = NULL; - - pixbuf = _gdk_pixbuf_new_from_stream_scaled (stream, 0, cancellable, error); - if (pixbuf) - { - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - } - - return texture; -} - -GdkTexture * -gdk_texture_new_from_resource_at_scale (const char *path, - int width, - int height, - gboolean preserve_aspect, - GError **error) -{ - GdkPixbuf *pixbuf; - GdkTexture *texture = NULL; - - pixbuf = _gdk_pixbuf_new_from_resource_at_scale (path, width, height, preserve_aspect, error); - if (pixbuf) - { - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - } - - return texture; -} - -/* }}} */ -/* {{{ Symbolic texture API */ - -GdkTexture * -gdk_texture_new_from_path_symbolic (const char *path, - int width, - int height, - double scale, - GError **error) -{ - GdkPixbuf *pixbuf; - GdkTexture *texture = NULL; - - pixbuf = make_symbolic_pixbuf_from_path (path, width, height, scale, error); - if (pixbuf) - { - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - } - - return texture; -} - -GdkTexture * -gtk_load_symbolic_texture_from_resource (const char *path) -{ - return gdk_texture_new_from_resource (path); -} - -GdkTexture * -gdk_texture_new_from_resource_symbolic (const char *path, - int width, - int height, - double scale, - GError **error) -{ - GdkPixbuf *pixbuf; - GdkTexture *texture = NULL; - - pixbuf = make_symbolic_pixbuf_from_resource (path, width, height, scale, error); - if (pixbuf) - { - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - } - - return texture; -} - -GdkTexture * -gtk_load_symbolic_texture_from_file (GFile *file) -{ - GdkPixbuf *pixbuf; - GdkTexture *texture; - GInputStream *stream; - - stream = G_INPUT_STREAM (g_file_read (file, NULL, NULL)); - if (stream == NULL) - return NULL; - - pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL); - g_object_unref (stream); - if (pixbuf == NULL) - return NULL; - - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - - return texture; -} - -GdkTexture * -gdk_texture_new_from_file_symbolic (GFile *file, - int width, - int height, - double scale, - GError **error) -{ - GdkPixbuf *pixbuf; - GdkTexture *texture; - - pixbuf = make_symbolic_pixbuf_from_file (file, width, height, scale, error); - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - - return texture; -} - -/* }}} */ -/* {{{ Scaled paintable API */ - -typedef struct { - int scale_factor; -} LoaderData; - -static void -on_loader_size_prepared (GdkPixbufLoader *loader, - int width, - int height, - gpointer user_data) -{ - LoaderData *loader_data = user_data; - GdkPixbufFormat *format; - - /* Let the regular icon helper code path handle non-scalable images */ - format = gdk_pixbuf_loader_get_format (loader); - if (!gdk_pixbuf_format_is_scalable (format)) - { - loader_data->scale_factor = 1; - return; - } - - gdk_pixbuf_loader_set_size (loader, - width * loader_data->scale_factor, - height * loader_data->scale_factor); -} - -static GdkPaintable * -gdk_paintable_new_from_bytes_scaled (GBytes *bytes, - int scale_factor) -{ - LoaderData loader_data; - GdkTexture *texture; - GdkPaintable *paintable; - - loader_data.scale_factor = scale_factor; - - if (gdk_texture_can_load (bytes)) - { - texture = gdk_texture_new_from_bytes (bytes, NULL); - if (texture == NULL) - return NULL; - - /* We know these formats can't be scaled */ - paintable = GDK_PAINTABLE (texture); - } - else - { - GdkPixbufLoader *loader; - gboolean success; - - loader = gdk_pixbuf_loader_new (); - g_signal_connect (loader, "size-prepared", - G_CALLBACK (on_loader_size_prepared), &loader_data); - - success = gdk_pixbuf_loader_write_bytes (loader, bytes, NULL); - /* close even when writing failed */ - success &= gdk_pixbuf_loader_close (loader, NULL); - - if (!success) - return NULL; - - texture = gdk_texture_new_for_pixbuf (gdk_pixbuf_loader_get_pixbuf (loader)); - g_object_unref (loader); - - if (loader_data.scale_factor != 1) - paintable = gtk_scaler_new (GDK_PAINTABLE (texture), loader_data.scale_factor); - else - paintable = g_object_ref (GDK_PAINTABLE (texture)); - - g_object_unref (texture); - } - - return paintable; -} - -GdkPaintable * -gdk_paintable_new_from_path_scaled (const char *path, - int scale_factor) -{ - char *contents; - gsize length; - GBytes *bytes; - GdkPaintable *paintable; - - if (!g_file_get_contents (path, &contents, &length, NULL)) - return NULL; - - bytes = g_bytes_new_take (contents, length); - - paintable = gdk_paintable_new_from_bytes_scaled (bytes, scale_factor); - - g_bytes_unref (bytes); - - return paintable; -} - -GdkPaintable * -gdk_paintable_new_from_resource_scaled (const char *path, - int scale_factor) -{ - GBytes *bytes; - GdkPaintable *paintable; - - bytes = g_resources_lookup_data (path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); - if (!bytes) - return NULL; - - paintable = gdk_paintable_new_from_bytes_scaled (bytes, scale_factor); - g_bytes_unref (bytes); - - return paintable; -} - -GdkPaintable * -gdk_paintable_new_from_file_scaled (GFile *file, - int scale_factor) -{ - GBytes *bytes; - GdkPaintable *paintable; - - bytes = g_file_load_bytes (file, NULL, NULL, NULL); - if (!bytes) - return NULL; - - paintable = gdk_paintable_new_from_bytes_scaled (bytes, scale_factor); - - g_bytes_unref (bytes); - - return paintable; -} - -/* }}} */ - -/* vim:set foldmethod=marker expandtab: */ |