@@ -158,6 +158,10 @@ auto right_edge(vamp_zero::score_layout_item const& item) -> std::float32_t {
|
||||
return item.bounds.x + item.bounds.width;
|
||||
}
|
||||
|
||||
auto bottom_edge(vamp_zero::score_layout_item const& item) -> std::float32_t {
|
||||
return item.bounds.y + item.bounds.height;
|
||||
}
|
||||
|
||||
auto near(std::float32_t left, std::float32_t right) -> std::bool_t {
|
||||
return std::abs(left - right) < 0.02F;
|
||||
}
|
||||
@@ -448,6 +452,99 @@ BOOST_AUTO_TEST_CASE(score_layout_keeps_dense_notation_inside_measure_guard) {
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(score_layout_places_lyrics_below_low_vocal_notation) {
|
||||
auto low = note({pitch('c', "n", 3)});
|
||||
low.lyric = "low";
|
||||
auto score = score_with_notes({std::move(low)});
|
||||
auto layout = vamp_zero::layout_score_page({.x = 0.0F, .y = 0.0F, .width = 976.0F, .height = 484.0F}, score, 0U);
|
||||
|
||||
auto lyrics = layout_items(layout, vamp_zero::score_layout_item_role::LYRIC, 0U, 0U, 0U);
|
||||
BOOST_REQUIRE_EQUAL(lyrics.size(), 1U);
|
||||
|
||||
auto notation_bottom = std::numeric_limits<std::float32_t>::lowest();
|
||||
auto roles = {
|
||||
vamp_zero::score_layout_item_role::NOTEHEAD,
|
||||
vamp_zero::score_layout_item_role::ACCIDENTAL,
|
||||
vamp_zero::score_layout_item_role::STEM,
|
||||
vamp_zero::score_layout_item_role::FLAG,
|
||||
vamp_zero::score_layout_item_role::DOT,
|
||||
vamp_zero::score_layout_item_role::STAFF_LINE,
|
||||
};
|
||||
for (auto role : roles) {
|
||||
for (auto const* item : layout_items(layout, role, 0U, 0U, 0U)) {
|
||||
notation_bottom = std::max(notation_bottom, bottom_edge(*item));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST(lyrics.front()->bounds.y >= notation_bottom + layout.staff_spacing * 0.70F);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(score_layout_ties_to_the_actual_next_measure_notehead) {
|
||||
auto tied = note_with_ticks({pitch('b', "b")}, 16384);
|
||||
tied.tie_to_next = true;
|
||||
auto target = note_with_ticks({pitch('b', "b")}, 4096);
|
||||
target.tie_from_previous = true;
|
||||
auto score = score_with_measure({
|
||||
.time_signature = "4/4",
|
||||
.key_signature = "F",
|
||||
.notes = {std::move(tied)},
|
||||
}, "F");
|
||||
score.measures.push_back({
|
||||
.time_signature = "4/4",
|
||||
.key_signature = "F",
|
||||
.notes = {std::move(target)},
|
||||
});
|
||||
|
||||
auto layout = vamp_zero::layout_score_page({.x = 0.0F, .y = 0.0F, .width = 976.0F, .height = 484.0F}, score, 0U);
|
||||
|
||||
auto ties = layout_items(layout, vamp_zero::score_layout_item_role::TIE, 0U, 0U, 0U);
|
||||
auto start_heads = layout_items(layout, vamp_zero::score_layout_item_role::NOTEHEAD, 0U, 0U, 0U);
|
||||
auto target_heads = layout_items(layout, vamp_zero::score_layout_item_role::NOTEHEAD, 0U, 1U, 0U);
|
||||
BOOST_REQUIRE_EQUAL(ties.size(), 1U);
|
||||
BOOST_REQUIRE_EQUAL(start_heads.size(), 1U);
|
||||
BOOST_REQUIRE_EQUAL(target_heads.size(), 1U);
|
||||
|
||||
BOOST_TEST(ties.front()->from.x > right_edge(*start_heads.front()));
|
||||
BOOST_TEST(ties.front()->to.x < target_heads.front()->bounds.x);
|
||||
BOOST_TEST(ties.front()->to.x > right_edge(*start_heads.front()));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(score_layout_draws_tie_continuations_across_system_breaks) {
|
||||
auto measures = std::vector<vamp_zero::score_measure>{};
|
||||
for (auto index = std::size_t{}; index < 5U; ++index) {
|
||||
auto value = note_with_ticks({pitch('a', "n")}, 16384);
|
||||
if (index == 3U) {
|
||||
value.tie_to_next = true;
|
||||
}
|
||||
if (index == 4U) {
|
||||
value.tie_from_previous = true;
|
||||
}
|
||||
measures.push_back({
|
||||
.time_signature = "4/4",
|
||||
.key_signature = "C",
|
||||
.notes = {std::move(value)},
|
||||
});
|
||||
}
|
||||
auto score = vamp_zero::score_document{
|
||||
.title = "Break Tie",
|
||||
.composer = "Composer",
|
||||
.key_signature = "C",
|
||||
.time_signature = "4/4",
|
||||
.clef = "treble",
|
||||
.part = "Lead",
|
||||
.measures = std::move(measures),
|
||||
};
|
||||
|
||||
auto layout = vamp_zero::layout_score_page({.x = 0.0F, .y = 0.0F, .width = 976.0F, .height = 484.0F}, score, 0U);
|
||||
auto outgoing = layout_items(layout, vamp_zero::score_layout_item_role::TIE, 0U, 3U, 0U);
|
||||
auto incoming = layout_items(layout, vamp_zero::score_layout_item_role::TIE, 1U, 4U, 0U);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(outgoing.size(), 1U);
|
||||
BOOST_REQUIRE_EQUAL(incoming.size(), 1U);
|
||||
BOOST_TEST(outgoing.front()->to.x > outgoing.front()->from.x);
|
||||
BOOST_TEST(incoming.front()->to.x > incoming.front()->from.x);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(score_layout_raises_chord_symbols_above_high_notation) {
|
||||
auto high = note({pitch('c', "n", 6)});
|
||||
high.chord_symbol = "Cmaj7";
|
||||
|
||||
Reference in New Issue
Block a user