]> git.donarmstrong.com Git - lilypond.git/blob - lily/slur.cc
release: 0.1.41
[lilypond.git] / lily / slur.cc
1 /*
2   slur.cc -- implement  Slur
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
8
9 /*
10   TODO:
11   
12   think about crossing stems.
13   Begin and end should be treated as a Script.
14  */
15 #include "slur.hh"
16 #include "scalar.hh"
17 #include "lookup.hh"
18 #include "paper-def.hh"
19 #include "note-column.hh"
20 #include "stem.hh"
21 #include "p-col.hh"
22 #include "molecule.hh"
23 #include "debug.hh"
24 #include "boxes.hh"
25
26
27
28 void
29 Slur::add (Note_column*n)
30 {
31   encompass_arr_.push (n);
32   add_dependency (n);
33 }
34
35 void
36 Slur::set_default_dir()
37 {
38   dir_ = DOWN;
39   for (int i=0; i < encompass_arr_.size(); i ++) 
40     {
41       if (encompass_arr_[i]->dir_ < 0) 
42         {
43           dir_ =UP;
44           break;
45         }
46     }
47 }
48
49 void
50 Slur::do_add_processing()
51 {
52   set_bounds(LEFT, encompass_arr_[0]);    
53   if (encompass_arr_.size () > 1)
54     set_bounds(RIGHT, encompass_arr_.top());
55 }
56
57 void
58 Slur::do_pre_processing ()
59 {
60   // don't set directions
61 }
62
63 void
64 Slur::do_substitute_dependency (Score_elem*o, Score_elem*n)
65 {
66   int i;
67   while ((i = encompass_arr_.find_i ((Note_column*)o->item())) >=0) 
68     {
69       if (n)
70         encompass_arr_[i] = (Note_column*)n->item();
71       else
72         encompass_arr_.del (i);
73     }
74 }
75
76
77 static int 
78 Note_column_compare (Note_column *const&n1 , Note_column* const&n2)
79 {
80   return Item::left_right_compare(n1, n2);
81 }
82
83 void
84 Slur::do_post_processing()
85 {
86   encompass_arr_.sort (Note_column_compare);
87   if (!dir_)
88     set_default_dir();
89   Real interline_f = paper ()->interline_f ();
90   Real inter_f = interline_f / 2;
91
92   /* 
93    [OSU]: slur and tie placement
94
95    slurs:
96    * x = centre of head (upside-down: inner raakpunt stem) - d * gap
97
98    * y = length < 5ss : horizontal raakpunt + d * 0.25 ss
99      y = length >= 5ss : y next interline - d * 0.25 ss
100      --> height <= 5 length ?? we use <= 3 length, now...
101
102    * suggested gap = ss / 5;
103    */
104   // jcn: 1/5 seems so small?
105   Real gap_f = interline_f / 2; // 5;
106   
107   Drul_array<Note_column*> extrema;
108   extrema[LEFT] = encompass_arr_[0];
109   extrema[RIGHT] = encompass_arr_.top();
110
111   Direction d=LEFT;
112   Real nw_f = paper()->note_width ();
113  
114   do 
115     {
116       if  (extrema[d] != spanned_drul_[d]) 
117         {
118           dx_f_drul_[d] = -d 
119             *(spanned_drul_[d]->width ().length () -0.5*nw_f);
120         }
121       else if (extrema[d]->stem_l_ && !extrema[d]->stem_l_->transparent_b_) 
122         {
123           dy_f_drul_[d] = (int)rint (extrema[d]->stem_l_->height()[dir_]);
124           /* normal slur from notehead centre to notehead centre, minus gap */
125           dx_f_drul_[d] += -d * gap_f;
126         }
127       else 
128         {
129           dy_f_drul_[d] = (int)rint (extrema[d]->head_positions_interval()[dir_])* inter_f;
130         }
131       dy_f_drul_[d] += dir_ * interline_f;
132     }
133   while ((d *= -1) != LEFT);
134 }
135
136 IMPLEMENT_IS_TYPE_B1(Slur,Spanner);