diff --git a/src/rendering/chorus.ts b/src/rendering/chorus.ts index 0487d6033..150764fc6 100644 --- a/src/rendering/chorus.ts +++ b/src/rendering/chorus.ts @@ -98,6 +98,20 @@ export class Chorus { }); } + @util.memoize() + getVoices(): Voice[] { + switch (this.data.type) { + case 'wholerest': + return this.createWholeRest(); + case 'multivoice': + return this.createMultiVoice({ + keySignature: this.data.keySignature, + measureEntries: this.data.measureEntries, + quarterNoteDivisions: this.data.quarterNoteDivisions, + }); + } + } + /** Returns the minimum justify width for the stave in a measure context. */ @util.memoize() getMinJustifyWidth(address: Address<'chorus'>): number { @@ -139,20 +153,6 @@ export class Chorus { }; } - @util.memoize() - private getVoices(): Voice[] { - switch (this.data.type) { - case 'wholerest': - return this.createWholeRest(); - case 'multivoice': - return this.createMultiVoice({ - keySignature: this.data.keySignature, - measureEntries: this.data.measureEntries, - quarterNoteDivisions: this.data.quarterNoteDivisions, - }); - } - } - private createWholeRest(): Voice[] { return [ Voice.wholeRest({ diff --git a/src/rendering/measure.ts b/src/rendering/measure.ts index da0e85ead..8621de957 100644 --- a/src/rendering/measure.ts +++ b/src/rendering/measure.ts @@ -62,6 +62,129 @@ export class Measure { this.measureEntries = opts.measureEntries; } + @util.memoize() + getFragments(): MeasureFragment[] { + const fragments = new Array(); + + const measureIndex = this.index; + + const beginningBarStyle = + this.musicXml.measure + .getBarlines() + .find((barline) => barline.getLocation() === 'left') + ?.getBarStyle() ?? 'regular'; + + const endBarStyle = + this.musicXml.measure + .getEndingMeasure() + .getBarlines() + .find((barline) => barline.getLocation() === 'right') + ?.getBarStyle() ?? 'regular'; + + let staveSignature = this.leadingStaveSignature; + let currentMeasureEntries = new Array(); + + const config = this.config; + const staveCount = this.staveCount; + const staveLayouts = this.musicXml.staveLayouts; + + let measureFragmentIndex = 0; + + function addFragment( + leadingStaveSignature: StaveSignature, + measureEntries: MeasureEntry[], + beginningBarStyle: musicxml.BarStyle, + endBarStyle: musicxml.BarStyle + ) { + const fragment = new MeasureFragment({ + config, + index: measureFragmentIndex++, + leadingStaveSignature, + beginningBarStyle: beginningBarStyle, + endBarStyle: endBarStyle, + staveCount, + staveLayouts, + measureEntries, + }); + fragments.push(fragment); + } + + for (let measureEntryIndex = 0; measureEntryIndex < this.measureEntries.length; measureEntryIndex++) { + const measureEntry = this.measureEntries[measureEntryIndex]; + const isLastMeasureEntry = measureEntryIndex === this.measureEntries.length - 1; + + if (measureEntry instanceof StaveSignature) { + const didStaveModifiersChange = measureEntry.getChangedStaveModifiers().length > 0; + if (didStaveModifiersChange && currentMeasureEntries.length > 0) { + // prettier-ignore + addFragment( + staveSignature, + currentMeasureEntries, + fragments.length === 0 ? beginningBarStyle : 'none', + 'none' + ); + currentMeasureEntries = []; + } + + staveSignature = measureEntry; + } else if ( + measureEntry instanceof musicxml.Direction && + measureEntry.getTypes().some((directionType) => { + const content = directionType.getContent(); + return content.type === 'metronome' && content.metronome.isSupported(); + }) && + currentMeasureEntries.length > 0 + ) { + // prettier-ignore + addFragment( + staveSignature, + currentMeasureEntries, + fragments.length === 0 ? beginningBarStyle : 'none', + 'none' + ) + currentMeasureEntries = []; + } + + currentMeasureEntries.push(measureEntry); + + if (isLastMeasureEntry) { + const nextStaveSignature = staveSignature?.getNext(); + const hasClefChangeAtMeasureBoundary = + nextStaveSignature?.getChangedStaveModifiers().includes('clef') && + nextStaveSignature?.getMeasureIndex() === measureIndex + 1 && + nextStaveSignature?.getMeasureEntryIndex() === 0; + + if (hasClefChangeAtMeasureBoundary) { + // prettier-ignore + addFragment( + staveSignature, + currentMeasureEntries, + fragments.length === 0 ? beginningBarStyle : 'none', + 'none', + ); + + // prettier-ignore + addFragment( + nextStaveSignature, + [nextStaveSignature], + 'none', + endBarStyle + ); + } else { + // prettier-ignore + addFragment( + staveSignature, + currentMeasureEntries, + fragments.length === 0 ? beginningBarStyle : 'none', + endBarStyle + ); + } + } + } + + return fragments; + } + /** Returns the index of the measure. */ getIndex(): number { return this.index; @@ -186,129 +309,6 @@ export class Measure { }; } - @util.memoize() - private getFragments(): MeasureFragment[] { - const fragments = new Array(); - - const measureIndex = this.index; - - const beginningBarStyle = - this.musicXml.measure - .getBarlines() - .find((barline) => barline.getLocation() === 'left') - ?.getBarStyle() ?? 'regular'; - - const endBarStyle = - this.musicXml.measure - .getEndingMeasure() - .getBarlines() - .find((barline) => barline.getLocation() === 'right') - ?.getBarStyle() ?? 'regular'; - - let staveSignature = this.leadingStaveSignature; - let currentMeasureEntries = new Array(); - - const config = this.config; - const staveCount = this.staveCount; - const staveLayouts = this.musicXml.staveLayouts; - - let measureFragmentIndex = 0; - - function addFragment( - leadingStaveSignature: StaveSignature, - measureEntries: MeasureEntry[], - beginningBarStyle: musicxml.BarStyle, - endBarStyle: musicxml.BarStyle - ) { - const fragment = new MeasureFragment({ - config, - index: measureFragmentIndex++, - leadingStaveSignature, - beginningBarStyle: beginningBarStyle, - endBarStyle: endBarStyle, - staveCount, - staveLayouts, - measureEntries, - }); - fragments.push(fragment); - } - - for (let measureEntryIndex = 0; measureEntryIndex < this.measureEntries.length; measureEntryIndex++) { - const measureEntry = this.measureEntries[measureEntryIndex]; - const isLastMeasureEntry = measureEntryIndex === this.measureEntries.length - 1; - - if (measureEntry instanceof StaveSignature) { - const didStaveModifiersChange = measureEntry.getChangedStaveModifiers().length > 0; - if (didStaveModifiersChange && currentMeasureEntries.length > 0) { - // prettier-ignore - addFragment( - staveSignature, - currentMeasureEntries, - fragments.length === 0 ? beginningBarStyle : 'none', - 'none' - ); - currentMeasureEntries = []; - } - - staveSignature = measureEntry; - } else if ( - measureEntry instanceof musicxml.Direction && - measureEntry.getTypes().some((directionType) => { - const content = directionType.getContent(); - return content.type === 'metronome' && content.metronome.isSupported(); - }) && - currentMeasureEntries.length > 0 - ) { - // prettier-ignore - addFragment( - staveSignature, - currentMeasureEntries, - fragments.length === 0 ? beginningBarStyle : 'none', - 'none' - ) - currentMeasureEntries = []; - } - - currentMeasureEntries.push(measureEntry); - - if (isLastMeasureEntry) { - const nextStaveSignature = staveSignature?.getNext(); - const hasClefChangeAtMeasureBoundary = - nextStaveSignature?.getChangedStaveModifiers().includes('clef') && - nextStaveSignature?.getMeasureIndex() === measureIndex + 1 && - nextStaveSignature?.getMeasureEntryIndex() === 0; - - if (hasClefChangeAtMeasureBoundary) { - // prettier-ignore - addFragment( - staveSignature, - currentMeasureEntries, - fragments.length === 0 ? beginningBarStyle : 'none', - 'none', - ); - - // prettier-ignore - addFragment( - nextStaveSignature, - [nextStaveSignature], - 'none', - endBarStyle - ); - } else { - // prettier-ignore - addFragment( - staveSignature, - currentMeasureEntries, - fragments.length === 0 ? beginningBarStyle : 'none', - endBarStyle - ); - } - } - } - - return fragments; - } - private getLabel(): string { return this.musicXml.measure.isImplicit() ? '' : this.musicXml.measure.getNumber() || (this.index + 1).toString(); } diff --git a/src/rendering/measurefragment.ts b/src/rendering/measurefragment.ts index 507ea2e0a..033d07359 100644 --- a/src/rendering/measurefragment.ts +++ b/src/rendering/measurefragment.ts @@ -52,6 +52,31 @@ export class MeasureFragment { this.endBarStyle = opts.endBarStyle; } + @util.memoize() + getStaves(): Stave[] { + const staves = new Array(this.staveCount); + + for (let staveIndex = 0; staveIndex < this.staveCount; staveIndex++) { + const staveNumber = staveIndex + 1; + + staves[staveIndex] = new Stave({ + config: this.config, + staveSignature: this.leadingStaveSignature, + number: staveNumber, + beginningBarStyle: this.beginningBarStyle, + endBarStyle: this.endBarStyle, + measureEntries: this.measureEntries.filter((entry) => { + if (entry instanceof musicxml.Note) { + return entry.getStaveNumber() === staveNumber; + } + return true; + }), + }); + } + + return staves; + } + /** Returns the index of the measure fragment within the measure. */ getIndex(): number { return this.index; @@ -151,31 +176,6 @@ export class MeasureFragment { }; } - @util.memoize() - private getStaves(): Stave[] { - const staves = new Array(this.staveCount); - - for (let staveIndex = 0; staveIndex < this.staveCount; staveIndex++) { - const staveNumber = staveIndex + 1; - - staves[staveIndex] = new Stave({ - config: this.config, - staveSignature: this.leadingStaveSignature, - number: staveNumber, - beginningBarStyle: this.beginningBarStyle, - endBarStyle: this.endBarStyle, - measureEntries: this.measureEntries.filter((entry) => { - if (entry instanceof musicxml.Note) { - return entry.getStaveNumber() === staveNumber; - } - return true; - }), - }); - } - - return staves; - } - /** Returns the minimum justify width. */ @util.memoize() private getMinJustifyWidth(address: Address<'measurefragment'>): number { diff --git a/src/rendering/stave.ts b/src/rendering/stave.ts index 4143162c3..75ad0bba6 100644 --- a/src/rendering/stave.ts +++ b/src/rendering/stave.ts @@ -89,6 +89,39 @@ export class Stave { return 0; } + @util.memoize() + getEntry(): StaveEntry { + const config = this.config; + const timeSignature = this.getTimeSignature(); + const clef = this.getClef(); + const multiRestCount = this.getMultiRestCount(); + const measureEntries = this.measureEntries; + const quarterNoteDivisions = this.getQuarterNoteDivisions(); + const keySignature = this.getKeySignature(); + + if (multiRestCount === 1) { + return Chorus.wholeRest({ config, clef, timeSignature }); + } + + if (multiRestCount > 1) { + return new MultiRest({ count: multiRestCount }); + } + + if (this.getClef().getType() === 'tab') { + // TODO: Render tablature correctly. + return new Tablature(); + } + + return Chorus.multiVoice({ + config, + measureEntries, + quarterNoteDivisions, + keySignature, + clef, + timeSignature, + }); + } + /** Returns the stave number. */ getNumber(): number { return this.number; @@ -246,39 +279,6 @@ export class Stave { ); } - @util.memoize() - private getEntry(): StaveEntry { - const config = this.config; - const timeSignature = this.getTimeSignature(); - const clef = this.getClef(); - const multiRestCount = this.getMultiRestCount(); - const measureEntries = this.measureEntries; - const quarterNoteDivisions = this.getQuarterNoteDivisions(); - const keySignature = this.getKeySignature(); - - if (multiRestCount === 1) { - return Chorus.wholeRest({ config, clef, timeSignature }); - } - - if (multiRestCount > 1) { - return new MultiRest({ count: multiRestCount }); - } - - if (this.getClef().getType() === 'tab') { - // TODO: Render tablature correctly. - return new Tablature(); - } - - return Chorus.multiVoice({ - config, - measureEntries, - quarterNoteDivisions, - keySignature, - clef, - timeSignature, - }); - } - private getClef(): Clef { return this.staveSignature.getClef(this.number); }