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