]> git.sur5r.net Git - glabels/blobdiff - src/label-box.c
Imported Upstream version 3.0.0
[glabels] / src / label-box.c
index a42ad75b38b2914cce2ab6772b860f0fa00f86fa..fd63e24f762fb600b8c62e8341538e2a33e2a16d 100644 (file)
@@ -1,35 +1,31 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
-
 /*
- *  (GLABELS) Label and Business Card Creation program for GNOME
- *
- *  label_box.c:  GLabels label box object
+ *  label-box.c
+ *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
  *
- *  Copyright (C) 2001-2007  Jim Evins <evins@snaught.com>.
+ *  This file is part of gLabels.
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  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 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
- *  This program is distributed in the hope that it will be useful,
+ *  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 this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "label-box.h"
 
-#include <glib/gmem.h>
-#include <glib/gstrfuncs.h>
-#include <glib/gmessages.h>
+#include <glib/gi18n.h>
+#include <glib.h>
 
 #include "debug.h"
 
+
 /*========================================================*/
 /* Private types.                                         */
 /*========================================================*/
@@ -40,10 +36,12 @@ struct _glLabelBoxPrivate {
        glColorNode      *fill_color_node;
 };
 
+
 /*========================================================*/
 /* Private globals.                                       */
 /*========================================================*/
 
+
 /*========================================================*/
 /* Private function prototypes.                           */
 /*========================================================*/
@@ -54,13 +52,16 @@ static void    copy                       (glLabelObject   *dst_object,
                                           glLabelObject   *src_object);
 
 static void    set_fill_color             (glLabelObject   *object,
-                                          glColorNode     *fill_color_node);
+                                          glColorNode     *fill_color_node,
+                                           gboolean         checkpoint);
 
 static void    set_line_color             (glLabelObject   *object,
-                                          glColorNode     *line_color_node);
+                                          glColorNode     *line_color_node,
+                                           gboolean         checkpoint);
 
 static void    set_line_width             (glLabelObject   *object,
-                                          gdouble          line_width);
+                                          gdouble          line_width,
+                                           gboolean         checkpoint);
 
 static glColorNode*   get_fill_color      (glLabelObject   *object);
 
@@ -78,14 +79,17 @@ static void    draw_shadow                (glLabelObject     *object,
                                            gboolean           screen_flag,
                                            glMergeRecord     *record);
 
+static gboolean object_at                 (glLabelObject     *object,
+                                           cairo_t           *cr,
+                                           gdouble            x_pixels,
+                                           gdouble            y_pixels);
 
 
-
-\f
 /*****************************************************************************/
 /* Boilerplate object stuff.                                                 */
 /*****************************************************************************/
-G_DEFINE_TYPE (glLabelBox, gl_label_box, GL_TYPE_LABEL_OBJECT);
+G_DEFINE_TYPE (glLabelBox, gl_label_box, GL_TYPE_LABEL_OBJECT)
+
 
 static void
 gl_label_box_class_init (glLabelBoxClass *class)
@@ -104,18 +108,19 @@ gl_label_box_class_init (glLabelBoxClass *class)
        label_object_class->get_line_width = get_line_width;
         label_object_class->draw_object    = draw_object;
         label_object_class->draw_shadow    = draw_shadow;
+        label_object_class->object_at      = object_at;
 
        object_class->finalize = gl_label_box_finalize;
 }
 
+
 static void
 gl_label_box_init (glLabelBox *lbox)
 {
        lbox->priv = g_new0 (glLabelBoxPrivate, 1);
-       lbox->priv->line_color_node = gl_color_node_new_default ();
-       lbox->priv->fill_color_node = gl_color_node_new_default ();
 }
 
+
 static void
 gl_label_box_finalize (GObject *object)
 {
@@ -130,21 +135,45 @@ gl_label_box_finalize (GObject *object)
        G_OBJECT_CLASS (gl_label_box_parent_class)->finalize (object);
 }
 
+
 /*****************************************************************************/
 /* NEW label "box" object.                                                   */
 /*****************************************************************************/
 GObject *
