Skip to content

Commit

Permalink
Merge pull request 0xfe#1598 from RyoSusami/hotfix/ornament_delayed_draw
Browse files Browse the repository at this point in the history
Fix ornament delayed draw, such as on a grand staff.
  • Loading branch information
rvilarl authored Oct 5, 2023
2 parents e5f7786 + adc4cbb commit 7e7eb97
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
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

0 comments on commit 7e7eb97

Please sign in to comment.