feat(rendering): add per-beat rest display position via beat.restDisplayTone, beat.restDisplayOctave#2721
Conversation
| return ApplyNodeResult.Applied; | ||
| case 'restdisplaypitch': { | ||
| const pitchText = (p.arguments!.arguments[0] as AlphaTexTextNode).text.toUpperCase(); | ||
| const toneChar = pitchText[0] as keyof typeof Tone; |
There was a problem hiding this comment.
This code cannot be transpiled to C# and Kotlin.
You can reuse alphaTab.model.Tuning to parse such strings
| export enum Tone { | ||
| C = 0, | ||
| D = 2, | ||
| E = 4, | ||
| F = 5, | ||
| G = 7, | ||
| A = 9, | ||
| B = 11 | ||
| } |
There was a problem hiding this comment.
The idea with the enum is good, but it is in conflict with how alphaTab handles tones at all other places. I'd prefer consistency (using raw numnber properties) until we can introduce such an enum consistently at all places.
| } | ||
|
|
||
| const spelling = ModelUtils.resolveSpelling(bar.keySignature, noteValue, NoteAccidentalMode.Default); | ||
| return AccidentalHelper.calculateNoteSteps(bar.clef, spelling) + 0.5; |
There was a problem hiding this comment.
+ 0.5 seems like a workaround indicating to a problem elsewhere. Can we eliminate or move this to the actual place where things where the need for the workaround gets clear?
There was a problem hiding this comment.
The issue of adding 0.5 is needed because the glyph baseline data contained in bravura_metadata.json varies per glyph.
For example, the black note head is perfectly centred vertically [0.5, -0.5] , but the rest glyphs all have different off-centre base lines.
The 0.5 is used to calculate the perfect positioning of the half note rest, so everything is adjusted by 0.5,
but visually the 0.5 aligns the half note perfectly.
Do we want all rests, quarter note, eighth note, 16th note, 32nd etc. notes to be aligned perfectly centred visually on the Y axis,either on the line or in the space, or is it just the half note that needs to be visually perfect?
If all rests need to be visually perfectly centered, then we'd need to include the Bravura metadata coordinates in the
calculation. Creating a helper function to do this.
We could call this after calling calculateRestDisplaySteps and add the result, the return value, to replace the 0.5 hard coded value.
| type ClefData = { | ||
| tex: string; | ||
| filler: string; | ||
| positions: [string, string][]; | ||
| primaryFiller: string; | ||
| secondaryFiller: string; | ||
| multiVoicePrimary: [string, string]; | ||
| multiVoiceSecondary: [string, string]; | ||
| }; | ||
|
|
||
| // Staff positions from bottom to top for each clef: [pitch, label] | ||
| const clefs: Record<string, ClefData> = { |
There was a problem hiding this comment.
Please write only code which is safe for transpilation.
…tch tag
Adds Beat.restDisplayTone (Tone enum) and Beat.restDisplayOctave to allow
specifying the vertical position of a rest on the staff on a per-beat basis.
The AlphaTex restdisplaypitch tag (e.g. r.4{restdisplaypitch E4}) sets these
values. AccidentalHelper.calculateRestDisplaySteps converts the pitch to
rendering steps, aligned to match the legacy RestPosition enum spacing (+0.5).
Includes 77 visual tests covering treble, bass, alto and tenor clefs across
all staff positions, durations, multi-voice scenarios, and variable line counts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
9625031 to
146eb34
Compare
Adds Beat.restDisplayTone (Tone enum) and Beat.restDisplayOctave to allow specifying the vertical position of a rest on the staff on a per-beat basis. The AlphaTex restdisplaypitch tag (e.g. r.4{restdisplaypitch E4}) sets these values. AccidentalHelper.calculateRestDisplaySteps converts the pitch to rendering steps, aligned to match the legacy RestPosition enum spacing (+0.5).
Includes 77 visual tests covering treble, bass, alto and tenor clefs across staff positions, durations, multi-voice scenarios, and variable line counts.
This PR only includes TypeScript changes
Issues
Fixes #
Proposed changes
Checklist
Further details