[glabels] Refinements to barcode objects - Draw outline around barcode objects. - Use a more sophisticated tes



commit 81941432d20338b56011444017b01799320a6e97
Author: Jim Evins <evins snaught com>
Date:   Sun Oct 31 20:35:48 2010 -0400

    Refinements to barcode objects
    - Draw outline around barcode objects.
    - Use a more sophisticated test for determining if cursor is on a barcode
      object: test against lines and glyphs instead of simple bounds test. The
      test will also indicate that cursor is on the object if it is on the
      selection outline.  Similar to text objects.

 libglbarcode/lgl-barcode-render-to-cairo.c |  130 ++++++++++++++++++++++++++++
 libglbarcode/lgl-barcode-render-to-cairo.h |    7 +-
 src/label-barcode.c                        |   85 +++++++++++++++++--
 3 files changed, 214 insertions(+), 8 deletions(-)
---
diff --git a/libglbarcode/lgl-barcode-render-to-cairo.c b/libglbarcode/lgl-barcode-render-to-cairo.c
index 6cb84b3..1dd1700 100644
--- a/libglbarcode/lgl-barcode-render-to-cairo.c
+++ b/libglbarcode/lgl-barcode-render-to-cairo.c
@@ -184,6 +184,136 @@ lgl_barcode_render_to_cairo (const lglBarcode  *bc,
 }
 
 
+/****************************************************************************/
+/* Render barcode to cairo context (creating a path only).                  */
+/****************************************************************************/
+void
+lgl_barcode_render_to_cairo_path (const lglBarcode  *bc,
+                                  cairo_t           *cr)
+{
+        GList                  *p;
+
+        lglBarcodeShape        *shape;
+        lglBarcodeShapeLine    *line;
+        lglBarcodeShapeBox     *box;
+        lglBarcodeShapeChar    *bchar;
+        lglBarcodeShapeString  *bstring;
+        lglBarcodeShapeRing    *ring;
+        lglBarcodeShapeHexagon *hexagon;
+
+        PangoLayout            *layout;
+        PangoFontDescription   *desc;
+        gchar                  *cstring;
+        gdouble                 x_offset, y_offset;
+        gint                    iw, ih;
+        gdouble                 layout_width;
+
+
+        for (p = bc->shapes; p != NULL; p = p->next) {
+
+                shape = (lglBarcodeShape *)p->data;
+
+                switch (shape->type)
+                {
+
+                case LGL_BARCODE_SHAPE_LINE:
+                        line = (lglBarcodeShapeLine *) shape;
+
+                        cairo_rectangle (cr, line->x - line->width/2, line->y, line->width, line->length);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_BOX:
+                        box = (lglBarcodeShapeBox *) shape;
+
+                        cairo_rectangle (cr, box->x, box->y, box->width, box->height);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_CHAR:
+                        bchar = (lglBarcodeShapeChar *) shape;
+
+                        layout = pango_cairo_create_layout (cr);
+
+                        desc = pango_font_description_new ();
+                        pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
+                        pango_font_description_set_size   (desc, bchar->fsize * PANGO_SCALE * FONT_SCALE);
+                        pango_layout_set_font_description (layout, desc);
+                        pango_font_description_free       (desc);
+
+                        cstring = g_strdup_printf ("%c", bchar->c);
+                        pango_layout_set_text (layout, cstring, -1);
+                        g_free (cstring);
+
+                        y_offset = 0.2 * bchar->fsize;
+
+                        cairo_move_to (cr, bchar->x, bchar->y-y_offset);
+                        pango_cairo_layout_path (cr, layout);
+
+                        g_object_unref (layout);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_STRING:
+                        bstring = (lglBarcodeShapeString *) shape;
+
+                        layout = pango_cairo_create_layout (cr);
+
+                        desc = pango_font_description_new ();
+                        pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
+                        pango_font_description_set_size   (desc, bstring->fsize * PANGO_SCALE * FONT_SCALE);
+                        pango_layout_set_font_description (layout, desc);
+                        pango_font_description_free       (desc);
+
+                        pango_layout_set_text (layout, bstring->string, -1);
+
+                        pango_layout_get_size (layout, &iw, &ih);
+                        layout_width = (gdouble)iw / (gdouble)PANGO_SCALE;
+
+                        x_offset = layout_width / 2.0;
+                        y_offset = 0.2 * bstring->fsize;
+
+                        cairo_move_to (cr, (bstring->x - x_offset), (bstring->y - y_offset));
+                        pango_cairo_layout_path (cr, layout);
+
+                        g_object_unref (layout);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_RING:
+                        ring = (lglBarcodeShapeRing *) shape;
+
+                        cairo_new_sub_path (cr);
+                        cairo_arc (cr, ring->x, ring->y, ring->radius + ring->line_width/2, 0.0, 2 * M_PI);
+                        cairo_close_path (cr);
+                        cairo_new_sub_path (cr);
+                        cairo_arc (cr, ring->x, ring->y, ring->radius - ring->line_width/2, 0.0, 2 * M_PI);
+                        cairo_close_path (cr);
+                        break;
+
+                case LGL_BARCODE_SHAPE_HEXAGON:
+                        hexagon = (lglBarcodeShapeHexagon *) shape;
+
+                        cairo_move_to (cr, hexagon->x, hexagon->y);
+                        cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
+                        cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
+                        cairo_line_to (cr, hexagon->x,                         hexagon->y +      hexagon->height);
+                        cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
+                        cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
+                        cairo_close_path (cr);
+                        break;
+
+                default:
+                        g_assert_not_reached ();
+                        break;
+
+                }
+
+        }
+
+}
+
+
 
 /*
  * Local Variables:       -- emacs
diff --git a/libglbarcode/lgl-barcode-render-to-cairo.h b/libglbarcode/lgl-barcode-render-to-cairo.h
index 3ad67ad..ae96ef9 100644
--- a/libglbarcode/lgl-barcode-render-to-cairo.h
+++ b/libglbarcode/lgl-barcode-render-to-cairo.h
@@ -26,8 +26,11 @@
 
 G_BEGIN_DECLS
 
-void  lgl_barcode_render_to_cairo (const lglBarcode *bc,
-                                   cairo_t          *cr);
+void  lgl_barcode_render_to_cairo      (const lglBarcode *bc,
+                                        cairo_t          *cr);
+
+void  lgl_barcode_render_to_cairo_path (const lglBarcode *bc,
+                                        cairo_t          *cr);
 
 G_END_DECLS
 
diff --git a/src/label-barcode.c b/src/label-barcode.c
index 6cc93b5..d5704df 100644
--- a/src/label-barcode.c
+++ b/src/label-barcode.c
@@ -38,6 +38,9 @@
 
 #define GL_BARCODE_FONT_FAMILY      "Sans"
 
+#define HANDLE_OUTLINE_RGBA_ARGS   0.5,   0.5,   0.5,   0.75
+#define HANDLE_OUTLINE_WIDTH_PIXELS   2.0
+
 
 /*========================================================*/
 /* Private types.                                         */
