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"
17 #include "musical-pitch.hh"
19 const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */
20 const int SHARP_TOP_PITCH=4; /* ais and bis typeset in lower octave */
30 Key_item::set (bool multi_octave_b,
31 Array<Musical_pitch> const &idx_arr,
32 Array<Musical_pitch> const &old_idx_arr)
34 multi_octave_b_ =multi_octave_b;
36 for (int i = 0; i < idx_arr.size(); i++)
38 Musical_pitch m_l =idx_arr[i];
42 add (m_l.notename_i_, m_l.accidental_i_);
45 for (int i = 0 ; i< old_idx_arr.size(); i++)
47 Musical_pitch m_l =old_idx_arr[i];
51 add_old (m_l.notename_i_, m_l.accidental_i_);
56 Key_item::set_c_position (int c0)
59 // Find the c in the range -4 through 2
60 int from_bottom_pos = c0 + 4;
61 from_bottom_pos = from_bottom_pos%7;
62 from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive.
63 c_position = from_bottom_pos - 4;
68 Key_item::add (int p, int a)
75 Key_item::add (const Musical_pitch& pitch_r)
77 pitch_arr_.push (pitch_r.steps());
78 acc_arr_.push (pitch_r.accidental_i_);
82 Key_item::add_old (int p, int a)
84 old_pitch_arr_.push (p);
85 old_acc_arr_.push (a);
89 Key_item::add_old (const Musical_pitch& pitch_r)
91 old_pitch_arr_.push (pitch_r.steps());
92 old_acc_arr_.push (pitch_r.accidental_i_);
96 Key_item::calculate_position(int p, int a) const
100 return p + c0_position;
103 if ((a<0 && ((p>FLAT_TOP_PITCH) || (p+c_position>4)) && (p+c_position>1))
105 (a>0 && ((p>SHARP_TOP_PITCH) || (p+c_position>5)) && (p+c_position>2)))
107 p -= 7; /* Typeset below c_position */
109 return p + c_position;
114 TODO space the `natural' signs wider
117 Key_item::brew_molecule_p() const
119 Molecule*output = new Molecule;
120 Real inter = paper()->internote_f ();
123 if ((break_status_dir_ == LEFT || break_status_dir_ == CENTER)
124 || old_pitch_arr_.size ())
126 for (int i =0; i < old_pitch_arr_.size(); i++)
128 for (j =0; (j < pitch_arr_.size())
129 && (old_pitch_arr_[i] != pitch_arr_[j]); j++)
132 if (j == pitch_arr_.size()
133 || (old_pitch_arr_[i] == pitch_arr_[j]
134 && old_acc_arr_[i] != acc_arr_[j]))
136 Atom a =lookup_l ()->accidental (0);
137 a.translate_axis (calculate_position(old_pitch_arr_[i], old_acc_arr_[i]) * inter, Y_AXIS);
139 output->add_at_edge (X_AXIS, RIGHT, m);
144 Add half a space between cancellation and key sig.
146 As suggested by [Ross], p.148.
148 Interval x(0, inter);
151 output->add_at_edge (X_AXIS, RIGHT, lookup_l()->fill (Box(x,y)));
154 for (int i =0; i < pitch_arr_.size(); i++)
156 Atom a =lookup_l ()->accidental (acc_arr_[i]);
157 a.translate_axis (calculate_position(pitch_arr_[i], acc_arr_[i]) * inter, Y_AXIS);
159 output->add_at_edge (X_AXIS, RIGHT, m);
161 if (pitch_arr_.size())
163 Molecule m (lookup_l ()->fill (Box (
164 Interval (0, paper()->note_width ()),
167 output->add_at_edge (X_AXIS, RIGHT, m);
172 IMPLEMENT_IS_TYPE_B1(Key_item,Item);
175 Key_item::do_pre_processing()
179 transparent_b_ = (break_status_dir() != RIGHT);
180 set_empty (transparent_b_);