]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-column.cc
* scm/define-music-types.scm (music-descriptions): don't use
[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
122   Moment *mom = unsmob_moment (me->get_property ("when"));
123   String when = mom ? mom->to_string () : "?/?";
124     
125   SCM properties = Font_interface::text_font_alist_chain (me);
126
127   SCM scm_mol = Text_interface::interpret_markup (me->get_layout ()->self_scm (),
128                                                   properties,
129                                                   scm_makfrom0str (r.to_str0 ()));
130   SCM when_mol = Text_interface::interpret_markup (me->get_layout ()->self_scm (),
131                                                    properties,
132                                                    scm_makfrom0str (when.to_str0 ()));
133   Stencil t = *unsmob_stencil (scm_mol);
134   t.add_at_edge (Y_AXIS, DOWN, *unsmob_stencil (when_mol), 0.1, 0.1);
135   t.align_to (X_AXIS, CENTER);
136   t.align_to (Y_AXIS, DOWN);
137
138   Stencil l = Lookup::filled_box (Box (Interval (-0.01, 0.01),
139                                        Interval (-2, -1)));
140
141   t.add_stencil (l);
142   return t.smobbed_copy ();
143 }
144
145 /*
146   This is all too hairy. We use bounded-by-me to make sure that some
147   columns are kept "alive". Unfortunately, when spanners are suicided,
148   this falls apart again. (sigh.)
149
150   THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER.
151 */
152 MAKE_SCHEME_CALLBACK (Paper_column, before_line_breaking, 1);
153 SCM
154 Paper_column::before_line_breaking (SCM grob)
155 {
156   Grob *me = unsmob_grob (grob);
157
158   SCM c = me->get_property ("bounded-by-me");
159   SCM *ptrptr = &c;
160
161   while (scm_is_pair (*ptrptr))
162     {
163       Grob *g = unsmob_grob (scm_car (*ptrptr));
164
165       if (!g || !g->is_live ())
166         {
167           *ptrptr = scm_cdr (*ptrptr);
168         }
169       else
170         {
171           ptrptr = SCM_CDRLOC (*ptrptr);
172         }
173     }
174
175   me->set_property ("bounded-by-me", c);
176   return SCM_UNSPECIFIED;
177 }