]> git.donarmstrong.com Git - lilypond.git/blob - lily/paper-column.cc
* scm/framework-gnome.scm (item-event): Print grob id.
[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 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 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   if (Moment *when = unsmob_moment (m))
79     return *when;
80   return Moment (0);
81 }
82
83 bool
84 Paper_column::is_musical (Grob *me)
85 {
86   SCM m = me->get_property ("shortest-starter-duration");
87   Moment s (0);
88   if (unsmob_moment (m))
89     {
90       s = *unsmob_moment (m);
91     }
92   return s != Moment (0);
93 }
94   
95
96 bool
97 Paper_column::is_used (Grob*me)
98 {
99   return scm_is_pair (me->get_property ("elements")) ||  Item::is_breakable (me)
100     || scm_is_pair (me->get_property ("bounded-by-me"))
101     ;
102 }
103
104 /*
105   Print a vertical line and  the rank number, to aid debugging.  
106  */
107
108 MAKE_SCHEME_CALLBACK (Paper_column,print,1);
109 SCM
110 Paper_column::print (SCM p)
111 {
112   Grob *me = unsmob_grob (p);
113
114   String r = to_string (Paper_column::get_rank (me));
115   SCM properties = Font_interface::text_font_alist_chain (me);
116
117   SCM scm_mol = Text_interface::interpret_markup (me->get_layout ()->self_scm (),
118                                              properties,
119                                              scm_makfrom0str (r.to_str0 ()));
120   Stencil t = *unsmob_stencil (scm_mol);
121   t.align_to (X_AXIS, CENTER);
122   t.align_to (Y_AXIS, DOWN);
123   
124   Stencil l = Lookup::filled_box (Box (Interval (-0.01, 0.01),
125                                        Interval (-2, -1)));
126
127   t.add_stencil (l);
128   return t.smobbed_copy ();                                             
129 }
130
131 /*
132   This is all too hairy. We use bounded-by-me to make sure that some
133   columns are kept "alive". Unfortunately, when spanners are suicided,
134   this falls apart again. (sigh.)
135
136   THIS IS BROKEN KLUDGE. WE SHOULD INVENT SOMETHING BETTER. 
137  */
138 MAKE_SCHEME_CALLBACK (Paper_column,before_line_breaking,1);
139 SCM
140 Paper_column::before_line_breaking (SCM grob)
141 {
142   Grob *me = unsmob_grob (grob);
143
144   SCM c = me->get_property ("bounded-by-me");
145   SCM *ptrptr = &c;
146
147   while (scm_is_pair (*ptrptr))
148     {
149       Grob * g = unsmob_grob (scm_car (*ptrptr));
150
151       if (!g || !g->is_live ())
152         {
153           *ptrptr = scm_cdr (*ptrptr);
154         }
155       else
156         {
157           ptrptr = SCM_CDRLOC (*ptrptr);
158         }
159     }
160
161   me->set_property ("bounded-by-me", c);
162   return SCM_UNSPECIFIED;
163 }