OLD | NEW |
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) 2005--2011 Han-Wen Nienhuys <hanwen@xs4all.nl> | 4 Copyright (C) 2005--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 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 { | 105 { |
106 if (base_cols[j]->get_system () == which) | 106 if (base_cols[j]->get_system () == which) |
107 right = dynamic_cast<Item *> ((Grob *)base_cols[j]); | 107 right = dynamic_cast<Item *> ((Grob *)base_cols[j]); |
108 } | 108 } |
109 } | 109 } |
110 | 110 |
111 Grob *common = right->common_refpoint (left, X_AXIS); | 111 Grob *common = right->common_refpoint (left, X_AXIS); |
112 | 112 |
113 clique.push_back (right); | 113 clique.push_back (right); |
114 | 114 |
| 115 /* |
| 116 We use two vectors to keep track of loose column spacing: |
| 117 clique_spacing keeps track of ideal spaces. |
| 118 clique_tight_spacing keeps track of minimum spaces. |
| 119 Below, a scale factor is applied to the shifting of loose columns that |
| 120 aims to preserve clique_spacing but gets closer to clique_tight_spacing
as the |
| 121 space becomes smaller. This is used because the rods placed for loose c
olumns |
| 122 are tight (meaning they use minimum distances - see set_distances_for_lo
ose_columns). |
| 123 However, other rods may widen this distance, in which case we don't want
a crammed score. |
| 124 Thus, we aim for non-crammed, and fall back on crammed as needed. |
| 125 */ |
115 vector<Real> clique_spacing; | 126 vector<Real> clique_spacing; |
| 127 vector<Real> clique_tight_spacing; |
116 clique_spacing.push_back (0.0); | 128 clique_spacing.push_back (0.0); |
| 129 clique_tight_spacing.push_back (0.0); |
117 for (vsize j = 1; j + 1 < clique.size (); j++) | 130 for (vsize j = 1; j + 1 < clique.size (); j++) |
118 { | 131 { |
119 Grob *clique_col = clique[j]; | 132 Grob *clique_col = clique[j]; |
120 | 133 |
121 Paper_column *loose_col = dynamic_cast<Paper_column *> (clique[j]); | 134 Paper_column *loose_col = dynamic_cast<Paper_column *> (clique[j]); |
122 Paper_column *next_col = dynamic_cast<Paper_column *> (clique[j + 1]); | 135 Paper_column *next_col = dynamic_cast<Paper_column *> (clique[j + 1]); |
123 | 136 |
124 Grob *spacing = unsmob_grob (clique_col->get_object ("spacing")); | 137 Grob *spacing = unsmob_grob (clique_col->get_object ("spacing")); |
125 if (Grob *grace_spacing = unsmob_grob (clique_col->get_object ("grace-
spacing"))) | 138 if (Grob *grace_spacing = unsmob_grob (clique_col->get_object ("grace-
spacing"))) |
126 { | 139 { |
127 spacing = grace_spacing; | 140 spacing = grace_spacing; |
128 } | 141 } |
129 | 142 |
130 Spacing_options options; | 143 Spacing_options options; |
131 if (spacing) | 144 if (spacing) |
132 options.init_from_grob (spacing); | 145 options.init_from_grob (spacing); |
133 else | 146 else |
134 programming_error ("Column without spacing object"); | 147 programming_error ("Column without spacing object"); |
135 | 148 |
136 Real base_note_space = 0.0; | 149 Real base_note_space = 0.0; |
| 150 Real tight_note_space = 0.0; |
137 | 151 |
138 if (Paper_column::is_musical (next_col) | 152 if (Paper_column::is_musical (next_col) |
139 && Paper_column::is_musical (loose_col)) | 153 && Paper_column::is_musical (loose_col)) |
140 base_note_space = Spacing_spanner::note_spacing (spacing, loose_col,
next_col, | 154 { |
141 &options); | 155 Real base = Spacing_spanner::note_spacing (spacing, loose_col, nex
t_col, |
| 156 &options); |
| 157 if (Note_spacing::has_interface (spacing)) |
| 158 { |
| 159 Spring spring = Note_spacing::get_spacing (spacing, next_col,
base, options.increment_);; |
| 160 base_note_space = spring.distance (); |
| 161 tight_note_space = spring.min_distance (); |
| 162 } |
| 163 else |
| 164 { |
| 165 base_note_space = base; |
| 166 tight_note_space = base; |
| 167 } |
| 168 } |
142 else | 169 else |
143 { | 170 { |
144 Spring spring = Spacing_spanner::standard_breakable_column_spacing
(spacing, | 171 Spring spring = Spacing_spanner::standard_breakable_column_spacing
(spacing, |
145 loose_col, next_col, | 172 loose_col, next_col, |
146 &options); | 173 &options); |
147 | 174 |
148 base_note_space = spring.distance (); | 175 base_note_space = spring.distance (); |
| 176 tight_note_space = spring.min_distance (); |
149 } | 177 } |
150 | 178 |
151 base_note_space = max (base_note_space, | |
152 robust_relative_extent (loose_col, loose_col, X
_AXIS)[RIGHT] | |
153 - robust_relative_extent (next_col, next_col, X
_AXIS)[LEFT]); | |
154 | |
155 clique_spacing.push_back (base_note_space); | 179 clique_spacing.push_back (base_note_space); |
| 180 clique_tight_spacing.push_back (tight_note_space); |
156 } | 181 } |
157 | 182 |
158 Real default_padding = 1.0; | 183 Real permissible_distance = clique.back ()->relative_coordinate (common, X
_AXIS) - robust_relative_extent (clique[0], common, X_AXIS)[RIGHT]; |
159 clique_spacing.push_back (default_padding); | |
160 | |
161 Real right_point = robust_relative_extent (clique.back (), common, X_AXIS)
[LEFT]; | 184 Real right_point = robust_relative_extent (clique.back (), common, X_AXIS)
[LEFT]; |
162 | |
163 Grob *finished_right_column = clique.back (); | 185 Grob *finished_right_column = clique.back (); |
164 | 186 |
| 187 Real sum_tight_spacing = 0; |
| 188 Real sum_spacing = 0; |
| 189 // currently a magic number - what would be a good grob to hold this prope
rty? |
| 190 Real left_padding = 0.15; |
| 191 for (vsize j = 0; j < clique_spacing.size (); j++) |
| 192 { |
| 193 sum_tight_spacing += clique_tight_spacing[j]; |
| 194 sum_spacing += clique_spacing[j]; |
| 195 } |
| 196 Real scale_factor = max (0.0, min (1.0, (permissible_distance - left_paddi
ng - sum_tight_spacing) / (sum_spacing - sum_tight_spacing))); |
165 for (vsize j = clique.size () - 2; j > 0; j--) | 197 for (vsize j = clique.size () - 2; j > 0; j--) |
166 { | 198 { |
167 Paper_column *clique_col = dynamic_cast<Paper_column *> (clique[j]); | 199 Paper_column *clique_col = dynamic_cast<Paper_column *> (clique[j]); |
168 | 200 |
169 right_point = finished_right_column->relative_coordinate (common, X_AX
IS); | 201 right_point = finished_right_column->relative_coordinate (common, X_AX
IS); |
170 | 202 |
171 Real distance_to_next = clique_spacing[j]; | 203 Real distance_to_next = clique_tight_spacing[j] + (clique_spacing[j] -
clique_tight_spacing[j]) * scale_factor; |
172 | 204 |
173 Real my_offset = right_point - distance_to_next; | 205 Real my_offset = right_point - distance_to_next; |
174 | 206 |
175 clique_col->translate_axis (my_offset - clique_col->relative_coordinat
e (common, X_AXIS), X_AXIS); | 207 clique_col->translate_axis (my_offset - clique_col->relative_coordinat
e (common, X_AXIS), X_AXIS); |
176 | 208 |
177 finished_right_column = clique_col; | 209 finished_right_column = clique_col; |
178 } | 210 } |
179 } | 211 } |
180 } | 212 } |
181 | 213 |
OLD | NEW |