-gl_label_box_new (glLabel *label)
+gl_label_box_new (glLabel *label,
+                  gboolean checkpoint)
 {
-       glLabelBox *lbox;
+       glLabelBox          *lbox;
+       glColorNode         *fill_color_node;
+       glColorNode         *line_color_node;
 
        lbox = g_object_new (gl_label_box_get_type(), NULL);
 
-       gl_label_object_set_parent (GL_LABEL_OBJECT(lbox), label);
+        if (label != NULL)
+        {
+                if ( checkpoint )
+                {
+                        gl_label_checkpoint (label, _("Create box object"));
+                }
+
+                fill_color_node = gl_color_node_new_default ();
+                line_color_node = gl_color_node_new_default ();
+
+                line_color_node->color = gl_label_get_default_line_color(label);
+                fill_color_node->color = gl_label_get_default_fill_color(label);
+
+                lbox->priv->line_width      = gl_label_get_default_line_width(label);
+                lbox->priv->line_color_node = line_color_node;
+                lbox->priv->fill_color_node = fill_color_node;
+
+                gl_label_add_object (label, GL_LABEL_OBJECT (lbox));
+                gl_label_object_set_parent (GL_LABEL_OBJECT (lbox), label);
+        }
 
        return G_OBJECT (lbox);
 }
 
+
 /*****************************************************************************/
 /* Copy object contents.                                                     */
 /*****************************************************************************/
@@ -167,9 +196,9 @@ copy (glLabelObject *dst_object,
        line_color_node = get_line_color (src_object);
        fill_color_node = get_fill_color (src_object);
 
-       set_line_width (dst_object, line_width);
-       set_line_color (dst_object, line_color_node);
-       set_fill_color (dst_object, fill_color_node);
+       set_line_width (dst_object, line_width, FALSE);
+       set_line_color (dst_object, line_color_node, FALSE);
+       set_fill_color (dst_object, fill_color_node, FALSE);
        
        gl_color_node_free (&line_color_node);
        gl_color_node_free (&fill_color_node);
@@ -183,54 +212,83 @@ copy (glLabelObject *dst_object,
 /*---------------------------------------------------------------------------*/
 static void
 set_fill_color (glLabelObject *object,
-               glColorNode   *fill_color_node)
+               glColorNode   *fill_color_node,
+                gboolean       checkpoint)
 {
        glLabelBox *lbox = (glLabelBox *)object;
+        glLabel    *label;
        
        gl_debug (DEBUG_LABEL, "START");
 
        g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
 
-       if (!gl_color_node_equal (lbox->priv->fill_color_node, fill_color_node)) {
+       if (!gl_color_node_equal (lbox->priv->fill_color_node, fill_color_node))
+        {
+                if ( checkpoint )
+                {
+                        label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbox));
+                        gl_label_checkpoint (label, _("Fill color"));
+                }
 
                gl_color_node_free (&(lbox->priv->fill_color_node));
                lbox->priv->fill_color_node = gl_color_node_dup (fill_color_node);
 
                gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
        }
+
        gl_debug (DEBUG_LABEL, "END");
 }
 
+
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Set line color method.                                          */
 /*---------------------------------------------------------------------------*/
 static void
 set_line_color (glLabelObject *object,
-               glColorNode   *line_color_node)
+               glColorNode   *line_color_node,
+                gboolean       checkpoint)
 {
        glLabelBox *lbox = (glLabelBox *)object;
+        glLabel    *label;
 
        g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
 
-       if ( !gl_color_node_equal (lbox->priv->line_color_node, line_color_node )) {
+       if ( !gl_color_node_equal (lbox->priv->line_color_node, line_color_node ))
+        {
+                if ( checkpoint )
+                {
+                        label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbox));
+                        gl_label_checkpoint (label, _("Line color"));
+                }
+
                gl_color_node_free (&(lbox->priv->line_color_node));
                lbox->priv->line_color_node = gl_color_node_dup (line_color_node);
                gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
        }
 }
 
+
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Set line width method.                                          */
 /*---------------------------------------------------------------------------*/
 static void
 set_line_width (glLabelObject *object,
-               gdouble        line_width)
+               gdouble        line_width,
+                gboolean       checkpoint)
 {
        glLabelBox *lbox = (glLabelBox *)object;
+        glLabel    *label;
 
        g_return_if_fail (lbox && GL_IS_LABEL_BOX (lbox));
 
-       if ( lbox->priv->line_width != line_width ) {
+       if ( lbox->priv->line_width != line_width )
+        {
+                if ( checkpoint )
+                {
+                        label = gl_label_object_get_parent (GL_LABEL_OBJECT (lbox));
+                        gl_label_checkpoint (label, _("Line width"));
+                }
+
                lbox->priv->line_width = line_width;
                gl_label_object_emit_changed (GL_LABEL_OBJECT(lbox));
        }
@@ -250,6 +308,7 @@ get_line_width (glLabelObject *object)
        return lbox->priv->line_width;
 }
 
+
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Get line color method.                                          */
 /*---------------------------------------------------------------------------*/
@@ -263,6 +322,7 @@ get_line_color (glLabelObject *object)
        return gl_color_node_dup (lbox->priv->line_color_node);
 }
 
