]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-column.cc
(LY_DEFINE): use Scheme style naming for
[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--2004 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 "stencil.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                "@code{Paper_column} objects form the top-most X-parents for items. "
26                "  The are two types of columns: musical columns, where are attached to, and "
27                "  non-musical columns, where bar-lines, clefs etc. are attached to. "
28                "  The spacing engine determines the X-positions of these objects."
29                "\n\n"
30                "They are\n"
31                "  numbered, the first (leftmost) is column 0. Numbering happens before\n"
32                "  line-breaking, and columns are not renumbered after line breaking.\n"
33                "  Since many columns go unused, you should only use the rank field to\n"
34                "  get ordering information.  Two adjacent columns may have\n"
35                "  non-adjacent numbers.\n"
36                "\n"
37                ,
38                "between-cols between-system-string when bounded-by-me "
39                "shortest-playing-duration shortest-starter-duration");
40
41 void
42 Paper_column::do_break_processing ()
43 {
44   Spaceable_grob::remove_interface (this);
45   Item::do_break_processing ();
46 }
47
48
49 int
50 Paper_column::get_rank (Grob*me) 
51 {
52   return dynamic_cast<Paper_column*> (me)->rank_;
53 }
54
55 System*
56 Paper_column::get_system () const
57 {
58   return system_;
59 }
60
61 Paper_column*
62 Paper_column::get_column () const
63 {
64   return (Paper_column*) (this);
65 }
66
67 Paper_column::Paper_column (SCM l)
68   : Item (l)            // guh.?
69 {
70   system_=0;
71   rank_ = -1;
72 }
73
74 Moment
75 Paper_column::when_mom (Grob*me)
76 {
77   SCM m = me->get_property ("when");
78   Moment s (0);
79   if (unsmob_moment (m))
80     {
81       return *unsmob_moment (m);
82     }
83   return s;
84 }
85
86 bool
87 Paper_column::is_musical (Grob *me)
88 {
89   SCM m = me->get_property ("shortest-starter-duration");
90   Moment s (0);
91   if (unsmob_moment (m))
92     {
93       s = *unsmob_moment (m);
94     }
95   return s != Moment (0);
96 }
97   
98
99 bool
100 Paper_column::is_used (Grob*me)
101 {
102   return gh_pair_p (me->get_property ("elements")) ||  Item::is_breakable (me)
103     || gh_pair_p (me->get_property ("bounded-by-me"))
104     ;
105 }
106
107 /*
108   Print a vertical line and  the rank number, to aid debugging.  
109  */
110
111 MAKE_SCHEME_CALLBACK(Paper_column,print,1);
112 SCM
113 Paper_column::print (SCM p)
114 {
115   Grob *me = unsmob_grob (p);
116
117   String r = to_string (Paper_column::get_rank (me));
118   SCM properties = Font_interface::font_alist_chain (me);
119
120   SCM scm_mol = Text_item::interpret_markup (me->get_paper ()->self_scm (),
121                                              properties,
122                                              scm_makfrom0str (r.to_str0 ()));
123   Stencil t = *unsmob_stencil (scm_mol);
124   t.align_to (X_AXIS, CENTER);
125   t.align_to (Y_AXIS, DOWN);
126   
127   Stencil l = Lookup::filled_box (Box (Interval (-0.01, 0.01),
128                                        Interval (-2, -1)));
129
130   t.add_stencil (l);
131   return t.smobbed_copy ();                                             
132 }
133
134 /*
135   This is all too hairy. We use bounded-by-me to make sure that some
136   columns are kept "alive". Unfortunately, when spanners are suicided,
137   this falls apart again. (sigh.)
138
139   THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER. 
140  */
141 MAKE_SCHEME_CALLBACK(Paper_column,before_line_breaking,1);
142 SCM
143 Paper_column::before_line_breaking (SCM grob)
144 {
145   Grob *me = unsmob_grob (grob);
146
147   SCM c = me->get_property ("bounded-by-me");
148   SCM *ptrptr = &c;
149
150   while (gh_pair_p (*ptrptr))
151     {
152       Grob * g = unsmob_grob (gh_car (*ptrptr));
153
154       if (!g || !g->live ())
155         {
156           *ptrptr = gh_cdr (*ptrptr);
157         }
158       else
159         {
160           ptrptr = SCM_CDRLOC (*ptrptr);
161         }
162     }
163
164   me->set_property ("bounded-by-me", c);
165   return SCM_UNSPECIFIED;
166 }