From 81941432d20338b56011444017b01799320a6e97 Mon Sep 17 00:00:00 2001 From: Jim Evins Date: Sun, 31 Oct 2010 20:35:48 -0400 Subject: [PATCH] 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 6cb84b35..1dd1700f 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 3ad67ad1..ae96ef91 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 6cc93b5c..d5704df8 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,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. */ /*****************************************************************************/ -- 2.39.5