]> git.donarmstrong.com Git - lilypond.git/blob - lily/melody-spanner.cc
use classnames for interface naming; remove inclusion of
[lilypond.git] / lily / melody-spanner.cc
1 /*
2   melody-spanner.cc -- implement Melody_spanner
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7
8 */
9
10 #include "melody-spanner.hh"
11 #include "grob.hh"
12 #include "pointer-group-interface.hh"
13
14 /*
15   TODO: this could be either item or spanner. For efficiency reasons,
16   let's take item for now.
17 */
18
19                  
20 /*
21   Interpolate stem directions for neutral stems.
22  */
23 MAKE_SCHEME_CALLBACK(Melody_spanner,calc_neutral_stem_direction, 1);
24 SCM
25 Melody_spanner::calc_neutral_stem_direction (SCM smob)
26 {
27   Grob *stem = unsmob_grob (smob);
28   Grob *me =  unsmob_grob (stem->get_object ("melody-spanner"));
29   if (!me || !me->is_live ())
30     return SCM_UNSPECIFIED;
31   
32   extract_grob_set (me, "stems", stems);
33
34   vector<Direction> dirs;
35   for (vsize i = 0; i < stems.size (); i++)
36     dirs.push_back (to_dir (stems[i]->get_property ("default-direction")));
37
38   vsize last_nonneutral = VPOS;
39   vsize next_nonneutral = 0;
40   while (next_nonneutral != VPOS && next_nonneutral < dirs.size ()
41          &&  !dirs[next_nonneutral])
42     next_nonneutral++;
43
44   while (last_nonneutral == VPOS || last_nonneutral < dirs.size () - 1) 
45     {
46       Direction d1 = CENTER;
47       Direction d2 = CENTER;
48       if (last_nonneutral != VPOS)
49         d1 = dirs[last_nonneutral];
50       if (next_nonneutral < dirs.size ())
51         d2 = dirs[next_nonneutral];
52
53       Direction total = CENTER;
54       if (d1 && d1 == d2)
55         total = d1;
56       else if (d1 && !d2)
57         total = d1;
58       else if (d2 && !d1)
59         total = d2;
60       else
61         total = to_dir (me->get_property ("neutral-direction"));
62       
63       for (vsize i = last_nonneutral + 1; i <  next_nonneutral; i++)
64         stems[i]->set_property ("neutral-direction", scm_from_int (total));
65
66
67       last_nonneutral = next_nonneutral;
68       while (last_nonneutral < dirs.size ()
69              && dirs[last_nonneutral])
70         last_nonneutral++;
71       next_nonneutral = last_nonneutral;
72       last_nonneutral--;
73
74       while (next_nonneutral < dirs.size ()
75              && !dirs[next_nonneutral])
76         next_nonneutral++;
77     }
78
79   me->suicide ();
80   return SCM_UNSPECIFIED;
81 }
82
83 void
84 Melody_spanner::add_stem (Grob *me, Grob *stem)
85 {
86   Pointer_group_interface::add_grob (me, ly_symbol2scm ("stems"), stem);
87   stem->set_object ("melody-spanner", me->self_scm ());
88   stem->set_property ("neutral-direction", Melody_spanner::calc_neutral_stem_direction_proc);
89 }
90
91 ADD_INTERFACE (Melody_spanner,
92                "Context dependent typesetting decisions.",
93
94                "stems "
95                "neutral-direction ");
96
97