[glabels] Add shadow property to image objects.



commit 907a32752b637186451c56cc79fa19b35e7e33e2
Author: Jim Evins <evins snaught com>
Date:   Sat Jun 12 20:40:24 2010 -0400

    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(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b25206d..72f8e05 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 f957351..7b7181e 100644
--- a/src/label-image.c
+++ b/src/label-image.c
@@ -26,6 +26,7 @@
 #include <glib.h>
 #include <gdk/gdk.h>
 
+#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);
@@ -447,6 +451,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?                                                 */
 /*****************************************************************************/
 static gboolean
diff --git a/src/object-editor.c b/src/object-editor.c
index c792e7c..d544c55 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 0000000..910a19f
--- /dev/null
+++ b/src/pixbuf-util.c
@@ -0,0 +1,143 @@
+/*
+ *  pixbuf-util.c
+ *  Copyright (C) 2010  Jim Evins <evins snaught com>.
+ *
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#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 0000000..84dcb42
--- /dev/null
+++ b/src/pixbuf-util.h
@@ -0,0 +1,49 @@
+/*
+ *  pixbuf-util.h
+ *  Copyright (C) 2010  Jim Evins <evins snaught com>.
+ *
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __PIXBUF_UTIL_H__
+#define __PIXBUF_UTIL_H__
+
+#include <glib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+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
+ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]