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