summaryrefslogtreecommitdiffstats
path: root/libgimpwidgets/gimpcairo-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgimpwidgets/gimpcairo-utils.c')
-rw-r--r--libgimpwidgets/gimpcairo-utils.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/libgimpwidgets/gimpcairo-utils.c b/libgimpwidgets/gimpcairo-utils.c
new file mode 100644
index 0000000..a956f28
--- /dev/null
+++ b/libgimpwidgets/gimpcairo-utils.c
@@ -0,0 +1,202 @@
+/* LIBGIMP - The GIMP Library
+ * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
+ *
+ * gimpcairo-utils.c
+ * Copyright (C) 2007 Sven Neumann <sven@gimp.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 3 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
+ * <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+
+#include "gimpcairo-utils.h"
+
+
+/**
+ * SECTION: gimpcairo-utils
+ * @title: GimpCairo-utils
+ * @short_description: Utility functions for cairo
+ *
+ * Utility functions that make cairo easier to use with common
+ * GIMP data types.
+ **/
+
+
+/**
+ * gimp_cairo_set_focus_line_pattern:
+ * @cr: Cairo context
+ * @widget: widget to draw the focus indicator on
+ *
+ * Sets color and dash pattern for stroking a focus line on the given
+ * @cr. The line pattern is taken from @widget.
+ *
+ * Return value: %TRUE if the widget style has a focus line pattern,
+ * %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+gimp_cairo_set_focus_line_pattern (cairo_t *cr,
+ GtkWidget *widget)
+{
+ gint8 *dash_list;
+ gboolean retval = FALSE;
+
+ g_return_val_if_fail (cr != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+
+ gtk_widget_style_get (widget,
+ "focus-line-pattern", (gchar *) &dash_list,
+ NULL);
+
+ if (dash_list[0])
+ {
+ /* Taken straight from gtk_default_draw_focus()
+ */
+ gint n_dashes = strlen ((const gchar *) dash_list);
+ gdouble *dashes = g_new (gdouble, n_dashes);
+ gdouble total_length = 0;
+ gint i;
+
+ for (i = 0; i < n_dashes; i++)
+ {
+ dashes[i] = dash_list[i];
+ total_length += dash_list[i];
+ }
+
+ cairo_set_dash (cr, dashes, n_dashes, 0.5);
+
+ g_free (dashes);
+
+ retval = TRUE;
+ }
+
+ g_free (dash_list);
+
+ return retval;
+}
+
+/**
+ * gimp_cairo_surface_create_from_pixbuf:
+ * @pixbuf: a #GdkPixbuf
+ *
+ * Create a Cairo image surface from a GdkPixbuf.
+ *
+ * You should avoid calling this function as there are probably more
+ * efficient ways of achieving the result you are looking for.
+ *
+ * Returns: a #cairo_surface_t.
+ *
+ * Since: 2.6
+ **/
+cairo_surface_t *
+gimp_cairo_surface_create_from_pixbuf (GdkPixbuf *pixbuf)
+{
+ cairo_surface_t *surface;
+ cairo_format_t format;
+ guchar *dest;
+ const guchar *src;
+ gint width;
+ gint height;
+ gint src_stride;
+ gint dest_stride;
+ gint y;
+
+ g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+
+ switch (gdk_pixbuf_get_n_channels (pixbuf))
+ {
+ case 3:
+ format = CAIRO_FORMAT_RGB24;
+ break;
+ case 4:
+ format = CAIRO_FORMAT_ARGB32;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ surface = cairo_image_surface_create (format, width, height);
+
+ cairo_surface_flush (surface);
+
+ src = gdk_pixbuf_get_pixels (pixbuf);
+ src_stride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ dest = cairo_image_surface_get_data (surface);
+ dest_stride = cairo_image_surface_get_stride (surface);
+
+ switch (format)
+ {
+ case CAIRO_FORMAT_RGB24:
+ for (y = 0; y < height; y++)
+ {
+ const guchar *s = src;
+ guchar *d = dest;
+ gint w = width;
+
+ while (w--)
+ {
+ GIMP_CAIRO_RGB24_SET_PIXEL (d, s[0], s[1], s[2]);
+
+ s += 3;
+ d += 4;
+ }
+
+ src += src_stride;
+ dest += dest_stride;
+ }
+ break;
+
+ case CAIRO_FORMAT_ARGB32:
+ for (y = 0; y < height; y++)
+ {
+ const guchar *s = src;
+ guchar *d = dest;
+ gint w = width;
+
+ while (w--)
+ {
+ GIMP_CAIRO_ARGB32_SET_PIXEL (d, s[0], s[1], s[2], s[3]);
+
+ s += 4;
+ d += 4;
+ }
+
+ src += src_stride;
+ dest += dest_stride;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ cairo_surface_mark_dirty (surface);
+
+ return surface;
+}