Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ornament delayed draw, such as on a grand staff. #1598

Merged
merged 5 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/ornament.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { ModifierContextState } from './modifiercontext';
import { Stem } from './stem';
import { StemmableNote } from './stemmablenote';
import { Tables } from './tables';
import { TickContext } from './tickcontext';
import { Category, isTabNote } from './typeguard';
import { defined, log, RuntimeError } from './util';

Expand Down Expand Up @@ -303,16 +302,18 @@ export class Ornament extends Modifier {
// Ajdust x position if ornament is delayed
if (this.delayed) {
let delayXShift = 0;
const startX = glyphX - (stave.getX() - 10);
const startX = glyphX - stave.getNoteStartX();
if (this.delayXShift !== undefined) {
delayXShift = this.delayXShift;
} else {
delayXShift += this.glyph.getMetrics().width / 2;
const nextContext = TickContext.getNextContext(note.getTickContext());
const tickables = note.getVoice().getTickables();
const index = tickables.indexOf(note);
const nextContext = index + 1 < tickables.length ? tickables[index + 1].checkTickContext() : undefined;
if (nextContext) {
delayXShift += (nextContext.getX() - startX) * 0.5;
} else {
delayXShift += (stave.getX() + stave.getWidth() - startX) * 0.5;
delayXShift += (stave.getX() + stave.getWidth() - glyphX) * 0.5;
}
this.delayXShift = delayXShift;
}
Expand Down
41 changes: 41 additions & 0 deletions tests/ornament_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const OrnamentTests = {
run('Ornaments Vertically Shifted', drawOrnamentsDisplaced);
run('Ornaments - Delayed turns', drawOrnamentsDelayed);
run('Ornaments - Delayed turns, Multiple Draws', drawOrnamentsDelayedMultipleDraws);
run('Ornaments - Delayed turns, Multiple Voices', drawOrnamentsDelayedMultipleVoices);
run('Stacked', drawOrnamentsStacked);
run('With Upper/Lower Accidentals', drawOrnamentsWithAccidentals);
run('Jazz Ornaments', jazzOrnaments);
Expand Down Expand Up @@ -167,6 +168,46 @@ function drawOrnamentsDelayedMultipleDraws(options: TestOptions): void {
Formatter.FormatAndDraw(context, stave, notes);
}

function drawOrnamentsDelayedMultipleVoices(options: TestOptions, contextBuilder: ContextBuilder): void {
options.assert.expect(0);

// Get the rendering context
const ctx = contextBuilder(options.elementId, 550, 195);

const stave = new Stave(10, 30, 500);
stave.addClef('treble');
stave.addKeySignature('C#');
stave.addTimeSignature('4/4');

const notes1 = [
new StaveNote({ keys: ['f/5'], duration: '2r'}),
new StaveNote({ keys: ['c/5'], duration: '2', stem_direction: 1 }),
];
const notes2 = [
new StaveNote({ keys: ['a/4'], duration: '4', stem_direction: -1 }),
new StaveNote({ keys: ['e/4'], duration: '4r'}),
new StaveNote({ keys: ['e/4'], duration: '2r'}),
];

notes1[1].addModifier(new Ornament('turn_inverted').setDelayed(true), 0);
notes2[0].addModifier(new Ornament('turn').setDelayed(true), 0);

const voice1 = new Voice({ num_beats: 4, beat_value: 4, });
voice1.addTickables(notes1);
const voice2 = new Voice({ num_beats: 4, beat_value: 4, });
voice2.addTickables(notes2);

const formatWidth = stave.getNoteEndX() - stave.getNoteStartX();
const formatter = new Formatter();
formatter.joinVoices([voice1]);
formatter.joinVoices([voice2]);
formatter.format([voice1, voice2], formatWidth);

stave.setContext(ctx).draw();
voice1.draw(ctx, stave);
voice2.draw(ctx, stave);
}

function drawOrnamentsStacked(options: TestOptions): void {
options.assert.expect(0);

Expand Down