X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fkey-item.cc;h=c87f51ed7f226298f7528d8af356faff8aead0ce;hb=4eb6f42fc6ca20d65c788a73eb78dfcc22ea0453;hp=58a91cac61d2245c34b2f627fcf34ce757d611f3;hpb=fd67592c6acb9b8e9ac10135d688b3f4938ac0b1;p=lilypond.git diff --git a/lily/key-item.cc b/lily/key-item.cc index 58a91cac61..c87f51ed7f 100644 --- a/lily/key-item.cc +++ b/lily/key-item.cc @@ -3,177 +3,155 @@ source file of the GNU LilyPond music typesetter - (c) 1996, 1997--1998 Han-Wen Nienhuys + (c) 1996--2001 Han-Wen Nienhuys keyplacement by Mats Bengtsson */ +#include "item.hh" #include "key-item.hh" -#include "key.hh" -#include "debug.hh" #include "molecule.hh" #include "paper-def.hh" +#include "font-interface.hh" +#include "staff-symbol-referencer.hh" #include "lookup.hh" -#include "key-engraver.hh" - +/* + FIXME: too much hardcoding here. + */ const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */ const int SHARP_TOP_PITCH=4; /* ais and bis typeset in lower octave */ -Key_item::Key_item () -{ - breakable_b_ =true; - default_b_ = false; - set_c_position (0); -} - -void -Key_item::read (Key_engraver const & key_grav_r) -{ - multi_octave_b_ = key_grav_r.key_.multi_octave_b_; - const Array &idx_arr = key_grav_r.accidental_idx_arr_; - for (int i = 0; i < idx_arr.size(); i++) - { - Musical_pitch m_l =idx_arr[i]; - if (multi_octave_b_) - add (m_l); - else - add (m_l.notename_i_, m_l.accidental_i_); - } - const Array &old_idx_arr = key_grav_r.old_accidental_idx_arr_; - for (int i = 0 ; i< old_idx_arr.size(); i++) - { - Musical_pitch m_l =old_idx_arr[i]; - if (multi_octave_b_) - add_old (m_l); - else - add_old (m_l.notename_i_, m_l.accidental_i_); - } -} - -void -Key_item::set_c_position (int c0) -{ - c0_position = c0; - // Find the c in the range -4 through 2 - int from_bottom_pos = c0 + 4; - from_bottom_pos = from_bottom_pos%7; - from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive. - c_position = from_bottom_pos - 4; -} +/* + FIXME: key-item should just get a list of (position, acc), and leave + the thinking to other parties. -void -Key_item::add (int p, int a) -{ - pitch.push (p); - acc.push (a); -} + - TODO: put this in Scheme + + - lots of values trivially shared (key doesn't change very + often). Compute those once, and use that as cache for the rest. -void -Key_item::add (const Musical_pitch& pitch_r) +*/ +int +alteration_pos (SCM what, int alter, int c0p) { - pitch.push (pitch_r.steps()); - acc.push (pitch_r.accidental_i_); -} + if (gh_pair_p (what)) + return gh_scm2int (gh_car (what)) * 7 + gh_scm2int (gh_cdr (what)) + c0p; -void -Key_item::add_old (int p, int a) -{ - old_pitch.push (p); - old_acc.push (a); -} + int p = gh_scm2int (what); -void -Key_item::add_old (const Musical_pitch& pitch_r) -{ - old_pitch.push (pitch_r.steps()); - old_acc.push (pitch_r.accidental_i_); -} + // Find the c in the range -4 through 2 + int from_bottom_pos = c0p + 4; + from_bottom_pos = from_bottom_pos%7; + from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive. + int c0 = from_bottom_pos - 4; -int -Key_item::calculate_position(int p, int a) const -{ - if (multi_octave_b_) + + if ((alter <0 && ((p>FLAT_TOP_PITCH) || (p+c0>4)) && (p+c0>1)) + || + (alter >0 && ((p>SHARP_TOP_PITCH) || (p+c0>5)) && (p+c0>2))) { - return p + c0_position; + p -= 7; /* Typeset below c_position */ } - else { - if ((a<0 && ((p>FLAT_TOP_PITCH) || (p+c_position>4)) && (p+c_position>1)) - || - (a>0 && ((p>SHARP_TOP_PITCH) || (p+c_position>5)) && (p+c_position>2))) - { - p -= 7; /* Typeset below c_position */ - } - return p + c_position; - } + /* Provide for the four cases in which there's a glitch + it's a hack, but probably not worth + the effort of finding a nicer solution. + --dl. */ + if (c0==2 && alter >0 && p==3) + p -= 7; + if (c0==-3 && alter>0 && p==-1) + p += 7; + if (c0==-4 && alter<0 && p==-1) + p += 7; + if (c0==-2 && alter<0 && p==-3) + p += 7; + + return p + c0; } /* - TODO space the `natural' signs wider + TODO + - space the `natural' signs wider */ -Molecule* -Key_item::brew_molecule_p() const +MAKE_SCHEME_CALLBACK (Key_item,brew_molecule,1); +SCM +Key_item::brew_molecule (SCM smob) { - Molecule*output = new Molecule; - Real inter = paper()->internote_f (); + Grob*me =unsmob_grob (smob); + + Real inter = Staff_symbol_referencer::staff_space (me)/2.0; - int j; - if ((break_status_dir_ == LEFT || break_status_dir_ == CENTER) - || old_pitch.size ()) + SCM newas = me->get_grob_property ("new-accidentals"); + Molecule mol; + /* + SCM lists are stacks, so we work from right to left, ending with + the cancellation signature. + */ + int c0p = gh_scm2int (me->get_grob_property ("c0-position")); + for (SCM s = newas; gh_pair_p (s); s = gh_cdr (s)) { - for (int i =0; i < old_pitch.size(); i++) - { - for (j =0; (j < pitch.size()) && (old_pitch[i] != pitch[j]); j++) - ; - - if (j == pitch.size() - || (old_pitch[i] == pitch[j] && old_acc[i] != acc[j])) - { - Atom a =lookup_l ()->accidental (0); - a.translate_axis (calculate_position(old_pitch[i], old_acc[i]) * inter, Y_AXIS); - Molecule m (a); - output->add_at_edge (X_AXIS, RIGHT, m); - } - } + SCM what = gh_caar (s); + int alter = gh_scm2int (gh_cdar (s)); + int pos = alteration_pos (what, alter, c0p); + + Molecule m = Font_interface::get_default_font (me)->find_by_name ("accidentals-" + to_str (alter)); + m.translate_axis (pos * inter, Y_AXIS); + mol.add_at_edge (X_AXIS, LEFT, m, 0); + } + Item *it = dynamic_cast (me) ; + if (it->break_status_dir () != RIGHT) + { + SCM old = me->get_grob_property ("old-accidentals"); + /* Add half a space between cancellation and key sig. As suggested by [Ross], p.148. */ - Interval x(0, inter); - Interval y(0,0); + Interval x (0, inter); + Interval y (0,0); - output->add_at_edge (X_AXIS, RIGHT, lookup_l()->fill (Box(x,y))); - } - - for (int i =0; i < pitch.size(); i++) - { - Atom a =lookup_l ()->accidental (acc[i]); - a.translate_axis (calculate_position(pitch[i], acc[i]) * inter, Y_AXIS); - Molecule m (a); - output->add_at_edge (X_AXIS, RIGHT, m); - } - if (pitch.size()) - { - Molecule m (lookup_l ()->fill (Box ( - Interval (0, paper()->note_width ()), - Interval (0,0)))); + mol.add_at_edge (X_AXIS, LEFT, Lookup::blank (Box (x,y)),0); + + Molecule natural; + if (gh_pair_p (old)) + natural=Font_interface::get_default_font (me)->find_by_name ("accidentals-0"); - output->add_at_edge (X_AXIS, RIGHT, m); + for (; gh_pair_p (old); old = gh_cdr (old)) + { + SCM found = scm_assoc (gh_caar (old), newas); + if (found == SCM_BOOL_F + || gh_cdr (found) != gh_cdar (old)) + { + SCM what = gh_caar (old); + int alter = 0; + int pos = alteration_pos (what, alter, c0p); + + Molecule m = natural; + m.translate_axis (pos* inter, Y_AXIS); + + mol.add_at_edge (X_AXIS, LEFT, m, 0); + } + } } - return output; + + return mol.smobbed_copy (); } -IMPLEMENT_IS_TYPE_B1(Key_item,Item); -void -Key_item::do_pre_processing() + + + +bool +Key_item::has_interface (Grob*m) { - if (default_b_) - { - transparent_b_ = (break_status_dir() != RIGHT); - set_empty (transparent_b_); - } + return m && m->has_interface (ly_symbol2scm ("key-signature-interface")); +} + +void +Key_item::set_interface (Grob*m) +{ + m->set_interface (ly_symbol2scm ("key-signature-interface")); }