From 6024b2beade6f8376df4795d407fa2704c23befb Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 16 Sep 2011 23:55:51 -0700 Subject: [PATCH] Draw a second staff (and vertical lines at the beginning and end of staff). This is almost the grand staff necessary for a piano score, (missing the brace). The _draw_grand_staff function is a bit too specialized. A more general approach will involve the ability to add an arbitrary number of staffs (staves?) to the score, and selectively tie some together (with or without a brace). --- score.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++------ score.h | 26 ++++++++++++++++--------- 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/score.c b/score.c index 4f0efdd..8937162 100644 --- a/score.c +++ b/score.c @@ -20,20 +20,50 @@ #include "score.h" +struct score +{ + /* Height of a single staff */ + int staff_height; + + /* Height of one space within a staff */ + int space_height; + + /* Full width of staff */ + int width; +}; + void score_init (score_t *score) { - score->space_height = 6; + score_set_staff_height (score, 24); +} + +int +score_set_staff_height (score_t *score, int height) +{ + score->space_height = (int) height / 4; + score->staff_height = score->space_height * 4; + return score->staff_height; } void +score_set_width (score_t *score, int width) +{ + score->width = width; +} + +static void _draw_staff (score_t *score, cairo_t *cr) { int i; cairo_save (cr); - for (i = 0; i < 5; i++) { + cairo_rectangle (cr, + 0.5, 0.5, + score->width - 1.0, score->space_height * 4); + + for (i = 1; i < 4; i++) { cairo_move_to (cr, 0, i * score->space_height + 0.5); cairo_rel_line_to (cr, score->width, 0); } @@ -46,14 +76,32 @@ _draw_staff (score_t *score, cairo_t *cr) cairo_restore (cr); } -void -score_set_width (score_t *score, int width) +static void +_draw_grand_staff (score_t *score, cairo_t *cr) { - score->width = width; + cairo_save (cr); + + /* Vertical lines at each end */ + cairo_rectangle (cr, + 0.5, 0.5, + score->width - 1.0, + score->staff_height * 3); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_set_line_width (cr, 1.0); + cairo_stroke (cr); + + /* Top staff */ + _draw_staff (score, cr); + + /* Bottom staff */ + cairo_translate (cr, 0, score->staff_height * 2); + _draw_staff (score, cr); + + cairo_restore (cr); } void score_draw (score_t *score, cairo_t *cr) { - _draw_staff (score, cr); + _draw_grand_staff (score, cr); } diff --git a/score.h b/score.h index 26b9766..ece3951 100644 --- a/score.h +++ b/score.h @@ -23,18 +23,26 @@ #include -typedef struct score -{ - /* Height of each space on staff. */ - int space_height; +typedef struct score score_t; - /* Total width available to score. */ - int width; -} score_t; +/* Allocate a new, empty score object, (with optional ctx as talloc + * owner). If ctx is NULL, the caller should call talloc_free on the + * score_t* when done with it. Otherwise, the object will be freed + * when ctx is freed. */ +score_t * +score_create (void *ctx); -void -score_init (score_t *score); +/* Set an (approximate) staff height. The actual staff height may + * differ due to rounding to achieve evenly spaced, sharply rendered + * lines. the actual staff height is returned. */ +int +score_set_staff_height (score_t *score, int height); +/* Draw the given score_t onto the given cairo_t. + * + * The caller can call cairo_translate before calling score_draw to + * position the result as desired, (and can call cairo_clip to clip it + * if desired). */ void score_draw (score_t *score, cairo_t *cr); -- 2.43.0