]> git.donarmstrong.com Git - lilypond.git/blob - lily/break-align-engraver.cc
patch::: 1.3.18.jcn1
[lilypond.git] / lily / break-align-engraver.cc
1 /*   
2   break-align-engraver.cc --  implement Break_align_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8 */
9
10 #include "engraver.hh"
11 #include "protected-scm.hh"
12 #include "break-align-item.hh"
13 #include "axis-group-item.hh"
14
15 class Break_align_engraver : public Engraver
16 {
17   Break_align_item *align_l_;
18   Protected_scm column_alist_;
19 protected:
20   virtual void acknowledge_element(Score_element_info i);
21   virtual void do_pre_move_processing ();
22   void add_column (SCM);
23   
24 public:
25   VIRTUAL_COPY_CONS(Translator);
26   Break_align_engraver ();
27 };
28
29 ADD_THIS_TRANSLATOR (Break_align_engraver);
30
31 void
32 Break_align_engraver::add_column (SCM smob)
33 {
34   Score_element * e = unsmob_element (smob);
35   align_l_->add_element (e);
36   typeset_element (e);
37 }
38
39 void
40 Break_align_engraver::do_pre_move_processing ()
41 {
42   SCM order = get_property ("breakAlignOrder", 0);
43   for (; gh_pair_p (order); order = gh_cdr (order))
44     {
45       SCM p = scm_assoc ( gh_car (order), column_alist_);
46       if (gh_pair_p (p))
47         {
48           add_column (gh_cdr (p));
49           column_alist_ = scm_assoc_remove_x (column_alist_, gh_car (order));
50         }
51     }
52
53   for (SCM p = column_alist_; gh_pair_p (p); p = gh_cdr (p))
54     {
55       SCM pair = gh_car (p);
56       add_column (gh_cdr (pair));
57     }
58
59   
60   column_alist_ = SCM_EOL;
61
62   if (align_l_)
63     {
64       typeset_element (align_l_);
65       align_l_ = 0;
66     }
67 }
68
69
70 Break_align_engraver::Break_align_engraver ()
71 {
72   column_alist_ = SCM_EOL;
73   align_l_ =0;
74 }
75
76 void
77 Break_align_engraver::acknowledge_element (Score_element_info inf)
78 {
79   if (Item * item_l = dynamic_cast <Item *> (inf.elem_l_))
80     {
81       if (item_l->empty_b (X_AXIS) || item_l->parent_l (X_AXIS))
82         return;
83
84       SCM bp=item_l->remove_elt_property ("breakable");
85       bool breakable = (to_boolean (bp));
86       if (!breakable)
87         return ;
88
89       SCM al = item_l->remove_elt_property ("break-aligned");
90       if (!gh_boolean_p (al ) || !gh_scm2bool (al))
91         return ;
92
93       
94       if (!align_l_)
95         {
96           align_l_ = new Break_align_item;
97           align_l_->set_elt_property ("breakable", SCM_BOOL_T);
98           announce_element (Score_element_info (align_l_,0));
99         }
100
101       SCM name = ly_str02scm (inf.elem_l_->name());
102       SCM s = scm_assoc (name, column_alist_);
103
104       Axis_group_item * group = 0;
105       if (s != SCM_BOOL_F)
106         {
107           Score_element *e =  unsmob_element (gh_cdr(s));
108           group = dynamic_cast<Axis_group_item*> (e);
109         }
110       else
111         {
112           group = new Axis_group_item;
113           group->set_axes (X_AXIS,X_AXIS);
114           group->set_elt_property ("origin", name);
115           group->set_parent (align_l_, Y_AXIS);
116           announce_element (Score_element_info (group, 0));
117           column_alist_ = scm_assoc_set_x (column_alist_, name, group->self_scm_);
118         }
119       group->add_element (item_l);
120     }
121 }