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