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