]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-column.cc
* flower/include/axis.hh: rename from axes.hh
[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--2005 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "paper-column.hh"
10
11 #include "moment.hh"
12 #include "paper-score.hh"
13 #include "warn.hh"
14 #include "axis-group-interface.hh"
15 #include "spaceable-grob.hh"
16 #include "text-interface.hh"
17 #include "lookup.hh"
18 #include "font-interface.hh"
19 #include "output-def.hh"
20
21 Grob *
22 Paper_column::clone (int count) const
23 {
24   return new Paper_column (*this, count);
25 }
26
27 ADD_INTERFACE (Paper_column, "paper-column-interface",
28                "@code{Paper_column} objects form the top-most X-parents for items. "
29                "  The are two types of columns: musical columns, where are attached to, and "
30                "  non-musical columns, where bar-lines, clefs etc. are attached to. "
31                "  The spacing engine determines the X-positions of these objects."
32                "\n\n"
33                "They are\n"
34                "  numbered, the first (leftmost) is column 0. Numbering happens before\n"
35                "  line-breaking, and columns are not renumbered after line breaking.\n"
36                "  Since many columns go unused, you should only use the rank field to\n"
37                "  get ordering information.  Two adjacent columns may have\n"
38                "  non-adjacent numbers.\n"
39                "\n",
40                "between-cols when bounded-by-me "
41                "page-penalty shortest-playing-duration shortest-starter-duration");
42
43 void
44 Paper_column::do_break_processing ()
45 {
46   Spaceable_grob::remove_interface (this);
47   Item::do_break_processing ();
48 }
49
50 int
51 Paper_column::get_rank (Grob *me)
52 {
53   return dynamic_cast<Paper_column *> (me)->rank_;
54 }
55
56 System *
57 Paper_column::get_system () const
58 {
59   return system_;
60 }
61
62 Paper_column *
63 Paper_column::get_column () const
64 {
65   return (Paper_column *) (this);
66 }
67
68 Paper_column::Paper_column (SCM l, Object_key const *key)
69   : Item (l, key)               // guh.?
70 {
71   system_ = 0;
72   rank_ = -1;
73 }
74
75 Paper_column::Paper_column (Paper_column const &src, int count)
76   : Item (src, count)
77 {
78   system_ = 0;
79   rank_ = src.rank_;
80 }
81
82 Moment
83 Paper_column::when_mom (Grob *me)
84 {
85   SCM m = me->get_property ("when");
86   if (Moment *when = unsmob_moment (m))
87     return *when;
88   return Moment (0);
89 }
90
91 bool
92 Paper_column::is_musical (Grob *me)
93 {
94   SCM m = me->get_property ("shortest-starter-duration");
95   Moment s (0);
96   if (unsmob_moment (m))
97     {
98       s = *unsmob_moment (m);
99     }
100   return s != Moment (0);
101 }
102
103 bool
104 Paper_column::is_used (Grob *me)
105 {
106   return scm_is_pair (me->get_property ("elements")) || Item::is_breakable (me)
107     || scm_is_pair (me->get_property ("bounded-by-me"));
108 }
109
110 /*
111   Print a vertical line and  the rank number, to aid debugging.
112 */
113
114 MAKE_SCHEME_CALLBACK (Paper_column, print, 1);
115 SCM
116 Paper_column::print (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::text_font_alist_chain (me);
122
123   SCM scm_mol = Text_interface::interpret_markup (me->get_layout ()->self_scm (),
124                                                   properties,
125                                                   scm_makfrom0str (r.to_str0 ()));
126   Stencil t = *unsmob_stencil (scm_mol);
127   t.align_to (X_AXIS, CENTER);
128   t.align_to (Y_AXIS, DOWN);
129
130   Stencil l = Lookup::filled_box (Box (Interval (-0.01, 0.01),
131                                        Interval (-2, -1)));
132
133   t.add_stencil (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_property ("bounded-by-me");
151   SCM *ptrptr = &c;
152
153   while (scm_is_pair (*ptrptr))
154     {
155       Grob *g = unsmob_grob (scm_car (*ptrptr));
156
157       if (!g || !g->is_live ())
158         {
159           *ptrptr = scm_cdr (*ptrptr);
160         }
161       else
162         {
163           ptrptr = SCM_CDRLOC (*ptrptr);
164         }
165     }
166
167   me->set_property ("bounded-by-me", c);
168   return SCM_UNSPECIFIED;
169 }