]> git.donarmstrong.com Git - lilypond.git/blob - lily/third-try.cc
release: 1.5.26
[lilypond.git] / lily / third-try.cc
1 /*   
2   spacing-spanner.cc -- implement Spacing_spanner
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10
11 #include "paper-column.hh"
12
13
14 class Third_spacing_spanner
15 {
16 public:
17   void find_loose_columns () {}
18   void prune_loose_colunms (Link_array<Grob> *cols);
19   void find_loose_columns (Link_array<Grob> cols);
20 };
21
22
23
24 static bool
25 fixed_neighbor (Grob *col, SCM nm)
26 {
27   SCM l = col->internal_get_grob_property (nm);
28
29   if (!gh_pair_p (l))
30     return false;
31
32   Item * left = dynamic_cast<Item*>  (unsmob_grob (gh_car (l)));
33   return abs (Paper_column::rank_i (left->column_l ()) - Paper_column::rank_i (col)) == 1 ;
34 }
35
36 void
37 Third_spacing_spanner::prune_loose_colunms (Link_array<Grob> *cols)
38 {
39    for (int i=cols->size ();  i--; )
40      {
41
42        if (Item::breakable_b (cols->elem(i)))
43          continue;
44        
45        if (!fixed_neighbor (cols->elem(i), ly_symbol2scm ("left-neighbors"))
46            || !fixed_neighbor (cols->elem(i), ly_symbol2scm ("right-neighbors")))
47          cols->del (i);
48      }
49 }
50
51 void
52 Third_spacing_spanner::find_loose_columns (Link_array<Grob> cols)
53 {
54   for (int i=0; i< cols.size(); i++)
55     {
56       SCM right_neighbors = SCM_EOL;
57       int min_rank = 100000;    // inf.
58       
59       for (SCM s = cols[i]-> get_grob_property ("spacing-wishes");
60            gh_pair_p (s); s = gh_cdr (s))
61         {
62           Grob * wish = unsmob_grob (gh_car (s));
63
64           Grob * left = unsmob_grob (wish->get_grob_property ("left-item"));
65           Grob * right = unsmob_grob (wish->get_grob_property ("right-item"));
66
67           Item * li = dynamic_cast<Item*> (left);
68           Item * ri = dynamic_cast<Item*> (right);        
69
70           assert (li->column_l () == cols[i]);
71
72           Item * rc = ri->column_l ();
73           Item * lc = li->column_l ();
74           int newrank = Paper_column::rank_i (lc);
75
76           SCM neighbors = rc->get_grob_property ("left-neighbors");
77           Item  * left_neighbor = gh_pair_p (neighbors)
78             ? dynamic_cast<Item*> (unsmob_grob (gh_car (neighbors))) : 0;
79
80           left_neighbor = left_neighbor->column_l ();
81           if (left_neighbor)
82             {
83               int oldrank = Paper_column::rank_i (left_neighbor->column_l ());
84
85               if (newrank > oldrank)
86                 {
87                   neighbors= gh_cons (wish->self_scm (), SCM_EOL);
88                 }
89               else if (newrank == oldrank)
90                 {
91                   neighbors = gh_cons (wish->self_scm (), neighbors); 
92                 }
93             }
94
95           if (newrank < min_rank)
96             {
97               right_neighbors = gh_cons (wish->self_scm(), SCM_EOL);
98               min_rank = newrank;
99             }
100           else if (newrank == min_rank)
101             {
102               right_neighbors = gh_cons (wish->self_scm (), right_neighbors); 
103             }
104         }
105
106       cols[i]->set_grob_property ("right-neighbors", right_neighbors);
107     }
108 }