Skip to content
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
26 changes: 15 additions & 11 deletions src/rendering/glyphs/ScoreBrushGlyph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,34 @@ export class ScoreBrushGlyph extends Glyph {
}

public override doLayout(): void {
this.width = 10 * this.scale;
this.width =
this._beat.brushType === BrushType.ArpeggioUp || this._beat.brushType === BrushType.ArpeggioDown
? 10 * this.scale
: 0;
}

public override paint(cx: number, cy: number, canvas: ICanvas): void {
let scoreBarRenderer: ScoreBarRenderer = this.renderer as ScoreBarRenderer;
let lineSize: number = scoreBarRenderer.lineOffset;
let startY: number = cy + this.y + (scoreBarRenderer.getNoteY(this._beat.maxNote!, NoteYPosition.Bottom) - lineSize);
let endY: number = cy + this.y + scoreBarRenderer.getNoteY(this._beat.minNote!, NoteYPosition.Top) + lineSize;
let arrowX: number = cx + this.x + this.width / 2;
let arrowSize: number = 8 * this.scale;
if (this._beat.brushType !== BrushType.None) {
if (this._beat.brushType === BrushType.ArpeggioUp || this._beat.brushType === BrushType.ArpeggioDown) {
let scoreBarRenderer: ScoreBarRenderer = this.renderer as ScoreBarRenderer;
let lineSize: number = scoreBarRenderer.lineOffset;
let startY: number =
cy + this.y + (scoreBarRenderer.getNoteY(this._beat.maxNote!, NoteYPosition.Bottom) - lineSize);
let endY: number =
cy + this.y + scoreBarRenderer.getNoteY(this._beat.minNote!, NoteYPosition.Top) + lineSize;
let arrowX: number = cx + this.x + this.width / 2;
let arrowSize: number = 8 * this.scale;

let glyph: NoteVibratoGlyph = new NoteVibratoGlyph(0, 0, VibratoType.Slight, 1.2, true);
glyph.renderer = this.renderer;
glyph.doLayout();

let waveOffset = -glyph.height / 2;

if (this._beat.brushType === BrushType.ArpeggioUp) {

let lineStartY: number = startY + arrowSize;
let lineEndY: number = endY - arrowSize;
glyph.width = Math.abs(lineEndY - lineStartY);

canvas.beginRotate(cx + this.x + 5 * this.scale, lineEndY, -90);
glyph.paint(0, waveOffset, canvas);
canvas.endRotate();
Expand All @@ -50,7 +55,6 @@ export class ScoreBrushGlyph extends Glyph {
canvas.closePath();
canvas.fill();
} else if (this._beat.brushType === BrushType.ArpeggioDown) {

let lineStartY: number = startY + arrowSize;
let lineEndY: number = endY;
glyph.width = Math.abs(lineEndY - lineStartY);
Expand Down
40 changes: 26 additions & 14 deletions src/rendering/glyphs/VoiceContainerGlyph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,45 +42,58 @@ export class VoiceContainerGlyph extends GlyphGroup {

switch (currentBeatGlyph.beat.graceType) {
case GraceType.None:
currentBeatGlyph.x = positions.get(currentBeatGlyph.beat.absoluteDisplayStart)! * scale - currentBeatGlyph.onTimeX;
currentBeatGlyph.x =
positions.get(currentBeatGlyph.beat.absoluteDisplayStart)! * scale - currentBeatGlyph.onTimeX;
break;
default:
const graceDisplayStart = currentBeatGlyph.beat.graceGroup!.beats[0].absoluteDisplayStart;
const graceGroupId = currentBeatGlyph.beat.graceGroup!.id;
// placement for proper grace notes which have a following note
if (currentBeatGlyph.beat.graceGroup!.isComplete && positions.has(graceDisplayStart)) {
currentBeatGlyph.x = positions.get(graceDisplayStart)! * scale - currentBeatGlyph.onTimeX;

let graceSprings = this.renderer.layoutingInfo.allGraceRods.get(graceGroupId)!;
let graceTargetPreBeat = this.renderer.layoutingInfo.springs.get(graceDisplayStart)!.preBeatWidth;

// get the pre beat stretch of this voice/staff, not the
// shared space. This way we use the potentially empty space (see discussions/1092).
const afterGraceBeat =
currentBeatGlyph.beat.graceGroup!.beats[currentBeatGlyph.beat.graceGroup!.beats.length - 1]
.nextBeat;
const preBeatStretch = afterGraceBeat
? this.renderer.layoutingInfo.getPreBeatSize(afterGraceBeat) +
BeatContainerGlyph.GraceBeatPadding * this.renderer.scale
: 0;

// move right in front to the note
currentBeatGlyph.x -= graceTargetPreBeat;
currentBeatGlyph.x -= preBeatStretch;
// respect the post beat width of the grace note
currentBeatGlyph.x -= graceSprings[currentBeatGlyph.beat.graceIndex].postSpringWidth;
// shift to right position of the particular grace note
currentBeatGlyph.x += graceSprings[currentBeatGlyph.beat.graceIndex].graceBeatWidth;
// move the whole group again forward for cases where another track has e.g. 3 beats and here we have only 2.
// move the whole group again forward for cases where another track has e.g. 3 beats and here we have only 2.
// so we shift the whole group of this voice to stick to the end of the group.
const lastGraceSpring = graceSprings[currentBeatGlyph.beat.graceGroup!.beats.length - 1];
currentBeatGlyph.x -= lastGraceSpring.graceBeatWidth;

} else {
// placement for improper grace beats where no beat in the same bar follows
let graceSpring = this.renderer.layoutingInfo.incompleteGraceRods.get(graceGroupId)!;
const relativeOffset = graceSpring[currentBeatGlyph.beat.graceIndex].postSpringWidth
- graceSpring[currentBeatGlyph.beat.graceIndex].preSpringWidth
const relativeOffset =
graceSpring[currentBeatGlyph.beat.graceIndex].postSpringWidth -
graceSpring[currentBeatGlyph.beat.graceIndex].preSpringWidth;

if (i > 0) {
if (currentBeatGlyph.beat.graceIndex === 0) {
// we place the grace beat directly after the previous one
// otherwise this causes flickers on resizing
// otherwise this causes flickers on resizing
currentBeatGlyph.x = beatGlyphs[i - 1].x + beatGlyphs[i - 1].width;
} else {
// for the multiple grace glyphs we take the width of the grace rod
// this width setting is aligned with the positioning logic below
currentBeatGlyph.x = beatGlyphs[i - 1].x
+ graceSpring[currentBeatGlyph.beat.graceIndex - 1].postSpringWidth
- graceSpring[currentBeatGlyph.beat.graceIndex - 1].preSpringWidth
- relativeOffset;
currentBeatGlyph.x =
beatGlyphs[i - 1].x +
graceSpring[currentBeatGlyph.beat.graceIndex - 1].postSpringWidth -
graceSpring[currentBeatGlyph.beat.graceIndex - 1].preSpringWidth -
relativeOffset;
}
} else {
currentBeatGlyph.x = -relativeOffset;
Expand Down Expand Up @@ -134,8 +147,7 @@ export class VoiceContainerGlyph extends GlyphGroup {
}
}

public override doLayout(): void {
}
public override doLayout(): void {}

public override paint(cx: number, cy: number, canvas: ICanvas): void {
// canvas.color = Color.random();
Expand Down
24 changes: 12 additions & 12 deletions src/rendering/staves/BarLayoutingInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,43 +44,43 @@ export class BarLayoutingInfo {
}

public setPreBeatSize(beat: Beat, size: number): void {
if (!this.preBeatSizes.has(beat.index) || this.preBeatSizes.get(beat.index)! < size) {
this.preBeatSizes.set(beat.index, size);
if (!this.preBeatSizes.has(beat.id) || this.preBeatSizes.get(beat.id)! < size) {
this.preBeatSizes.set(beat.id, size);
this.version++;
}
}

public getPreBeatSize(beat: Beat): number {
if (this.preBeatSizes.has(beat.index)) {
return this.preBeatSizes.get(beat.index)!;
if (this.preBeatSizes.has(beat.id)) {
return this.preBeatSizes.get(beat.id)!;
}
return 0;
}

public setOnBeatSize(beat: Beat, size: number): void {
if (!this.onBeatSizes.has(beat.index) || this.onBeatSizes.get(beat.index)! < size) {
this.onBeatSizes.set(beat.index, size);
if (!this.onBeatSizes.has(beat.id) || this.onBeatSizes.get(beat.id)! < size) {
this.onBeatSizes.set(beat.id, size);
this.version++;
}
}

public getOnBeatSize(beat: Beat): number {
if (this.onBeatSizes.has(beat.index)) {
return this.onBeatSizes.get(beat.index)!;
if (this.onBeatSizes.has(beat.id)) {
return this.onBeatSizes.get(beat.id)!;
}
return 0;
}

public getBeatCenterX(beat: Beat): number {
if (this.onBeatCenterX.has(beat.index)) {
return this.onBeatCenterX.get(beat.index)!;
if (this.onBeatCenterX.has(beat.id)) {
return this.onBeatCenterX.get(beat.id)!;
}
return 0;
}

public setBeatCenterX(beat: Beat, x: number): void {
if (!this.onBeatCenterX.has(beat.index) || this.onBeatCenterX.get(beat.index)! < x) {
this.onBeatCenterX.set(beat.index, x);
if (!this.onBeatCenterX.has(beat.id) || this.onBeatCenterX.get(beat.id)! < x) {
this.onBeatCenterX.set(beat.id, x);
this.version++;
}
}
Expand Down
Binary file modified test-data/visual-tests/effects-and-annotations/brush.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/music-notation/brushes-ukulele.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/notation-legend/bends-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/notation-legend/bends-songbook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/notation-legend/full-songbook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/notation-legend/grace-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/notation-legend/grace-songbook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/notation-legend/multi-grace-default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/notation-legend/multi-grace-songbook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/special-notes/grace-notes-advanced.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test-data/visual-tests/special-notes/grace-notes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions test/visualTests/features/SpecialNotes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ describe('SpecialNotesTests', () => {
await VisualTestHelper.runVisualTest('special-notes/grace-notes-advanced.gp', undefined, [0, 1], undefined, 1, true);
});

it('grace-alignment', async () => {
await VisualTestHelper.runVisualTest('special-notes/grace-notes-alignment.gp', undefined, [0, 1]);
});

it('dead-notes', async () => {
await VisualTestHelper.runVisualTest('special-notes/dead-notes.gp');
});
Expand Down