]> git.donarmstrong.com Git - lilypond.git/blob - lily/item.cc
release: 1.3.37
[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--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8
9 #include "dimension-cache.hh"
10 #include "paper-score.hh"
11 #include "debug.hh"
12 #include "item.hh"
13 #include "paper-column.hh"
14 #include "spanner.hh"
15 #include "lily-guile.hh"
16
17 Item::Item ()
18 {
19   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT]=0;
20 }
21
22 /**
23    Item copy ctor.  Copy nothing: everything should be a elt property
24    or a special purpose poitner (such as broken_to_drul_[]) */
25 Item::Item (Item const &s)
26   : Score_element (s)
27 {
28   broken_to_drul_[LEFT] = broken_to_drul_[RIGHT] =0;
29 }
30
31
32
33 bool
34 Item::breakable_b () const
35 {
36   if (original_l_ )
37     return false;
38   
39   Item * i  =dynamic_cast<Item*> (parent_l (X_AXIS));
40   return (i) ?  i->breakable_b () : to_boolean (get_elt_property( "breakable"));
41 }
42
43 Line_of_score *
44 Item::line_l() const
45 {
46   Score_element *g = parent_l (X_AXIS);
47   if (!g)
48     return 0;
49   return dynamic_cast<Score_element *> (g)-> line_l ();
50 }
51
52
53 void
54 Item::copy_breakable_items()
55 {
56   Drul_array<Item *> new_copies;
57   Direction  i=LEFT;
58   do 
59     {
60       Score_element * dolly = clone();
61       Item * item_p = dynamic_cast<Item*>(dolly);
62       pscore_l_->typeset_element (item_p);
63       new_copies[i] =item_p;
64     }
65   while (flip(&i) != LEFT);
66   broken_to_drul_= new_copies;
67
68   do 
69     {
70        broken_to_drul_[i]->handle_prebroken_dependencies();
71        broken_to_drul_[i]->try_visibility_lambda();
72     }
73   while (flip(&i) != LEFT);
74 }
75
76 void
77 Item::try_visibility_lambda ()
78 {
79   SCM vis = remove_elt_property ("visibility-lambda");
80   if (gh_procedure_p (vis))
81     {
82       SCM args = scm_listify (gh_int2scm (break_status_dir ()), SCM_UNDEFINED);
83       SCM result = gh_apply (vis, args);
84       bool trans = gh_scm2bool (gh_car (result));
85       bool empty = gh_scm2bool (gh_cdr (result));
86
87       if (empty)
88         {
89           set_empty (X_AXIS);
90           set_empty ( Y_AXIS);
91         }
92       if (trans)
93         set_elt_property ("transparent", SCM_BOOL_T);
94     }
95 }
96
97 bool
98 Item::broken_b () const
99 {
100   return broken_to_drul_[LEFT] || broken_to_drul_[RIGHT];
101 }
102
103 void
104 Item::do_break ()
105 {
106   if (broken_b ())
107     return;
108
109   if (breakable_b ())
110     {
111       copy_breakable_items();
112       handle_prebroken_dependencies();
113   
114       /*
115     Otherwise the broken items won't be pre_process()'ed.
116   */
117   
118       if (broken_to_drul_[LEFT])
119         {
120           add_dependency (broken_to_drul_[LEFT]);
121           add_dependency (broken_to_drul_[RIGHT]);
122         }
123     }
124   try_visibility_lambda ();     // ugh.
125 }
126
127 void
128 Item::do_breakable_col_processing()
129 {
130   do_break ();
131 }
132
133 Score_element*
134 Item::find_broken_piece (Line_of_score*l) const
135 {
136   if (line_l() == l) 
137     return (Item*)(this);
138
139   Direction d = LEFT;
140   do {
141     Score_element *s = find_broken_piece (d);
142     if (s && s->line_l () == l)
143       return s;
144   }
145   while (flip (&d) != LEFT);
146
147   return 0;
148 }
149
150 Item*
151 Item::find_broken_piece (Direction d) const
152 {
153   Item * me = (Item *) (this);  
154   if (!d)
155     return me;
156   else if (breakable_b ())
157     {
158       me->do_break ();
159       return dynamic_cast<Item*> (broken_to_drul_[d]);
160     }
161   else
162     return 0;
163 }
164
165 Paper_column *
166 Item::column_l () const
167 {
168   return dynamic_cast<Item*> (parent_l (X_AXIS))->column_l ();
169 }
170
171 Direction
172 Item::break_status_dir () const
173 {
174   if (original_l_)
175     {
176       Item * i = dynamic_cast<Item*> (original_l_);
177
178       return (i->broken_to_drul_[LEFT] == this) ? LEFT : RIGHT;
179     }
180   else
181     return CENTER;
182 }
183
184