From: Jim Evins Date: Mon, 1 Nov 2010 00:35:48 +0000 (-0400) Subject: Refinements to barcode objects X-Git-Tag: glabels-2_3_1~152 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=81941432d20338b56011444017b01799320a6e97;p=glabels 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. --- 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. */ /*****************************************************************************/