#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);
}
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);
}
#include <cairo.h>
-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);