]> git.donarmstrong.com Git - lilypond.git/blob - lily/note-head.cc
* configure.in: Test for and accept lmodern if EC fonts not found.
[lilypond.git] / lily / note-head.cc
1 /*
2   notehead.cc -- implement Note_head
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "note-head.hh"
10
11 #include <cmath>
12 #include <cctype>
13
14 #include "staff-symbol.hh"
15 #include "misc.hh"
16 #include "dots.hh"
17 #include "warn.hh"
18 #include "font-interface.hh"
19 #include "event.hh"
20 #include "rhythmic-head.hh"
21 #include "staff-symbol-referencer.hh"
22 #include "lookup.hh"
23 #include "output-def.hh"
24
25 /*
26   clean up the mess left by ledger line handling.
27 */
28 static Stencil
29 internal_print (Grob *me)
30 {
31   SCM style  = me->get_property ("style");
32   if (!scm_is_symbol (style))
33     {
34       return Stencil ();
35     }
36
37   SCM log = scm_int2num (Note_head::get_balltype (me));
38   SCM proc = me->get_property ("glyph-name-procedure");
39   SCM scm_font_char = scm_call_2 (proc, log, style);
40   String font_char = "noteheads-" + ly_scm2string (scm_font_char);
41
42   Font_metric * fm = Font_interface::get_default_font (me);
43   Stencil out = fm->find_by_name (font_char);
44   if (out.is_empty ())
45     {
46       me->warning (_f ("note head `%s' not found", font_char.to_str0 ()));
47     }
48
49   return out;
50 }
51
52
53 MAKE_SCHEME_CALLBACK (Note_head,print,1);
54 SCM
55 Note_head::print (SCM smob)  
56 {
57   Grob *me = unsmob_grob (smob);
58
59   return internal_print (me).smobbed_copy ();
60 }
61
62
63 MAKE_SCHEME_CALLBACK (Note_head,brew_ez_stencil,1);
64 SCM
65 Note_head::brew_ez_stencil (SCM smob)
66 {
67   Grob *me = unsmob_grob (smob);
68   int l = Note_head::get_balltype (me);
69
70   int b = (l >= 2);
71
72   SCM cause = me->get_property ("cause");
73   SCM spitch = unsmob_music (cause)->get_property ("pitch");
74   Pitch* pit =  unsmob_pitch (spitch);
75
76   SCM idx = scm_int2num (pit->get_notename ());
77   SCM names = me->get_property ("note-names");
78   SCM charstr = SCM_EOL;
79   if (ly_c_vector_p (names))
80     charstr = scm_vector_ref (names, idx);
81   else
82     {
83       char s[2] = "a";
84       s[0] = (pit->get_notename () + 2)%7 + 'a';
85       s[0] = toupper (s[0]);
86       charstr = scm_makfrom0str (s);
87     }
88   
89   SCM at = scm_list_n (ly_symbol2scm ("ez-ball"),
90                        charstr,
91                        scm_int2num (b),
92                        scm_int2num (1-b),
93                        SCM_UNDEFINED);
94   Box bx (Interval (0, 1.0), Interval (-0.5, 0.5));
95   Stencil m (bx, at);
96
97   return m.smobbed_copy ();
98 }
99
100
101 Real
102 Note_head::stem_attachment_coordinate (Grob *me, Axis a)
103 {
104   SCM brewer = me->get_property ("print-function");
105   Font_metric * fm  = Font_interface::get_default_font (me);
106   
107   if (brewer == Note_head::print_proc)
108     {
109       SCM style  = me->get_property ("style");
110       if (!scm_is_symbol (style))
111         {
112           return 0.0;
113         }
114       
115       SCM log = scm_int2num (Note_head::get_balltype (me));
116       SCM proc = me->get_property ("glyph-name-procedure");
117       SCM scm_font_char = scm_call_2 (proc, log, style);
118       String font_char = "noteheads-" + ly_scm2string (scm_font_char);
119
120       int k = fm->name_to_index (font_char) ;
121
122       if (k >= 0)
123         {
124           Box b = fm->get_indexed_char (k);
125           Offset wxwy = fm->get_indexed_wxwy (k);
126           Interval v = b[a];
127           if (!v.is_empty ())
128             return 2 * (wxwy[a] - v.center ()) / v.length ();
129         }
130     }
131   
132   /*
133     Fallback
134    */
135   SCM v = me->get_property ("stem-attachment-function");
136   if (!ly_c_procedure_p (v))
137     return 0.0;
138   
139   SCM result = scm_call_2 (v, me->self_scm (), scm_int2num (a));
140   if (!scm_is_pair (result))
141     return 0.0;
142
143   result = (a == X_AXIS) ? scm_car (result) : scm_cdr (result);
144   
145   return robust_scm2double (result,0);
146 }
147
148 int
149 Note_head::get_balltype (Grob*me) 
150 {
151   SCM s = me->get_property ("duration-log");
152   return scm_is_number (s) ? scm_to_int (s) <? 2 : 0;
153 }
154
155 ADD_INTERFACE (Note_head,"note-head-interface",
156   "Note head",
157   "note-names glyph-name-procedure accidental-grob style stem-attachment-function");
158