]> git.cworth.org Git - scherzo/blobdiff - score.c
Add some scaling controls with plus/minus keybindings.
[scherzo] / score.c
diff --git a/score.c b/score.c
index 4f0efdd2f8ba7dcc4aab9a191ce32cdd73a8a5db..5bb79096c394a45741810d3cb3b22e6ebeeeb552 100644 (file)
--- a/score.c
+++ b/score.c
 
 #include "score.h"
 
-void
-score_init (score_t *score)
+struct score
+{
+    /* Height of a single staff */
+    int staff_height;
+
+    /* 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;
+};
+
+score_t *
+score_create (void *ctx)
+{
+    score_t *score;
+
+    score = talloc (ctx, score_t);
+    score_set_staff_height (score, 24);
+
+    return score;
+}
+
+int
+score_set_staff_height (score_t *score, int height)
 {
-    score->space_height = 6;
+    score->space_height = (int) height / 4;
+    score->staff_height = score->space_height * 4;
+
+    score->line_width = score->space_height / 15;
+    if (score->line_width == 0)
+       score->line_width = 1;
+
+    return score->staff_height;
 }
 
 void
-_draw_staff (score_t *score, cairo_t *cr)
+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, score_clef_t clef)
 {
     int i;
+    cairo_glyph_t glyph;
 
     cairo_save (cr);
 
-    for (i = 0; i < 5; i++) {
-       cairo_move_to (cr, 0, i * score->space_height + 0.5);
+    cairo_select_font_face (cr, "Gonville-26", 0, 0);
+
+    /* XXX: This font size is a rough guess at best. We should figure
+     * out to correctly measure, size, and place clefs. */
+    cairo_set_font_size (cr, 24);
+
+    /* 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 = 2;
+
+    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
+    cairo_show_glyphs (cr, &glyph, 1);
+
+    cairo_rectangle (cr,
+                    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 + 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);
@@ -46,14 +122,62 @@ _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;
+#define BRACE_GLYPHS 1
+    cairo_glyph_t brace;
+    cairo_save (cr);
+
+    /* Brace test */
+    cairo_select_font_face (cr, "Gonville-Brace", 0, 0);
+
+    /* 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, 40);
+
+    cairo_translate (cr, 5, 0);
+    score->width -= 5;
+
+    /* 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 = 185;
+    brace.x = 0;
+    brace.y = score->staff_height * 1.5;
+
+    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,
+                    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); /* black */
+    cairo_set_line_width (cr, score->line_width);
+    cairo_stroke (cr);
+
+    /* Top staff */
+    _draw_staff (score, cr, SCORE_CLEF_G);
+
+    /* Bottom staff */
+    cairo_translate (cr, 0, score->staff_height * 2);
+    _draw_staff (score, cr, SCORE_CLEF_F);
+
+    cairo_restore (cr);
 }
 
 void
 score_draw (score_t *score, cairo_t *cr)
 {
-    _draw_staff (score, cr);
+    _draw_grand_staff (score, cr);
 }