]> git.cworth.org Git - scherzo/blobdiff - score.c
Fix high octave numbers (8+) to not be interpreted as 0.
[scherzo] / score.c
diff --git a/score.c b/score.c
index 0a6016bcb706785db4460460a37ebdde235a8563..f8373ab1ad1c949d7635d66693aa4c5f8494e0a4 100644 (file)
--- a/score.c
+++ b/score.c
@@ -78,8 +78,8 @@ struct score
     /* Full width of staff */
     int width;
 
-    /* the pitch class of the current (diatonic) key */
-    pitch_t key;
+    /* Current (diatonic) key */
+    scherzo_key_t key;
 
     score_brace_t **braces;
     int num_braces;
@@ -105,7 +105,9 @@ score_create (void *ctx)
     score->width = 1000;
 
     /* Default to C, of course */
-    score->key = PITCH_CLASS_LITERAL (C, NATURAL);
+    score->key.pitch = PITCH_CLASS_LITERAL (C, NATURAL);
+    score->key.num_sharps = 0;
+    score->key.num_flats = 0;
 
     score->braces = NULL;
     score->num_braces = 0;
@@ -138,9 +140,10 @@ score_set_width (score_t *score, int width)
 void
 score_set_key (score_t *score, pitch_t key)
 {
-    score->key = key;
+    scherzo_key_init (&score->key, key);
 }
 
