]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-column.cc
58706b60e984f1e804cbcd1a691c13e5b2f5359d
[lilypond.git] / lily / paper-column.cc
1 /*
2   paper-column.cc -- implement Paper_column
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "moment.hh"
10 #include "paper-column.hh"
11 #include "paper-score.hh"
12 #include "warn.hh"
13 #include "axis-group-interface.hh"
14 #include "spaceable-grob.hh"
15 #include "molecule.hh"
16 #include "text-item.hh"
17 #include "lookup.hh"
18 #include "font-interface.hh"
19 #include "paper-def.hh"
20
21
22
23
24 ADD_INTERFACE (Paper_column, "paper-column-interface",
25   "  Paper_columns form the top-most item parent. (The Paper_columns X\n"
26 "  parent is System, which is a spanner.)\n"
27 "\n"
28 "  Paper_columns form the units for the spacing engine. They are\n"
29 "  numbered, the first (leftmost) is column 0. Numbering happens before\n"
30 "  line-breaking, and columns are not renumbered after line breaking.\n"
31 "\n"
32 "  Since many columns go unused, you should only use the rank field to\n"
33 "  get ordering information.  Two adjacent columns may have\n"
34 "  non-adjacent numbers.\n"
35 "\n"
36 "  Don't be confused by right-items: each spacing wish can also contain\n"
37 "  a number of items, with which a spacing constraint may be kept. It's\n"
38 "  a little baroque, but it might come in handy later on?\n"
39 "\n",
40   "between-cols between-system-string when bounded-by-me shortest-playing-duration shortest-starter-duration");
41
42
43 void
44 Paper_column::do_break_processing ()
45 {
46   Spaceable_grob::remove_interface (this);
47   Item::do_break_processing ();
48 }
49
50
51 int
52 Paper_column::get_rank (Grob*me) 
53 {
54   return dynamic_cast<Paper_column*> (me)->rank_;
55 }
56
57 System*
58 Paper_column::get_system () const
59 {
60   return system_;
61 }
62
63 Paper_column*
64 Paper_column::get_column () const
65 {
66   return (Paper_column*) (this);
67 }
68
69 Paper_column::Paper_column (SCM l)
70   : Item (l)            // guh.?
71 {
72   system_=0;
73   rank_ = -1;
74 }
75
76 Moment
77 Paper_column::when_mom (Grob*me)
78 {
79   SCM m = me->get_grob_property ("when");
80   Moment s (0);
81   if (unsmob_moment (m))
82     {
83       return *unsmob_moment (m);
84     }
85   return s;
86 }
87
88 bool
89 Paper_column::musical_b (Grob *me)
90 {
91   SCM m = me->get_grob_property ("shortest-starter-duration");
92   Moment s (0);
93   if (unsmob_moment (m))
94     {
95       s = *unsmob_moment (m);
96     }
97   return s != Moment (0);
98   
99 }
100   
101
102 bool
103 Paper_column::used_b (Grob*me)
104 {
105   return gh_pair_p (me->get_grob_property ("elements")) ||  Item::breakable_b (me)
106     || gh_pair_p (me->get_grob_property ("bounded-by-me"))
107     ;
108 }
109
110 /*
111   Print a vertical line and  the rank number, to aid debugging.  
112  */
113
114 MAKE_SCHEME_CALLBACK(Paper_column,brew_molecule,1);
115 SCM
116 Paper_column::brew_molecule (SCM p)
117 {
118   Grob *me = unsmob_grob (p);
119
120   String r = to_string (Paper_column::get_rank (me));
121   SCM properties = Font_interface::font_alist_chain (me);
122
123   SCM scm_mol = Text_item::interpret_markup (me->get_paper ()->self_scm (),
124                                              properties,
125                                              scm_makfrom0str (r.to_str0 ()));
126   Molecule t = *unsmob_molecule (scm_mol);
127   t.align_to (X_AXIS, CENTER);
128   t.align_to (Y_AXIS, DOWN);
129   
130   Molecule l = Lookup::filled_box (Box (Interval (-0.01, 0.01),
131                                        Interval (-2, -1)));
132
133   t.add_molecule (l);
134   return t.smobbed_copy ();                                             
135 }
136
137 /*
138   This is all too hairy. We use bounded-by-me to make sure that some
139   columns are kept "alive". Unfortunately, when spanners are suicided,
140   this falls apart again. (sigh.)
141
142   THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER. 
143  */
144 MAKE_SCHEME_CALLBACK(Paper_column,before_line_breaking,1);
145 SCM
146 Paper_column::before_line_breaking (SCM grob)
147 {
148   Grob *me = unsmob_grob (grob);
149
150   SCM c = me->get_grob_property ("bounded-by-me");
151   SCM *ptrptr = &c;
152
153   while (gh_pair_p (*ptrptr))
154     {
155       Grob * g = unsmob_grob (gh_car (*ptrptr));
156
157       if (!g || !g->live ())
158         {
159           *ptrptr = gh_cdr (*ptrptr);
160         }
161       else
162         {
163           ptrptr = SCM_CDRLOC (*ptrptr);
164         }
165     }
166
167   me->set_grob_property ("bounded-by-me", c);
168   return SCM_UNSPECIFIED;
169 }