* Documentation/user/tutorial.itely (A lead sheet): remove
[lilypond.git] / lily / item.cc
blob89eb804389031d79e3ab42cf8c642a7238d85e7f
1 /*
2 item.cc -- implement Item
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "paper-score.hh"
10 #include "warn.hh"
11 #include "item.hh"
12 #include "paper-column.hh"
13 #include "spanner.hh"
14 #include "lily-guile.hh"
15 #include "system.hh"
16 #include "group-interface.hh"
18 Item::Item (SCM s)
19 : Grob (s)
21 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
22 Group_interface::add_thing (this, ly_symbol2scm ("interfaces"), ly_symbol2scm ("item-interface"));
25 /**
26 Item copy ctor. Copy nothing: everything should be a elt property
27 or a special purpose pointer (such as broken_to_drul_[]) */
28 Item::Item (Item const &s)
29 : Grob (s)
31 broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
35 bool
36 Item::breakable_b (Grob*me)
38 if (me->original_)
39 return false;
41 if (!dynamic_cast<Item*> (me))
42 me->programming_error ("only items can be breakable.");
44 Item * i =dynamic_cast<Item*> (me->get_parent (X_AXIS));
45 return (i) ? Item::breakable_b (i) : to_boolean (me->get_grob_property ("breakable"));
48 Paper_column *
49 Item::get_column () const
51 Item *parent = dynamic_cast<Item*> (get_parent (X_AXIS));
52 return parent ? parent->get_column () : 0;
55 System *
56 Item::get_system () const
58 Grob *g = get_parent (X_AXIS);
59 return g ? g->get_system () : 0;
63 void
64 Item::copy_breakable_items ()
66 Drul_array<Item *> new_copies;
67 Direction i=LEFT;
68 do
70 Grob * dolly = clone ();
71 Item * item = dynamic_cast<Item*> (dolly);
72 pscore_->system_->typeset_grob (item);
73 new_copies[i] =item;
75 while (flip (&i) != LEFT);
76 broken_to_drul_= new_copies;
80 bool
81 Item::broken_b () const
83 return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
88 Generate items for begin and end-of line.
90 void
91 Item::discretionary_processing ()
93 if (broken_b ())
94 return;
96 if (Item::breakable_b (this))
97 copy_breakable_items ();
100 Grob*
101 Item::find_broken_piece (System*l) const
103 if (get_system () == l)
104 return (Item*) (this);
106 Direction d = LEFT;
107 do {
108 Grob *s = broken_to_drul_[d];
109 if (s && s->get_system () == l)
110 return s;
112 while (flip (&d) != LEFT);
114 return 0;
118 Item*
119 Item::find_prebroken_piece (Direction d) const
121 Item * me = (Item *) (this);
122 if (!d)
123 return me;
124 return dynamic_cast<Item*> (broken_to_drul_[d]);
128 Direction
129 Item::break_status_dir () const
131 if (original_)
133 Item * i = dynamic_cast<Item*> (original_);
135 return (i->broken_to_drul_[LEFT] == this) ? LEFT : RIGHT;
137 else
138 return CENTER;
141 void
142 Item::handle_prebroken_dependencies ()
144 Grob::handle_prebroken_dependencies ();
147 Can't do this earlier, because try_visibility_lambda () might set
148 the elt property transparent, which would then be copied.
150 TODO:
152 give the item to break-visibility itself, so the function can do
153 more complicated things.
155 SCM vis = get_grob_property ("break-visibility");
156 if (gh_procedure_p (vis))
158 SCM args = scm_list_n (gh_int2scm (break_status_dir ()), SCM_UNDEFINED);
159 SCM result = gh_apply (vis, args);
160 bool trans = gh_scm2bool (ly_car (result));
161 bool empty = gh_scm2bool (ly_cdr (result));
163 if (empty && trans)
164 suicide ();
165 else if (empty)
167 set_extent (SCM_EOL, X_AXIS);
168 set_extent (SCM_EOL, Y_AXIS);
170 else if (trans)
171 set_grob_property ("molecule-callback", SCM_EOL);
176 Item::do_derived_mark ()const
178 if (broken_to_drul_[LEFT])
179 scm_gc_mark (broken_to_drul_[LEFT]->self_scm ());
180 if (broken_to_drul_[RIGHT])
181 scm_gc_mark (broken_to_drul_[RIGHT]->self_scm ());
182 return SCM_EOL;
185 Item*
186 unsmob_item (SCM s )
188 return dynamic_cast<Item*> (unsmob_grob (s));
193 ADD_INTERFACE(Item,
194 "item-interface",
195 "\n"
196 "\n"
197 "Grobs can be distinguished in their role in the horizontal spacing.\n"
198 "Many grobs define constraints on the spacing by their sizes. For\n"
199 "example, note heads, clefs, stems, and all other symbols with a fixed\n"
200 "shape. These grobs form a subtype called @code{Item}.\n"
201 "\n"
202 "\n"
203 "Some items need special treatment for line breaking. For example, a\n"
204 "clef is normally only printed at the start of a line (i.e. after a\n"
205 "line break). To model this, `breakable' items (clef, key signature,\n"
206 "bar lines, etc.) are copied twice. Then we have three versions of each\n"
207 "breakable item: one version if there is no line break, one version\n"
208 "that is printed before the line break (at the end of a system), one\n"
209 "version that is printed after the line break.\n"
210 "\n"
211 "Whether these versions are visible and take up space, is determined by\n"
212 "the outcome of the @code{break-visibility}. This grob property is a\n"
213 "function taking a direction (-1, 0 or 1) as argument. It returns a\n"
214 "cons of booleans, signifying whether this grob should be transparent\n"
215 "and have no extent.\n",
216 "no-spacing-rods break-visibility breakable")