X-Git-Url: https://git.cworth.org/git?p=scherzo;a=blobdiff_plain;f=score.c;h=f8373ab1ad1c949d7635d66693aa4c5f8494e0a4;hp=0a6016bcb706785db4460460a37ebdde235a8563;hb=a53d70ed61f87a5a49426b1e3066dbba09907199;hpb=54d2b1cb13bf52df22c93e58377a00b757644b94 diff --git a/score.c b/score.c index 0a6016b..f8373ab 100644 --- 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);