Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 1997--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
11 LilyPond is distributed in the hope that it will be useful, | 11 LilyPond is distributed in the hope that it will be useful, |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 GNU General Public License for more details. | 14 GNU General Public License for more details. |
15 | 15 |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. | 17 along with LilyPond. If not, see <http://www.gnu.org/licenses/>. |
18 */ | 18 */ |
19 | |
20 #include <algorithm> // for reverse | |
19 | 21 |
20 #include "paper-column.hh" | 22 #include "paper-column.hh" |
21 #include "output-def.hh" | 23 #include "output-def.hh" |
22 #include "side-position-interface.hh" | 24 #include "side-position-interface.hh" |
23 #include "engraver.hh" | 25 #include "engraver.hh" |
24 #include "context.hh" | 26 #include "context.hh" |
25 #include "grob-array.hh" | 27 #include "grob-array.hh" |
28 #include "stream-event.hh" | |
26 | 29 |
27 #include "translator.icc" | 30 #include "translator.icc" |
28 | 31 |
29 /* | 32 /* |
30 TODO: detect the top staff (stavesFound), and acknowledge staff-group | 33 TODO: detect the top staff (stavesFound), and acknowledge staff-group |
31 system-start-delims. If we find these, and the top staff is in the | 34 system-start-delims. If we find these, and the top staff is in the |
32 staff-group, add padding to the bar number. | 35 staff-group, add padding to the bar number. |
33 */ | 36 */ |
34 class Bar_number_engraver : public Engraver | 37 class Bar_number_engraver : public Engraver |
35 { | 38 { |
36 protected: | 39 protected: |
37 Item *text_; | 40 Item *text_; |
38 int renvoi_number_; | 41 int alternative_starting_bar_number_; |
Keith
2011/11/29 03:54:42
maybe "alternative_number_"
Isn't there already a
MikeSol
2011/11/29 12:08:52
Done.
| |
42 int alternative_number_; | |
43 int alternative_number_increment_; | |
44 Stream_event *alternative_event_; | |
39 | 45 |
40 protected: | 46 protected: |
41 void stop_translation_timestep (); | 47 void stop_translation_timestep (); |
48 DECLARE_TRANSLATOR_LISTENER (alternative); | |
42 DECLARE_ACKNOWLEDGER (break_alignment); | 49 DECLARE_ACKNOWLEDGER (break_alignment); |
43 void process_music (); | 50 void process_music (); |
44 void create_items (); | 51 void create_items (); |
45 TRANSLATOR_DECLARATIONS (Bar_number_engraver); | 52 TRANSLATOR_DECLARATIONS (Bar_number_engraver); |
46 }; | 53 }; |
54 | |
55 IMPLEMENT_TRANSLATOR_LISTENER (Bar_number_engraver, alternative); | |
56 void | |
57 Bar_number_engraver::listen_alternative (Stream_event *ev) | |
58 { | |
59 if (alternative_event_) | |
60 return; | |
61 | |
62 alternative_event_ = ev; | |
63 int current_barnumber = robust_scm2int (get_property ("currentBarNumber"), 0); | |
64 Direction alternative_dir = robust_scm2dir (ev->get_property ("alternative-dir "), CENTER); | |
65 bool make_alternative = get_property ("alternativeNumberingStyle") == ly_symbo l2scm ("numbers") | |
66 || get_property ("alternativeNumberingStyle") == ly_sy mbol2scm ("numbers-with-letters"); | |
67 if (make_alternative) | |
68 { | |
69 /* | |
70 if we're starting the first alternative, we set the starting | |
71 bar number to the current bar number | |
72 */ | |
73 if (alternative_dir == LEFT) | |
74 alternative_starting_bar_number_ = current_barnumber; | |
75 | |
76 /* | |
77 if the alternative is not the last one, we send the | |
78 current bar number back to the alternative bar number. | |
79 */ | |
80 if (alternative_dir < RIGHT) | |
81 current_barnumber = alternative_starting_bar_number_; | |
82 | |
83 context ()->set_property ("currentBarNumber", scm_from_int (current_barnum ber)); | |
84 } | |
85 } | |
86 | |
87 int | |
88 int_pow (int n, int i) | |
89 { | |
90 if (i == 1) | |
91 return n; | |
92 if (i <= 0) | |
93 return 1; | |
94 return int_pow (n * n, i - 1); | |
95 } | |
47 | 96 |
48 void | 97 void |
49 Bar_number_engraver::process_music () | 98 Bar_number_engraver::process_music () |
50 { | 99 { |
51 SCM wb = get_property ("whichBar"); | 100 SCM wb = get_property ("whichBar"); |
52 | 101 |
53 if (scm_is_string (wb)) | 102 if (scm_is_string (wb)) |
54 { | 103 { |
55 Moment mp (robust_scm2moment (get_property ("measurePosition"), Moment (0) )); | 104 Moment mp (robust_scm2moment (get_property ("measurePosition"), Moment (0) )); |
56 if (mp.main_part_ == Rational (0)) | 105 if (mp.main_part_ == Rational (0)) |
57 { | 106 { |
58 SCM bn = get_property ("currentBarNumber"); | 107 SCM bn = get_property ("currentBarNumber"); |
59 SCM proc = get_property ("barNumberVisibility"); | 108 SCM proc = get_property ("barNumberVisibility"); |
60 if (scm_is_number (bn) && ly_is_procedure (proc) | 109 if (scm_is_number (bn) && ly_is_procedure (proc) |
61 && to_boolean (scm_call_1 (proc, bn))) | 110 && to_boolean (scm_call_1 (proc, bn))) |
62 { | 111 { |
63 create_items (); | 112 create_items (); |
64 SCM renvoi_dir_scm = context ()->get_property ("renvoiDir"); | 113 SCM alternative_style = get_property ("alternativeNumberingStyle") ; |
Keith
2011/11/29 03:54:42
maybe "FirstOrLastAlternative"
I guess you made it
MikeSol
2011/11/29 12:08:52
Done.
| |
65 SCM renvoi_style = context ()->get_property ("renvoiStyle"); | |
Keith
2011/11/29 03:54:42
"AlternateNumberingStyle"
MikeSol
2011/11/29 12:08:52
Done.
| |
66 string text_tag = ""; | 114 string text_tag = ""; |
67 if (renvoi_style == ly_symbol2scm ("repeat-measure-numbers-with-le tter-tags")) | 115 if (alternative_style == ly_symbol2scm ("numbers-with-letters")) |
68 {·················· | 116 { |
69 Direction renvoi_dir = robust_scm2dir (renvoi_dir_scm, RIGHT); | 117 if (alternative_event_) |
70 if (renvoi_dir == LEFT) | |
71 renvoi_number_ = 0; | |
72 if (is_direction (renvoi_dir_scm) && renvoi_dir == RIGHT) | |
73 renvoi_number_ = -1; | |
74 else if (renvoi_number_ >= 0) | |
75 { | 118 { |
76 if (renvoi_dir == CENTER) | 119 Direction alternative_dir = robust_scm2dir (alternative_ev ent_->get_property ("alternative-dir"), RIGHT); |
77 renvoi_number_++; | 120 switch (alternative_dir) |
121 { | |
122 case LEFT: | |
123 alternative_number_ = 0; | |
124 break; | |
125 case CENTER: | |
126 break; | |
127 case RIGHT: | |
128 alternative_number_ = INT_MIN; | |
129 break; | |
130 default: | |
131 assert (false); | |
132 } | |
133 alternative_number_ += alternative_number_increment_; | |
134 ······················ | |
135 alternative_number_increment_ = robust_scm2int (alternativ e_event_->get_property ("alternative-increment"), 1); | |
136 } | |
137 if (alternative_number_ >= 0) | |
138 { | |
78 string alphabet = "abcdefghijklmnopqrstuvwxyz"; | 139 string alphabet = "abcdefghijklmnopqrstuvwxyz"; |
79 for (int i = 0; i < renvoi_number_ / 26; i++) | 140 int power = 0; |
80 text_tag += alphabet.at (renvoi_number_ / 26); | 141 int running_sum = 0; |
81 text_tag += alphabet.at (renvoi_number_ % 26); | 142 int scratch = alternative_number_; |
143 while (running_sum <= alternative_number_) | |
144 { | |
145 power++; | |
146 running_sum += int_pow (26, power); | |
147 } | |
148 scratch += int_pow (26, power) - running_sum; | |
149 for (int i = power; i--;) | |
150 text_tag += alphabet.at ((scratch / int_pow (26, i)) % 2 6); | |
82 } | 151 } |
83 } | 152 } |
84 // guh. | 153 // guh. |
85 text_->set_property | 154 text_->set_property |
86 ("text", | 155 ("text", |
87 scm_string_concatenate (scm_list_2 (scm_number_to_string (bn, scm_from_int (10)), | 156 scm_string_concatenate (scm_list_2 (scm_number_to_string (bn, scm_from_int (10)), |
Neil Puttock
2011/12/06 12:04:54
Would be better to have a barNumberFormatter funct
| |
88 ly_string2scm (text_tag))) ); | 157 ly_string2scm (text_tag))) ); |
89 } | 158 } |
90 } | 159 } |
91 } | 160 } |
92 context ()->set_property ("renvoiDir", SCM_BOOL_F); | |
93 } | 161 } |
94 | 162 |
95 Bar_number_engraver::Bar_number_engraver () | 163 Bar_number_engraver::Bar_number_engraver () |
96 { | 164 { |
97 text_ = 0; | 165 text_ = 0; |
98 renvoi_number_ = -1; | 166 alternative_starting_bar_number_ = 0; |
167 alternative_number_increment_ = 0; | |
168 alternative_number_ = INT_MIN; | |
169 alternative_event_ = 0; | |
99 } | 170 } |
100 | 171 |
101 void | 172 void |
102 Bar_number_engraver::acknowledge_break_alignment (Grob_info inf) | 173 Bar_number_engraver::acknowledge_break_alignment (Grob_info inf) |
103 { | 174 { |
104 Grob *s = inf.grob (); | 175 Grob *s = inf.grob (); |
105 if (text_ | 176 if (text_ |
106 && dynamic_cast<Item *> (s)) | 177 && dynamic_cast<Item *> (s)) |
107 { | 178 { |
108 text_->set_parent (s, X_AXIS); | 179 text_->set_parent (s, X_AXIS); |
109 } | 180 } |
110 } | 181 } |
111 | 182 |
112 void | 183 void |
113 Bar_number_engraver::stop_translation_timestep () | 184 Bar_number_engraver::stop_translation_timestep () |
114 { | 185 { |
186 alternative_event_ = 0; | |
115 if (text_) | 187 if (text_) |
116 { | 188 { |
117 text_->set_object ("side-support-elements", | 189 text_->set_object ("side-support-elements", |
118 grob_list_to_grob_array (get_property ("stavesFound"))) ; | 190 grob_list_to_grob_array (get_property ("stavesFound"))) ; |
119 text_ = 0; | 191 text_ = 0; |
120 } | 192 } |
121 } | 193 } |
122 | 194 |
123 void | 195 void |
124 Bar_number_engraver::create_items () | 196 Bar_number_engraver::create_items () |
(...skipping 16 matching lines...) Expand all Loading... | |
141 " @ref{Staff_collecting_engraver}.", | 213 " @ref{Staff_collecting_engraver}.", |
142 | 214 |
143 /* create */ | 215 /* create */ |
144 "BarNumber ", | 216 "BarNumber ", |
145 | 217 |
146 /* read */ | 218 /* read */ |
147 "currentBarNumber " | 219 "currentBarNumber " |
148 "whichBar " | 220 "whichBar " |
149 "stavesFound " | 221 "stavesFound " |
150 "barNumberVisibility " | 222 "barNumberVisibility " |
151 "renvoiDir " | 223 "alternativeNumberingStyle ", |
152 "renvoiStyle ", | |
153 | 224 |
154 /* write */ | 225 /* write */ |
155 "renvoiDir " | 226 "currentBarNumber " |
156 ); | 227 ); |
LEFT | RIGHT |