123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- import Vex from "vexflow";
- import {IGraphicalSymbolFactory} from "../../Interfaces/IGraphicalSymbolFactory";
- import {MusicSystem} from "../MusicSystem";
- import {VexFlowMusicSystem} from "./VexFlowMusicSystem";
- import {Staff} from "../../VoiceData/Staff";
- import {StaffLine} from "../StaffLine";
- import {SourceMeasure} from "../../VoiceData/SourceMeasure";
- import {GraphicalMeasure} from "../GraphicalMeasure";
- import {VexFlowMeasure} from "./VexFlowMeasure";
- import {SourceStaffEntry} from "../../VoiceData/SourceStaffEntry";
- import {GraphicalStaffEntry} from "../GraphicalStaffEntry";
- import {VexFlowStaffEntry} from "./VexFlowStaffEntry";
- import {Note} from "../../VoiceData/Note";
- import {ClefInstruction} from "../../VoiceData/Instructions/ClefInstruction";
- import {OctaveEnum} from "../../VoiceData/Expressions/ContinuousExpressions/OctaveShift";
- import {GraphicalNote} from "../GraphicalNote";
- import {Pitch} from "../../../Common/DataObjects/Pitch";
- import {VexFlowGraphicalNote} from "./VexFlowGraphicalNote";
- import {Fraction} from "../../../Common/DataObjects/Fraction";
- import {GraphicalChordSymbolContainer} from "../GraphicalChordSymbolContainer";
- import {GraphicalLabel} from "../GraphicalLabel";
- import {EngravingRules} from "../EngravingRules";
- import { TechnicalInstruction } from "../../VoiceData/Instructions/TechnicalInstruction";
- import { GraphicalVoiceEntry } from "../GraphicalVoiceEntry";
- import { VoiceEntry } from "../../VoiceData/VoiceEntry";
- import { VexFlowVoiceEntry } from "./VexFlowVoiceEntry";
- import { VexFlowConverter } from "./VexFlowConverter";
- import { VexFlowTabMeasure } from "./VexFlowTabMeasure";
- import { VexFlowStaffLine } from "./VexFlowStaffLine";
- import { KeyInstruction } from "../../VoiceData/Instructions/KeyInstruction";
- import { VexFlowMultiRestMeasure } from "./VexFlowMultiRestMeasure";
- export class VexFlowGraphicalSymbolFactory implements IGraphicalSymbolFactory {
- /**
- * Create a new music system for the given page.
- * Currently only one vertically endless page exists where all systems are put to.
- * @param page
- * @param systemIndex
- * @returns {VexFlowMusicSystem}
- */
- public createMusicSystem(systemIndex: number, rules: EngravingRules): MusicSystem {
- return new VexFlowMusicSystem(systemIndex, rules);
- }
- /**
- * Create a staffline object containing all staff measures belonging to a given system and staff.
- * @param parentSystem
- * @param parentStaff
- * @returns {VexFlowStaffLine}
- */
- public createStaffLine(parentSystem: MusicSystem, parentStaff: Staff): StaffLine {
- return new VexFlowStaffLine(parentSystem, parentStaff);
- }
- /**
- * Construct an empty graphicalMeasure from the given source measure and staff.
- * @param sourceMeasure
- * @param staff
- * @returns {VexFlowMeasure}
- */
- public createGraphicalMeasure(sourceMeasure: SourceMeasure, staff: Staff, isTabMeasure: boolean = false): GraphicalMeasure {
- return new VexFlowMeasure(staff, sourceMeasure, undefined);
- }
- /**
- * Construct a MultiRestMeasure from the given source measure and staff.
- * @param sourceMeasure
- * @param staff
- * @returns {VexFlowMultiRestMeasure}
- */
- public createMultiRestMeasure(sourceMeasure: SourceMeasure, staff: Staff, staffLine?: StaffLine): GraphicalMeasure {
- return new VexFlowMultiRestMeasure(staff, sourceMeasure, staffLine);
- }
- /**
- * Construct an empty Tab staffMeasure from the given source measure and staff.
- * @param sourceMeasure
- * @param staff
- * @returns {VexFlowTabMeasure}
- */
- public createTabStaffMeasure(sourceMeasure: SourceMeasure, staff: Staff): GraphicalMeasure {
- return new VexFlowTabMeasure(staff, sourceMeasure);
- }
- /**
- * Create empty measure, which will be used to show key, rhythm changes at the end of the system.
- * @param staffLine
- * @returns {VexFlowMeasure}
- */
- public createExtraGraphicalMeasure(staffLine: StaffLine): GraphicalMeasure {
- return new VexFlowMeasure(staffLine.ParentStaff, undefined, staffLine);
- }
- /**
- * Create a staffEntry in the given measure for a given sourceStaffEntry.
- * @param sourceStaffEntry
- * @param measure
- * @returns {VexFlowStaffEntry}
- */
- public createStaffEntry(sourceStaffEntry: SourceStaffEntry, measure: GraphicalMeasure): GraphicalStaffEntry {
- return new VexFlowStaffEntry(<VexFlowMeasure>measure, sourceStaffEntry, undefined);
- }
- public createVoiceEntry(parentVoiceEntry: VoiceEntry, parentStaffEntry: GraphicalStaffEntry): GraphicalVoiceEntry {
- return new VexFlowVoiceEntry(parentVoiceEntry, parentStaffEntry);
- }
- /**
- * Create a Graphical Note for given note and clef and as part of graphicalStaffEntry.
- * @param note
- * @param numberOfDots The number of dots the note has to increase its musical duration.
- * @param graphicalStaffEntry
- * @param activeClef The currently active clef, needed for positioning the note vertically
- * @param octaveShift The currently active octave transposition enum, needed for positioning the note vertically
- * @returns {GraphicalNote}
- */
- public createNote(note: Note, graphicalVoiceEntry: GraphicalVoiceEntry, activeClef: ClefInstruction,
- octaveShift: OctaveEnum = OctaveEnum.NONE, rules: EngravingRules,
- graphicalNoteLength: Fraction = undefined): GraphicalNote {
- return new VexFlowGraphicalNote(note, graphicalVoiceEntry, activeClef, octaveShift, rules, graphicalNoteLength);
- }
- /**
- * Create a Graphical Grace Note (smaller head, stem...) for given note and clef and as part of graphicalStaffEntry.
- * @param note
- * @param numberOfDots
- * @param graphicalVoiceEntry
- * @param activeClef
- * @param octaveShift
- * @returns {GraphicalNote}
- */
- public createGraceNote(note: Note, graphicalVoiceEntry: GraphicalVoiceEntry,
- activeClef: ClefInstruction, rules: EngravingRules,
- octaveShift: OctaveEnum = OctaveEnum.NONE): GraphicalNote {
- return new VexFlowGraphicalNote(note, graphicalVoiceEntry, activeClef, octaveShift, rules);
- }
- /**
- * Sets a pitch which will be used for rendering the given graphical note (not changing the original pitch of the note!!!).
- * Will be only called if the displayed accidental is different from the original (e.g. a C# with C# as key instruction)
- * @param graphicalNote
- * @param pitch The pitch which will be rendered.
- */
- public addGraphicalAccidental(graphicalNote: GraphicalNote, pitch: Pitch): void {
- const note: VexFlowGraphicalNote = (graphicalNote as VexFlowGraphicalNote);
- // accidental is added in setPitch
- note.setAccidental(pitch);
- }
- /**
- * Adds a Fermata symbol at the last note of the given tied Note.
- * The last graphical note of this tied note is located at the given graphicalStaffEntry.
- * A Fermata has to be located at the last tied note.
- * @param tiedNote
- * @param graphicalStaffEntry
- */
- public addFermataAtTiedEndNote(tiedNote: Note, graphicalStaffEntry: GraphicalStaffEntry): void {
- return;
- }
- /**
- * Adds a clef change within a measure before the given staff entry.
- * @param graphicalStaffEntry
- * @param clefInstruction
- */
- public createInStaffClef(graphicalStaffEntry: GraphicalStaffEntry, clefInstruction: ClefInstruction): void {
- const se: VexFlowStaffEntry = graphicalStaffEntry as VexFlowStaffEntry;
- const vfClefParams: { type: string, size: string, annotation: string } = VexFlowConverter.Clef(clefInstruction, "small");
- se.vfClefBefore = new Vex.Flow.ClefNote(vfClefParams.type, vfClefParams.size, vfClefParams.annotation);
- return;
- }
- /**
- * Adds a chord symbol at the given staff entry
- * @param sourceStaffEntry
- * @param graphicalStaffEntry
- * @param transposeHalftones
- */
- public createChordSymbols( sourceStaffEntry: SourceStaffEntry,
- graphicalStaffEntry: GraphicalStaffEntry,
- keyInstruction: KeyInstruction,
- transposeHalftones: number): void {
- const rules: EngravingRules = graphicalStaffEntry.parentMeasure.parentSourceMeasure.Rules;
- let xShift: number = 0;
- const chordSymbolSpacing: number = rules.ChordSymbolXSpacing;
- for (const chordSymbolContainer of sourceStaffEntry.ChordContainers) {
- const graphicalChordSymbolContainer: GraphicalChordSymbolContainer =
- new GraphicalChordSymbolContainer(chordSymbolContainer,
- graphicalStaffEntry.PositionAndShape,
- rules.ChordSymbolTextHeight,
- keyInstruction,
- transposeHalftones,
- graphicalStaffEntry.parentMeasure.parentSourceMeasure.Rules // TODO undefined sometimes
- );
- const graphicalLabel: GraphicalLabel = graphicalChordSymbolContainer.GraphicalLabel;
- graphicalLabel.PositionAndShape.RelativePosition.y -= rules.ChordSymbolYOffset;
- graphicalLabel.PositionAndShape.RelativePosition.x += xShift;
- // TODO check for available space until next staffEntry or chord symbol (x direction)
- graphicalLabel.setLabelPositionAndShapeBorders();
- graphicalChordSymbolContainer.PositionAndShape.calculateBoundingBox();
- graphicalStaffEntry.graphicalChordContainers.push(graphicalChordSymbolContainer);
- xShift += graphicalLabel.PositionAndShape.Size.width + chordSymbolSpacing;
- }
- }
- /**
- * Adds a technical instruction at the given staff entry.
- * @param technicalInstruction
- * @param graphicalStaffEntry
- */
- public createGraphicalTechnicalInstruction(technicalInstruction: TechnicalInstruction, graphicalStaffEntry: GraphicalStaffEntry): void {
- return;
- }
- }
|