]> git.sur5r.net Git - glabels/commitdiff
Refinements to barcode objects
authorJim Evins <evins@snaught.com>
Mon, 1 Nov 2010 00:35:48 +0000 (20:35 -0400)
committerJim Evins <evins@snaught.com>
Mon, 1 Nov 2010 00:35:48 +0000 (20:35 -0400)
- 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
libglbarcode/lgl-barcode-render-to-cairo.h
src/label-barcode.c

index 6cb84b35e5331db408cb8851b44409e1644c6744..1dd1700f5815352b75809b99adea1ec6364ad3f1 100644 (file)
@@ -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
index 3ad67ad1c5c6df6d2062ff351397757b72494544..ae96ef9154be34e93313474c9ace32371566e2dd 100644 (file)
 
 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
 
index 6cc93b5c6cc2d17a44279b0002c1ef3b2be5db42..d5704df8c5f0504d612bf30a1db7e5b807a81042 100644 (file)
@@ -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,22 +508,89 @@ 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;
 }
 
 
+/*****************************************************************************/
+/* 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.                                                  */
 /*****************************************************************************/