diff --git a/CHANGELOG.md b/CHANGELOG.md index 206c25446..190e06ad2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. As of v3.0.0 this project adheres to [Semantic Versioning](http://semver.org/). It follows [some conventions](http://keepachangelog.com/). ## [Unreleased][unreleased] +### Fixed +- Corrected the rendering of explicit automatic and manual custos at the end of lines when the clef change that follows it is pushed to the next line (see [#569](https://github.com/gregorio-project/gregorio/issues/569)). ## [4.0.0-beta] - 2015-08-01 diff --git a/doc/Command_Index_gregorio.tex b/doc/Command_Index_gregorio.tex index 4050f9bf3..98d816898 100644 --- a/doc/Command_Index_gregorio.tex +++ b/doc/Command_Index_gregorio.tex @@ -469,7 +469,7 @@ \section{Gregorio Controls} & 1 & Choral sign occurs before last note of podatus, porrectus, or torculus resupinus.\\ \end{argtable} -\macroname{\textbackslash GreManualCusto}{\#1}{gregoriotex-signs.tex} +\macroname{\textbackslash GreManualCustos}{\#1}{gregoriotex-signs.tex} Macro to typeset a custo manually. \begin{argtable} diff --git a/src/dump/dump.c b/src/dump/dump.c index 33a05833e..595d9b5b7 100644 --- a/src/dump/dump.c +++ b/src/dump/dump.c @@ -179,8 +179,8 @@ static const char *dump_type(gregorio_type type) return "GRE_END_OF_LINE"; case GRE_END_OF_PAR: return "GRE_END_OF_PAR"; - case GRE_CUSTO: - return "GRE_CUSTO"; + case GRE_CUSTOS: + return "GRE_CUSTOS"; case GRE_SPACE: return "GRE_SPACE"; case GRE_BAR: @@ -689,11 +689,14 @@ void dump_write_score(FILE *f, gregorio_score *score) element->type, dump_type(element->type)); } switch (element->type) { - case GRE_CUSTO: + case GRE_CUSTOS: if (element->u.misc.pitched.pitch) { fprintf(f, " pitch %s\n", dump_pitch(element->u.misc.pitched.pitch)); } + if (element->u.misc.pitched.force_pitch) { + fprintf(f, " force_pitch true\n"); + } break; case GRE_SPACE: if (element->u.misc.unpitched.info.space) { @@ -795,7 +798,6 @@ void dump_write_score(FILE *f, gregorio_score *score) case GRE_FLAT: case GRE_NATURAL: case GRE_SHARP: - case GRE_MANUAL_CUSTOS: fprintf(f, " pitch %s\n", dump_pitch(glyph->u.misc.pitched.pitch)); break; diff --git a/src/gabc/gabc-elements-determination.c b/src/gabc/gabc-elements-determination.c index 50e76db67..eefdc86e4 100644 --- a/src/gabc/gabc-elements-determination.c +++ b/src/gabc/gabc-elements-determination.c @@ -125,12 +125,6 @@ static gregorio_element *gabc_det_elements_from_glyphs( while (current_glyph) { if (current_glyph->type != GRE_GLYPH) { - if (current_glyph->type == GRE_MANUAL_CUSTOS) { - first_element = current_element; - close_element(¤t_element, &first_glyph, current_glyph); - current_glyph = current_glyph->next; - continue; - } /* we ignore flats and naturals, except if they are alone */ if (current_glyph->type == GRE_NATURAL || current_glyph->type == GRE_FLAT diff --git a/src/gabc/gabc-glyphs-determination.c b/src/gabc/gabc-glyphs-determination.c index 350bc23d6..90e1853ea 100644 --- a/src/gabc/gabc-glyphs-determination.c +++ b/src/gabc/gabc-glyphs-determination.c @@ -663,6 +663,7 @@ gregorio_glyph *gabc_det_glyphs_from_notes(gregorio_note *current_note, gregorio_type type = current_note->type; char pitch = USELESS_VALUE; bool flat = false; + bool force = false; gregorio_sign sign = _NO_SIGN; if (current_glyph_type != G_UNDETERMINED) { @@ -698,11 +699,17 @@ gregorio_glyph *gabc_det_glyphs_from_notes(gregorio_note *current_note, flat = true; break; - case GRE_CUSTO: + case GRE_CUSTOS: pitch = gabc_determine_custo_pitch(current_note->next, *current_key); break; + case GRE_MANUAL_CUSTOS: + pitch = current_note->u.note.pitch; + type = GRE_CUSTOS; + force = true; + break; + case GRE_BAR: /* we calculate the signs of the bars */ if (current_note->signs == _V_EPISEMUS) { @@ -735,7 +742,7 @@ gregorio_glyph *gabc_det_glyphs_from_notes(gregorio_note *current_note, current_note->u.other, sign, current_note->texverb); } else { gregorio_add_pitched_element_as_glyph(&last_glyph, type, pitch, - flat, current_note->texverb); + flat, force, current_note->texverb); } current_glyph_first_note = current_note->next; current_note->texverb = NULL; diff --git a/src/gabc/gabc-score-determination.y b/src/gabc/gabc-score-determination.y index 23c6fd70c..4b2956991 100644 --- a/src/gabc/gabc-score-determination.y +++ b/src/gabc/gabc-score-determination.y @@ -126,8 +126,9 @@ static void gabc_fix_custos(gregorio_score *score_to_check) while (current_syllable) { current_element = (current_syllable->elements)[0]; while (current_element) { - if (current_element->type == GRE_CUSTO) { + if (current_element->type == GRE_CUSTOS) { custo_element = current_element; + pitch = custo_element->u.misc.pitched.pitch; /* we look for the key */ while (current_element) { switch (current_element->type) { @@ -138,7 +139,7 @@ static void gabc_fix_custos(gregorio_score *score_to_check) newkey = gregorio_calculate_new_key(C_KEY, current_element->u.misc.pitched.pitch - '0'); pitch_difference = (char) newkey - (char) current_key; - custo_element->u.misc.pitched.pitch = pitch - pitch_difference; + pitch -= pitch_difference; current_key = newkey; break; case GRE_F_KEY_CHANGE: @@ -148,17 +149,20 @@ static void gabc_fix_custos(gregorio_score *score_to_check) newkey = gregorio_calculate_new_key(F_KEY, current_element->u.misc.pitched.pitch - '0'); pitch_difference = (char) newkey - (char) current_key; - custo_element->u.misc.pitched.pitch = pitch - pitch_difference; + pitch -= pitch_difference; current_key = newkey; break; default: break; } - while (custo_element->u.misc.pitched.pitch < LOWEST_PITCH) { - custo_element->u.misc.pitched.pitch += 7; - } - while (custo_element->u.misc.pitched.pitch > HIGHEST_PITCH) { - custo_element->u.misc.pitched.pitch -= 7; + if (!custo_element->u.misc.pitched.force_pitch) { + while (pitch < LOWEST_PITCH) { + pitch += 7; + } + while (pitch > HIGHEST_PITCH) { + pitch -= 7; + } + custo_element->u.misc.pitched.pitch = pitch; } assert(custo_element->u.misc.pitched.pitch >= LOWEST_PITCH && custo_element->u.misc.pitched.pitch diff --git a/src/gabc/gabc-write.c b/src/gabc/gabc-write.c index 17560426c..e5375f623 100644 --- a/src/gabc/gabc-write.c +++ b/src/gabc/gabc-write.c @@ -223,9 +223,9 @@ static void gabc_write_key_change(FILE *f, char step, int line, bool flatted_key) { if (flatted_key) { - fprintf(f, "%c%d", step, line); - } else { fprintf(f, "%cb%d", step, line); + } else { + fprintf(f, "%c%d", step, line); } } @@ -680,6 +680,13 @@ static void gabc_write_gregorio_element(FILE *f, gregorio_element *element) case GRE_END_OF_LINE: fprintf(f, "z"); break; + case GRE_CUSTOS: + if (element->u.misc.pitched.force_pitch) { + fprintf(f, "%c+", pitch_letter(element->u.misc.pitched.pitch)); + } else { + fprintf(f, "z0"); + } + break; default: gregorio_message(_("call with an argument which type is unknown"), "gabc_write_gregorio_element", VERBOSITY_ERROR, 0); diff --git a/src/gregoriotex/gregoriotex-write.c b/src/gregoriotex/gregoriotex-write.c index 9511bba1c..66b605ab2 100644 --- a/src/gregoriotex/gregoriotex-write.c +++ b/src/gregoriotex/gregoriotex-write.c @@ -807,7 +807,7 @@ static gregorio_element *gregoriotex_syllable_is_clef_change(gregorio_syllable } element = syllable->elements[0]; /* we just detect the foud cases */ - if (element->type == GRE_CUSTO && element->next + if (element->type == GRE_CUSTOS && element->next && (is_clef(element->next->type)) && !element->next->next) { return element->next; } @@ -818,7 +818,7 @@ static gregorio_element *gregoriotex_syllable_is_clef_change(gregorio_syllable if ((is_clef(element->type)) && !element->next) { return element; } - if (element->type == GRE_CUSTO && element->next + if (element->type == GRE_CUSTOS && element->next && element->next->type == GRE_BAR && element->next->next && (is_clef(element->next->next->type)) && !element->next->next->next) { @@ -2511,11 +2511,6 @@ static void gregoriotex_write_element(FILE *f, gregorio_syllable *syllable, pitch_value(glyph->u.misc.pitched.pitch)); break; - case GRE_MANUAL_CUSTOS: - fprintf(f, "\\GreManualCusto{%d}%%\n", - pitch_value(glyph->u.misc.pitched.pitch)); - break; - default: /* at this point glyph->type is GRE_GLYPH */ assert(glyph->type == GRE_GLYPH); @@ -2618,7 +2613,6 @@ static void handle_final_bar(FILE *f, const char *type, gregorio_syllable *sylla /* first element will be the bar, which we just handled, so skip it */ for (element = (*syllable->elements)->next; element; element = element->next) { - gregorio_glyph *glyph; switch (element->type) { case GRE_TEXVERB_ELEMENT: if (element->texverb) { @@ -2627,14 +2621,10 @@ static void handle_final_bar(FILE *f, const char *type, gregorio_syllable *sylla } break; - case GRE_ELEMENT: - for (glyph = element->u.first_glyph; glyph; - glyph = glyph->next) { - if (glyph->type == GRE_MANUAL_CUSTOS) { - fprintf(f, "\\GreManualCusto{%d}%%\n", - pitch_value(glyph->u.misc.pitched.pitch)); - } - } + case GRE_CUSTOS: + assert(element->u.misc.pitched.force_pitch); + fprintf(f, "\\GreManualCustos{%d}%%\n", + pitch_value(element->u.misc.pitched.pitch)); break; default: @@ -2979,14 +2969,15 @@ static void gregoriotex_write_syllable(FILE *f, gregorio_syllable *syllable, } break; - case GRE_CUSTO: + case GRE_CUSTOS: if (first_of_disc != 1) { /* * We don't print custos before a bar at the end of a line */ /* we also print an unbreakable larger space before the custo */ - fprintf(f, "\\GreEndOfElement{1}{1}%%\n\\GreCustos{%d}" + fprintf(f, "\\GreEndOfElement{1}{1}%%\n\\Gre%sCustos{%d}" "\\GreNextCustos{%d}%%\n", + element->u.misc.pitched.force_pitch? "Manual" : "", pitch_value(element->u.misc.pitched.pitch), pitch_value(gregorio_determine_next_pitch(syllable, element, NULL))); diff --git a/src/struct.c b/src/struct.c index c24831bc1..e73ce9733 100644 --- a/src/struct.c +++ b/src/struct.c @@ -152,7 +152,7 @@ void gregorio_add_custo_as_note(gregorio_note **current_note, { gregorio_note *element = create_and_link_note(current_note, loc); if (element) { - element->type = GRE_CUSTO; + element->type = GRE_CUSTOS; } } @@ -656,17 +656,19 @@ void gregorio_add_glyph(gregorio_glyph **current_glyph, } void gregorio_add_pitched_element_as_glyph(gregorio_glyph **current_glyph, - gregorio_type type, signed char pitch, bool flatted_key, char *texverb) + gregorio_type type, signed char pitch, bool flatted_key, + bool force_pitch, char *texverb) { gregorio_glyph *next_glyph = create_and_link_glyph(current_glyph); assert(type == GRE_C_KEY_CHANGE || type == GRE_F_KEY_CHANGE || type == GRE_C_KEY_CHANGE_FLATED || type == GRE_F_KEY_CHANGE_FLATED - || type == GRE_CUSTO || type == GRE_FLAT || type == GRE_NATURAL + || type == GRE_CUSTOS || type == GRE_FLAT || type == GRE_NATURAL || type == GRE_SHARP); if (next_glyph) { next_glyph->type = type; next_glyph->u.misc.pitched.pitch = pitch; next_glyph->u.misc.pitched.flatted_key = flatted_key; + next_glyph->u.misc.pitched.force_pitch = force_pitch; next_glyph->texverb = texverb; } } @@ -679,7 +681,7 @@ void gregorio_add_unpitched_element_as_glyph(gregorio_glyph **current_glyph, assert(type != GRE_NOTE && type != GRE_GLYPH && type != GRE_ELEMENT && type != GRE_C_KEY_CHANGE && type != GRE_F_KEY_CHANGE && type != GRE_C_KEY_CHANGE_FLATED && type != GRE_F_KEY_CHANGE_FLATED - && type != GRE_CUSTO && type != GRE_FLAT && type != GRE_NATURAL + && type != GRE_CUSTOS && type != GRE_FLAT && type != GRE_NATURAL && type != GRE_SHARP); if (next_glyph) { next_glyph->type = type; @@ -1489,15 +1491,12 @@ static signed char gregorio_syllable_first_note(gregorio_syllable *syllable) } element = syllable->elements[0]; while (element) { - if (element->type == GRE_CUSTO) { + if (element->type == GRE_CUSTOS) { return element->u.misc.pitched.pitch; } if (element->type == GRE_ELEMENT && element->u.first_glyph) { glyph = element->u.first_glyph; while (glyph) { - if (glyph->type == GRE_MANUAL_CUSTOS) { - return glyph->u.misc.pitched.pitch; - } if (glyph->type == GRE_GLYPH && glyph->u.notes.first_note) { assert(glyph->u.notes.first_note->type == GRE_NOTE); return glyph->u.notes.first_note->u.note.pitch; @@ -1523,9 +1522,6 @@ signed char gregorio_determine_next_pitch(gregorio_syllable *syllable, if (glyph) { glyph = glyph->next; while (glyph) { - if (glyph->type == GRE_MANUAL_CUSTOS) { - return glyph->u.misc.pitched.pitch; - } if (glyph->type == GRE_GLYPH && glyph->u.notes.first_note) { assert(glyph->u.notes.first_note->type == GRE_NOTE); return glyph->u.notes.first_note->u.note.pitch; @@ -1536,15 +1532,12 @@ signed char gregorio_determine_next_pitch(gregorio_syllable *syllable, /* then we do the same with the elements */ element = element->next; while (element) { - if (element->type == GRE_CUSTO) { + if (element->type == GRE_CUSTOS) { return element->u.misc.pitched.pitch; } if (element->type == GRE_ELEMENT && element->u.first_glyph) { glyph = element->u.first_glyph; while (glyph) { - if (glyph->type == GRE_MANUAL_CUSTOS) { - return glyph->u.misc.pitched.pitch; - } if (glyph->type == GRE_GLYPH && glyph->u.notes.first_note) { assert(glyph->u.notes.first_note->type == GRE_NOTE); return glyph->u.notes.first_note->u.note.pitch; diff --git a/src/struct.h b/src/struct.h index 2cf3b423b..539c33e4e 100644 --- a/src/struct.h +++ b/src/struct.h @@ -75,7 +75,7 @@ typedef enum gregorio_type { GRE_SPACE, GRE_BAR, GRE_END_OF_PAR, - GRE_CUSTO, + GRE_CUSTOS, /* I don't really know how I could use the a TEXVERB_NOTE in gregoriotex, * as we don't write note by note... */ /* GRE_TEXVERB_NOTE, */ @@ -353,7 +353,7 @@ typedef struct gregorio_extra_info { } gregorio_extra_info; typedef union gregorio_misc_element_info { - /* pitched is used for GRE_CUSTO, GRE_FLAT, GRE_SHARP, GRE_NATURAL, + /* pitched is used for GRE_CUSTOS, GRE_FLAT, GRE_SHARP, GRE_NATURAL, * GRE_C_KEY_CHANGE, GRE_F_KEY_CHANGE, GRE_C_KEY_CHANGE_FLATED, and * GRE_F_KEY_CHANGE_FLATED */ struct { @@ -363,6 +363,7 @@ typedef union gregorio_misc_element_info { signed char pitch; /* boolean indicating a clef with a B-flat */ bool flatted_key:1; + bool force_pitch:1; } pitched; /* unpitched is used for everything else */ struct { @@ -786,7 +787,8 @@ void gregorio_free_one_glyph(gregorio_glyph **glyph); void gregorio_free_score(gregorio_score *score); void gregorio_go_to_first_character(gregorio_character **character); void gregorio_add_pitched_element_as_glyph(gregorio_glyph **current_glyph, - gregorio_type type, signed char pitch, bool flatted_key, char *texverb); + gregorio_type type, signed char pitch, bool flatted_key, + bool force_pitch, char *texverb); void gregorio_add_unpitched_element_as_glyph(gregorio_glyph **current_glyph, gregorio_type type, gregorio_extra_info info, gregorio_sign sign, char *texverb); diff --git a/tex/gregoriotex-signs.tex b/tex/gregoriotex-signs.tex index cde36c5dc..d9b6a02c6 100644 --- a/tex/gregoriotex-signs.tex +++ b/tex/gregoriotex-signs.tex @@ -327,7 +327,7 @@ \relax% }% -\def\GreManualCusto#1{% +\def\GreManualCustos#1{% \gre@skip@temp@four = \gre@skip@spacebeforecusto% \kern\gre@skip@temp@four\GreCustos{#1}% }%