]> git.donarmstrong.com Git - lilypond.git/blob - lily/break-align-engraver.cc
tremolo fixes
[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--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9 #include "engraver.hh"
10 #include "protected-scm.hh"
11 #include "break-align-interface.hh"
12 #include "item.hh"
13 #include "align-interface.hh"
14 #include "axis-group-interface.hh"
15
16
17 class Break_align_engraver : public Engraver
18 {
19   Item *align_l_;
20   Protected_scm column_alist_;
21   void add_to_group (SCM,Item*);
22 protected:
23   virtual void finalize ();
24   virtual void acknowledge_grob (Grob_info i);
25   virtual void stop_translation_timestep ();
26   void add_column (SCM);
27   
28 public:
29   TRANSLATOR_DECLARATIONS(Break_align_engraver);
30 };
31
32 void
33 Break_align_engraver::add_column (SCM smob)
34 {
35   Grob * e = unsmob_grob (smob);
36   Break_align_interface::add_element (align_l_,e);
37   typeset_grob (e);
38 }
39
40 void
41 Break_align_engraver::finalize ()
42 {
43   column_alist_ = SCM_EOL;
44 }
45
46 void
47 Break_align_engraver::stop_translation_timestep ()
48 {
49   SCM order = get_property ("breakAlignOrder");
50   for (; gh_pair_p (order); order = ly_cdr (order))
51     {
52       SCM p = scm_assoc (ly_car (order), column_alist_);
53       if (gh_pair_p (p))
54         {
55           add_column (ly_cdr (p));
56           column_alist_ = scm_assoc_remove_x (column_alist_, ly_car (order));
57         }
58     }
59
60   for (SCM p = column_alist_; gh_pair_p (p); p = ly_cdr (p))
61     {
62       SCM pair = ly_car (p);
63       add_column (ly_cdr (pair));
64     }
65
66   
67   column_alist_ = SCM_EOL;
68
69   if (align_l_)
70     {
71       typeset_grob (align_l_);
72       align_l_ = 0;
73     }
74 }
75
76
77 Break_align_engraver::Break_align_engraver ()
78 {
79   column_alist_ = SCM_EOL;
80   align_l_ =0;
81 }
82
83 void
84 Break_align_engraver::acknowledge_grob (Grob_info inf)
85 {
86   if (Item * item_l = dynamic_cast <Item *> (inf.grob_l_))
87     {
88       if (item_l->empty_b (X_AXIS) || item_l->get_parent (X_AXIS))
89         return;
90
91       SCM bp=item_l->get_grob_property ("breakable");
92       bool breakable = (to_boolean (bp));
93       if (!breakable)
94         return ;
95
96       SCM align_name = item_l->get_grob_property ("break-align-symbol");
97       if (!gh_symbol_p (align_name))
98         return ;
99
100       if (!align_l_)
101         {
102           align_l_ = new Item (get_property ("BreakAlignment"));
103
104           announce_grob (align_l_, SCM_EOL);
105
106           Item * edge = new Item (get_property ("LeftEdge"));
107           add_to_group (edge->get_grob_property ("break-align-symbol"), edge);
108           announce_grob(edge, SCM_EOL);
109         }
110       
111       add_to_group (align_name, item_l);
112     }
113 }
114
115 void
116 Break_align_engraver::add_to_group(SCM align_name, Item*item_l)
117 {
118   SCM s = scm_assoc (align_name, column_alist_);
119   Item * group = 0;
120
121   if (s != SCM_BOOL_F)
122     {
123       Grob *e =  unsmob_grob (ly_cdr (s));
124       group = dynamic_cast<Item*> (e);
125     }
126   else
127     {
128       group = new Item (get_property ("BreakAlignGroup"));
129
130       group->set_grob_property ("break-align-symbol", align_name);
131       group->set_parent (align_l_, Y_AXIS);
132       announce_grob(group, item_l->self_scm());
133           
134       column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ());
135
136     }
137   Axis_group_interface::add_element (group, item_l);
138 }
139
140 ENTER_DESCRIPTION(Break_align_engraver,
141 /* descr */       "Align grobs with corresponding break-align-symbols into groups, and order the groups according to breakAlignOrder",
142 /* creats*/       "BreakAlignment BreakAlignGroup LeftEdge",
143 /* acks  */       "grob-interface", // break-aligned-interface ?
144 /* reads */       "breakAlignOrder",
145 /* write */       "");