+
 /*---------------------------------------------------------------------------*/
 /* PRIVATE.  Get line width method.                                          */
 /*---------------------------------------------------------------------------*/
@@ -276,6 +336,7 @@ get_fill_color (glLabelObject *object)
        return gl_color_node_dup (lbox->priv->fill_color_node);
 }
 
+
 /*****************************************************************************/
 /* Draw object method.                                                       */
 /*****************************************************************************/
@@ -329,6 +390,7 @@ draw_object (glLabelObject *object,
        gl_debug (DEBUG_LABEL, "END");
 }
 
+
 /*****************************************************************************/
 /* Draw shadow method.                                                       */
 /*****************************************************************************/
@@ -347,11 +409,11 @@ draw_shadow (glLabelObject *object,
        glColorNode   *shadow_color_node;
         guint          shadow_color;
        gdouble        shadow_opacity;
-       guint          shadow_line_color;
-       guint          shadow_fill_color;
 
        gl_debug (DEBUG_LABEL, "START");
 
+        cairo_save (cr);
+
         gl_label_object_get_size (object, &w, &h);
 
        line_width = gl_label_object_get_line_width (object);
@@ -376,27 +438,94 @@ draw_shadow (glLabelObject *object,
                shadow_color = GL_COLOR_SHADOW_MERGE_DEFAULT;
        }
        shadow_opacity = gl_label_object_get_shadow_opacity (object);
-       shadow_line_color = gl_color_shadow (shadow_color, shadow_opacity, line_color_node->color);
-       shadow_fill_color = gl_color_shadow (shadow_color, shadow_opacity, fill_color_node->color);
+       shadow_color = gl_color_set_opacity (shadow_color, shadow_opacity);
        
 
-        cairo_rectangle (cr, 0.0, 0.0, w, h);
-
-
-        /* Draw fill shadow */
-        cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_fill_color));
-        cairo_fill_preserve (cr);
+        cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_color));
 
-        /* Draw outline shadow */
-        cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_line_color));
-        cairo_set_line_width (cr, line_width);
-        cairo_stroke (cr);
+        if ( GL_COLOR_F_ALPHA (fill_color) )
+        {
+                if ( GL_COLOR_F_ALPHA (line_color) )
+                {
+                        /* Has FILL and OUTLINE: adjust size to account for line width. */
+                        cairo_rectangle (cr,
+                                         -line_width/2, -line_width/2,
+                                         w+line_width, h+line_width);
+
+                }
+                else
+                {
+                        /* Has FILL but no OUTLINE. */
+                        cairo_rectangle (cr, 0.0, 0.0, w, h);
+                }
+
+                /* Draw shadow */
+                cairo_fill (cr);
+        }
+        else
+        {
+                if ( GL_COLOR_F_ALPHA (line_color) )
+                {
+                        /* Has only OUTLINE. */
+                        cairo_rectangle (cr, 0.0, 0.0, w, h);
+
+                        /* Draw shadow of outline */
+                        cairo_set_line_width (cr, line_width);
+                        cairo_stroke (cr);
+                }
+        }
 
 
        gl_color_node_free (&line_color_node);
        gl_color_node_free (&fill_color_node);
        gl_color_node_free (&shadow_color_node);
 
+        cairo_restore (cr);
+
        gl_debug (DEBUG_LABEL, "END");
 }
 
+
+/*****************************************************************************/
+/* Is object at coordinates?                                                 */
+/*****************************************************************************/
+static gboolean
+object_at (glLabelObject *object,
+           cairo_t       *cr,
+           gdouble        x,
+           gdouble        y)
+{
+        gdouble           w, h;
+        gdouble           line_width;
+
+        gl_label_object_get_size (object, &w, &h);
+
+        cairo_new_path (cr);
+        cairo_rectangle (cr, 0.0, 0.0, w, h);
+
+        if (cairo_in_fill (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        line_width = gl_label_object_get_line_width (object);
+        cairo_set_line_width (cr, line_width);
+        if (cairo_in_stroke (cr, x, y))
+        {
+                return TRUE;
+        }
+
+        return FALSE;
+}
+
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */