X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fvaticana-ligature-engraver.cc;h=e6b0f002b87730f9311a81e6bf0e2b24ab5a9547;hb=1cd3b2484a4095d4e3fb6422dbc695a1a1219eea;hp=f902e2fda3dba0cdf27e047c91920d29a4626bbc;hpb=c4e1c3c8080b54b22a651701aa82a3f3666a4555;p=lilypond.git diff --git a/lily/vaticana-ligature-engraver.cc b/lily/vaticana-ligature-engraver.cc index f902e2fda3..e6b0f002b8 100644 --- a/lily/vaticana-ligature-engraver.cc +++ b/lily/vaticana-ligature-engraver.cc @@ -1,36 +1,41 @@ /* vaticana-ligature-engraver.cc -- implement Vaticana_ligature_engraver - + source file of the GNU LilyPond music typesetter - - (c) 2003 Juergen Reuter - */ + + (c) 2003--2005 Juergen Reuter +*/ #include "gregorian-ligature-engraver.hh" #include "gregorian-ligature.hh" #include "vaticana-ligature.hh" -#include "item.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" #include "font-interface.hh" #include "warn.hh" -#include "paper-def.hh" +#include "output-def.hh" +#include "paper-column.hh" + +/* + * This class implements the notation specific aspects of Vaticana + * style ligatures for Gregorian chant notation. + */ class Vaticana_ligature_engraver : public Gregorian_ligature_engraver { private: - Real finish_primitive (Item *first_primitive, - Item *primitive, - int context_info, - String glyph_name, - int pitch_delta, - Real flexa_width, - Real join_thickness, - Real distance); + static bool + need_extra_horizontal_space (int prev_prefix_set, int prefix_set, + int context_info, int delta_pitch); + bool is_stacked_head (int prefix_set, + int context_info); + Real align_heads (Array primitives, + Real flexa_width, + Real thickness); public: - TRANSLATOR_DECLARATIONS(Vaticana_ligature_engraver); + TRANSLATOR_DECLARATIONS (Vaticana_ligature_engraver); protected: virtual Spanner *create_ligature_spanner (); @@ -45,49 +50,192 @@ Vaticana_ligature_engraver::Vaticana_ligature_engraver () Spanner * Vaticana_ligature_engraver::create_ligature_spanner () { - return new Spanner (get_property ("VaticanaLigature")); + return make_spanner ("VaticanaLigature", SCM_EOL); +} + +bool +Vaticana_ligature_engraver::is_stacked_head (int prefix_set, + int context_info) +{ + bool is_stacked_b; + + // upper head of pes is stacked upon lower head of pes ... + is_stacked_b = context_info & PES_UPPER; + + // ... unless this note starts a flexa + if (context_info & FLEXA_LEFT) + is_stacked_b = false; + + // ... or another pes + if (context_info & PES_LOWER) + is_stacked_b = false; + + // ... or the previous note is a semivocalis or inclinatum + if (context_info & AFTER_DEMINUTUM) + is_stacked_b = false; + + // auctum head is never stacked upon preceding note + if (prefix_set & AUCTUM) + is_stacked_b = false; + + // virga is never stacked upon preceding note + if (prefix_set & VIRGA) + is_stacked_b = false; + + // oriscus is never stacked upon preceding note + if (prefix_set & ORISCUS) + is_stacked_b = false; + + if ((prefix_set & DEMINUTUM) + && ! (prefix_set & INCLINATUM) + && (context_info & FLEXA_RIGHT)) + is_stacked_b = true; // semivocalis head of deminutus form + + return is_stacked_b; +} + +/* + * When aligning the heads, sometimes extra space is needed, e.g. to + * avoid clashing with the appendix of an adjacent notehead or with an + * adjacent notehead itself if it has the same pitch. Extra space is + * added at most once between to heads. + */ +bool +Vaticana_ligature_engraver::need_extra_horizontal_space (int prev_prefix_set, int prefix_set, + int context_info, int delta_pitch) +{ + if (prev_prefix_set & VIRGA) + /* + * After a virga, make a an additional small space such that the + * appendix on the right side of the head does not touch the + * following head. + */ + return true; + + if ((prefix_set & INCLINATUM) + && ! (prev_prefix_set & INCLINATUM)) + /* + * Always start a series of inclinatum heads with an extra space. + */ + return true; + + if ((context_info & FLEXA_LEFT) && ! (context_info & PES_UPPER)) + /* + * Before a flexa (but not within a torculus), make a an + * additional small space such that the appendix on the left side + * of the flexa does not touch the this head. + */ + return true; + + if (delta_pitch == 0) + /* + * If there are two adjacent noteheads with the same pitch, add + * additional small space between them, such that they do not + * touch each other. + */ + return true; + + return false; } Real -Vaticana_ligature_engraver::finish_primitive (Item *first_primitive, - Item *primitive, - int context_info, - String glyph_name, - int pitch_delta, - Real flexa_width, - Real join_thickness, - Real distance) +Vaticana_ligature_engraver::align_heads (Array primitives, + Real flexa_width, + Real thickness) { - if (primitive) + if (!primitives.size ()) { - // determine width of previous head and x-offset + programming_error ("Vaticana_ligature: " + "empty ligature [ignored]"); + return 0.0; + } + + /* + * The paper column where we put the whole ligature into. + */ + Paper_column *column + = dynamic_cast (primitives[0].grob ())->get_column (); + + Real join_thickness + = thickness * column->get_layout ()->get_dimension (ly_symbol2scm ("linethickness")); + + /* + * Amount of extra space two put between some particular + * configurations of adjacent heads. + * + * TODO: make this a property of primtive grobs. + */ + Real extra_space = 4.0 * join_thickness; + + /* + * Keep track of the total width of the ligature. + */ + Real ligature_width = 0.0; + + Item *prev_primitive = 0; + int prev_prefix_set = 0; + for (int i = 0; i < primitives.size (); i++) + { + Item *primitive = dynamic_cast (primitives[i].grob ()); + int prefix_set + = scm_to_int (primitive->get_property ("prefix-set")); + int context_info + = scm_to_int (primitive->get_property ("context-info")); + + /* + * Get glyph_name, delta_pitch and context_info for this head. + */ + + SCM glyph_name_scm = primitive->get_property ("glyph-name"); + if (glyph_name_scm == SCM_EOL) + { + primitive->programming_error ("Vaticana_ligature:" + "undefined glyph-name -> " + "ignoring grob"); + continue; + } + String glyph_name = ly_scm2string (glyph_name_scm); + + int delta_pitch = 0; + if (prev_primitive) /* urgh, need prev_primitive only here */ + { + SCM delta_pitch_scm = prev_primitive->get_property ("delta-pitch"); + if (delta_pitch_scm != SCM_EOL) + { + delta_pitch = scm_to_int (delta_pitch_scm); + } + else + { + primitive->programming_error ("Vaticana_ligature:" + "delta-pitch undefined -> " + "ignoring grob"); + continue; + } + } + + /* + * Now determine width and x-offset of head. + */ + Real head_width; Real x_offset; - bool is_stacked; - is_stacked = context_info & PES_UPPER; - if (context_info & FLEXA_LEFT) - is_stacked = false; - if (!String::compare (glyph_name, "vaticana_cephalicus") && - !(context_info & PES_LOWER)) - is_stacked = true; - if (context_info & AUCTUM) - is_stacked = false; - if (is_stacked) + + if (context_info & STACKED_HEAD) { /* - * This head is stacked upon another one; hence, it does not - * contribute to the total width of the ligature, hence its - * width is assumed to be 0.0. Moreover, it is shifted to - * the left by its width such that the right side of this - * and the other head are horizontally aligned. + * This head is stacked upon the previous one; hence, it + * does not contribute to the total width of the ligature, + * and its width is assumed to be 0.0. Moreover, it is + * shifted to the left by its width such that the right side + * of this and the other head are horizontally aligned. */ head_width = 0.0; - x_offset = join_thickness - - Font_interface::get_default_font (primitive)-> - find_by_name ("noteheads-" + glyph_name).extent (X_AXIS).length (); + x_offset = join_thickness + - Font_interface::get_default_font (primitive)-> + find_by_name ("noteheads." + glyph_name).extent (X_AXIS).length (); } - else if (!String::compare (glyph_name, "flexa") || - !String::compare (glyph_name, "")) + else if (!String::compare (glyph_name, "flexa") + || !String::compare (glyph_name, "")) { /* * This head represents either half of a flexa shape. @@ -96,240 +244,360 @@ Vaticana_ligature_engraver::finish_primitive (Item *first_primitive, head_width = 0.5 * flexa_width; x_offset = 0.0; } - else // retrieve width from corresponding font + else { - head_width = - Font_interface::get_default_font (primitive)-> - find_by_name ("noteheads-" + glyph_name).extent (X_AXIS).length (); + /* + * This is a regular head, placed right to the previous one. + * Retrieve its width from corresponding font. + */ + head_width + = Font_interface::get_default_font (primitive)-> + find_by_name ("noteheads." + glyph_name).extent (X_AXIS).length (); x_offset = 0.0; } /* - * Save the head's final shape and x-offset. + * Save the head's final x-offset. */ - primitive->set_grob_property ("glyph-name", - scm_makfrom0str (glyph_name.to_str0 ())); - primitive->set_grob_property ("x-offset", - gh_double2scm (x_offset)); + primitive->set_property ("x-offset", + scm_make_real (x_offset)); /* * If the head is the 2nd head of a pes or flexa (but not a * flexa shape), mark this head to be joined with the left-side * neighbour head (i.e. the previous head) by a vertical beam. */ - if ((context_info & PES_UPPER) || - ((context_info & FLEXA_RIGHT) && - !(context_info & PES_LOWER))) + if ((context_info & PES_UPPER) + || ((context_info & FLEXA_RIGHT) + && ! (context_info & PES_LOWER))) { - primitive->set_grob_property ("join-left", - gh_int2scm (pitch_delta)); + if (!prev_primitive) + { + primitive->programming_error ("vaticana ligature: add-join: " + "missing previous primitive"); + } + else + { + prev_primitive->set_property ("add-join", + ly_bool2scm (true)); - /* - * Create a small overlap of adjacent heads so that the join - * can be drawn perfectly between them. - */ - distance -= join_thickness; + /* + * Create a small overlap of adjacent heads so that the join + * can be drawn perfectly between them. + */ + ligature_width -= join_thickness; + } } else if (!String::compare (glyph_name, "")) { /* - * 2nd (virtual) head of flexa shape: join tightly with 1st - * head, i.e. do *not* add additional space, such that next - * head will not be off from the flexa shape. - */ - } - else if (context_info & AFTER_VIRGA) - { - /* - * Make a small space after a virga. + * This is the 2nd (virtual) head of flexa shape. Join it + * tightly with 1st head, i.e. do *not* add additional + * space, such that next head will not be off from the flexa + * shape. */ - distance += 2 * join_thickness; } + if (need_extra_horizontal_space (prev_prefix_set, prefix_set, + context_info, delta_pitch)) + ligature_width += extra_space; + /* * Horizontally line-up this head to form a ligature. */ - get_set_column (primitive, first_primitive->get_column ()); - primitive->translate_axis (distance, X_AXIS); - distance += head_width; + get_set_column (primitive, column); + primitive->translate_axis (ligature_width, X_AXIS); + ligature_width += head_width; + + prev_primitive = primitive; + prev_prefix_set = prefix_set; } - return distance; + + /* + * Add extra horizontal padding space after ligature, such that + * neighbouring ligatures do not touch each other. + */ + ligature_width += extra_space; + + return ligature_width; } +/* + * Depending on the typographical features of a particular ligature + * style, some prefixes may be ignored. In particular, if a curved + * flexa shape is produced, any prefixes to either of the two + * contributing heads that would select a head other than punctum, is + * by definition ignored. + * + * This function prints a warning, if the given primitive is prefixed + * such that a head other than punctum would be chosen, if this + * primitive were engraved as a stand-alone head. + */ void -Vaticana_ligature_engraver::transform_heads (Spanner *ligature, - Array primitives) +check_for_prefix_loss (Item *primitive) { - Real flexa_width; - SCM flexa_width_scm = ligature->get_grob_property ("flexa-width"); - if (flexa_width_scm != SCM_EOL) - { - flexa_width = gh_scm2double (flexa_width_scm); - } - else + int prefix_set + = scm_to_int (primitive->get_property ("prefix-set")); + if (prefix_set & ~PES_OR_FLEXA) { - programming_error ("Vaticana_ligature_engraver:" - "flexa-width undefined; assuming 2.0 staff space"); - flexa_width = - 2.0 * Staff_symbol_referencer::staff_space (ligature); + String prefs = Gregorian_ligature::prefixes_to_str (primitive); + primitive->warning (_f ("ignored prefix (es) `%s' of this head according " + "to restrictions of the selected ligature style", + prefs.to_str0 ())); } +} - Real join_thickness; - SCM join_thickness_scm = ligature->get_grob_property ("thickness"); - if (join_thickness_scm != SCM_EOL) - { - join_thickness = gh_scm2double (join_thickness_scm); - } - else - { - programming_error ("Vaticana_ligature_engraver:" - "thickness undefined; assuming 1.4 linethickness"); - join_thickness = 1.4; - } - join_thickness *= ligature->get_paper ()->get_var ("linethickness"); +void +Vaticana_ligature_engraver::transform_heads (Spanner *ligature, + Array primitives) +{ + Real flexa_width = robust_scm2double (ligature->get_property ("flexa-width"), 2); + + Real thickness = robust_scm2double (ligature->get_property ("thickness"), 1); - Item *first_primitive = 0; Item *prev_primitive = 0; + int prev_prefix_set = 0; int prev_context_info = 0; - int prev_pitch = 0; - int prev_pitch_delta = 0; + int prev_delta_pitch = 0; String prev_glyph_name = ""; - Real prev_distance = 0.0; - for (int i = 0; i < primitives.size(); i++) { - Item *primitive = dynamic_cast (primitives[i].grob_); - Music *music_cause = primitives[i].music_cause (); - int context_info = gh_scm2int (primitive->get_grob_property ("context-info")); - int pitch = unsmob_pitch (music_cause->get_mus_property ("pitch"))->steps (); - String glyph_name; - if (!first_primitive) - first_primitive = primitive; - int prefix_set = gh_scm2int (primitive->get_grob_property ("prefix-set")); + for (int i = 0; i < primitives.size (); i++) + { + Item *primitive = dynamic_cast (primitives[i].grob ()); - /* - * Now determine which head to typeset (this is context sensitive - * information, since it depends on neighbouring heads; therefore, - * this decision must be made here in the engraver rather than in - * the backend). - */ - if (prefix_set & VIRGA) - glyph_name = "vaticana_virga"; - else if (prefix_set & QUILISMA) - glyph_name = "vaticana_quilisma"; - else if (prefix_set & ORISCUS) - glyph_name = "solesmes_oriscus"; - else if (prefix_set & STROPHA) - if (prefix_set & AUCTUM) - glyph_name = "solesmes_stropha_aucta"; - else glyph_name = "solesmes_stropha"; - else if (prefix_set & SEMIVOCALIS) - if (pitch > prev_pitch) - glyph_name = "vaticana_epiphonus"; - else glyph_name = "vaticana_cephalicus"; - else if (prefix_set & INCLINATUM) - if (prefix_set & AUCTUM) - glyph_name = "solesmes_incl_auctum"; - else if (prefix_set & DEMINUTUM) - glyph_name = "solesmes_incl_parvum"; - else - glyph_name = "vaticana_inclinatum"; - else if (prefix_set & (CAVUM | LINEA)) - if ((prefix_set & CAVUM) && (prefix_set & LINEA)) - glyph_name = "vaticana_linea_punctum_cavum"; - else if (prefix_set & CAVUM) - glyph_name = "vaticana_punctum_cavum"; - else - glyph_name = "vaticana_linea_punctum"; - else if (prefix_set & AUCTUM) - if (prefix_set & ASCENDENS) - glyph_name = "solesmes_auct_asc"; - else - glyph_name = "solesmes_auct_desc"; - else if (prefix_set & DEMINUTUM) - glyph_name = "vaticana_plica"; - else if ((prefix_set & PES_OR_FLEXA) && - (context_info & PES_LOWER) && - (context_info & FLEXA_RIGHT)) - glyph_name = ""; // second head of flexa shape - else if (context_info & PES_UPPER) - if (pitch - prev_pitch > 1) - glyph_name = "vaticana_upes"; + int delta_pitch; + SCM delta_pitch_scm = primitive->get_property ("delta-pitch"); + if (delta_pitch_scm != SCM_EOL) + { + delta_pitch = scm_to_int (delta_pitch_scm); + } else - glyph_name = "vaticana_vupes"; - else - glyph_name = "vaticana_punctum"; + { + primitive->programming_error ("Vaticana_ligature:" + "delta-pitch undefined -> " + "ignoring grob"); + continue; + } - /* - * May need updating previous head, depending on the current head. - */ - if (prefix_set & PES_OR_FLEXA) - if ((context_info & PES_LOWER) && - (context_info & FLEXA_RIGHT)) // flexa shape + /* retrieve & complete prefix_set and context_info */ + int prefix_set + = scm_to_int (primitive->get_property ("prefix-set")); + int context_info + = scm_to_int (primitive->get_property ("context-info")); + if (is_stacked_head (prefix_set, context_info)) { - prev_glyph_name = "flexa"; - prev_primitive->set_grob_property ("flexa-height", - gh_int2scm (pitch - prev_pitch)); - prev_primitive->set_grob_property ("flexa-width", - gh_double2scm (flexa_width)); - bool add_stem = - !(prev_context_info & PES_UPPER) && - !(prev_context_info & FLEXA_RIGHT); - prev_primitive->set_grob_property ("add-stem", - gh_bool2scm (add_stem)); + context_info |= STACKED_HEAD; + primitive->set_property ("context-info", + scm_int2num (context_info)); } - else if (context_info & PES_UPPER) + + /* + * Now determine which head to typeset (this is context sensitive + * information, since it depends on neighbouring heads; therefore, + * this decision must be made here in the engraver rather than in + * the backend). + */ + String glyph_name; + if (prefix_set & VIRGA) { - if (!String::compare (prev_glyph_name, "vaticana_punctum")) - prev_glyph_name = "vaticana_lpes"; + glyph_name = "svaticana.punctum"; + primitive->set_property ("add-stem", ly_bool2scm (true)); } - else // flexa + else if (prefix_set & QUILISMA) + glyph_name = "svaticana.quilisma"; + else if (prefix_set & ORISCUS) + glyph_name = "ssolesmes.oriscus"; + else if (prefix_set & STROPHA) + if (prefix_set & AUCTUM) + glyph_name = "ssolesmes.stropha.aucta"; + else glyph_name = "ssolesmes.stropha"; + else if (prefix_set & INCLINATUM) + if (prefix_set & AUCTUM) + glyph_name = "ssolesmes.incl.auctum"; + else if (prefix_set & DEMINUTUM) + glyph_name = "ssolesmes.incl.parvum"; + else + glyph_name = "svaticana.inclinatum"; + else if (prefix_set & DEMINUTUM) + if (i == 0) + { + // initio debilis + glyph_name = "svaticana.reverse.plica"; + } + else if (prev_delta_pitch > 0) + { + // epiphonus + if (! (prev_context_info & FLEXA_RIGHT)) + /* correct head of previous primitive */ + if (prev_delta_pitch > 1) + { + prev_glyph_name = "svaticana.epiphonus"; + glyph_name = "svaticana.plica"; + } + else + { + prev_glyph_name = "svaticana.vepiphonus"; + glyph_name = "svaticana.vplica"; + } + } + else if (prev_delta_pitch < 0) + { + // cephalicus + if (! (prev_context_info & FLEXA_RIGHT)) + /* correct head of previous primitive */ + { + if (i > 1) + { + /* cephalicus head with fixed size cauda */ + prev_glyph_name = "svaticana.inner.cephalicus"; + } + else + { + /* cephalicus head without cauda */ + prev_glyph_name = "svaticana.cephalicus"; + } + + /* + * Flexa has no variable size cauda if its left head is + * stacked on the right head. This is true for + * cephalicus. Hence, remove the cauda. + * + * Urgh: for the current implementation, this rule only + * applies for cephalicus; but it is a fundamental rule. + * Therefore, the following line of code should be + * placed somewhere else. + */ + prev_primitive->set_property ("add-cauda", + ly_bool2scm (false)); + } + if (prev_delta_pitch < - 1) + { + glyph_name = "svaticana.reverse.plica"; + } + else + { + glyph_name = "svaticana.reverse.vplica"; + } + } + else // (prev_delta_pitch == 0) + { + primitive->programming_error ("Vaticana_ligature:" + "deminutum head must have different " + "pitch -> ignoring grob"); + } + else if (prefix_set & (CAVUM | LINEA)) + if ((prefix_set & CAVUM) && (prefix_set & LINEA)) + glyph_name = "svaticana.linea.punctum.cavum"; + else if (prefix_set & CAVUM) + glyph_name = "svaticana.punctum.cavum"; + else + glyph_name = "svaticana.linea.punctum"; + else if (prefix_set & AUCTUM) + if (prefix_set & ASCENDENS) + glyph_name = "ssolesmes.auct.asc"; + else + glyph_name = "ssolesmes.auct.desc"; + else if ((context_info & STACKED_HEAD) + && (context_info & PES_UPPER)) + if (prev_delta_pitch > 1) + glyph_name = "svaticana.upes"; + else + glyph_name = "svaticana.vupes"; + else + glyph_name = "svaticana.punctum"; + + /* + * This head needs a cauda, if it starts a flexa, is not the upper + * head of a pes, and if it is a punctum. + */ + if ((context_info & FLEXA_LEFT) && ! (context_info & PES_UPPER)) + if (!String::compare (glyph_name, "svaticana.punctum")) + primitive->set_property ("add-cauda", ly_bool2scm (true)); + + /* + * Execptional rule for porrectus: + * + * If the current head is preceded by a \flexa and succeded by a + * \pes (e.g. "a \flexa g \pes a"), then join the current head and + * the previous head into a single curved flexa shape. + */ + if ((context_info & FLEXA_RIGHT) && (context_info & PES_LOWER)) { - if (!String::compare (prev_glyph_name, "vaticana_punctum")) - prev_glyph_name = "vaticana_rvirga"; + check_for_prefix_loss (prev_primitive); + prev_glyph_name = "flexa"; + prev_primitive->set_property ("flexa-height", + scm_int2num (prev_delta_pitch)); + prev_primitive->set_property ("flexa-width", + scm_make_real (flexa_width)); + bool add_cauda = !(prev_prefix_set && PES_OR_FLEXA); + prev_primitive->set_property ("add-cauda", + ly_bool2scm (add_cauda)); + check_for_prefix_loss (primitive); + glyph_name = ""; + primitive->set_property ("flexa-width", + scm_make_real (flexa_width)); } - /* - * In the backend, flexa shapes and joins need to know about - * thickness. Hence, for simplicity, let's distribute the - * ligature grob's value for thickness to each ligature head (even - * if not all of them need to know). - */ - primitive->set_grob_property ("thickness", gh_double2scm (join_thickness)); + /* + * Exceptional rule for pes: + * + * If this head is stacked on the previous one due to a \pes, then + * set the glyph of the previous head to that for this special + * case, thereby avoiding potential vertical collision with the + * current head. + */ + if (prefix_set & PES_OR_FLEXA) + { + if ((context_info & PES_UPPER) && (context_info & STACKED_HEAD)) + { + if (!String::compare (prev_glyph_name, "svaticana.punctum")) + if (prev_delta_pitch > 1) + prev_glyph_name = "svaticana.lpes"; + else + prev_glyph_name = "svaticana.vlpes"; + } + } - /* - * The head of the current iteration still may change during the - * next iteration due to the context sensitiveness of the - * transformation. However, the head of the previous iteration is - * now fully attributed and can be prepared for the backend. - */ + if (prev_primitive) + prev_primitive->set_property ("glyph-name", + scm_makfrom0str (prev_glyph_name.to_str0 ())); - /* - * Finish head of previous iteration for backend. - */ - prev_distance = - finish_primitive (first_primitive, prev_primitive, - prev_context_info, prev_glyph_name, prev_pitch_delta, - flexa_width, join_thickness, prev_distance); - - prev_primitive = primitive; - prev_context_info = context_info; - prev_pitch_delta = pitch - prev_pitch; - prev_pitch = pitch; - prev_glyph_name = glyph_name; - } + /* + * In the backend, flexa shapes and joins need to know about line + * thickness. Hence, for simplicity, let's distribute the + * ligature grob's value for thickness to each ligature head (even + * if not all of them need to know). + */ + primitive->set_property ("thickness", scm_make_real (thickness)); - /* - * Finish head of last iteration for backend. - */ - finish_primitive (first_primitive, prev_primitive, - prev_context_info, prev_glyph_name, prev_pitch_delta, - flexa_width, join_thickness, prev_distance); -} + prev_primitive = primitive; + prev_prefix_set = prefix_set; + prev_context_info = context_info; + prev_delta_pitch = delta_pitch; + prev_glyph_name = glyph_name; + } + + prev_primitive->set_property ("glyph-name", + scm_makfrom0str (prev_glyph_name.to_str0 ())); + align_heads (primitives, flexa_width, thickness); + +#if 0 // experimental code to collapse spacing after ligature + /* TODO: set to max (old/new spacing-increment), since other + voices/staves also may want to set this property. */ + Item *first_primitive = dynamic_cast (primitives[0].grob ()); + Paper_column *paper_column = first_primitive->get_column (); + paper_column->warning (_f ("Vaticana_ligature_engraver: " + "setting `spacing-increment = %f': ptr =%ul", + ligature_width, paper_column)); + paper_column-> + set_property ("forced-spacing", scm_make_real (ligature_width)); +#endif +} -ENTER_DESCRIPTION (Vaticana_ligature_engraver, -/* descr */ "Handles ligatures by glueing special ligature heads together.", -/* creats*/ "VaticanaLigature", -/* accepts */ "ligature-event abort-event", -/* acks */ "ligature-head-interface note-head-interface rest-interface", -/* reads */ "", -/* write */ ""); +ADD_TRANSLATOR (Vaticana_ligature_engraver, + /* descr */ "Handles ligatures by glueing special ligature heads together.", + /* creats*/ "VaticanaLigature", + /* accepts */ "ligature-event", + /* acks */ "note-head-interface rest-interface", + /* reads */ "", + /* write */ "");