From 907a32752b637186451c56cc79fa19b35e7e33e2 Mon Sep 17 00:00:00 2001 From: Jim Evins Date: Sat, 12 Jun 2010 20:40:24 -0400 Subject: [PATCH] Add shadow property to image objects. Added shadow support to image objects. Shadow is created from the image's alpha channel, so the shadow will work properly for images with transparent backgrounds. More work needs to be done to better optimize the performance. --- src/Makefile.am | 4 ++ src/label-image.c | 60 ++++++++++++++++++- src/object-editor.c | 2 +- src/pixbuf-util.c | 143 ++++++++++++++++++++++++++++++++++++++++++++ src/pixbuf-util.h | 49 +++++++++++++++ 5 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 src/pixbuf-util.c create mode 100644 src/pixbuf-util.h diff --git a/src/Makefile.am b/src/Makefile.am index b25206db..72f8e05b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -147,6 +147,8 @@ glabels_3_SOURCES = \ label-image.h \ label-barcode.c \ label-barcode.h \ + pixbuf-util.c \ + pixbuf-util.h \ xml-label.c \ xml-label.h \ xml-label-04.c \ @@ -270,6 +272,8 @@ glabels_3_batch_SOURCES = \ label-image.h \ label-barcode.c \ label-barcode.h \ + pixbuf-util.c \ + pixbuf-util.h \ xml-label.c \ xml-label.h \ xml-label-04.c \ diff --git a/src/label-image.c b/src/label-image.c index f9573513..7b7181ea 100644 --- a/src/label-image.c +++ b/src/label-image.c @@ -26,6 +26,7 @@ #include #include +#include "pixbuf-util.h" #include "pixmaps/checkerboard.xpm" #include "debug.h" @@ -70,6 +71,11 @@ static void draw_object (glLabelObject *object, gboolean screen_flag, glMergeRecord *record); +static void draw_shadow (glLabelObject *object, + cairo_t *cr, + gboolean screen_flag, + glMergeRecord *record); + static gboolean object_at (glLabelObject *object, cairo_t *cr, gdouble x_pixels, @@ -93,7 +99,7 @@ gl_label_image_class_init (glLabelImageClass *class) label_object_class->copy = copy; label_object_class->set_size = set_size; label_object_class->draw_object = draw_object; - label_object_class->draw_shadow = NULL; + label_object_class->draw_shadow = draw_shadow; label_object_class->object_at = object_at; object_class->finalize = gl_label_image_finalize; @@ -418,7 +424,6 @@ draw_object (glLabelObject *object, gboolean screen_flag, glMergeRecord *record) { - gdouble x0, y0; gdouble w, h; const GdkPixbuf *pixbuf; gint image_w, image_h; @@ -426,7 +431,6 @@ draw_object (glLabelObject *object, gl_debug (DEBUG_LABEL, "START"); gl_label_object_get_size (object, &w, &h); - gl_label_object_get_position (object, &x0, &y0); pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE (object), record); image_w = gdk_pixbuf_get_width (pixbuf); @@ -446,6 +450,56 @@ draw_object (glLabelObject *object, } +/*****************************************************************************/ +/* Draw shadow method. */ +/*****************************************************************************/ +static void +draw_shadow (glLabelObject *object, + cairo_t *cr, + gboolean screen_flag, + glMergeRecord *record) +{ + gdouble w, h; + const GdkPixbuf *pixbuf; + GdkPixbuf *shadow_pixbuf; + gint image_w, image_h; + glColorNode *shadow_color_node; + guint shadow_color; + gdouble shadow_opacity; + + gl_debug (DEBUG_LABEL, "START"); + + gl_label_object_get_size (object, &w, &h); + + shadow_color_node = gl_label_object_get_shadow_color (object); + shadow_color = gl_color_node_expand (shadow_color_node, record); + if (shadow_color_node->field_flag && screen_flag) + { + shadow_color = GL_COLOR_SHADOW_MERGE_DEFAULT; + } + shadow_opacity = gl_label_object_get_shadow_opacity (object); + + pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE (object), record); + image_w = gdk_pixbuf_get_width (pixbuf); + image_h = gdk_pixbuf_get_height (pixbuf); + shadow_pixbuf = gl_pixbuf_util_create_shadow_pixbuf (pixbuf, shadow_color, shadow_opacity); + + cairo_save (cr); + + cairo_rectangle (cr, 0.0, 0.0, w, h); + + cairo_scale (cr, w/image_w, h/image_h); + gdk_cairo_set_source_pixbuf (cr, (GdkPixbuf *)shadow_pixbuf, 0, 0); + cairo_fill (cr); + + cairo_restore (cr); + + g_object_unref (G_OBJECT (shadow_pixbuf)); + + gl_debug (DEBUG_LABEL, "END"); +} + + /*****************************************************************************/ /* Is object at coordinates? */ /*****************************************************************************/ diff --git a/src/object-editor.c b/src/object-editor.c index c792e7c2..d544c55f 100644 --- a/src/object-editor.c +++ b/src/object-editor.c @@ -373,7 +373,7 @@ set_object (glObjectEditor *editor, gtk_widget_hide (editor->priv->edit_page_vbox); gtk_widget_hide (editor->priv->bc_page_vbox); gtk_widget_hide (editor->priv->data_page_vbox); - gtk_widget_hide (editor->priv->shadow_page_vbox); + gtk_widget_show_all (editor->priv->shadow_page_vbox); } else if (GL_IS_LABEL_TEXT (object)) { diff --git a/src/pixbuf-util.c b/src/pixbuf-util.c new file mode 100644 index 00000000..910a19f5 --- /dev/null +++ b/src/pixbuf-util.c @@ -0,0 +1,143 @@ +/* + * pixbuf-util.c + * Copyright (C) 2010 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gLabels 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gLabels. If not, see . + */ + +#include + +#include "pixbuf-util.h" + +#include "color.h" + +#include "debug.h" + + +/*========================================================*/ +/* Private macros and constants. */ +/*========================================================*/ + + +/*========================================================*/ +/* Private types. */ +/*========================================================*/ + + +/*========================================================*/ +/* Private globals. */ +/*========================================================*/ + + +/*========================================================*/ +/* Private function prototypes. */ +/*========================================================*/ + + +/****************************************************************************/ +/* Create shadow version of given pixbuf. */ +/****************************************************************************/ +GdkPixbuf * +gl_pixbuf_util_create_shadow_pixbuf (const GdkPixbuf *pixbuf, + guint shadow_color, + gdouble shadow_opacity) +{ + gint bits_per_sample, channels; + gboolean src_has_alpha; + gint width, height, src_rowstride, dest_rowstride; + GdkPixbuf *dest_pixbuf; + guchar *buf_src, *buf_dest; + guchar *p_src, *p_dest; + gint ix, iy; + guchar shadow_r, shadow_g, shadow_b; + + g_return_val_if_fail (pixbuf && GDK_IS_PIXBUF (pixbuf), NULL); + + shadow_r = GL_COLOR_F_RED (shadow_color) * 255.0; + shadow_g = GL_COLOR_F_GREEN (shadow_color) * 255.0; + shadow_b = GL_COLOR_F_BLUE (shadow_color) * 255.0; + + /* extract pixels and parameters from source pixbuf. */ + buf_src = gdk_pixbuf_get_pixels (pixbuf); + bits_per_sample = gdk_pixbuf_get_bits_per_sample (pixbuf); + channels = gdk_pixbuf_get_n_channels (pixbuf); + src_has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + src_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + + /* validate assumptions about source pixbuf. */ + g_return_val_if_fail (buf_src, NULL); + g_return_val_if_fail (bits_per_sample == 8, NULL); + g_return_val_if_fail ((channels >= 3) && (channels <= 4), NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + g_return_val_if_fail (src_rowstride > 0, NULL); + + /* Allocate a destination pixbuf */ + dest_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, bits_per_sample, width, height); + dest_rowstride = gdk_pixbuf_get_rowstride (dest_pixbuf); + buf_dest = gdk_pixbuf_get_pixels (dest_pixbuf); + if (!buf_dest) { + return NULL; + } + + /* Process pixels: set rgb components and composite alpha with shadow_opacity. */ + p_src = buf_src; + p_dest = buf_dest; + for ( iy=0; iy < height; iy++ ) + { + + p_src = buf_src + iy*src_rowstride; + p_dest = buf_dest + iy*dest_rowstride; + + for ( ix=0; ix < width; ix++ ) + { + + p_src += 3; /* skip RGB */ + + *p_dest++ = shadow_r; + *p_dest++ = shadow_g; + *p_dest++ = shadow_b; + + if ( src_has_alpha ) + { + *p_dest++ = *p_src++ * shadow_opacity; + } + else + { + *p_dest++ = shadow_opacity * 255.0; + } + + + } + + } + + return dest_pixbuf; +} + + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/pixbuf-util.h b/src/pixbuf-util.h new file mode 100644 index 00000000..84dcb423 --- /dev/null +++ b/src/pixbuf-util.h @@ -0,0 +1,49 @@ +/* + * pixbuf-util.h + * Copyright (C) 2010 Jim Evins . + * + * This file is part of gLabels. + * + * gLabels is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * gLabels 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with gLabels. If not, see . + */ + +#ifndef __PIXBUF_UTIL_H__ +#define __PIXBUF_UTIL_H__ + +#include +#include + +G_BEGIN_DECLS + + +GdkPixbuf *gl_pixbuf_util_create_shadow_pixbuf (const GdkPixbuf *pixbuf, + guint shadow_color, + gdouble shadow_opacity); + + +G_END_DECLS + +#endif /* __PIXBUF_UTIL_H__ */ + + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ -- 2.39.5