diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ca4b0a3..facbb3514 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ As of v3.0.0 this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Adjustments to the heuristic for ledger lines to include adjacent notes (see [#862](https://github.com/gregorio-project/gregorio/issues/862)). - The stem length determination will use the ledger line below the note with the stem (see [#863](https://github.com/gregorio-project/gregorio/issues/863)). +- Made the oriscus orientation dependent on the note that follows. Using `1` will force the ascending oriscus and `0` will force the descending oriscus. The old behavior may be restored by setting the `oriscus-orientation` gabc header to `legacy`. See UPGRADE.md for details (for the change request, see [#774](https://github.com/gregorio-project/gregorio/issues/774) and [#898](https://github.com/gregorio-project/gregorio/issues/898)). +- Add new lines as needed to the gabc output. (see [#905](https://github.com/gregorio-project/gregorio/issues/905)). ### Added - Controls for tuning horizontal episema vertical position. See GregorioRef for details (for the change request, see [#872](https://github.com/gregorio-project/gregorio/issues/872)). @@ -66,7 +68,6 @@ As of v3.0.0 this project adheres to [Semantic Versioning](http://semver.org/). - The space between note and horizontal episema has been tightened for notes at the `c` or `k` height when there is no ledger line. Due to the intricacies of measurement, the system tries to make a best guess as to the existence of the ledger line. If the guess is wrong, you may use the `[hl:n]` and `[ll:n]` notations in gabc to override the guess. See [UPGRADE.md](UPGRADE.md) for details (for the change request, see [#716](https://github.com/gregorio-project/gregorio/issues/716)). - The custos that might appear immediately before a `` block is now suppressed by default. This behavior is controlled by the `\greseteolcustosbeforeeuouae` command. See GregorioRef and [UPGRADE.md](UPGRADE.md) for details (for the change request, see [#761](https://github.com/gregorio-project/gregorio/issues/761)). - Different glyphs will now be used for the liquescent stropha on a line or between lines, if supported by the font. If you prefer the old behavior, use `\grechangeglyph{StrophaAuctaLongtail}{*}{StrophaAucta}` in your TeX file. See [#773](https://github.com/gregorio-project/gregorio/issues/773). -- Made the oriscus orientation dependent on the note that follows. Using `<` will force the ascending oriscus and `>` will force the descending oriscus. The old behavior may be restored by setting the `oriscus-orientation` gabc header to `legacy`. See UPGRADE.md for details (for the change request, see [#774](https://github.com/gregorio-project/gregorio/issues/774)). - Headers not recognized by gregorio, rather than inducing an error, are now simply accepted by gregorio. Most of the old "standard" headers, like `book` and `manuscript-location`, are now handled in this way and thus are no longer limited to one instance. See GregorioRef for details. - `mode` will now be converted to Roman numerals in lower case so that it shows up as small capitals using the default `modeline` style. See [UPGRADE.md](UPGRADE.md) for details (for the change request, see [#756](https://github.com/gregorio-project/gregorio/issues/756)). - `\grecommentary` is now less restrictive about where it occurs and need not occur directly before the score anymore. diff --git a/UPGRADE.md b/UPGRADE.md index 47f655894..2966f00ff 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -56,7 +56,7 @@ By default, these are sized one half millimeter larger than their "non-text" cou ### Oriscus orientation -The oriscus orientation (whether it points up or down) is now dependent on the note the follows, even if the note is not directly connected to the oriscus (as it would be in a salicus or a pressus). Appending a `<` to an unconnected oriscus in gabc will force the oriscus to point upwards and `>` will force the oriscus to point downwards. +The oriscus orientation (whether it points up or down) is now dependent on the note the follows, even if the note is not directly connected to the oriscus (as it would be in a salicus or a pressus). Appending a `1` to an unconnected oriscus in gabc will force the oriscus to point upwards and `0` will force the oriscus to point downwards. Prior to version 4.1, Gregorio automatically oriented the oriscus when it was within a neume, but left the orientation up the user otherwise. If you prefer this behavior, set the `oriscus-orientation` header in gabc to `legacy`. In legacy mode, the orientation of an unconnected oriscus will (by default) point downwards and may be reversed by appending `<` or `>` to the oriscus. diff --git a/contrib/gabc.vim b/contrib/gabc.vim index 6f7235f2e..cb8b08b7f 100644 --- a/contrib/gabc.vim +++ b/contrib/gabc.vim @@ -11,9 +11,9 @@ syn match gabcAttributeName /^[^:]*:/ syn match gabcAttributeEnd ";" syn match gabcNoteError "." contained syn match gabcBasicNote "[a-npA-NP]" contained -syn match gabcAlteration "[\<\>~xy#vVoOwWqQR\-Ss\.+]" contained +syn match gabcAlteration "[\<\>~xy#vVwWqQR\-Ss\.+]" contained syn match gabcAlteration "_[0-5]*" contained -syn match gabcAlteration "['\.][01]\?" contained +syn match gabcAlteration "[oO'\.][01]\?" contained syn match gabcAlteration "r[0-5]\?" contained syn match gabcClef "[cf]b\?[1-5]" contained syn match gabcTextMarkup "" contained diff --git a/fonts/squarize.py b/fonts/squarize.py index fc9298455..dceaf5346 100644 --- a/fonts/squarize.py +++ b/fonts/squarize.py @@ -453,7 +453,7 @@ def get_width(glyphName): S_ORISCUS_SCAPUS = 'OriscusScapus' S_ORISCUS_SCAPUS_LONGQUEUE = 'OriscusScapusLongqueue' S_ORISCUS_SCAPUS_OPENQUEUE = 'OriscusScapusOpenqueue' -S_ORISCUS_REVERSUS_SCAPUS = 'OriscusScapusRev' +S_ORISCUS_REVERSUS_SCAPUS = 'OriscusScapusReversus' S_ORISCUS_REVERSUS_SCAPUS_LONGQUEUE= 'OriscusScapusReversusLongqueue' S_ORISCUS_REVERSUS_SCAPUS_OPENQUEUE= 'OriscusScapusReversusOpenqueue' S_UPPER_ORISCUS = 'UpperOriscus' diff --git a/src/gabc/gabc-glyphs-determination.c b/src/gabc/gabc-glyphs-determination.c index 8c5a0b869..3d06eadda 100644 --- a/src/gabc/gabc-glyphs-determination.c +++ b/src/gabc/gabc-glyphs-determination.c @@ -281,7 +281,9 @@ static char gregorio_add_note_to_a_glyph(gregorio_glyph_type current_glyph_type, *end_of_glyph = DET_END_OF_PREVIOUS; next_glyph_type = G_PES_QUILISMA_QUADRATUM_FIRST_PART; break; - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_UNDETERMINED: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: if (current_glyph_type == G_PUNCTUM && last_pitch < current_pitch) { next_glyph_type = G_VIRGA_STRATA; } else { @@ -997,7 +999,7 @@ gregorio_glyph *gabc_det_glyphs_from_notes(gregorio_note *current_note, switch (current_note->u.note.shape) { case S_PUNCTUM: case S_ORISCUS_UNDETERMINED: - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_UNDETERMINED: case S_QUILISMA: case S_QUADRATUM: case S_QUILISMA_QUADRATUM: diff --git a/src/gabc/gabc-notes-determination.l b/src/gabc/gabc-notes-determination.l index 315c88f9e..9682d53c7 100644 --- a/src/gabc/gabc-notes-determination.l +++ b/src/gabc/gabc-notes-determination.l @@ -1248,8 +1248,24 @@ o { gregorio_change_shape(current_note, S_ORISCUS_UNDETERMINED, legacy_oriscus_orientation); } +o0 { + gregorio_change_shape(current_note, S_ORISCUS_DESCENDENS, + legacy_oriscus_orientation); + } +o1 { + gregorio_change_shape(current_note, S_ORISCUS_ASCENDENS, + legacy_oriscus_orientation); + } O { - gregorio_change_shape(current_note, S_ORISCUS_SCAPUS, + gregorio_change_shape(current_note, S_ORISCUS_SCAPUS_UNDETERMINED, + legacy_oriscus_orientation); + } +O0 { + gregorio_change_shape(current_note, S_ORISCUS_SCAPUS_DESCENDENS, + legacy_oriscus_orientation); + } +O1 { + gregorio_change_shape(current_note, S_ORISCUS_SCAPUS_ASCENDENS, legacy_oriscus_orientation); } w { diff --git a/src/gabc/gabc-score-determination.y b/src/gabc/gabc-score-determination.y index 5a8460ac5..fb964071b 100644 --- a/src/gabc/gabc-score-determination.y +++ b/src/gabc/gabc-score-determination.y @@ -576,6 +576,10 @@ static void determine_oriscus_orientation(gregorio_score *score) { oriscus->u.note.shape = S_ORISCUS_DESCENDENS; break; + case S_ORISCUS_SCAPUS_UNDETERMINED: + oriscus->u.note.shape = + S_ORISCUS_SCAPUS_DESCENDENS; + break; case S_ORISCUS_CAVUM_UNDETERMINED: oriscus->u.note.shape = S_ORISCUS_CAVUM_DESCENDENS; @@ -596,6 +600,10 @@ static void determine_oriscus_orientation(gregorio_score *score) { oriscus->u.note.shape = S_ORISCUS_ASCENDENS; break; + case S_ORISCUS_SCAPUS_UNDETERMINED: + oriscus->u.note.shape = + S_ORISCUS_SCAPUS_ASCENDENS; + break; case S_ORISCUS_CAVUM_UNDETERMINED: oriscus->u.note.shape = S_ORISCUS_CAVUM_ASCENDENS; @@ -616,6 +624,7 @@ static void determine_oriscus_orientation(gregorio_score *score) { switch (note->u.note.shape) { case S_ORISCUS_UNDETERMINED: + case S_ORISCUS_SCAPUS_UNDETERMINED: case S_ORISCUS_CAVUM_UNDETERMINED: oriscus = note; break; @@ -637,6 +646,9 @@ static void determine_oriscus_orientation(gregorio_score *score) { case S_ORISCUS_UNDETERMINED: oriscus->u.note.shape = S_ORISCUS_DESCENDENS; break; + case S_ORISCUS_SCAPUS_UNDETERMINED: + oriscus->u.note.shape = S_ORISCUS_SCAPUS_DESCENDENS; + break; case S_ORISCUS_CAVUM_UNDETERMINED: oriscus->u.note.shape = S_ORISCUS_CAVUM_DESCENDENS; break; diff --git a/src/gabc/gabc-write.c b/src/gabc/gabc-write.c index 46ac340bb..e29a5be46 100644 --- a/src/gabc/gabc-write.c +++ b/src/gabc/gabc-write.c @@ -515,16 +515,24 @@ static void gabc_write_gregorio_note(FILE *f, gregorio_note *note, fprintf(f, "%cV", pitch_letter(note->u.note.pitch)); break; case S_ORISCUS_ASCENDENS: + fprintf(f, "%co1", pitch_letter(note->u.note.pitch)); + break; case S_ORISCUS_DESCENDENS: + fprintf(f, "%co0", pitch_letter(note->u.note.pitch)); + break; case S_ORISCUS_DEMINUTUS: fprintf(f, "%co", pitch_letter(note->u.note.pitch)); - /* Note: the ASCENDENS, DESCENDENS, or DEMINUTUS is also in the liquescentia */ + /* Note: the DEMINUTUS is also in the liquescentia */ break; case S_ORISCUS_CAVUM_ASCENDENS: + fprintf(f, "%co1r", pitch_letter(note->u.note.pitch)); + break; case S_ORISCUS_CAVUM_DESCENDENS: + fprintf(f, "%co0r", pitch_letter(note->u.note.pitch)); + break; case S_ORISCUS_CAVUM_DEMINUTUS: fprintf(f, "%cor", pitch_letter(note->u.note.pitch)); - /* Note: the ASCENDENS, DESCENDENS, or DEMINUTUS is also in the liquescentia */ + /* Note: the DEMINUTUS is also in the liquescentia */ break; case S_QUILISMA: if (is_quadratum) { @@ -545,8 +553,11 @@ static void gabc_write_gregorio_note(FILE *f, gregorio_note *note, case S_LINEA_PUNCTUM_CAVUM: fprintf(f, "%cr0", pitch_letter(note->u.note.pitch)); break; - case S_ORISCUS_SCAPUS: - fprintf(f, "%cO", pitch_letter(note->u.note.pitch)); + case S_ORISCUS_SCAPUS_ASCENDENS: + fprintf(f, "%cO1", pitch_letter(note->u.note.pitch)); + break; + case S_ORISCUS_SCAPUS_DESCENDENS: + fprintf(f, "%cO0", pitch_letter(note->u.note.pitch)); break; case S_STROPHA: case S_STROPHA_AUCTA: @@ -969,9 +980,10 @@ static void gabc_write_gregorio_element(FILE *f, gregorio_element *element, * */ -static void gabc_write_gregorio_elements(FILE *f, gregorio_element *element, +static bool gabc_write_gregorio_elements(FILE *f, gregorio_element *element, glyph_context *context) { + bool linebreak_or_bar_in_element = false; while (element) { context->element = element; gabc_write_gregorio_element(f, element, context); @@ -982,8 +994,13 @@ static void gabc_write_gregorio_elements(FILE *f, gregorio_element *element, && element->next && element->next->type == GRE_ELEMENT) { fprintf(f, "/"); } + if (element->type == GRE_END_OF_LINE || element->type == GRE_BAR) + { + linebreak_or_bar_in_element = true; + } element = element->next; } + return linebreak_or_bar_in_element; } /* @@ -995,6 +1012,7 @@ static void gabc_write_gregorio_elements(FILE *f, gregorio_element *element, static void gabc_write_gregorio_syllable(FILE *f, gregorio_syllable *syllable, glyph_context *context) { + bool linebreak_or_bar_in_element; gregorio_assert(syllable, gabc_write_gregorio_syllable, "call with NULL argument", return); if (syllable->no_linebreak_area == NLBA_BEGINNING) { @@ -1027,14 +1045,19 @@ static void gabc_write_gregorio_syllable(FILE *f, gregorio_syllable *syllable, } fprintf(f, "("); /* we write all the elements of the syllable. */ - gabc_write_gregorio_elements(f, syllable->elements[0], context); - if (syllable->position == WORD_END - || syllable->position == WORD_ONE_SYLLABLE - || gregorio_is_only_special(syllable->elements[0])) + linebreak_or_bar_in_element = gabc_write_gregorio_elements(f, syllable->elements[0], context); + if (linebreak_or_bar_in_element) { - fprintf(f, ") "); + fprintf(f, ")\n"); } else { - fprintf(f, ")"); + if (syllable->position == WORD_END + || syllable->position == WORD_ONE_SYLLABLE + || gregorio_is_only_special(syllable->elements[0])) + { + fprintf(f, ") "); + } else { + fprintf(f, ")"); + } } } diff --git a/src/gregoriotex/gregoriotex-position.c b/src/gregoriotex/gregoriotex-position.c index 58a06625a..4702113d4 100644 --- a/src/gregoriotex/gregoriotex-position.c +++ b/src/gregoriotex/gregoriotex-position.c @@ -1613,7 +1613,8 @@ static __inline int compute_fused_shift(const gregorio_glyph *glyph) * fusible from above */ if (shift < 0 && ((next_is_fused && glyph->u.notes.glyph_type == G_FLEXA) || glyph->u.notes.glyph_type == G_PORRECTUS - || glyph->u.notes.glyph_type == G_PODATUS + || (glyph->u.notes.glyph_type == G_PODATUS + && !(glyph->u.notes.liquescentia & L_DEMINUTUS)) || (previous->u.notes.glyph_type == G_PUNCTUM && is_initio_debilis(previous->u.notes.liquescentia)))) { /* may not be fused from above */ @@ -1626,7 +1627,8 @@ static __inline int compute_fused_shift(const gregorio_glyph *glyph) const gregorio_glyph *next_glyph; case S_ORISCUS_ASCENDENS: case S_ORISCUS_DESCENDENS: - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: next_note = first_note->next; if (!next_note && (next_glyph = gregorio_next_non_texverb_glyph(glyph)) && next_glyph->type == GRE_GLYPH diff --git a/src/gregoriotex/gregoriotex-write.c b/src/gregoriotex/gregoriotex-write.c index dcebb68b9..4fcece9b2 100644 --- a/src/gregoriotex/gregoriotex-write.c +++ b/src/gregoriotex/gregoriotex-write.c @@ -96,6 +96,9 @@ SHAPE(OriscusReversusLineTL); SHAPE(OriscusScapus); SHAPE(OriscusScapusLongqueue); SHAPE(OriscusScapusOpenqueue); +SHAPE(OriscusScapusReversus); +SHAPE(OriscusScapusReversusLongqueue); +SHAPE(OriscusScapusReversusOpenqueue); SHAPE(Pes); SHAPE(PesQuadratum); SHAPE(PesQuadratumLongqueue); @@ -108,10 +111,10 @@ SHAPE(PesQuilismaQuadratum); SHAPE(PesQuilismaQuadratumLongqueue); SHAPE(PesQuilismaQuadratumOpenqueue); SHAPE(Porrectus); -SHAPE(PorrectusLongqueue); SHAPE(PorrectusFlexus); SHAPE(PorrectusFlexusLongqueue); SHAPE(PorrectusFlexusNobar); +SHAPE(PorrectusLongqueue); SHAPE(PorrectusNobar); SHAPE(Punctum); SHAPE(PunctumAscendens); @@ -345,7 +348,8 @@ static const char *compute_glyph_name(const gregorio_glyph *const glyph, switch (previous_note->u.note.shape) { case S_ORISCUS_ASCENDENS: case S_ORISCUS_DESCENDENS: - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: fuse_head = FUSE_Lower; break; default: @@ -397,6 +401,24 @@ static const char *compute_glyph_name(const gregorio_glyph *const glyph, shape = SHAPE_Oriscus; } + if (*fuse_tail) { + if (is_fused(glyph->u.notes.liquescentia)) { + if (shape == SHAPE_OriscusScapusReversus + || shape == SHAPE_OriscusScapusReversusLongqueue + || shape == SHAPE_OriscusScapusReversusOpenqueue) { + shape = SHAPE_Oriscus; + } + } else { + if (shape == SHAPE_OriscusScapusReversus) { + shape = SHAPE_OriscusScapus; + } else if (shape == SHAPE_OriscusScapusReversusLongqueue) { + shape = SHAPE_OriscusScapusLongqueue; + } else if (shape == SHAPE_OriscusScapusReversusOpenqueue) { + shape = SHAPE_OriscusScapusOpenqueue; + } + } + } + current_note = glyph->u.notes.first_note; if (is_single_note) { if (liquescentia == LIQ_Nothing) { @@ -486,25 +508,34 @@ static const char *fusible_queued_shape(const gregorio_note *const note, const char *const base_shape, const char *const longqueue_shape, const char *const openqueue_shape) { - const char *name = ""; + const char *name = NULL; if (glyph->u.notes.fuse_to_next_glyph < 0) { /* queue size depends on the following note if fused down */ - if (glyph->u.notes.fuse_to_next_glyph == -1) { - switch (adjusted_queuetype_of(note, note, - glyph->u.notes.fuse_to_next_glyph)) { - case Q_ON_SPACE_BELOW_BOTTOM_LINE: - case Q_ON_BOTTOM_LINE: + bool ambitus_one = (glyph->u.notes.fuse_to_next_glyph == -1); + switch (adjusted_queuetype_of(note, note, + glyph->u.notes.fuse_to_next_glyph)) { + case Q_ON_SPACE_BELOW_BOTTOM_LINE: + if (ambitus_one) { name = openqueue_shape; break; - case Q_ON_SPACE_ABOVE_BOTTOM_LINE: - name = base_shape; - break; - case Q_ON_LINE_ABOVE_BOTTOM_LINE: - name = longqueue_shape; + } + /* else fall through */ + case Q_ON_SPACE_ABOVE_BOTTOM_LINE: + /* at ambitus one, long and short are swapped becuase the queue where + * the second note is on a space is longer than on a line */ + name = ambitus_one? longqueue_shape : base_shape; + break; + case Q_ON_BOTTOM_LINE: + if (ambitus_one) { + name = openqueue_shape; break; } - } else { - name = base_shape; + /* else fall through */ + case Q_ON_LINE_ABOVE_BOTTOM_LINE: + /* at ambitus one, long and short are swapped becuase the queue where + * the second note is on a line is shorter than on a space */ + name = ambitus_one? base_shape : longqueue_shape; + break; } } else { switch (queuetype_of(note)) { @@ -518,6 +549,7 @@ static const char *fusible_queued_shape(const gregorio_note *const note, break; } } + gregorio_not_null(name, fusible_queued_shape, return base_shape); return compute_glyph_name(glyph, name, LG_NONE, true); } @@ -613,9 +645,13 @@ static const char *gregoriotex_determine_note_glyph_name(gregorio_note *note, case S_QUILISMA: *type = AT_QUILISMA; return compute_glyph_name(glyph, SHAPE_Quilisma, LG_NONE, true); - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_ASCENDENS: return fusible_queued_shape(note, glyph, SHAPE_OriscusScapus, SHAPE_OriscusScapusLongqueue, SHAPE_OriscusScapusOpenqueue); + case S_ORISCUS_SCAPUS_DESCENDENS: + return fusible_queued_shape(note, glyph, SHAPE_OriscusScapusReversus, + SHAPE_OriscusScapusReversusLongqueue, + SHAPE_OriscusScapusReversusOpenqueue); case S_STROPHA: *type = AT_STROPHA; if (!(note->u.note.liquescentia & @@ -828,7 +864,8 @@ const char *gregoriotex_determine_glyph_name(const gregorio_glyph *const glyph, break; case S_ORISCUS_ASCENDENS: case S_ORISCUS_DESCENDENS: - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: *type = AT_ORISCUS; *gtype = T_PESQUASSUS; shape = quadratum_shape(glyph, SHAPE_PesQuassus, @@ -893,7 +930,8 @@ const char *gregoriotex_determine_glyph_name(const gregorio_glyph *const glyph, ltype = LG_NO_INITIO; break; - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: *gtype = T_FLEXUS_ORISCUS_SCAPUS; shape = flexus_shape(glyph, ambitus, SHAPE_FlexusOriscusScapus, SHAPE_FlexusOriscusScapusLongqueue, @@ -2843,7 +2881,8 @@ static void write_glyph(FILE *f, gregorio_syllable *syllable, case S_ORISCUS_CAVUM_ASCENDENS: case S_ORISCUS_CAVUM_DESCENDENS: case S_ORISCUS_CAVUM_DEMINUTUS: - case S_ORISCUS_SCAPUS: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: /* don't change the oriscus */ break; diff --git a/src/struct.c b/src/struct.c index 2b2d0856b..cd260b488 100644 --- a/src/struct.c +++ b/src/struct.c @@ -357,20 +357,32 @@ static void fix_oriscus_liquescentia(gregorio_note *const note, break; } } else { + note->u.note.liquescentia &= ((~TAIL_LIQUESCENTIA_MASK) | L_DEMINUTUS); + if (note->u.note.liquescentia & L_DEMINUTUS) { + note->u.note.shape = S_ORISCUS_DEMINUTUS; + } + } +} + +static void fix_oriscus_scapus_liquescentia(gregorio_note *const note, + const bool legacy_oriscus_orientation) +{ + if (legacy_oriscus_orientation) { switch (note->u.note.liquescentia) { case L_AUCTUS_ASCENDENS: - note->u.note.shape = S_ORISCUS_ASCENDENS; - break; + note->u.note.liquescentia = + (note->u.note.liquescentia & ~TAIL_LIQUESCENTIA_MASK) + | L_AUCTUS_DESCENDENS; + /* fall through */ case L_AUCTUS_DESCENDENS: - note->u.note.shape = S_ORISCUS_DESCENDENS; - break; - case L_DEMINUTUS: - note->u.note.shape = S_ORISCUS_DEMINUTUS; + note->u.note.shape = S_ORISCUS_SCAPUS_DESCENDENS; break; default: - note->u.note.shape = S_ORISCUS_UNDETERMINED; + note->u.note.shape = S_ORISCUS_SCAPUS_ASCENDENS; break; } + } else { + note->u.note.liquescentia &= ~TAIL_LIQUESCENTIA_MASK; } } @@ -395,19 +407,9 @@ static void fix_oriscus_cavum_liquescentia(gregorio_note *const note, break; } } else { - switch (note->u.note.liquescentia) { - case L_AUCTUS_ASCENDENS: - note->u.note.shape = S_ORISCUS_CAVUM_ASCENDENS; - break; - case L_AUCTUS_DESCENDENS: - note->u.note.shape = S_ORISCUS_CAVUM_DESCENDENS; - break; - case L_DEMINUTUS: + note->u.note.liquescentia &= ((~TAIL_LIQUESCENTIA_MASK) | L_DEMINUTUS); + if (note->u.note.liquescentia & L_DEMINUTUS) { note->u.note.shape = S_ORISCUS_CAVUM_DEMINUTUS; - break; - default: - note->u.note.shape = S_ORISCUS_CAVUM_UNDETERMINED; - break; } } } @@ -434,13 +436,24 @@ void gregorio_change_shape(gregorio_note *const note, break; case S_ORISCUS_UNDETERMINED: - case S_ORISCUS_ASCENDENS: - case S_ORISCUS_DESCENDENS: case S_ORISCUS_DEMINUTUS: + case S_ORISCUS_SCAPUS_UNDETERMINED: note->u.note.shape = S_ORISCUS_CAVUM_UNDETERMINED; fix_oriscus_cavum_liquescentia(note, legacy_oriscus_orientation); break; + case S_ORISCUS_ASCENDENS: + case S_ORISCUS_SCAPUS_ASCENDENS: + note->u.note.shape = S_ORISCUS_CAVUM_ASCENDENS; + fix_oriscus_cavum_liquescentia(note, legacy_oriscus_orientation); + break; + + case S_ORISCUS_DESCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: + note->u.note.shape = S_ORISCUS_CAVUM_DESCENDENS; + fix_oriscus_cavum_liquescentia(note, legacy_oriscus_orientation); + break; + default: break; } @@ -453,6 +466,28 @@ void gregorio_change_shape(gregorio_note *const note, break; case S_ORISCUS_UNDETERMINED: + switch (old_shape) { + case S_PUNCTUM_CAVUM: + case S_PUNCTUM_CAVUM_INCLINATUM: + note->u.note.shape = S_ORISCUS_CAVUM_UNDETERMINED; + fix_oriscus_cavum_liquescentia(note, legacy_oriscus_orientation); + break; + + case S_ORISCUS_CAVUM_UNDETERMINED: + case S_ORISCUS_CAVUM_ASCENDENS: + case S_ORISCUS_CAVUM_DESCENDENS: + case S_ORISCUS_CAVUM_DEMINUTUS: + note->u.note.shape = old_shape; + fix_oriscus_cavum_liquescentia(note, legacy_oriscus_orientation); + break; + + default: + fix_oriscus_liquescentia(note, legacy_oriscus_orientation); + break; + } + break; + + case S_ORISCUS_ASCENDENS: switch (old_shape) { case S_PUNCTUM_CAVUM: case S_PUNCTUM_CAVUM_INCLINATUM: @@ -460,7 +495,25 @@ void gregorio_change_shape(gregorio_note *const note, case S_ORISCUS_CAVUM_ASCENDENS: case S_ORISCUS_CAVUM_DESCENDENS: case S_ORISCUS_CAVUM_DEMINUTUS: - note->u.note.shape = S_ORISCUS_CAVUM_UNDETERMINED; + note->u.note.shape = S_ORISCUS_CAVUM_ASCENDENS; + fix_oriscus_cavum_liquescentia(note, legacy_oriscus_orientation); + break; + + default: + fix_oriscus_liquescentia(note, legacy_oriscus_orientation); + break; + } + break; + + case S_ORISCUS_DESCENDENS: + switch (old_shape) { + case S_PUNCTUM_CAVUM: + case S_PUNCTUM_CAVUM_INCLINATUM: + case S_ORISCUS_CAVUM_UNDETERMINED: + case S_ORISCUS_CAVUM_ASCENDENS: + case S_ORISCUS_CAVUM_DESCENDENS: + case S_ORISCUS_CAVUM_DEMINUTUS: + note->u.note.shape = S_ORISCUS_CAVUM_DESCENDENS; fix_oriscus_cavum_liquescentia(note, legacy_oriscus_orientation); break; @@ -470,6 +523,12 @@ void gregorio_change_shape(gregorio_note *const note, } break; + case S_ORISCUS_SCAPUS_UNDETERMINED: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: + fix_oriscus_scapus_liquescentia(note, legacy_oriscus_orientation); + break; + default: break; } @@ -489,6 +548,10 @@ void gregorio_add_tail_liquescentia(gregorio_note *note, | (liq & TAIL_LIQUESCENTIA_MASK); switch (note->u.note.shape) { + case S_PUNCTUM_CAVUM_INCLINATUM: + fix_punctum_cavum_inclinatum_liquescentia(note); + break; + case S_STROPHA: case S_DISTROPHA: case S_TRISTROPHA: @@ -506,8 +569,10 @@ void gregorio_add_tail_liquescentia(gregorio_note *note, fix_oriscus_liquescentia(note, legacy_oriscus_orientation); break; - case S_PUNCTUM_CAVUM_INCLINATUM: - fix_punctum_cavum_inclinatum_liquescentia(note); + case S_ORISCUS_SCAPUS_UNDETERMINED: + case S_ORISCUS_SCAPUS_ASCENDENS: + case S_ORISCUS_SCAPUS_DESCENDENS: + fix_oriscus_scapus_liquescentia(note, legacy_oriscus_orientation); break; case S_ORISCUS_CAVUM_UNDETERMINED: diff --git a/src/struct.h b/src/struct.h index e1076e124..636c00820 100644 --- a/src/struct.h +++ b/src/struct.h @@ -108,7 +108,8 @@ ENUM(gregorio_clef, GREGORIO_CLEF); E(S_ORISCUS_ASCENDENS) \ E(S_ORISCUS_DESCENDENS) \ E(S_ORISCUS_DEMINUTUS) \ - E(S_ORISCUS_SCAPUS) \ + E(S_ORISCUS_SCAPUS_ASCENDENS) \ + E(S_ORISCUS_SCAPUS_DESCENDENS) \ E(S_QUILISMA) \ E(S_STROPHA) \ E(S_STROPHA_AUCTA) \ @@ -130,6 +131,7 @@ ENUM(gregorio_clef, GREGORIO_CLEF); * and quilisma quadratum is the shape of the first note of a pes * quislisma quadratum */ \ E(S_ORISCUS_UNDETERMINED) \ + E(S_ORISCUS_SCAPUS_UNDETERMINED) \ E(S_ORISCUS_CAVUM_UNDETERMINED) \ E(S_QUADRATUM) \ /* those shapes are for now used only in gregoriotex */ \