Fix arpeggio overshoot for some chords which reach centre line.
[lilypond.git] / lily / easy-notation.cc
blobc5d886147b59b5c5c3de32a12cf3fe6b0dde8e9e
1 /*
2 easy-notation.cc -- implement easy notation heads
4 source file of the GNU LilyPond music typesetter
6 (c) 2005--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
9 #include "note-head.hh"
11 #include <cctype>
12 using namespace std;
14 #include "font-interface.hh"
15 #include "grob.hh"
16 #include "music.hh"
17 #include "output-def.hh"
18 #include "staff-symbol-referencer.hh"
19 #include "stem.hh"
20 #include "stream-event.hh"
21 #include "text-interface.hh"
22 #include "rhythmic-head.hh"
26 TODO: move to scheme
29 MAKE_SCHEME_CALLBACK (Note_head, brew_ez_stencil, 1);
30 SCM
31 Note_head::brew_ez_stencil (SCM smob)
33 Grob *me = unsmob_grob (smob);
34 int log = Rhythmic_head::duration_log (me);
36 SCM cause = me->get_property ("cause");
37 SCM spitch = unsmob_stream_event (cause)->get_property ("pitch");
38 Pitch *pit = unsmob_pitch (spitch);
40 SCM idx = scm_from_int (pit->get_notename ());
41 SCM names = me->get_property ("note-names");
42 SCM charstr = SCM_EOL;
43 if (scm_is_vector (names))
44 charstr = scm_vector_ref (names, idx);
45 else
47 char s[2] = "a";
48 s[0] = char ((pit->get_notename () + 2) % 7 + 'a');
49 s[0] = char (toupper (s[0]));
50 charstr = scm_from_locale_string (s);
53 SCM letter
54 = Text_interface::interpret_string (me->layout ()->self_scm (),
55 Font_interface::text_font_alist_chain (me),
56 charstr);
58 Stencil l (*unsmob_stencil (letter));
59 l.align_to (X_AXIS, CENTER);
60 l.align_to (Y_AXIS, CENTER);
62 l = Stencil (Box (), l.expr ());
63 Real ss = Staff_symbol_referencer::staff_space (me);
64 Real lt = Staff_symbol_referencer::line_thickness (me);
66 Real radius = (ss + lt) / 2.0;
67 Real stem_thick = 1.3 * lt;
68 if (Grob *stem = unsmob_grob (me->get_object ("stem")))
69 stem_thick = Stem::thickness (stem);
71 int black = (log >= 2);
73 Stencil head;
74 Box extent (Interval (-radius, radius),
75 Interval (-radius, radius));
77 Stencil black_head (extent,
78 scm_list_4 (ly_symbol2scm ("circle"),
79 scm_from_double (radius),
80 scm_from_double (0.0),
81 SCM_BOOL_T));
82 Stencil white_head;
83 if (black)
84 l = l.in_color (1, 1, 1);
85 else
87 white_head = Stencil (extent,
88 scm_list_4 (ly_symbol2scm ("circle"),
89 scm_from_double (radius - stem_thick),
90 scm_from_double (0.0),
91 SCM_BOOL_T));
93 white_head = white_head.in_color (1, 1, 1);
96 Stencil total;
97 total.add_stencil (l);
98 total.add_stencil (white_head);
99 total.add_stencil (black_head);
100 total.translate_axis (radius, X_AXIS);
102 return total.smobbed_copy ();