Skip to content

Commit

Permalink
Suppressed a z0 custos separated from a line break (z) by only bars/c…
Browse files Browse the repository at this point in the history
…lefs.

Fixes gregorio-project#1190.
  • Loading branch information
henryso committed Aug 6, 2016
1 parent b7016b7 commit 6d6af20
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ As of v3.0.0 this project adheres to [Semantic Versioning](http://semver.org/).
[Unreleased][unreleased]
## Changed
- Notes are now left-aligned as if all clefs had the same width as the largest clef in the score. You can get previous behavior back with `\grebolshiftcleftype{current}`, or temporary force alignment until the end of a score with `\grelocalbolshiftcleftype`. See Documentation of these functions and [#1189](https://github.com/gregorio-project/gregorio/issues/1189).
- If only bars and clefs are between an explicit custos `(z0)` and a line break `(z)`, the explicit custos will be suppressed (see [1190](https://github.com/gregorio-project/gregorio/issues/1190)).

### Added
- More cavum shapes are now available. To use them, simply add `r` in gabc to any note in a glyph. See [#844](https://github.com/gregorio-project/gregorio/issues/844).
Expand Down
2 changes: 1 addition & 1 deletion src/gabc/gabc-notes-determination.l
Original file line number Diff line number Diff line change
Expand Up @@ -1116,7 +1116,7 @@ void gabc_det_notes_finish(void)
}
[\t\r\n]+ /* ignore ends of line and tabs */;
z0 {
gregorio_add_custo_as_note(&current_note, &notes_lloc);
gregorio_add_custos_as_note(&current_note, &notes_lloc);
}
z {
gregorio_add_end_of_line_as_note(&current_note, false, false, false,
Expand Down
63 changes: 51 additions & 12 deletions src/gabc/gabc-score-determination.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,50 @@
#include "gabc-score-determination.h"
#include "messages.h"

void fix_custos(gregorio_score *score_to_check)
void gabc_suppress_extra_custos_at_linebreak(gregorio_score *score)
{
gregorio_syllable *syllable;
gregorio_element **custos = NULL;

for (syllable = score->first_syllable; syllable;
syllable = syllable->next_syllable) {
gregorio_element **element;
for (element = syllable->elements; element && *element;
element = &((*element)->next)) {
switch ((*element)->type) {
case GRE_CUSTOS:
if (!((*element)->u.misc.pitched.force_pitch)) {
/* save the encountered non-forced custos */
custos = element;
} else {
/* forget the (previous) custos */
custos = NULL;
}
break;
case GRE_CLEF:
case GRE_BAR:
/* remember the custos if only these appear before linebreak */
break;
case GRE_END_OF_LINE:
if (custos) {
/* suppress the custos when linebreak follows */
gregorio_free_one_element(custos);
}
/* fall through */
default:
/* forget the custos */
custos = NULL;
break;
}
}
}
}

void gabc_fix_custos_pitches(gregorio_score *score_to_check)
{
gregorio_syllable *current_syllable;
gregorio_element *current_element;
gregorio_element *custo_element;
gregorio_element *custos_element;
char pitch = 0;
char pitch_difference = 0;
int newkey;
Expand All @@ -52,8 +91,8 @@ void fix_custos(gregorio_score *score_to_check)
current_element = (current_syllable->elements)[0];
while (current_element) {
if (current_element->type == GRE_CUSTOS) {
custo_element = current_element;
pitch = custo_element->u.misc.pitched.pitch;
custos_element = current_element;
pitch = custos_element->u.misc.pitched.pitch;
/* we look for the key */
while (current_element) {
if (current_element->type == GRE_CLEF) {
Expand All @@ -65,17 +104,17 @@ void fix_custos(gregorio_score *score_to_check)
pitch -= pitch_difference;
current_key = newkey;
}
if (!custo_element->u.misc.pitched.force_pitch) {
if (!custos_element->u.misc.pitched.force_pitch) {
while (pitch < LOWEST_PITCH) {
pitch += 7;
}
while (pitch > score_to_check->highest_pitch) {
pitch -= 7;
}
custo_element->u.misc.pitched.pitch = pitch;
custos_element->u.misc.pitched.pitch = pitch;
}
assert(custo_element->u.misc.pitched.pitch >= LOWEST_PITCH
&& custo_element->u.misc.pitched.pitch
assert(custos_element->u.misc.pitched.pitch >= LOWEST_PITCH
&& custos_element->u.misc.pitched.pitch
<= score_to_check->highest_pitch);
current_element = current_element->next;
}
Expand All @@ -96,7 +135,7 @@ void fix_custos(gregorio_score *score_to_check)
* A function that checks the score integrity.
*/

bool check_score_integrity(gregorio_score *score_to_check)
bool gabc_check_score_integrity(gregorio_score *score_to_check)
{
bool good = true;

Expand Down Expand Up @@ -144,7 +183,7 @@ bool check_score_integrity(gregorio_score *score_to_check)
* Another function to be improved: this one checks the validity of the voice_infos.
*/

bool check_infos_integrity(gregorio_score *score_to_check)
bool gabc_check_infos_integrity(gregorio_score *score_to_check)
{
if (!score_to_check->name) {
gregorio_message(_("no name specified, put `name:...;' at the "
Expand Down Expand Up @@ -213,7 +252,7 @@ static void oriscus_orientation_visit(
}
}

void determine_oriscus_orientation(const gregorio_score *const score)
void gabc_determine_oriscus_orientation(const gregorio_score *const score)
{
gregorio_note *oriscus = NULL;

Expand Down Expand Up @@ -329,7 +368,7 @@ static void punctum_inclinatum_orientation_visit(
v->previous = *p;
}

void determine_punctum_inclinatum_orientation(
void gabc_determine_punctum_inclinatum_orientation(
const gregorio_score *const score)
{
punctum_inclinatum_vars v = {
Expand Down
11 changes: 6 additions & 5 deletions src/gabc/gabc-score-determination.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ YY_DECL;

#define YYLTYPE gregorio_scanner_location

void fix_custos(gregorio_score *score_to_check);
bool check_score_integrity(gregorio_score *score_to_check);
bool check_infos_integrity(gregorio_score *score_to_check);
void determine_oriscus_orientation(const gregorio_score *score);
void determine_punctum_inclinatum_orientation(const gregorio_score *score);
void gabc_suppress_extra_custos_at_linebreak(gregorio_score *score);
void gabc_fix_custos_pitches(gregorio_score *score_to_check);
bool gabc_check_score_integrity(gregorio_score *score_to_check);
bool gabc_check_infos_integrity(gregorio_score *score_to_check);
void gabc_determine_oriscus_orientation(const gregorio_score *score);
void gabc_determine_punctum_inclinatum_orientation(const gregorio_score *score);

#endif
11 changes: 6 additions & 5 deletions src/gabc/gabc-score-determination.y
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ static void end_definitions(void)
{
int i;

gregorio_assert_only(check_infos_integrity(score), end_definitions,
gregorio_assert_only(gabc_check_infos_integrity(score), end_definitions,
"can't determine valid infos on the score");

elements = (gregorio_element **) gregorio_malloc(number_of_voices *
Expand Down Expand Up @@ -505,16 +505,17 @@ gregorio_score *gabc_read_score(FILE *f_in, bool point_and_click)
* initialized) */
gabc_score_determination_parse();
if (!score->legacy_oriscus_orientation) {
determine_oriscus_orientation(score);
gabc_determine_oriscus_orientation(score);
}
determine_punctum_inclinatum_orientation(score);
gabc_determine_punctum_inclinatum_orientation(score);
gregorio_fix_initial_keys(score, gregorio_default_clef);
rebuild_score_characters();
fix_custos(score);
gabc_suppress_extra_custos_at_linebreak(score);
gabc_fix_custos_pitches(score);
gabc_det_notes_finish();
free_variables();
/* then we check the validity and integrity of the score we have built. */
if (!check_score_integrity(score)) {
if (!gabc_check_score_integrity(score)) {
gregorio_message(_("unable to determine a valid score from file"),
"gabc_read_score", VERBOSITY_ERROR, 0);
}
Expand Down
20 changes: 10 additions & 10 deletions src/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ void gregorio_add_end_of_line_as_note(gregorio_note **current_note,
element->u.other.eol_forces_custos_on = eol_forces_custos_on;
}

void gregorio_add_custo_as_note(gregorio_note **current_note,
void gregorio_add_custos_as_note(gregorio_note **current_note,
const gregorio_scanner_location *const loc)
{
gregorio_note *element = create_and_link_note(current_note, loc);
Expand Down Expand Up @@ -897,22 +897,22 @@ static __inline void free_one_element(gregorio_element *element)
free(element);
}

static void gregorio_free_one_element(gregorio_element **element)
void gregorio_free_one_element(gregorio_element **element)
{
gregorio_element *next = NULL;
gregorio_element *to_free;
gregorio_not_null_ptr(element, gregorio_free_one_element, return);
if ((*element)->next) {
(*element)->next->previous = NULL;
next = (*element)->next;
to_free = *element;
if (to_free->next) {
to_free->next->previous = NULL;
next = to_free->next;
}
if ((*element)->previous) {
/* this doesn't currently happen, but it's safer to leave this in */
/* LCOV_EXCL_START */
(*element)->previous->next = NULL;
if (to_free->previous) {
to_free->previous->next = NULL;
}
/* The previous line is probably optimized out */
/* LCOV_EXCL_STOP */
free_one_element(*element);
free_one_element(to_free);
*element = next;
}

Expand Down
8 changes: 4 additions & 4 deletions src/struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,9 +548,8 @@ typedef struct gregorio_element {
/* index to a string containing a possible TeX verbatim; necessary during
* structure generation. */
unsigned short texverb;
/* type can have the values GRE_ELEMENT, GRE_BAR, GRE_C_KEY_CHANGE,
* GRE_F_KEY_CHANGE, GRE_END_OF_LINE, GRE_SPACE, GRE_TEXVERB_ELEMENT
* or GRE_NLBA */
/* type can have the values GRE_ELEMENT, GRE_BAR, GRE_CLEF, GRE_CUSTOS,
* GRE_END_OF_LINE, GRE_SPACE, GRE_TEXVERB_ELEMENT or GRE_NLBA */
ENUM_BITFIELD(gregorio_type) type:8;
} gregorio_element;

Expand Down Expand Up @@ -823,6 +822,7 @@ void gregorio_add_voice_info(gregorio_voice_info **current_voice_info);
void gregorio_free_voice_infos(gregorio_voice_info *voice_info);
void gregorio_free_one_note(gregorio_note **note);
void gregorio_free_one_glyph(gregorio_glyph **glyph);
void gregorio_free_one_element(gregorio_element **element);
void gregorio_free_score(gregorio_score *score);
void gregorio_free_characters(gregorio_character *current_character);
void gregorio_go_to_first_character(const gregorio_character **character);
Expand All @@ -837,7 +837,7 @@ void gregorio_add_unpitched_element_as_glyph(gregorio_glyph **current_glyph,
void gregorio_add_end_of_line_as_note(gregorio_note **current_note,
bool eol_ragged, bool eol_forces_custos, bool eol_forces_custos_on,
const gregorio_scanner_location *loc);
void gregorio_add_custo_as_note(gregorio_note **current_note,
void gregorio_add_custos_as_note(gregorio_note **current_note,
const gregorio_scanner_location *loc);
void gregorio_add_manual_custos_as_note(gregorio_note **current_note,
signed char pitch, const gregorio_scanner_location *loc);
Expand Down

0 comments on commit 6d6af20

Please sign in to comment.