@@ -86,6 +89,9 @@ static gboolean object_at                   (glLabelObject       *object,
                                              gdouble              x_pixels,
                                              gdouble              y_pixels);
 
+static void     draw_handles                (glLabelObject       *object,
+                                             cairo_t             *cr);
+
 
 /*****************************************************************************/
 /* Boilerplate object stuff.                                                 */
@@ -108,6 +114,7 @@ gl_label_barcode_class_init (glLabelBarcodeClass *class)
         label_object_class->draw_object    = draw_object;
         label_object_class->draw_shadow    = NULL;
         label_object_class->object_at      = object_at;
+        label_object_class->draw_handles   = draw_handles;
 
         object_class->finalize = gl_label_barcode_finalize;
 }
@@ -442,7 +449,6 @@ draw_object (glLabelObject *object,
 
         gl_label_object_get_size (object, &w, &h);
 
-        text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
         text = gl_text_node_expand (text_node, record);
         if (text_node->field_flag && screen_flag) {
                 text = gl_barcode_backends_style_default_digits (style->backend_id, style->id, style->format_digits);
@@ -502,16 +508,50 @@ object_at (glLabelObject *object,
            gdouble        x,
            gdouble        y)
 {
-        gdouble           w, h;
+        gdouble               w, h;
+        lglBarcode           *gbc;
+        glLabelBarcodeStyle  *style;
+        glTextNode           *text_node;
+        gchar                *text;
 
         gl_label_object_get_size (object, &w, &h);
 
-        cairo_new_path (cr);
-        cairo_rectangle (cr, 0.0, 0.0, w, h);
+        if ( (x >= 0) && (x <= w) && (y >= 0) && (y <= h) )
+        {
+
+                style = gl_label_barcode_get_style (GL_LABEL_BARCODE (object));
+                text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
+                text = gl_text_node_expand (text_node, NULL);
+                if (text_node->field_flag) {
+                        text = gl_barcode_backends_style_default_digits (style->backend_id, style->id, style->format_digits);
+                }
+                gbc = gl_barcode_backends_new_barcode (style->backend_id,
+                                                       style->id,
+                                                       style->text_flag,
+                                                       style->checksum_flag,
+                                                       w, h,
+                                                       text);
+                if ( gbc )
+                {
+                        lgl_barcode_render_to_cairo_path (gbc, cr);
+                        lgl_barcode_free (gbc);
+                }
+
+                if (cairo_in_fill (cr, x, y))
+                {
+                        return TRUE;
+                }
+
+        }
 
-        if (cairo_in_fill (cr, x, y))
+        if (gl_label_object_is_selected (object))
         {
-                return TRUE;
+                cairo_new_path (cr);
+                cairo_rectangle (cr, 0, 0, w, h);
+                if (cairo_in_stroke (cr, x, y))
+                {
+                        return TRUE;
+                }
         }
 
         return FALSE;
@@ -519,6 +559,39 @@ object_at (glLabelObject *object,
 
 
 /*****************************************************************************/
+/* Draw barcode style handles.                                               */
+/*****************************************************************************/
+static void
+draw_handles (glLabelObject     *object,
+              cairo_t           *cr)
+{
+        gdouble w, h;
+        gdouble scale_x, scale_y;
+        gdouble dashes[2] = { 2, 2 };
+
+        gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
+
+        cairo_save (cr);
+
+        cairo_rectangle (cr, 0, 0, w, h);
+
+        scale_x = 1.0;
+        scale_y = 1.0;
+        cairo_device_to_user_distance (cr, &scale_x, &scale_y);
+        cairo_scale (cr, scale_x, scale_y);
+
+        cairo_set_dash (cr, dashes, 2, 0);
+        cairo_set_line_width (cr, HANDLE_OUTLINE_WIDTH_PIXELS);
+        cairo_set_source_rgba (cr, HANDLE_OUTLINE_RGBA_ARGS);
+        cairo_stroke (cr);
+
+        cairo_restore (cr);
+
+        gl_label_object_draw_handles_box (object, cr);
+}
+
+
+/*****************************************************************************/
 /* Barcode style utilities.                                                  */
 /*****************************************************************************/
 glLabelBarcodeStyle *



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