+
 /* Returns in brace_width the width of the brace */
 static void
 _draw_brace (score_t *score, cairo_t *cr,
@@ -269,8 +272,13 @@ _draw_chord (score_t *score, cairo_t *cr,
     cairo_restore (cr);
 }
 
-/* Draw 'note' with accidental (if not NATURAL) at its correct
- * position on 'staff'.
+/* Draw 'note' at its correct position on 'staff'.
+ * If the accidental of 'note' is not contained within the current
+ * key, then draw the accidental as well.
+ *
+ * As a special case, if the note's duration is 0, draw the accidental
+ * alone, regardless of the key. This is useful for drawing the
+ * accidentals of the key signature.
  *
  * Returns the width of the drawn glyphs.
  */
@@ -328,7 +336,8 @@ _draw_note (score_t *score, cairo_t *cr,
            break;
     }
 
-    if (PITCH_ACCIDENTAL (note->pitch) != PITCH_ACCIDENTAL_NATURAL)
+    if (note->duration == 0 ||
+       ! scherzo_key_contains_pitch (&score->key, note->pitch))
     {
            note_glyph[num_glyphs].x = 0;
 
@@ -425,8 +434,8 @@ _draw_accidental (score_t *score,
 }
 
 static void
-_draw_sharps_key_signature (score_t *score, cairo_t *cr,
-                           score_staff_t *staff, int num_sharps)
+_draw_key_signature (score_t *score, cairo_t *cr,
+                    score_staff_t *staff)
 {
     pitch_t pitch;
     double width;
@@ -445,31 +454,7 @@ _draw_sharps_key_signature (score_t *score, cairo_t *cr,
        PITCH_LITERAL (B, SHARP, 4)
     };
 
-    for (i = 0; i < num_sharps; i++) {
-       pitch = sharps_order[i];
-
-       if (staff->clef == SCORE_CLEF_BASS)
-           pitch = pitch_lower_by_octaves (pitch, 2);
-
-       width = _draw_accidental (score, cr, staff, pitch);
-
-#define KEY_SIGNATURE_ACCIDENTAL_SPACING (score->space_height * .15)
-       cairo_translate (cr, ceil (width + KEY_SIGNATURE_ACCIDENTAL_SPACING), 0);
-    }
-}
-
-static void
-_draw_flats_key_signature (score_t *score, cairo_t *cr,
-                          score_staff_t *staff, int num_flats)
-{
-    pitch_t pitch;
-    double width;
-    int i;
-
-    /* These octave numbers are correct for treble clef. For bass
-     * clef, subtract two.
-     */
-    pitch_name_t flats_order[] = {
+    pitch_t flats_order[] = {
        PITCH_LITERAL (B, FLAT, 4),
        PITCH_LITERAL (E, FLAT, 5),
        PITCH_LITERAL (A, FLAT, 4),
@@ -479,62 +464,28 @@ _draw_flats_key_signature (score_t *score, cairo_t *cr,
        PITCH_LITERAL (F, FLAT, 4),
     };
 
-    for (i = 0; i < num_flats; i++) {
-       pitch = flats_order[i];
+    for (i = 0; i < score->key.num_sharps; i++) {
+       pitch = sharps_order[i];
 
        if (staff->clef == SCORE_CLEF_BASS)
            pitch = pitch_lower_by_octaves (pitch, 2);
 
        width = _draw_accidental (score, cr, staff, pitch);
 
+#define KEY_SIGNATURE_ACCIDENTAL_SPACING (score->space_height * .15)
        cairo_translate (cr, ceil (width + KEY_SIGNATURE_ACCIDENTAL_SPACING), 0);
     }
-}
-
-static void
-_draw_key_signature (score_t *score, cairo_t *cr,
-                    score_staff_t *staff, pitch_t key)
-{
-    int i;
 
-    pitch_t sharp_keys[] = {
-       PITCH_CLASS_LITERAL (C, NATURAL),
-       PITCH_CLASS_LITERAL (G, NATURAL),
-       PITCH_CLASS_LITERAL (D, NATURAL),
-       PITCH_CLASS_LITERAL (A, NATURAL),
-       PITCH_CLASS_LITERAL (E, NATURAL),
-       PITCH_CLASS_LITERAL (B, NATURAL),
-       PITCH_CLASS_LITERAL (F, SHARP),
-       PITCH_CLASS_LITERAL (C, SHARP),
-    };
+    for (i = 0; i < score->key.num_flats; i++) {
+       pitch = flats_order[i];
 
-    pitch_t flat_keys[] = {
-       PITCH_CLASS_LITERAL (C, NATURAL),
-       PITCH_CLASS_LITERAL (F, NATURAL),
-       PITCH_CLASS_LITERAL (B, FLAT),
-       PITCH_CLASS_LITERAL (E, FLAT),
-       PITCH_CLASS_LITERAL (A, FLAT),
-       PITCH_CLASS_LITERAL (D, FLAT),
-       PITCH_CLASS_LITERAL (G, FLAT),
-       PITCH_CLASS_LITERAL (C, FLAT)
-    };
+       if (staff->clef == SCORE_CLEF_BASS)
+           pitch = pitch_lower_by_octaves (pitch, 2);
 
-    for (i = 0; i < ARRAY_SIZE (sharp_keys); i++) {
-       if (sharp_keys[i] == key) {
-           _draw_sharps_key_signature (score, cr, staff, i);
-           return;
-       }
-    }
+       width = _draw_accidental (score, cr, staff, pitch);
 
-    for (i = 0; i < ARRAY_SIZE (flat_keys); i++) {
-       if (flat_keys[i] == key) {
-           _draw_flats_key_signature (score, cr, staff, i);
-           return;
-       }
+       cairo_translate (cr, ceil (width + KEY_SIGNATURE_ACCIDENTAL_SPACING), 0);
     }
-
-    fprintf (stderr, "Internal error: Not a key: %s\n", pitch_string (key));
-    exit (1);
 }
 
 static void
@@ -593,7 +544,10 @@ _draw_staff (score_t *score, cairo_t *cr,
                               CLEF_KEY_SIGNATURE_SPACING), 0);
 
     /* Draw the key signature */
-    _draw_key_signature (score, cr, staff, score->key);
+    _draw_key_signature (score, cr, staff);
+
+#define KEY_SIGNATURE_NOTE_SPACING (score->space_height)
+    cairo_translate (cr, ceil (KEY_SIGNATURE_NOTE_SPACING), 0);
 
     /* Draw chord symbols */
     cairo_save (cr);