From 77c73f45040c6dcfda829af19955a443156d6442 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Thu, 29 Oct 2026 18:22:17 +0100 Subject: [PATCH] fix(rendering): draw triplet feel once per bar and capo once per staff The triplet feel indication was created for every voice and every staff of a bar, the capo text for every voice. Both now follow the guards used by tempo and marker effects. Fixes #2973 --- .../src/rendering/effects/CapoEffectInfo.ts | 4 +++- .../effects/TripletFeelEffectInfo.ts | 10 ++++----- .../triplet-feel-and-capo-multi-voice.png | Bin 0 -> 25411 bytes .../features/EffectsAndAnnotations.test.ts | 20 ++++++++++++++++++ 4 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 packages/alphatab/test-data/visual-tests/effects-and-annotations/triplet-feel-and-capo-multi-voice.png diff --git a/packages/alphatab/src/rendering/effects/CapoEffectInfo.ts b/packages/alphatab/src/rendering/effects/CapoEffectInfo.ts index 1882d4eca..d55d1936a 100644 --- a/packages/alphatab/src/rendering/effects/CapoEffectInfo.ts +++ b/packages/alphatab/src/rendering/effects/CapoEffectInfo.ts @@ -16,7 +16,9 @@ export const capoEffectInfo: EffectInfo = { hideOnMultiTrack: false, sizingMode: EffectBarGlyphSizing.SingleOnBeat, shouldCreateGlyph: (_renderer: BarRendererBase, beat: Beat): boolean => { - return beat.index === 0 && beat.voice.bar.index === 0 && beat.voice.bar.staff.capo !== 0; + return ( + beat.voice.index === 0 && beat.index === 0 && beat.voice.bar.index === 0 && beat.voice.bar.staff.capo !== 0 + ); }, createNewGlyph: (renderer: BarRendererBase, beat: Beat): EffectGlyph => { return new TextGlyph( diff --git a/packages/alphatab/src/rendering/effects/TripletFeelEffectInfo.ts b/packages/alphatab/src/rendering/effects/TripletFeelEffectInfo.ts index 45dd6ace1..b25a00727 100644 --- a/packages/alphatab/src/rendering/effects/TripletFeelEffectInfo.ts +++ b/packages/alphatab/src/rendering/effects/TripletFeelEffectInfo.ts @@ -16,12 +16,12 @@ export const tripletFeelEffectInfo: EffectInfo = { hideOnMultiTrack: true, sizingMode: EffectBarGlyphSizing.SinglePreBeat, shouldCreateGlyph: (_renderer: BarRendererBase, beat: Beat): boolean => { + const masterBar = beat.voice.bar.masterBar; + const isFirstBeat = beat.voice.bar.staff.index === 0 && beat.voice.index === 0 && beat.index === 0; return ( - beat.index === 0 && - ((beat.voice.bar.masterBar.index === 0 && - beat.voice.bar.masterBar.tripletFeel !== TripletFeel.NoTripletFeel) || - (beat.voice.bar.masterBar.index > 0 && - beat.voice.bar.masterBar.tripletFeel !== beat.voice.bar.masterBar.previousMasterBar!.tripletFeel)) + isFirstBeat && + ((masterBar.index === 0 && masterBar.tripletFeel !== TripletFeel.NoTripletFeel) || + (masterBar.index > 0 && masterBar.tripletFeel !== masterBar.previousMasterBar!.tripletFeel)) ); }, createNewGlyph: (_renderer: BarRendererBase, beat: Beat): EffectGlyph => { diff --git a/packages/alphatab/test-data/visual-tests/effects-and-annotations/triplet-feel-and-capo-multi-voice.png b/packages/alphatab/test-data/visual-tests/effects-and-annotations/triplet-feel-and-capo-multi-voice.png new file mode 100644 index 0000000000000000000000000000000000000000..3f95b8a6b13ca82d78c74edae901df8f36da6acc GIT binary patch literal 25411 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 literal 0 HcmV?d00001 diff --git a/packages/alphatab/test/visualTests/features/EffectsAndAnnotations.test.ts b/packages/alphatab/test/visualTests/features/EffectsAndAnnotations.test.ts index 334401aa8..228f1bec4 100644 --- a/packages/alphatab/test/visualTests/features/EffectsAndAnnotations.test.ts +++ b/packages/alphatab/test/visualTests/features/EffectsAndAnnotations.test.ts @@ -145,6 +145,26 @@ describe('EffectsAndAnnotationsTests', () => { await VisualTestHelper.runVisualTest('effects-and-annotations/triplet-feel.gp'); }); + it('triplet-feel-and-capo-multi-voice', async () => { + await VisualTestHelper.runVisualTestTex( + ` + \\track "Piano" + \\staff {score} + \\capo 2 + \\tf t8 + \\voice + :8 c5 d5 e5 f5 g5 a5 b5 c6 | \\tf t16 c5 d5 e5 f5 g5 a5 b5 c6 + \\voice + :2 c4 c4 | c4 c4 + \\staff {score} + \\capo 5 + \\clef F4 + :8 c3 d3 e3 f3 g3 a3 b3 c4 | c3 d3 e3 f3 g3 a3 b3 c4 + `, + 'test-data/visual-tests/effects-and-annotations/triplet-feel-and-capo-multi-voice.png' + ); + }); + it('free-time', async () => { await VisualTestHelper.runVisualTest('effects-and-annotations/free-time.gp'); });