X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=score.c;h=290059196853bd86cbbcabd870e2dd47df9101f9;hb=82d0481012c66ad272598b337e062310f3adc174;hp=89371622453998b9536e879922662254d580b9f3;hpb=6024b2beade6f8376df4795d407fa2704c23befb;p=scherzo diff --git a/score.c b/score.c index 8937162..2900591 100644 --- a/score.c +++ b/score.c @@ -28,14 +28,22 @@ struct score /* Height of one space within a staff */ int space_height; + /* Minimal line width for staff lines */ + int line_width; + /* Full width of staff */ int width; }; -void -score_init (score_t *score) +score_t * +score_create (void *ctx) { + score_t *score; + + score = talloc (ctx, score_t); score_set_staff_height (score, 24); + + return score; } int @@ -43,6 +51,11 @@ score_set_staff_height (score_t *score, int height) { score->space_height = (int) height / 4; score->staff_height = score->space_height * 4; + + score->line_width = score->space_height / 10; + if (score->line_width == 0) + score->line_width = 1; + return score->staff_height; } @@ -52,23 +65,55 @@ score_set_width (score_t *score, int width) score->width = width; } +typedef enum score_clef +{ + SCORE_CLEF_G, + SCORE_CLEF_F +} score_clef_t; + static void -_draw_staff (score_t *score, cairo_t *cr) +_draw_staff (score_t *score, cairo_t *cr, score_clef_t clef) { int i; + cairo_glyph_t glyph; cairo_save (cr); + cairo_select_font_face (cr, "Gonville-26", 0, 0); + + cairo_set_font_size (cr, score->staff_height); + + /* XXX: The hard-coded glyph indices here are very ugly. We should + * figure out how to lookup glyphs by name from this font. */ + switch (clef) { + case SCORE_CLEF_G: + default: + glyph.index = 46; + glyph.y = 3 * score->space_height; + break; + case SCORE_CLEF_F: + glyph.index = 45; + glyph.y = 1 * score->space_height; + break; + } + glyph.x = 3 * score->line_width; + glyph.y += 1; + + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_show_glyphs (cr, &glyph, 1); + cairo_rectangle (cr, - 0.5, 0.5, - score->width - 1.0, score->space_height * 4); + score->line_width / 2.0, + score->line_width / 2.0, + score->width - score->line_width, + score->space_height * 4); for (i = 1; i < 4; i++) { - cairo_move_to (cr, 0, i * score->space_height + 0.5); + cairo_move_to (cr, 0, i * score->space_height + score->line_width / 2.0); cairo_rel_line_to (cr, score->width, 0); } - cairo_set_line_width (cr, 1.0); + cairo_set_line_width (cr, score->line_width); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ cairo_stroke (cr); @@ -79,23 +124,56 @@ _draw_staff (score_t *score, cairo_t *cr) static void _draw_grand_staff (score_t *score, cairo_t *cr) { +#define BRACE_GLYPHS 1 + cairo_glyph_t brace; + cairo_text_extents_t brace_extents; cairo_save (cr); + /* Brace test */ + cairo_select_font_face (cr, "Gonville-Brace", 0, 0); + + /* XXX: This hard-coded glyph index is pretty ugly. We should + * figure out how to lookup the glyph we want, (though, as it + * turns out, this brace font pretty much just has numbered glyph + * names for different sizes, so it wouldn't be all that different + * than just the bare index here). */ + brace.index = 300; + brace.x = 0; + brace.y = (score->staff_height * 3) / 2 + 1; + + /* XXX: This font size (in conjunction with the glyph selection) + * is a rough guess at best. We should figure out how the brace + * font is intended to be used and actually measure to find the + * correctly-sized glyph. */ + cairo_set_font_size (cr, (score->staff_height * 3) / 3.85); + + cairo_glyph_extents (cr, &brace, 1, &brace_extents); + + cairo_translate (cr, -brace_extents.x_bearing, 0); + score->width += brace_extents.x_bearing; + + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_show_glyphs (cr, &brace, 1); + + cairo_translate (cr, 2, 0); + score->width -= 2; + /* Vertical lines at each end */ cairo_rectangle (cr, - 0.5, 0.5, - score->width - 1.0, + score->line_width / 2.0, + score->line_width / 2.0, + score->width - score->line_width, score->staff_height * 3); - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); - cairo_set_line_width (cr, 1.0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_set_line_width (cr, score->line_width); cairo_stroke (cr); /* Top staff */ - _draw_staff (score, cr); + _draw_staff (score, cr, SCORE_CLEF_G); /* Bottom staff */ cairo_translate (cr, 0, score->staff_height * 2); - _draw_staff (score, cr); + _draw_staff (score, cr, SCORE_CLEF_F); cairo_restore (cr); }