X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fchord-name.cc;h=0e8e1d094295bda6e27cc120283ccb73013aa861;hb=refs%2Ftags%2Frelease%2F1.3.53;hp=4b6eff78a91104e6649674a2863f17c026d8c633;hpb=3edf5d0b9e3346530cece55fdbcf905b10c8b693;p=lilypond.git diff --git a/lily/chord-name.cc b/lily/chord-name.cc index 4b6eff78a9..0e8e1d0942 100644 --- a/lily/chord-name.cc +++ b/lily/chord-name.cc @@ -3,7 +3,7 @@ source file of the GNU LilyPond music typesetter - (c) 1999 Jan Nieuwenhuizen + (c) 1999--2000 Jan Nieuwenhuizen */ #include "chord-name.hh" @@ -13,302 +13,152 @@ #include "molecule.hh" #include "paper-def.hh" #include "lookup.hh" -#include "lily-guile.icc" +#include "staff-symbol-referencer.hh" -/* - ugh, move to chord-name-engraver - - Hmm, why not represent complete chord as list? - ((tonic third fifth) (inversion bass)) - */ -void -Chord_name::set (Chord const& c) -{ - set_elt_property ("pitches", array_to_scm (c.pitch_arr_)); - if (c.inversion_b_) - set_elt_property ("inversion", to_scm (c.inversion_pitch_)); - if (c.bass_b_) - set_elt_property ("bass", to_scm (c.bass_pitch_)); -} /* - junkme + TODO: move text lookup out of Chord_name */ -SCM -notename2scm (Musical_pitch p) -{ - return gh_cons (gh_int2scm (p.notename_i_), gh_int2scm (p.accidental_i_)); -} - /* word is roman text or styled text: "text" ("style" . "text") */ -Molecule -Chord_name::ly_word2molecule (SCM scm) const -{ - String style; - if (gh_pair_p (scm)) - { - style = ly_scm2string (gh_car (scm)); - scm = gh_cdr (scm); - } - String text = ly_scm2string (scm); - return lookup_l ()->text (style, text, paper_l ()); -} /* - scm is word or list of words: - word - (word word) + UGH. remove Dictionary< > and use Scheme_hash_table */ Molecule -Chord_name::ly_text2molecule (SCM scm) const +Chord_name::ly_word2molecule (SCM word) const { - Molecule mol; - if (gh_list_p (scm)) - { - while (gh_cdr (scm) != SCM_EOL) - { - mol.add_at_edge (X_AXIS, RIGHT, - ly_word2molecule (gh_car (scm)), 0); - scm = gh_cdr (scm); - } - scm = gh_car (scm); - } - mol.add_at_edge (X_AXIS, RIGHT, - ly_word2molecule (scm), 0); - return mol; -} - -Molecule -Chord_name::pitch2molecule (Musical_pitch p) const -{ - SCM name = scm_eval (gh_list (ly_symbol2scm ("user-pitch-name"), ly_quote_scm (notename2scm (p)), SCM_UNDEFINED)); - - if (name != SCM_UNSPECIFIED) - { - return ly_text2molecule (name); - } - - Molecule mol = lookup_l ()->text ("", p.str ().left_str (1).upper_str (), paper_l ()); - /* - We want the smaller size, even if we're big ourselves. - */ - if (p.accidental_i_) - mol.add_at_edge (X_AXIS, RIGHT, - - paper_l ()->lookup_l (-2)->afm_find (String ("accidentals-") + to_str (p.accidental_i_)), 0.0); - return mol; -} - -Musical_pitch -diff_pitch (Musical_pitch tonic, Musical_pitch p) -{ - Musical_pitch diff (p.notename_i_ - tonic.notename_i_, - p.accidental_i_ - tonic.accidental_i_, - p.octave_i_ - tonic.octave_i_); + junkme. - while (diff.notename_i_ >= 7) - { - diff.notename_i_ -= 7; - diff.octave_i_ ++; - } - while (diff.notename_i_ < 0) + Using the dict doesn't save code, since you have to compare + dict entries by hand later on anyway. + + */ + Dictionary option_dict; + if (gh_pair_p (word)) { - diff.notename_i_ += 7; - diff.octave_i_ --; + SCM options = gh_cdr (word); + word = gh_car (word); + while (gh_pair_p (options)) + { + SCM option = gh_car (options); + if (gh_pair_p (option)) + { + SCM key = gh_car (option); + SCM val = gh_cdr (option); + String k; + if (gh_symbol_p (key)) + k = ly_symbol2string (key); + else if (gh_string_p (key)) + k = ly_scm2string (key); + else + continue; + option_dict[k] = val; + } + options = gh_cdr (options); + } } - diff.accidental_i_ -= (tonic.semitone_pitch () + diff.semitone_pitch ()) - - p.semitone_pitch (); - - return diff; -} - -bool -Chord_name::user_chord_name (Array pitch_arr, Chord_mol* name_p) const -{ - SCM chord = SCM_EOL; - Array chord_type = pitch_arr; - Chord::rebuild_transpose (&chord_type, diff_pitch (pitch_arr[0], Musical_pitch (0)), false); - - for (int i= chord_type.size (); i--; ) - chord = gh_cons (notename2scm (chord_type[i]), chord); - - SCM name = scm_eval (gh_list (ly_symbol2scm ("user-chord-name"), ly_quote_scm (chord), SCM_UNDEFINED)); - if (gh_pair_p (name)) + /* + UGH. Should read from font metric structure. + */ + Real ex = lookup_l ()->text ("", "x", paper_l ()).extent(Y_AXIS).length (); + if (gh_string_p (word)) { - name_p->modifier_mol = ly_text2molecule (gh_car (name)); - name_p->addition_mol = ly_text2molecule (gh_cdr (name)); - return true; - } - return false; -} + String w = ly_scm2string (word); + Molecule mol; + Offset offset; -void -Chord_name::banter (Array pitch_arr, Chord_mol* name_p) const -{ - Array add_arr; - Array sub_arr; - Chord::find_additions_and_subtractions (pitch_arr, &add_arr, &sub_arr); - - Array scale; - for (int i=0; i < 7; i++) - scale.push (Musical_pitch (i)); + int size = 0; + if (option_dict.elem_b ("size")) + size = gh_scm2int (option_dict["size"]); - Musical_pitch tonic = pitch_arr[0]; - Chord::rebuild_transpose (&scale, tonic, true); - - /* - Does chord include this step? -1 if flat - */ - int has[16]; - for (int i=0; i<16; i++) - has[i] = 0; + String style; + if (option_dict.elem_b ("style")) + style = ly_scm2string (option_dict["style"]); - String mod_str; - String add_str; - String sep_str; - for (int i = 0; i < add_arr.size (); i++) - { - Musical_pitch p = add_arr[i]; - int step = Chord::step_i (tonic, p); - int accidental = p.accidental_i_ - scale[(step - 1) % 7].accidental_i_; - if ((step < 16) && (has[step] != -1)) - has[step] = accidental == -1 ? -1 : 1; - // only from guile table ? - if ((step == 3) && (accidental == -1)) + if (option_dict.elem_b ("type") + && ly_scm2string (option_dict["type"]) == "super") { - mod_str = "m"; + Real super_y = ex / 2; + //super_y += -acc.extent (Y_AXIS)[MIN]; + offset = Offset (0, super_y); + if (!size) + size = -2; } - else if (accidental - || (!(step % 2) - || ((i == add_arr.size () - 1) && (step > 5)))) - { - add_str += sep_str; - sep_str = "/"; - if ((step == 7) && (accidental == 1)) - { - add_str += "maj7"; - } - else - { - add_str += to_str (step); - if (accidental) - add_str += accidental < 0 ? "-" : "+"; - } - } - } - - for (int i = 0; i < sub_arr.size (); i++) - { - Musical_pitch p = sub_arr[i]; - int step = Chord::step_i (tonic, p); - /* - if additions include 2 or 4, assume sus2/4 and don't display 'no3' - */ - if (!((step == 3) && (has[2] || has[4]))) + if (option_dict.elem_b ("offset")) { - add_str += sep_str + "no" + to_str (step); - sep_str = "/"; + // hmm + SCM s = option_dict["offset"]; + if (gh_pair_p (s)) + offset = Offset (gh_scm2double (gh_car (s)), + gh_scm2double (gh_cdr (s))) * ex; } - } + if (option_dict.elem_b ("font") + && ly_scm2string (option_dict["font"]) == "feta") + mol = paper_l ()->lookup_l (size)->afm_find (w); + else + mol = paper_l ()->lookup_l (size)->text (style, w, paper_l ()); - if (mod_str.length_i ()) - name_p->modifier_mol.add_at_edge (X_AXIS, RIGHT, - lookup_l ()->text ("roman", mod_str, paper_l ()), 0); - if (add_str.length_i ()) - { - if (!name_p->addition_mol.empty_b ()) - add_str = "/" + add_str; - name_p->addition_mol.add_at_edge (X_AXIS, RIGHT, - lookup_l ()->text ("script", add_str, paper_l ()), 0); + mol.translate (offset); + return mol; } + return Molecule (); } /* - TODO: - fix silly to-and-fro scm conversions + ;; text: list of word + ;; word: string + optional list of property + ;; property: align, kern, font (?), size */ -Molecule* -Chord_name::do_brew_molecule_p () const +Molecule +Chord_name::ly_text2molecule (SCM text) const { - Array pitch_arr; - scm_to_array (get_elt_property ("pitches"), &pitch_arr); - Musical_pitch tonic = pitch_arr[0]; - - Chord_mol name; - name.tonic_mol = pitch2molecule (tonic); - - /* - if user has explicitely listed chord name, use that - - TODO - urg - maybe we should check all sub-lists of pitches, not - just full list and base triad? - */ - if (!user_chord_name (pitch_arr, &name)) + Molecule mol; + if (gh_list_p (text)) { - /* - else, check if user has listed base triad - use user base name and add banter for remaining part - */ - if ((pitch_arr.size () > 2) - && user_chord_name (pitch_arr.slice (0, 3), &name)) + while (gh_cdr (text) != SCM_EOL) { - Array base = Chord::base_arr (tonic); - base.concat (pitch_arr.slice (3, pitch_arr.size ())); - banter (base, &name); + Molecule m = ly_word2molecule (gh_car (text)); + if (!m.empty_b ()) + mol.add_at_edge (X_AXIS, RIGHT, m, 0); + text = gh_cdr (text); } - /* - else, use pure banter - */ - else - { - banter (pitch_arr, &name); - } - } + text = gh_car (text); + } + Molecule m = ly_word2molecule (text); + if (!m.empty_b ()) + mol.add_at_edge (X_AXIS, RIGHT, m, 0); + return mol; +} - SCM s = get_elt_property ("inversion"); - if (s != SCM_UNDEFINED) - { - name.inversion_mol = lookup_l ()->text ("", "/", paper_l ()); - Musical_pitch p; - scm_to (s, &p); - Molecule mol = pitch2molecule (p); - name.inversion_mol.add_at_edge (X_AXIS, RIGHT, mol, 0); - } +Molecule +Chord_name::do_brew_molecule () const +{ + SCM style = get_elt_property ("style"); + if (style == SCM_UNDEFINED) + style = ly_str02scm ("banter"); - s = get_elt_property ("bass"); - if (s != SCM_UNDEFINED) - { - name.bass_mol = lookup_l ()->text ("", "/", paper_l ()); - Musical_pitch p; - scm_to (s, &p); - Molecule mol = pitch2molecule (p); - name.bass_mol.add_at_edge (X_AXIS, RIGHT, mol, 0); - } + SCM inversion = get_elt_property ("inversion"); + if (inversion == SCM_UNDEFINED) + inversion = SCM_BOOL_F; + + SCM bass = get_elt_property ("bass"); + if (bass == SCM_UNDEFINED) + bass = SCM_BOOL_F; + + SCM pitches = get_elt_property ("pitches"); - // urg, howto get a good superscript_y? - Real super_y = lookup_l ()->text ("", "x", paper_l ()).dim_.y ().length ()/2; - if (!name.addition_mol.empty_b ()) - name.addition_mol.translate (Offset (0, super_y)); + SCM text = scm_eval (gh_list (ly_symbol2scm ("chord::user-name"), + style, + ly_quote_scm (pitches), + ly_quote_scm (gh_cons (inversion, bass)), + SCM_UNDEFINED)); - Molecule* mol_p = new Molecule; - mol_p->add_at_edge (X_AXIS, RIGHT, name.tonic_mol, 0); - // huh? - if (!name.modifier_mol.empty_b ()) - mol_p->add_at_edge (X_AXIS, RIGHT, name.modifier_mol, 0); - if (!name.addition_mol.empty_b ()) - mol_p->add_at_edge (X_AXIS, RIGHT, name.addition_mol, 0); - if (!name.inversion_mol.empty_b ()) - mol_p->add_at_edge (X_AXIS, RIGHT, name.inversion_mol, 0); - if (!name.bass_mol.empty_b ()) - mol_p->add_at_edge (X_AXIS, RIGHT, name.bass_mol, 0); - return mol_p; + return ly_text2molecule (text); }