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