2 key-item.cc -- implement Key_signature_interface
4 source file of the GNU LilyPond music typesetter
6 (c) 1996--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
8 keyplacement by Mats Bengtsson
11 #include "accidental-interface.hh"
12 #include "font-interface.hh"
13 #include "international.hh"
16 #include "output-def.hh"
17 #include "staff-symbol-referencer.hh"
18 #include "rational.hh"
20 struct Key_signature_interface
22 DECLARE_SCHEME_CALLBACK (print
, (SCM
));
23 DECLARE_GROB_INTERFACE ();
29 - space the `natural' signs wider
31 MAKE_SCHEME_CALLBACK (Key_signature_interface
, print
, 1);
33 Key_signature_interface::print (SCM smob
)
35 Item
*me
= dynamic_cast<Item
*> (unsmob_grob (smob
));
37 Real inter
= Staff_symbol_referencer::staff_space (me
) / 2.0;
39 SCM scm_style
= me
->get_property ("style");
41 if (scm_is_symbol (scm_style
))
42 style
= ly_symbol2string (scm_style
);
48 SCM c0s
= me
->get_property ("c0-position");
50 bool is_cancellation
= me
->internal_has_interface
51 (ly_symbol2scm ("key-cancellation-interface"));
54 SCM lists are stacks, so we work from right to left, ending with
55 the cancellation signature.
59 SCM last_glyph_name
= SCM_BOOL_F
;
60 SCM padding_pairs
= me
->get_property ("padding-pairs");
62 Font_metric
*fm
= Font_interface::get_default_font (me
);
63 SCM alist
= me
->get_property ("glyph-name-alist");
65 for (SCM s
= me
->get_property ("alteration-alist"); scm_is_pair (s
); s
= scm_cdr (s
))
67 SCM alt
= is_cancellation
71 SCM glyph_name_scm
= ly_assoc_get (alt
, alist
, SCM_BOOL_F
);
72 if (!scm_is_string (glyph_name_scm
))
74 me
->warning (_f ("No glyph found for alteration: %s",
75 ly_scm2rational (alt
).to_string ().c_str ()));
79 string glyph_name
= ly_scm2string (glyph_name_scm
);
81 Stencil
acc (fm
->find_by_name (glyph_name
));
84 me
->warning (_ ("alteration not found"));
87 SCM what
= scm_caar (s
);
89 SCM proc
= ly_lily_module_constant ("key-signature-interface::alteration-position");
91 int pos
= scm_to_int (scm_call_3 (proc
, what
, scm_cdar (s
), c0s
));
92 acc
.translate_axis (pos
* inter
, Y_AXIS
);
95 The natural sign (unlike flat & sharp)
96 has vertical edges on both sides. A little padding is
97 needed to prevent collisions.
99 Real padding
= robust_scm2double (me
->get_property ("padding"),
101 SCM handle
= scm_assoc (scm_cons (glyph_name_scm
, last_glyph_name
),
103 if (scm_is_pair (handle
))
104 padding
= robust_scm2double (scm_cdr (handle
), 0.0);
105 else if (glyph_name
== "accidentals.natural"
106 && last_pos
< pos
+ 2
107 && last_pos
> pos
- 6)
110 mol
.add_at_edge (X_AXIS
, LEFT
, acc
, padding
);
113 last_glyph_name
= glyph_name_scm
;
117 mol
.align_to (X_AXIS
, LEFT
);
119 return mol
.smobbed_copy ();
122 ADD_INTERFACE (Key_signature_interface
,
123 "A group of accidentals, to be printed as signature sign.",