+64
-8
@@ -777,6 +777,45 @@ auto effective_time_signature(vamp_zero::score_document const& score, vamp_zero:
|
||||
return "4/4";
|
||||
}
|
||||
|
||||
auto notation_state_changes_before(vamp_zero::score_document const& score, std::size_t measure_index) -> std::bool_t {
|
||||
if (measure_index == 0U || measure_index >= score.measures.size()) {
|
||||
return false;
|
||||
}
|
||||
auto const& previous = score.measures[measure_index - 1U];
|
||||
auto const& current = score.measures[measure_index];
|
||||
return effective_key_signature(score, previous) != effective_key_signature(score, current)
|
||||
|| effective_time_signature(score, &previous) != effective_time_signature(score, ¤t);
|
||||
}
|
||||
|
||||
auto make_score_system_ranges(vamp_zero::score_document const& score) -> std::vector<vamp_zero::score_system_range> {
|
||||
auto ranges = std::vector<vamp_zero::score_system_range>{};
|
||||
if (score.measures.empty()) {
|
||||
return ranges;
|
||||
}
|
||||
|
||||
auto current = vamp_zero::score_system_range{.first_measure = 0U, .measure_count = 0U};
|
||||
for (auto measure_index = std::size_t{}; measure_index < score.measures.size(); ++measure_index) {
|
||||
if (current.measure_count != 0U
|
||||
&& (current.measure_count >= vamp_zero::score_measures_per_system || notation_state_changes_before(score, measure_index))) {
|
||||
ranges.push_back(current);
|
||||
current = vamp_zero::score_system_range{.first_measure = measure_index, .measure_count = 0U};
|
||||
}
|
||||
++current.measure_count;
|
||||
}
|
||||
if (current.measure_count != 0U) {
|
||||
ranges.push_back(current);
|
||||
}
|
||||
return ranges;
|
||||
}
|
||||
|
||||
auto show_time_signature_for_system(vamp_zero::score_document const& score, vamp_zero::score_system_range const& range) -> std::bool_t {
|
||||
if (range.first_measure == 0U) {
|
||||
return true;
|
||||
}
|
||||
return notation_state_changes_before(score, range.first_measure)
|
||||
&& effective_time_signature(score, &score.measures[range.first_measure - 1U]) != effective_time_signature(score, &score.measures[range.first_measure]);
|
||||
}
|
||||
|
||||
auto draw_curve(luma::draw_context& context, luma::point start, luma::point control, luma::point end, std::float32_t thickness, luma::color color) -> void {
|
||||
constexpr auto segments = std::int32_t{10};
|
||||
auto previous = start;
|
||||
@@ -2221,6 +2260,18 @@ auto vamp_zero::notated_accidentals_for_measure(vamp_zero::score_measure const&
|
||||
return accidentals;
|
||||
}
|
||||
|
||||
auto vamp_zero::score_system_ranges(vamp_zero::score_document const& score) -> std::vector<vamp_zero::score_system_range> {
|
||||
return make_score_system_ranges(score);
|
||||
}
|
||||
|
||||
auto vamp_zero::score_page_count(vamp_zero::score_document const& score) -> std::size_t {
|
||||
auto ranges = make_score_system_ranges(score);
|
||||
if (ranges.empty()) {
|
||||
return 1U;
|
||||
}
|
||||
return (ranges.size() + vamp_zero::score_systems_per_page - 1U) / vamp_zero::score_systems_per_page;
|
||||
}
|
||||
|
||||
auto vamp_zero::layout_score_page(luma::rect bounds, vamp_zero::score_document const& score, std::size_t page_index) -> vamp_zero::score_page_layout {
|
||||
auto layout = vamp_zero::score_page_layout{
|
||||
.bounds = bounds,
|
||||
@@ -2240,23 +2291,28 @@ auto vamp_zero::layout_score_page(luma::rect bounds, vamp_zero::score_document c
|
||||
auto const content_y = bounds.y + 84.0F;
|
||||
auto const content_width = std::max<std::float32_t>(spacing * 18.0F, bounds.width - margin * 2.0F);
|
||||
auto const system_height = (bounds.height - 108.0F) / static_cast<std::float32_t>(vamp_zero::score_systems_per_page);
|
||||
auto const first_measure = page_index * vamp_zero::score_measures_per_page;
|
||||
auto const system_ranges = make_score_system_ranges(score);
|
||||
auto const first_system = page_index * vamp_zero::score_systems_per_page;
|
||||
auto note_refs = std::vector<laid_out_note_ref>{};
|
||||
auto measure_refs = std::vector<laid_out_measure_ref>{};
|
||||
|
||||
for (auto system = std::size_t{}; system < vamp_zero::score_systems_per_page; ++system) {
|
||||
auto const system_y = content_y + static_cast<std::float32_t>(system) * system_height;
|
||||
auto const staff_top = system_y + spacing * 4.25F;
|
||||
auto const system_first_measure = first_measure + system * vamp_zero::score_measures_per_system;
|
||||
auto const* first_system_measure = system_first_measure < score.measures.size() ? &score.measures[system_first_measure] : nullptr;
|
||||
auto const range_index = first_system + system;
|
||||
auto const* range = range_index < system_ranges.size() ? &system_ranges[range_index] : nullptr;
|
||||
auto const* first_system_measure = range != nullptr && range->first_measure < score.measures.size() ? &score.measures[range->first_measure] : nullptr;
|
||||
layout_staff(layout, content_x, staff_top, content_width, spacing, system);
|
||||
auto const show_time = page_index == 0U && system == 0U;
|
||||
auto const show_time = range == nullptr ? page_index == 0U && system == 0U : show_time_signature_for_system(score, *range);
|
||||
auto const measure_start_x = layout_system_preamble(layout, score, first_system_measure, content_x, staff_top, spacing, show_time, system);
|
||||
auto const measure_area_width = std::max<std::float32_t>(spacing * 12.0F, content_x + content_width - measure_start_x);
|
||||
auto const measure_width = measure_area_width / static_cast<std::float32_t>(vamp_zero::score_measures_per_system);
|
||||
if (range == nullptr || range->measure_count == 0U) {
|
||||
continue;
|
||||
}
|
||||
auto const measure_width = measure_area_width / static_cast<std::float32_t>(range->measure_count);
|
||||
|
||||
for (auto measure = std::size_t{}; measure < vamp_zero::score_measures_per_system; ++measure) {
|
||||
auto const measure_index = system_first_measure + measure;
|
||||
for (auto measure = std::size_t{}; measure < range->measure_count; ++measure) {
|
||||
auto const measure_index = range->first_measure + measure;
|
||||
auto const x = measure_start_x + static_cast<std::float32_t>(measure) * measure_width;
|
||||
if (measure_index < score.measures.size()) {
|
||||
layout_measure(
|
||||
@@ -2274,7 +2330,7 @@ auto vamp_zero::layout_score_page(luma::rect bounds, vamp_zero::score_document c
|
||||
}
|
||||
|
||||
auto const bar_x = x + measure_width;
|
||||
auto const final_bar = measure + 1U == vamp_zero::score_measures_per_system || measure_index + 1U >= score.measures.size();
|
||||
auto const final_bar = measure + 1U == range->measure_count || measure_index + 1U >= score.measures.size();
|
||||
add_stroke_line(
|
||||
layout,
|
||||
final_bar ? vamp_zero::score_layout_item_role::FINAL_BARLINE : vamp_zero::score_layout_item_role::BARLINE,
|
||||
|
||||
Reference in New Issue
Block a user