2 key-item.cc -- implement Key_item
4 source file of the GNU LilyPond music typesetter
6 (c) 1996--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 keyplacement by Mats Bengtsson
11 #include "group-interface.hh"
12 #include "key-item.hh"
13 #include "molecule.hh"
14 #include "paper-def.hh"
16 #include "staff-symbol-referencer.hh"
18 Key_item::Key_item (SCM s
)
21 set_elt_property ("c0-position", gh_int2scm (0));
26 FIXME: too much hardcoding here.
28 const int FLAT_TOP_PITCH
=2; /* fes,ges,as and bes typeset in lower octave */
29 const int SHARP_TOP_PITCH
=4; /* ais and bis typeset in lower octave */
33 FIXME: key-item should just get a list of (position, acc), and leave
34 the thinking to other parties.
37 Key_item::calculate_position(SCM pair
) const
39 int p
= gh_scm2int (gh_car (pair
));
40 int a
= gh_scm2int (gh_cdr (pair
));
42 if (to_boolean (get_elt_property ("multi-octave")))
44 return p
+ gh_scm2int (get_elt_property ("c0-position"));
47 // Find the c in the range -4 through 2
48 int from_bottom_pos
= gh_scm2int (get_elt_property ("c0-position")) + 4;
49 from_bottom_pos
= from_bottom_pos
%7;
50 from_bottom_pos
= (from_bottom_pos
+ 7)%7; // Precaution to get positive.
51 int c0
= from_bottom_pos
- 4;
54 if ((a
<0 && ((p
>FLAT_TOP_PITCH
) || (p
+c0
>4)) && (p
+c0
>1))
56 (a
>0 && ((p
>SHARP_TOP_PITCH
) || (p
+c0
>5)) && (p
+c0
>2)))
58 p
-= 7; /* Typeset below c_position */
60 /* Provide for the four cases in which there's a glitch
61 it's a hack, but probably not worth
62 the effort of finding a nicer solution.
64 if (c0
==2 && a
>0 && p
==3)
66 if (c0
==-3 && a
>0 && p
==-1)
68 if (c0
==-4 && a
<0 && p
==-1)
70 if (c0
==-2 && a
<0 && p
==-3)
79 - space the `natural' signs wider
81 GLUE_SCORE_ELEMENT(Key_item
,brew_molecule
);
83 Key_item::member_brew_molecule () const
87 Staff_symbol_referencer_interface
si (this);
88 Real inter
= si
.staff_space ()/2.0;
90 SCM newas
= get_elt_property ("new-accidentals");
93 SCM lists are stacks, so we work from right to left, ending with
94 the cancellation signature.
96 for (SCM s
= newas
; gh_pair_p (s
); s
= gh_cdr (s
))
98 int a
= gh_scm2int (gh_cdar (s
));
99 Molecule m
= lookup_l ()->afm_find ("accidentals-" + to_str (a
));
100 m
.translate_axis (calculate_position(gh_car (s
)) * inter
, Y_AXIS
);
101 mol
.add_at_edge (X_AXIS
, LEFT
, m
, 0);
104 if (break_status_dir () != RIGHT
)
106 SCM old
= get_elt_property ("old-accidentals");
108 Add half a space between cancellation and key sig.
110 As suggested by [Ross], p.148.
112 Interval
x(0, inter
);
115 mol
.add_at_edge (X_AXIS
, LEFT
, lookup_l()->blank (Box(x
,y
)),0);
117 for (; gh_pair_p (old
); old
= gh_cdr (old
))
122 find correspondences in pitches
124 for (SCM s
= newas
; gh_pair_p (s
); s
= gh_cdr (s
))
125 if (gh_caar(s
) == gh_caar (old
))
128 if (found
== SCM_EOL
|| gh_cdr (found
) != gh_cdar (old
))
130 Molecule m
=lookup_l ()->afm_find ("accidentals-0");
132 m
.translate_axis (calculate_position(gh_car(old
)) * inter
, Y_AXIS
);
133 mol
.add_at_edge (X_AXIS
, LEFT
, m
,0);
138 return mol
.create_scheme();