]> git.sur5r.net Git - glabels/commitdiff
Add shadow property to image objects.
authorJim Evins <evins@snaught.com>
Sun, 13 Jun 2010 00:40:24 +0000 (20:40 -0400)
committerJim Evins <evins@snaught.com>
Sun, 13 Jun 2010 00:40:24 +0000 (20:40 -0400)
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
src/label-image.c
src/object-editor.c
src/pixbuf-util.c [new file with mode: 0644]
src/pixbuf-util.h [new file with mode: 0644]

index b25206db5005477d8a54708b3bbcfacc24a396df..72f8e05b9e51349f447f09097530d6841425e709 100644 (file)
@@ -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                  \
index f957351376bed3f2b61c76c7bfb054aaf60d3b97..7b7181ea5787d936dad4655ea837c6ef592135aa 100644 (file)
@@ -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);
@@ -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?                                                 */
 /*****************************************************************************/
index c792e7c2687eac9f5cbdc93e28a778bec9bc3736..d544c55f83d39327f0c404ccbaf7ba149ac3a5ef 100644 (file)
@@ -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 (file)
index 0000000..910a19f
--- /dev/null
@@ -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 (file)
index 0000000..84dcb42
--- /dev/null
@@ -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
+ */