2 key-item.cc -- implement Key_item
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 keyplacement by Mats Bengtsson
11 #include "key-item.hh"
14 #include "molecule.hh"
15 #include "paper-def.hh"
18 #include "key-engraver.hh"
20 const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */
21 const int SHARP_TOP_PITCH=4; /* ais and bis typeset in lower octave */
31 Key_item::read (Key_engraver const & key_grav_r)
33 multi_octave_b_ = key_grav_r.key_.multi_octave_b_;
34 const Array<Musical_pitch> &idx_arr = key_grav_r.accidental_idx_arr_;
35 for (int i = 0; i < idx_arr.size(); i++)
37 Musical_pitch m_l =idx_arr[i];
41 add (m_l.notename_i_, m_l.accidental_i_);
43 const Array<Musical_pitch> &old_idx_arr = key_grav_r.old_accidental_idx_arr_;
44 for (int i = 0 ; i< old_idx_arr.size(); i++)
46 Musical_pitch m_l =old_idx_arr[i];
50 add_old (m_l.notename_i_, m_l.accidental_i_);
55 Key_item::set_c_position (int c0)
58 // Find the c in the range -4 through 2
59 int from_bottom_pos = c0 + 4;
60 from_bottom_pos = from_bottom_pos%7;
61 from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive.
62 c_position = from_bottom_pos - 4;
67 Key_item::add (int p, int a)
74 Key_item::add (const Musical_pitch& pitch_r)
76 pitch.push (pitch_r.steps());
77 acc.push (pitch_r.accidental_i_);
81 Key_item::add_old (int p, int a)
88 Key_item::add_old (const Musical_pitch& pitch_r)
90 old_pitch.push (pitch_r.steps());
91 old_acc.push (pitch_r.accidental_i_);
95 Key_item::calculate_position(int p, int a) const
99 return p + c0_position;
102 if ((a<0 && ((p>FLAT_TOP_PITCH) || (p+c_position>4)) && (p+c_position>1))
104 (a>0 && ((p>SHARP_TOP_PITCH) || (p+c_position>5)) && (p+c_position>2)))
106 p -= 7; /* Typeset below c_position */
108 return p + c_position;
113 TODO space the `natural' signs wider
116 Key_item::brew_molecule_p() const
118 Molecule*output = new Molecule;
119 Real inter = paper()->internote_f ();
122 if ((break_status_dir_ == LEFT || break_status_dir_ == CENTER)
123 || old_pitch.size ())
125 for (int i =0; i < old_pitch.size(); i++)
127 for (j =0; (j < pitch.size()) && (old_pitch[i] != pitch[j]); j++)
130 if (j == pitch.size()
131 || (old_pitch[i] == pitch[j] && old_acc[i] != acc[j]))
133 Atom a =lookup_l ()->accidental (0);
134 a.translate_axis (calculate_position(old_pitch[i], old_acc[i]) * inter, Y_AXIS);
136 output->add_at_edge (X_AXIS, RIGHT, m);
141 Add half a space between cancellation and key sig.
143 As suggested by [Ross], p.148.
145 Interval x(0, inter);
148 output->add_at_edge (X_AXIS, RIGHT, lookup_l()->fill (Box(x,y)));
151 for (int i =0; i < pitch.size(); i++)
153 Atom a =lookup_l ()->accidental (acc[i]);
154 a.translate_axis (calculate_position(pitch[i], acc[i]) * inter, Y_AXIS);
156 output->add_at_edge (X_AXIS, RIGHT, m);
160 Molecule m (lookup_l ()->fill (Box (
161 Interval (0, paper()->note_width ()),
164 output->add_at_edge (X_AXIS, RIGHT, m);
169 IMPLEMENT_IS_TYPE_B1(Key_item,Item);
172 Key_item::do_pre_processing()
176 transparent_b_ = (break_status_dir() != RIGHT);
177 set_empty (transparent_b_);