MusicSheetCalculator.ts 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  1. import {GraphicalStaffEntry} from "./GraphicalStaffEntry";
  2. import {StaffLine} from "./StaffLine";
  3. import {GraphicalMusicSheet} from "./GraphicalMusicSheet";
  4. import {EngravingRules} from "./EngravingRules";
  5. import {Tie} from "../VoiceData/Tie";
  6. import {Fraction} from "../../Common/DataObjects/fraction";
  7. import {Note} from "../VoiceData/Note";
  8. import {MusicSheet} from "../MusicSheet";
  9. import {StaffMeasure} from "./StaffMeasure";
  10. import {ClefInstruction} from "../VoiceData/Instructions/ClefInstruction";
  11. import {LyricWord} from "../VoiceData/Lyrics/LyricsWord";
  12. import {SourceMeasure} from "../VoiceData/SourceMeasure";
  13. import {GraphicalMusicPage} from "./GraphicalMusicPage";
  14. import {GraphicalNote} from "./GraphicalNote";
  15. import {Beam} from "../VoiceData/Beam";
  16. import {OctaveEnum} from "../VoiceData/Expressions/ContinuousExpressions/octaveShift";
  17. import {LyricsEntry} from "../VoiceData/Lyrics/LyricsEntry";
  18. import {VoiceEntry} from "../VoiceData/VoiceEntry";
  19. import {OrnamentContainer} from "../VoiceData/OrnamentContainer";
  20. import {ArticulationEnum} from "../VoiceData/VoiceEntry";
  21. import {Tuplet} from "../VoiceData/Tuplet";
  22. import {MusicSystem} from "./MusicSystem";
  23. import {GraphicalTie} from "./GraphicalTie";
  24. import {RepetitionInstruction} from "../VoiceData/Instructions/RepetitionInstruction";
  25. import {MultiExpression} from "../VoiceData/Expressions/multiExpression";
  26. import {StaffEntryLink} from "../VoiceData/StaffEntryLink";
  27. import {MusicSystemBuilder} from "./MusicSystemBuilder";
  28. import {MultiTempoExpression} from "../VoiceData/Expressions/multiTempoExpression";
  29. import {Repetition} from "../MusicSource/Repetition";
  30. import {PointF2D} from "../../Common/DataObjects/PointF2D";
  31. import {SourceStaffEntry} from "../VoiceData/SourceStaffEntry";
  32. import {BoundingBox} from "./BoundingBox";
  33. import {Instrument} from "../Instrument";
  34. import {GraphicalLabel} from "./GraphicalLabel";
  35. import {TextAlignment} from "../../Common/Enums/TextAlignment";
  36. import {VerticalGraphicalStaffEntryContainer} from "./VerticalGraphicalStaffEntryContainer";
  37. import {KeyInstruction} from "../VoiceData/Instructions/KeyInstruction";
  38. import {AbstractNotationInstruction} from "../VoiceData/Instructions/AbstractNotationInstruction";
  39. import {ClefEnum} from "../VoiceData/Instructions/ClefInstruction";
  40. import {TechnicalInstruction} from "../VoiceData/Instructions/TechnicalInstruction";
  41. import {Pitch} from "../../Common/DataObjects/pitch";
  42. import {LinkedVoice} from "../VoiceData/LinkedVoice";
  43. import {ColDirEnum} from "./BoundingBox";
  44. import {IGraphicalSymbolFactory} from "../Interfaces/IGraphicalSymbolFactory";
  45. import {ITextMeasurer} from "../Interfaces/ITextMeasurer";
  46. import {ITransposeCalculator} from "../Interfaces/ITransposeCalculator";
  47. import {OctaveShiftParams} from "./OctaveShiftParams";
  48. import {AccidentalCalculator} from "./AccidentalCalculator";
  49. import {MidiInstrument} from "../VoiceData/Instructions/ClefInstruction";
  50. import {Staff} from "../VoiceData/Staff";
  51. import {OctaveShift} from "../VoiceData/Expressions/ContinuousExpressions/octaveShift";
  52. export class MusicSheetCalculator {
  53. public static TransposeCalculator: ITransposeCalculator;
  54. protected static textMeasurer: ITextMeasurer;
  55. protected staffEntriesWithGraphicalTies: GraphicalStaffEntry[] = [];
  56. protected staffEntriesWithOrnaments: GraphicalStaffEntry[] = [];
  57. protected staffEntriesWithChordSymbols: GraphicalStaffEntry[] = [];
  58. protected staffLinesWithLyricWords: StaffLine[] = [];
  59. protected staffLinesWithGraphicalExpressions: StaffLine[] = [];
  60. protected graphicalMusicSheet: GraphicalMusicSheet;
  61. protected rules: EngravingRules;
  62. protected symbolFactory: IGraphicalSymbolFactory;
  63. constructor(symbolFactory: IGraphicalSymbolFactory) {
  64. this.symbolFactory = symbolFactory;
  65. }
  66. public static get TextMeasurer(): ITextMeasurer {
  67. return MusicSheetCalculator.textMeasurer;
  68. }
  69. public static set TextMeasurer(value: ITextMeasurer) {
  70. MusicSheetCalculator.textMeasurer = value;
  71. }
  72. protected get leadSheet(): boolean {
  73. return this.graphicalMusicSheet.LeadSheet;
  74. }
  75. private static addTieToTieTimestampsDict(tieTimestampListDict: Dictionary<Tie, Fraction[]>, note: Note): void {
  76. note.NoteTie.initializeBoolList();
  77. let tieTimestampList: Fraction[] = [];
  78. for (let m: number = 0; m < note.NoteTie.Fractions.length; m++) {
  79. let musicTimestamp: Fraction;
  80. if (m === 0)
  81. musicTimestamp = new Fraction(note.calculateNoteLengthWithoutTie() + note.getAbsoluteTimestamp());
  82. else musicTimestamp = new Fraction(tieTimestampList[m - 1] + note.NoteTie.Fractions[m - 1]);
  83. tieTimestampList.push(musicTimestamp);
  84. }
  85. tieTimestampListDict.push(note.NoteTie, tieTimestampList);
  86. }
  87. public initialize(graphicalMusicSheet: GraphicalMusicSheet): void {
  88. this.graphicalMusicSheet = graphicalMusicSheet;
  89. this.rules = graphicalMusicSheet.ParentMusicSheet.rules;
  90. this.prepareGraphicalMusicSheet();
  91. this.calculate();
  92. }
  93. public prepareGraphicalMusicSheet(): void {
  94. this.graphicalMusicSheet.SystemImages.length = 0;
  95. let musicSheet: MusicSheet = this.graphicalMusicSheet.ParentMusicSheet;
  96. this.staffEntriesWithGraphicalTies = [];
  97. this.staffEntriesWithOrnaments = [];
  98. this.staffEntriesWithChordSymbols = [];
  99. this.staffLinesWithLyricWords = [];
  100. this.staffLinesWithGraphicalExpressions = [];
  101. this.graphicalMusicSheet.Initialize();
  102. let measureList: StaffMeasure[][] = this.graphicalMusicSheet.MeasureList;
  103. let accidentalCalculators: AccidentalCalculator[] = this.createAccidentalCalculators();
  104. let activeClefs: ClefInstruction[] = this.graphicalMusicSheet.initializeActiveClefs();
  105. let lyricWords: LyricWord[] = [];
  106. let completeNumberOfStaves: number = musicSheet.getCompleteNumberOfStaves();
  107. let openOctaveShifts: OctaveShiftParams[] = [];
  108. let tieTimestampListDictList: List<Dictionary<Tie, Fraction[]>> = new List<Dictionary<Tie, Fraction[]>>();
  109. for (let i: number = 0; i < completeNumberOfStaves; i++) {
  110. let tieTimestampListDict: Dictionary<Tie, Fraction[]> = new Dictionary<Tie, Fraction[]>();
  111. tieTimestampListDictList.push(tieTimestampListDict);
  112. openOctaveShifts.push(undefined);
  113. }
  114. for (let idx: number = 0, len: number = musicSheet.SourceMeasures.length; idx < len; ++idx) {
  115. let sourceMeasure: SourceMeasure = musicSheet.SourceMeasures[idx];
  116. let graphicalMeasures: StaffMeasure[] = this.createGraphicalMeasuresForSourceMeasure(sourceMeasure,
  117. accidentalCalculators,
  118. lyricWords,
  119. tieTimestampListDictList,
  120. openOctaveShifts,
  121. activeClefs);
  122. measureList.push(graphicalMeasures);
  123. }
  124. this.handleStaffEntries();
  125. this.calculateVerticalContainersList();
  126. this.setIndecesToVerticalGraphicalContainers();
  127. }
  128. public calculate(): void {
  129. this.clearSystemsAndMeasures();
  130. this.clearRecreatedObjects();
  131. this.createGraphicalTies();
  132. this.calculateSheetLabelBoundingBoxes();
  133. this.calculateXLayout(this.graphicalMusicSheet, this.maxInstrNameLabelLength());
  134. this.graphicalMusicSheet.MusicPages = [];
  135. this.calculateMusicSystems();
  136. this.graphicalMusicSheet.MusicPages[0].PositionAndShape.BorderMarginBottom += 9;
  137. GraphicalMusicSheet.transformRelativeToAbsolutePosition(this.graphicalMusicSheet);
  138. }
  139. public calculateXLayout(graphicalMusicSheet: GraphicalMusicSheet, maxInstrNameLabelLength: number): void {
  140. let maxLength: number = 0;
  141. let maxInstructionsLength: number = this.rules.MaxInstructionsConstValue;
  142. if (this.graphicalMusicSheet.MeasureList.length > 0) {
  143. maxLength = this.calculateMeasureXLayout(this.graphicalMusicSheet.MeasureList[0]) * 1.2 + maxInstrNameLabelLength + maxInstructionsLength;
  144. for (let i: number = 1; i < this.graphicalMusicSheet.MeasureList.length; i++) {
  145. let measures: StaffMeasure[] = this.graphicalMusicSheet.MeasureList[i];
  146. maxLength = Math.max(maxLength, this.calculateMeasureXLayout(measures) * 1.2 + maxInstructionsLength);
  147. }
  148. }
  149. this.graphicalMusicSheet.MaxAllowedSystemWidth = maxLength;
  150. }
  151. protected calculateMeasureXLayout(measures: StaffMeasure[]): number { throw new Error('not implemented'); }
  152. protected calculateSystemYLayout(): void { throw new Error('not implemented'); }
  153. protected initStaffMeasuresCreation(): void { throw new Error('not implemented'); }
  154. protected handleBeam(graphicalNote: GraphicalNote, beam: Beam, openBeams: Beam[]): void { throw new Error('not implemented'); }
  155. protected createGraphicalTieNote(beams: Beam[], activeClef: ClefInstruction,
  156. octaveShiftValue: OctaveEnum,
  157. graphicalStaffEntry: GraphicalStaffEntry, duration: Fraction, numberOfDots: number,
  158. openTie: Tie, isLastTieNote: boolean): void { throw new Error('not implemented'); }
  159. protected handleVoiceEntryLyrics(lyricsEntries: { [_: number]: LyricsEntry; }, voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry,
  160. openLyricWords: LyricWord[]): void { throw new Error('not implemented'); }
  161. protected handleVoiceEntryOrnaments(ornamentContainer: OrnamentContainer, voiceEntry: VoiceEntry,
  162. graphicalStaffEntry: GraphicalStaffEntry): void { throw new Error('not implemented'); }
  163. protected handleVoiceEntryArticulations(articulations: ArticulationEnum[],
  164. voiceEntry: VoiceEntry,
  165. graphicalStaffEntry: GraphicalStaffEntry): void { throw new Error('not implemented'); }
  166. protected handleTuplet(graphicalNote: GraphicalNote, tuplet: Tuplet, openTuplets: Tuplet[]): void { throw new Error('not implemented'); }
  167. protected layoutVoiceEntry(voiceEntry: VoiceEntry, graphicalNotes: GraphicalNote[], graphicalStaffEntry: GraphicalStaffEntry, hasPitchedNote: boolean, isGraceStaffEntry: boolean): void { throw new Error('not implemented'); }
  168. protected layoutStaffEntry(graphicalStaffEntry: GraphicalStaffEntry): void { throw new Error('not implemented'); }
  169. protected handleTie(tie: Tie, startGraphicalStaffEntry: GraphicalStaffEntry, staffIndex: number,
  170. measureIndex: number): void { throw new Error('not implemented'); }
  171. protected updateStaffLineBorders(staffLine: StaffLine): void { throw new Error('not implemented'); }
  172. protected calculateMeasureNumberPlacement(musicSystem: MusicSystem): void { throw new Error('not implemented'); }
  173. protected layoutGraphicalTie(tie: GraphicalTie, tieIsAtSystemBreak: boolean): void { throw new Error('not implemented'); }
  174. protected calculateSingleStaffLineLyricsPosition(staffLine: StaffLine, lyricVersesNumber: number[]): void { throw new Error('not implemented'); }
  175. protected calculateSingleOctaveShift(sourceMeasure: SourceMeasure, multiExpression: MultiExpression,
  176. measureIndex: number, staffIndex: number): void { throw new Error('not implemented'); }
  177. protected calculateWordRepetitionInstruction(repetitionInstruction: RepetitionInstruction,
  178. measureIndex: number): void { throw new Error('not implemented'); }
  179. protected calculateMoodAndUnknownExpression(multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void { throw new Error('not implemented'); }
  180. protected clearRecreatedObjects(): void {
  181. }
  182. protected handleStaffEntryLink(graphicalStaffEntry: GraphicalStaffEntry,
  183. staffEntryLinks: StaffEntryLink[]): void {
  184. }
  185. protected calculateMusicSystems(): void {
  186. if (this.graphicalMusicSheet.MeasureList === undefined) return;
  187. let allMeasures: StaffMeasure[][] = this.graphicalMusicSheet.MeasureList;
  188. if (allMeasures === undefined)
  189. return;
  190. let visibleMeasureList: StaffMeasure[][] = [];
  191. for (let idx: number = 0, len: number = allMeasures.length; idx < len; ++idx) {
  192. let staffMeasures: StaffMeasure[] = allMeasures[idx];
  193. let visibleStaffMeasures: StaffMeasure[] = [];
  194. for (let idx2: number = 0, len2: number = staffMeasures.length; idx2 < len2; ++idx2) {
  195. let staffMeasure: StaffMeasure = allMeasures[idx][idx2];
  196. if (staffMeasure.isVisible())
  197. visibleStaffMeasures.push(staffMeasure);
  198. }
  199. visibleMeasureList.push(visibleStaffMeasures);
  200. }
  201. let numberOfStaffLines: number = 0;
  202. for (let idx: number = 0, len: number = visibleMeasureList.length; idx < len; ++idx) {
  203. let gmlist: StaffMeasure[] = visibleMeasureList[idx];
  204. numberOfStaffLines = Math.max(gmlist.length, numberOfStaffLines);
  205. break;
  206. }
  207. if (numberOfStaffLines === 0)
  208. return;
  209. let musicSystemBuilder: MusicSystemBuilder = new MusicSystemBuilder();
  210. musicSystemBuilder.initialize(this.graphicalMusicSheet, visibleMeasureList, numberOfStaffLines, this.symbolFactory);
  211. musicSystemBuilder.buildMusicSystems();
  212. this.checkMeasuresForWholeRestNotes();
  213. if (!this.leadSheet) {
  214. this.calculateBeams();
  215. this.optimizeRestPlacement();
  216. this.calculateStaffEntryArticulationMarks();
  217. this.calculateTieCurves();
  218. }
  219. this.calculateSkyBottomLines();
  220. this.calculateTupletNumbers();
  221. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  222. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  223. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  224. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  225. this.calculateMeasureNumberPlacement(musicSystem);
  226. }
  227. }
  228. if (!this.leadSheet)
  229. this.calculateSlurs();
  230. if (!this.leadSheet)
  231. this.calculateOrnaments();
  232. this.updateSkyBottomLines();
  233. this.calculateChordSymbols();
  234. if (!this.leadSheet) {
  235. this.calculateDynamicExpressions();
  236. this.optimizeStaffLineDynamicExpressionsPositions();
  237. this.calculateMoodAndUnknownExpressions();
  238. this.calculateOctaveShifts();
  239. this.calculateWordRepetitionInstructions();
  240. }
  241. this.calculateRepetitionEndings();
  242. if (!this.leadSheet)
  243. this.calculateTempoExpressions();
  244. this.calculateLyricsPosition();
  245. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  246. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  247. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  248. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  249. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  250. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  251. this.updateStaffLineBorders(staffLine);
  252. }
  253. }
  254. }
  255. this.calculateComments();
  256. this.calculateSystemYLayout();
  257. this.calculateMarkedAreas();
  258. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  259. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  260. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  261. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  262. musicSystem.setMusicSystemLabelsYPosition();
  263. if (!this.leadSheet) {
  264. musicSystem.setYPositionsToVerticalLineObjectsAndCreateLines(this.rules);
  265. musicSystem.createSystemLeftVerticalLineObject(this.rules.SystemThinLineWidth, this.rules.SystemLabelsRightMargin);
  266. musicSystem.createInstrumentBrackets(this.graphicalMusicSheet.ParentMusicSheet.Instruments, this.rules.StaffHeight);
  267. musicSystem.createGroupBrackets(this.graphicalMusicSheet.ParentMusicSheet.InstrumentalGroups, this.rules.StaffHeight, 0);
  268. musicSystem.alignBeginInstructions();
  269. } else if (musicSystem === musicSystem.Parent.MusicSystems[0]) {
  270. musicSystem.createSystemLeftVerticalLineObject(this.rules.SystemThinLineWidth, this.rules.SystemLabelsRightMargin);
  271. }
  272. musicSystem.calculateBorders(this.rules);
  273. }
  274. let distance: number = graphicalMusicPage.MusicSystems[0].PositionAndShape.BorderTop;
  275. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  276. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  277. let newPosition: PointF2D = new PointF2D(musicSystem.PositionAndShape.RelativePosition.x, musicSystem.PositionAndShape.RelativePosition.y - distance);
  278. musicSystem.PositionAndShape.RelativePosition = newPosition;
  279. }
  280. if (graphicalMusicPage === this.graphicalMusicSheet.MusicPages[0])
  281. this.calculatePageLabels(graphicalMusicPage);
  282. graphicalMusicPage.PositionAndShape.calculateTopBottomBorders();
  283. }
  284. }
  285. protected updateSkyBottomLine(staffLine: StaffLine): void {
  286. }
  287. protected calculateSkyBottomLine(staffLine: StaffLine): void {
  288. }
  289. protected calculateMarkedAreas(): void {
  290. }
  291. protected calculateComments(): void {
  292. }
  293. protected optimizeStaffLineDynamicExpressionsPositions(): void {
  294. }
  295. protected calculateChordSymbols(): void {
  296. }
  297. protected layoutMeasureWithWholeRest(rest: GraphicalNote, gse: GraphicalStaffEntry,
  298. measure: StaffMeasure): void {
  299. }
  300. protected layoutBeams(staffEntry: GraphicalStaffEntry): void {
  301. }
  302. protected layoutArticulationMarks(articulations: ArticulationEnum[], voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry): void {
  303. }
  304. protected layoutOrnament(ornaments: OrnamentContainer, voiceEntry: VoiceEntry,
  305. graphicalStaffEntry: GraphicalStaffEntry): void {
  306. }
  307. protected calculateRestNotePlacementWithinGraphicalBeam(graphicalStaffEntry: GraphicalStaffEntry,
  308. restNote: GraphicalNote,
  309. previousNote: GraphicalNote,
  310. nextStaffEntry: GraphicalStaffEntry,
  311. nextNote: GraphicalNote): void {
  312. }
  313. protected calculateTupletNumbers(): void {
  314. }
  315. protected calculateSlurs(): void {
  316. }
  317. protected layoutFingering(staffLine: StaffLine, skyBottomLineCalculator: SkyBottomLineCalculator,
  318. staffEntry: GraphicalStaffEntry, measureRelativePosition: PointF2D): void {
  319. }
  320. protected calculateDynamicExpressionsForSingleMultiExpression(multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void {
  321. }
  322. protected calcGraphicalRepetitionEndingsRecursively(repetition: Repetition): void {
  323. }
  324. protected layoutSingleRepetitionEnding(start: StaffMeasure, end: StaffMeasure, numberText: string, offset: number, leftOpen: boolean, rightOpen: boolean): void {
  325. }
  326. protected calculateTempoExpressionsForSingleMultiTempoExpression(sourceMeasure: SourceMeasure, multiTempoExpression: MultiTempoExpression, measureIndex: number): void {
  327. }
  328. protected clearSystemsAndMeasures(): void {
  329. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  330. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  331. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  332. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  333. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  334. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  335. for (let idx4: number = 0, len4: number = staffLine.Measures.length; idx4 < len4; ++idx4) {
  336. let graphicalMeasure: StaffMeasure = staffLine.Measures[idx4];
  337. if (graphicalMeasure.FirstInstructionStaffEntry !== undefined) {
  338. graphicalMeasure.PositionAndShape.ChildElements.Remove(graphicalMeasure.FirstInstructionStaffEntry.PositionAndShape);
  339. graphicalMeasure.FirstInstructionStaffEntry = undefined;
  340. graphicalMeasure.beginInstructionsWidth = 0.0;
  341. }
  342. if (graphicalMeasure.LastInstructionStaffEntry !== undefined) {
  343. graphicalMeasure.PositionAndShape.ChildElements.Remove(graphicalMeasure.LastInstructionStaffEntry.PositionAndShape);
  344. graphicalMeasure.LastInstructionStaffEntry = undefined;
  345. graphicalMeasure.endInstructionsWidth = 0.0;
  346. }
  347. }
  348. staffLine.Measures = [];
  349. staffLine.PositionAndShape.ChildElements = [];
  350. }
  351. musicSystem.StaffLines = [];
  352. musicSystem.PositionAndShape.ChildElements = [];
  353. }
  354. graphicalMusicPage.MusicSystems = [];
  355. graphicalMusicPage.PositionAndShape.ChildElements = [];
  356. }
  357. this.graphicalMusicSheet.MusicPages = [];
  358. }
  359. protected handleVoiceEntry(voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry,
  360. accidentalCalculator: AccidentalCalculator, openLyricWords: LyricWord[],
  361. tieTimestampListDict: Dictionary<Tie, Fraction[]>, activeClef: ClefInstruction,
  362. openTuplets: Tuplet[], openBeams: Beam[],
  363. octaveShiftValue: OctaveEnum, grace: boolean = false, linkedNotes: Note[] = undefined, sourceStaffEntry: SourceStaffEntry = undefined): OctaveEnum {
  364. let graphicalNotes: GraphicalNote[] = graphicalStaffEntry.findOrCreateGraphicalNotesListFromVoiceEntry(voiceEntry);
  365. for (let idx: number = 0, len: number = voiceEntry.Notes.length; idx < len; ++idx) {
  366. let note: Note = voiceEntry.Notes[idx];
  367. if (sourceStaffEntry !== undefined && sourceStaffEntry.Link !== undefined && linkedNotes !== undefined && !linkedNotes.indexOf(note) !== -1)
  368. continue;
  369. let graphicalNote: GraphicalNote;
  370. let numberOfDots: number = note.calculateNumberOfNeededDots();
  371. if (grace)
  372. graphicalNote = this.symbolFactory.createGraceNote(note, numberOfDots, graphicalStaffEntry, activeClef, octaveShiftValue);
  373. else {
  374. graphicalNote = this.symbolFactory.createNote(note, numberOfDots, graphicalStaffEntry, activeClef, octaveShiftValue);
  375. }
  376. if (note.NoteTie !== undefined) {
  377. MusicSheetCalculator.addTieToTieTimestampsDict(tieTimestampListDict, note);
  378. }
  379. if (note.Pitch !== undefined) {
  380. this.checkNoteForAccidental(graphicalNote, accidentalCalculator, activeClef, octaveShiftValue, grace);
  381. }
  382. this.resetYPositionForLeadSheet(graphicalNote.PositionAndShape);
  383. graphicalStaffEntry.addGraphicalNoteToListAtCorrectYPosition(graphicalNotes, graphicalNote);
  384. graphicalStaffEntry.PositionAndShape.ChildElements.push(graphicalNote.PositionAndShape);
  385. graphicalNote.PositionAndShape.calculateBoundingBox();
  386. if (!this.leadSheet) {
  387. if (note.NoteBeam !== undefined)
  388. this.handleBeam(graphicalNote, note.NoteBeam, openBeams);
  389. if (note.NoteTuplet !== undefined)
  390. this.handleTuplet(graphicalNote, note.NoteTuplet, openTuplets);
  391. }
  392. }
  393. if (voiceEntry.Articulations.length > 0)
  394. this.handleVoiceEntryArticulations(voiceEntry.Articulations, voiceEntry, graphicalStaffEntry);
  395. if (voiceEntry.TechnicalInstructions.length > 0)
  396. this.checkVoiceEntriesForTechnicalInstructions(voiceEntry, graphicalStaffEntry);
  397. if (voiceEntry.LyricsEntries.length > 0)
  398. this.handleVoiceEntryLyrics(voiceEntry.LyricsEntries, voiceEntry, graphicalStaffEntry, openLyricWords);
  399. if (voiceEntry.OrnamentContainer !== undefined)
  400. this.handleVoiceEntryOrnaments(voiceEntry.OrnamentContainer, voiceEntry, graphicalStaffEntry);
  401. return octaveShiftValue;
  402. }
  403. protected handleVoiceEntryGraceNotes(graceEntries: VoiceEntry[], graphicalGraceEntries: GraphicalStaffEntry[], graphicalStaffEntry: GraphicalStaffEntry,
  404. accidentalCalculator: AccidentalCalculator, activeClef: ClefInstruction,
  405. octaveShiftValue: OctaveEnum, lyricWords: LyricWord[],
  406. tieTimestampListDict: Dictionary<Tie, Fraction[]>,
  407. tuplets: Tuplet[], beams: Beam[]): void {
  408. if (graceEntries !== undefined) {
  409. for (let idx: number = 0, len: number = graceEntries.length; idx < len; ++idx) {
  410. let graceVoiceEntry: VoiceEntry = graceEntries[idx];
  411. let graceStaffEntry: GraphicalStaffEntry = this.symbolFactory.createGraceStaffEntry(graphicalStaffEntry,
  412. graphicalStaffEntry.parentMeasure);
  413. graphicalGraceEntries.push(graceStaffEntry);
  414. graphicalStaffEntry.PositionAndShape.ChildElements.push(graceStaffEntry.PositionAndShape);
  415. this.handleVoiceEntry(graceVoiceEntry, graceStaffEntry, accidentalCalculator, lyricWords,
  416. tieTimestampListDict, activeClef, tuplets,
  417. beams, octaveShiftValue, true);
  418. }
  419. }
  420. }
  421. protected handleOpenTies(measure: StaffMeasure, beams: Beam[], tieTimestampListDict: Dictionary<Tie, Fraction[]>,
  422. activeClef: ClefInstruction, octaveShiftParams: OctaveShiftParams): void {
  423. for (let m: number = tieTimestampListDict.length - 1; m >= 0; m--) {
  424. let keyValuePair: KeyValuePair<Tie, Fraction[]> = tieTimestampListDict.ElementAt(m);
  425. let openTie: Tie = keyValuePair.Key;
  426. let tieTimestamps: Fraction[] = keyValuePair.Value;
  427. let absoluteTimestamp: Fraction = undefined;
  428. let k: number;
  429. for (; k < tieTimestamps.length; k++) {
  430. if (!openTie.NoteHasBeenCreated[k]) {
  431. absoluteTimestamp = tieTimestamps[k];
  432. if (absoluteTimestamp >= (measure.parentSourceMeasure.AbsoluteTimestamp + measure.parentSourceMeasure.Duration))
  433. continue;
  434. let graphicalStaffEntry: GraphicalStaffEntry = undefined;
  435. if (absoluteTimestamp !== undefined) {
  436. for (let idx: number = 0, len: number = measure.staffEntries.length; idx < len; ++idx) {
  437. let gse: GraphicalStaffEntry = measure.staffEntries[idx];
  438. if (gse.getAbsoluteTimestamp() === absoluteTimestamp) {
  439. graphicalStaffEntry = gse;
  440. break;
  441. }
  442. }
  443. if (graphicalStaffEntry === undefined) {
  444. graphicalStaffEntry = this.createStaffEntryForTieNote(measure, absoluteTimestamp, openTie);
  445. }
  446. }
  447. if (graphicalStaffEntry !== undefined) {
  448. let octaveShiftValue: OctaveEnum = OctaveEnum.NONE;
  449. if (octaveShiftParams !== undefined) {
  450. if (graphicalStaffEntry.getAbsoluteTimestamp() >= octaveShiftParams.getAbsoluteStartTimestamp && graphicalStaffEntry.getAbsoluteTimestamp() <= octaveShiftParams.getAbsoluteEndTimestamp) {
  451. octaveShiftValue = octaveShiftParams.getOpenOctaveShift.Type;
  452. }
  453. }
  454. let isLastTieNote: boolean = k === tieTimestamps.length - 1;
  455. let tieFraction: Fraction = openTie.Fractions[k];
  456. let numberOfDots: number = openTie.Start.calculateNumberOfNeededDots();
  457. this.createGraphicalTieNote(beams, activeClef, octaveShiftValue, graphicalStaffEntry, tieFraction, numberOfDots, openTie, isLastTieNote);
  458. let tieStartNote: Note = openTie.Start;
  459. if (isLastTieNote && tieStartNote.ParentVoiceEntry.Articulations.length === 1 && tieStartNote.ParentVoiceEntry.Articulations[0] === ArticulationEnum.fermata) {
  460. this.symbolFactory.addFermataAtTiedEndNote(tieStartNote, graphicalStaffEntry);
  461. }
  462. openTie.NoteHasBeenCreated[k] = true;
  463. if (openTie.allGraphicalNotesHaveBeenCreated())
  464. tieTimestampListDict.Remove(openTie);
  465. }
  466. }
  467. }
  468. }
  469. }
  470. protected resetYPositionForLeadSheet(psi: BoundingBox): void {
  471. if (this.leadSheet) {
  472. psi.RelativePosition = new PointF2D(psi.RelativePosition.x, 0.0);
  473. }
  474. }
  475. protected layoutVoiceEntries(graphicalStaffEntry: GraphicalStaffEntry): void {
  476. graphicalStaffEntry.PositionAndShape.RelativePosition = new PointF2D(0.0, 0.0);
  477. let isGraceStaffEntry: boolean = graphicalStaffEntry.staffEntryParent !== undefined;
  478. if (!this.leadSheet) {
  479. let graphicalStaffEntryNotes: GraphicalNote[][] = graphicalStaffEntry.notes;
  480. for (let idx4: number = 0, len4: number = graphicalStaffEntryNotes.length; idx4 < len4; ++idx4) {
  481. let graphicalNotes: GraphicalNote[] = graphicalStaffEntryNotes[idx4];
  482. if (graphicalNotes.length === 0)
  483. continue;
  484. let voiceEntry: VoiceEntry = graphicalNotes[0].sourceNote.ParentVoiceEntry;
  485. let hasPitchedNote: boolean = graphicalNotes[0].sourceNote.Pitch !== undefined;
  486. this.layoutVoiceEntry(voiceEntry, graphicalNotes, graphicalStaffEntry, hasPitchedNote, isGraceStaffEntry);
  487. }
  488. }
  489. }
  490. protected maxInstrNameLabelLength(): number {
  491. let maxLabelLength: number = 0.0;
  492. let instrumentsArr: Instrument[] = this.graphicalMusicSheet.ParentMusicSheet.Instruments.Where(i => i.Voices.length > 0 && i.Voices[0].Visible);
  493. for (let idx: number = 0, len: number = instrumentsArr.length; idx < len; ++idx) {
  494. let instrument: Instrument = instrumentsArr[idx];
  495. let graphicalLabel: GraphicalLabel = new GraphicalLabel(instrument.NameLabel, this.rules.InstrumentLabelTextHeight, TextAlignment.LeftCenter);
  496. graphicalLabel.setLabelPositionAndShapeBorders();
  497. maxLabelLength = Math.max(maxLabelLength, graphicalLabel.PositionAndShape.MarginSize.width);
  498. }
  499. return maxLabelLength;
  500. }
  501. protected calculateSheetLabelBoundingBoxes(): void {
  502. let musicSheet: MusicSheet = this.graphicalMusicSheet.ParentMusicSheet;
  503. if (musicSheet.Title !== undefined) {
  504. let title: GraphicalLabel = new GraphicalLabel(musicSheet.Title, this.rules.SheetTitleHeight, TextAlignment.CenterBottom);
  505. this.graphicalMusicSheet.Title = title;
  506. title.setLabelPositionAndShapeBorders();
  507. }
  508. if (musicSheet.Subtitle !== undefined) {
  509. let subtitle: GraphicalLabel = new GraphicalLabel(musicSheet.Subtitle, this.rules.SheetSubtitleHeight, TextAlignment.CenterCenter);
  510. this.graphicalMusicSheet.Subtitle = subtitle;
  511. subtitle.setLabelPositionAndShapeBorders();
  512. }
  513. if (musicSheet.Composer !== undefined) {
  514. let composer: GraphicalLabel = new GraphicalLabel(musicSheet.Composer, this.rules.SheetComposerHeight, TextAlignment.RightCenter);
  515. this.graphicalMusicSheet.Composer = composer;
  516. composer.setLabelPositionAndShapeBorders();
  517. }
  518. if (musicSheet.Lyricist !== undefined) {
  519. let lyricist: GraphicalLabel = new GraphicalLabel(musicSheet.Lyricist, this.rules.SheetAuthorHeight, TextAlignment.LeftCenter);
  520. this.graphicalMusicSheet.Lyricist = lyricist;
  521. lyricist.setLabelPositionAndShapeBorders();
  522. }
  523. }
  524. protected checkMeasuresForWholeRestNotes(): void {
  525. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  526. let musicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  527. for (let idx2: number = 0, len2: number = musicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  528. let musicSystem: MusicSystem = musicPage.MusicSystems[idx2];
  529. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  530. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  531. for (let idx4: number = 0, len4: number = staffLine.Measures.length; idx4 < len4; ++idx4) {
  532. let measure: StaffMeasure = staffLine.Measures[idx4];
  533. if (measure.staffEntries.length === 1) {
  534. let gse: GraphicalStaffEntry = measure.staffEntries[0];
  535. if (gse.notes.length > 0 && gse.notes[0].length > 0) {
  536. let graphicalNote: GraphicalNote = gse.notes[0][0];
  537. if (graphicalNote.sourceNote.Pitch === undefined && graphicalNote.sourceNote.length >= new Fraction(1, 2)) {
  538. this.layoutMeasureWithWholeRest(graphicalNote, gse, measure);
  539. }
  540. }
  541. }
  542. }
  543. }
  544. }
  545. }
  546. }
  547. protected optimizeRestNotePlacement(graphicalStaffEntry: GraphicalStaffEntry, measure: StaffMeasure): void {
  548. if (graphicalStaffEntry.notes.length === 0)
  549. return;
  550. let voice1Notes: GraphicalNote[] = graphicalStaffEntry.notes[0];
  551. if (voice1Notes.length === 0)
  552. return;
  553. let voice1Note1: GraphicalNote = voice1Notes[0];
  554. let voice1Note1IsRest: boolean = voice1Note1.sourceNote.Pitch === undefined;
  555. if (graphicalStaffEntry.notes.length === 2) {
  556. let voice2Note1IsRest: boolean = false;
  557. let voice2Notes: GraphicalNote[] = graphicalStaffEntry.notes[1];
  558. if (voice2Notes.length > 0) {
  559. let voice2Note1: GraphicalNote = voice1Notes[0];
  560. voice2Note1IsRest = voice2Note1.sourceNote.Pitch === undefined;
  561. }
  562. if (voice1Note1IsRest && voice2Note1IsRest) {
  563. this.calculateTwoRestNotesPlacementWithCollisionDetection(graphicalStaffEntry);
  564. } else if (voice1Note1IsRest || voice2Note1IsRest) {
  565. this.calculateRestNotePlacementWithCollisionDetectionFromGraphicalNote(graphicalStaffEntry);
  566. }
  567. } else if (voice1Note1IsRest && graphicalStaffEntry !== measure.staffEntries[0] && graphicalStaffEntry !== measure.staffEntries[measure.staffEntries.length - 1]) {
  568. let staffEntryIndex: number = measure.staffEntries.indexOf(graphicalStaffEntry);
  569. let previousStaffEntry: GraphicalStaffEntry = measure.staffEntries[staffEntryIndex - 1];
  570. let nextStaffEntry: GraphicalStaffEntry = measure.staffEntries[staffEntryIndex + 1];
  571. if (previousStaffEntry.notes.length === 1) {
  572. let previousNote: GraphicalNote = previousStaffEntry.notes[0][0];
  573. if (previousNote.sourceNote.NoteBeam !== undefined && nextStaffEntry.notes.length === 1) {
  574. let nextNote: GraphicalNote = nextStaffEntry.notes[0][0];
  575. if (nextNote.sourceNote.NoteBeam !== undefined && previousNote.sourceNote.NoteBeam === nextNote.sourceNote.NoteBeam) {
  576. this.calculateRestNotePlacementWithinGraphicalBeam(graphicalStaffEntry, voice1Note1,
  577. previousNote,
  578. nextStaffEntry,
  579. nextNote);
  580. graphicalStaffEntry.PositionAndShape.calculateBoundingBox();
  581. }
  582. }
  583. }
  584. }
  585. }
  586. protected getRelativePositionInStaffLineFromTimestamp(timestamp: Fraction, verticalIndex: number, staffLine: StaffLine,
  587. multiStaffInstrument: boolean, firstVisibleMeasureRelativeX: number = 0.0): PointF2D {
  588. let relative: PointF2D = new PointF2D();
  589. let leftStaffEntry: GraphicalStaffEntry = undefined;
  590. let rightStaffEntry: GraphicalStaffEntry = undefined;
  591. let numEntries: number = this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length;
  592. let index: number = this.graphicalMusicSheet.GetInterpolatedIndexInVerticalContainers(timestamp);
  593. let leftIndex: number = <number>Math.min(Math.floor(index), numEntries - 1);
  594. let rightIndex: number = <number>Math.min(Math.ceil(index), numEntries - 1);
  595. if (leftIndex < 0 || verticalIndex < 0)
  596. return relative;
  597. leftStaffEntry = this.getFirstLeftNotNullStaffEntryFromContainer(leftIndex, verticalIndex, multiStaffInstrument);
  598. rightStaffEntry = this.getFirstRightNotNullStaffEntryFromContainer(rightIndex, verticalIndex, multiStaffInstrument);
  599. if (leftStaffEntry !== undefined && rightStaffEntry !== undefined) {
  600. let measureRelativeX: number = leftStaffEntry.parentMeasure.PositionAndShape.RelativePosition.x;
  601. if (firstVisibleMeasureRelativeX > 0)
  602. measureRelativeX = firstVisibleMeasureRelativeX;
  603. let leftX: number = leftStaffEntry.PositionAndShape.RelativePosition.x + measureRelativeX;
  604. let rightX: number = rightStaffEntry.PositionAndShape.RelativePosition.x + rightStaffEntry.parentMeasure.PositionAndShape.RelativePosition.x;
  605. if (firstVisibleMeasureRelativeX > 0)
  606. rightX = rightStaffEntry.PositionAndShape.RelativePosition.x + measureRelativeX;
  607. let timestampQuotient: number = 0.0;
  608. if (leftStaffEntry !== rightStaffEntry) {
  609. let leftTimestamp: Fraction = leftStaffEntry.getAbsoluteTimestamp();
  610. let rightTimestamp: Fraction = rightStaffEntry.getAbsoluteTimestamp();
  611. let leftDifference: Fraction = new Fraction(timestamp - leftTimestamp);
  612. timestampQuotient = leftDifference.RealValue / (rightTimestamp - leftTimestamp).RealValue;
  613. }
  614. if (leftStaffEntry.parentMeasure.ParentStaffLine !== rightStaffEntry.parentMeasure.ParentStaffLine) {
  615. if (leftStaffEntry.parentMeasure.ParentStaffLine === staffLine)
  616. rightX = staffLine.PositionAndShape.Size.width;
  617. else leftX = staffLine.PositionAndShape.RelativePosition.x;
  618. }
  619. relative = new PointF2D(leftX + (rightX - leftX) * timestampQuotient, 0.0);
  620. }
  621. return relative;
  622. }
  623. protected getRelativeXPositionFromTimestamp(timestamp: Fraction): number {
  624. let numEntries: number = this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length;
  625. let index: number = this.graphicalMusicSheet.GetInterpolatedIndexInVerticalContainers(timestamp);
  626. let discreteIndex: number = <number>Math.max(0, Math.min(Math.round(index), numEntries - 1));
  627. let gse: GraphicalStaffEntry = this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[discreteIndex].getFirstNonNullStaffEntry();
  628. let posX: number = gse.PositionAndShape.RelativePosition.x + gse.parentMeasure.PositionAndShape.RelativePosition.x;
  629. return posX;
  630. }
  631. private createAccidentalCalculators(): AccidentalCalculator[] {
  632. let accidentalCalculators: AccidentalCalculator[] = [];
  633. let firstSourceMeasure: SourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.getFirstSourceMeasure();
  634. if (firstSourceMeasure !== undefined) {
  635. for (let i: number = 0; i < firstSourceMeasure.CompleteNumberOfStaves; i++) {
  636. for (let idx: number = 0, len: number = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions.length; idx < len; ++idx) {
  637. let abstractNotationInstruction: AbstractNotationInstruction = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions[idx];
  638. if (abstractNotationInstruction instanceof KeyInstruction) {
  639. let keyInstruction: KeyInstruction = <KeyInstruction>abstractNotationInstruction;
  640. let accidentalCalculator: AccidentalCalculator = new AccidentalCalculator(this.symbolFactory);
  641. accidentalCalculator.ActiveKeyInstruction = keyInstruction;
  642. accidentalCalculators.push(accidentalCalculator);
  643. }
  644. }
  645. }
  646. }
  647. return accidentalCalculators;
  648. }
  649. private calculateVerticalContainersList(): void {
  650. let numberOfEntries: number = this.graphicalMusicSheet.MeasureList[0].length;
  651. for (let i: number = 0; i < this.graphicalMusicSheet.MeasureList.length; i++) {
  652. for (let j: number = 0; j < numberOfEntries; j++) {
  653. let measure: StaffMeasure = this.graphicalMusicSheet.MeasureList[i][j];
  654. for (let idx: number = 0, len: number = measure.staffEntries.length; idx < len; ++idx) {
  655. let graphicalStaffEntry: GraphicalStaffEntry = measure.staffEntries[idx];
  656. let verticalContainer: VerticalGraphicalStaffEntryContainer = this.graphicalMusicSheet.getOrCreateVerticalContainer(graphicalStaffEntry.getAbsoluteTimestamp());
  657. if (verticalContainer !== undefined) {
  658. verticalContainer.StaffEntries[j] = graphicalStaffEntry;
  659. graphicalStaffEntry.parentVerticalContainer = verticalContainer;
  660. } else {
  661. }
  662. }
  663. }
  664. }
  665. }
  666. private setIndecesToVerticalGraphicalContainers(): void {
  667. for (let i: number = 0; i < this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length; i++)
  668. this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].Index = i;
  669. }
  670. private createGraphicalMeasuresForSourceMeasure(sourceMeasure: SourceMeasure, accidentalCalculators: AccidentalCalculator[],
  671. openLyricWords: LyricWord[],
  672. tieTimestampListDictList: List<Dictionary<Tie, Fraction[]>>,
  673. openOctaveShifts: OctaveShiftParams[], activeClefs: ClefInstruction[]): StaffMeasure[] {
  674. this.initStaffMeasuresCreation();
  675. let verticalMeasureList: StaffMeasure[] = [];
  676. let openBeams: Beam[] = [];
  677. let openTuplets: Tuplet[] = [];
  678. let staffEntryLinks: StaffEntryLink[] = [];
  679. for (let staffIndex: number = 0; staffIndex < sourceMeasure.CompleteNumberOfStaves; staffIndex++) {
  680. let measure: StaffMeasure = this.createGraphicalMeasure(sourceMeasure, tieTimestampListDictList[staffIndex], openTuplets, openBeams, accidentalCalculators[staffIndex], activeClefs, openOctaveShifts, openLyricWords, staffIndex, staffEntryLinks);
  681. verticalMeasureList.push(measure);
  682. }
  683. this.graphicalMusicSheet.SourceToGraphicalMeasureLinks[sourceMeasure] = verticalMeasureList;
  684. return verticalMeasureList;
  685. }
  686. private createGraphicalMeasure(sourceMeasure: SourceMeasure, tieTimestampListDict: Dictionary<Tie, Fraction[]>, openTuplets: Tuplet[], openBeams: Beam[],
  687. accidentalCalculator: AccidentalCalculator, activeClefs: ClefInstruction[], openOctaveShifts: OctaveShiftParams[], openLyricWords: LyricWord[], staffIndex: number,
  688. staffEntryLinks: StaffEntryLink[]): StaffMeasure {
  689. let staff: Staff = this.graphicalMusicSheet.ParentMusicSheet.getStaffFromIndex(staffIndex);
  690. let measure: StaffMeasure = this.symbolFactory.createStaffMeasure(sourceMeasure, staff);
  691. measure.hasError = sourceMeasure.getErrorInMeasure(staffIndex);
  692. if (sourceMeasure.FirstInstructionsStaffEntries[staffIndex] !== undefined) {
  693. for (let idx: number = 0, len: number = sourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions.length; idx < len; ++idx) {
  694. let instruction: AbstractNotationInstruction = sourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[idx];
  695. if (instruction instanceof KeyInstruction) {
  696. let key: KeyInstruction = new KeyInstruction(<KeyInstruction>instruction);
  697. if (this.graphicalMusicSheet.ParentMusicSheet.Transpose !== 0 && measure.ParentStaff.ParentInstrument.MidiInstrumentId !== Common.Enums.MidiInstrument.Percussion && MusicSheetCalculator.TransposeCalculator !== undefined)
  698. MusicSheetCalculator.TransposeCalculator.TransposeKey(key,
  699. this.graphicalMusicSheet.ParentMusicSheet.Transpose);
  700. accidentalCalculator.ActiveKeyInstruction = key;
  701. }
  702. }
  703. }
  704. for (let idx: number = 0, len: number = sourceMeasure.StaffLinkedExpressions[staffIndex].length; idx < len; ++idx) {
  705. let multiExpression: MultiExpression = sourceMeasure.StaffLinkedExpressions[staffIndex][idx];
  706. if (multiExpression.OctaveShiftStart !== undefined) {
  707. let openOctaveShift: OctaveShift = multiExpression.OctaveShiftStart;
  708. openOctaveShifts[staffIndex] = new OctaveShiftParams(openOctaveShift, multiExpression.AbsoluteTimestamp,
  709. openOctaveShift.ParentEndMultiExpression.AbsoluteTimestamp);
  710. }
  711. }
  712. for (let entryIndex: number = 0; entryIndex < sourceMeasure.VerticalSourceStaffEntryContainers.length; entryIndex++) {
  713. if (sourceMeasure.VerticalSourceStaffEntryContainers[entryIndex][staffIndex] !== undefined) {
  714. let sourceStaffEntry: SourceStaffEntry = sourceMeasure.VerticalSourceStaffEntryContainers[entryIndex][staffIndex];
  715. for (let idx: number = 0, len: number = sourceStaffEntry.Instructions.length; idx < len; ++idx) {
  716. let abstractNotationInstruction: AbstractNotationInstruction = sourceStaffEntry.Instructions[idx];
  717. if (abstractNotationInstruction instanceof ClefInstruction)
  718. activeClefs[staffIndex] = <ClefInstruction>abstractNotationInstruction;
  719. }
  720. let graphicalStaffEntry: GraphicalStaffEntry = this.symbolFactory.createStaffEntry(sourceStaffEntry, measure);
  721. if (measure.staffEntries.length > entryIndex) {
  722. measure.addGraphicalStaffEntryAtTimestamp(graphicalStaffEntry);
  723. } else measure.addGraphicalStaffEntry(graphicalStaffEntry);
  724. let linkedNotes: Note[] = [];
  725. if (sourceStaffEntry.Link !== undefined) {
  726. sourceStaffEntry.findLinkedNotes(linkedNotes);
  727. this.handleStaffEntryLink(graphicalStaffEntry, staffEntryLinks);
  728. }
  729. let octaveShiftValue: OctaveEnum = OctaveEnum.NONE;
  730. if (openOctaveShifts[staffIndex] !== undefined) {
  731. let octaveShiftParams: OctaveShiftParams = openOctaveShifts[staffIndex];
  732. if (sourceStaffEntry.AbsoluteTimestamp >= octaveShiftParams.getAbsoluteStartTimestamp && sourceStaffEntry.AbsoluteTimestamp <= octaveShiftParams.getAbsoluteEndTimestamp) {
  733. octaveShiftValue = octaveShiftParams.getOpenOctaveShift.Type;
  734. }
  735. }
  736. for (let idx: number = 0, len: number = sourceStaffEntry.VoiceEntries.length; idx < len; ++idx) {
  737. let voiceEntry: VoiceEntry = sourceStaffEntry.VoiceEntries[idx];
  738. this.handleVoiceEntryGraceNotes(voiceEntry.graceVoiceEntriesBefore, graphicalStaffEntry.graceStaffEntriesBefore, graphicalStaffEntry, accidentalCalculator, activeClefs[staffIndex], octaveShiftValue, openLyricWords,
  739. tieTimestampListDict,
  740. openTuplets,
  741. openBeams);
  742. octaveShiftValue = this.handleVoiceEntry(voiceEntry, graphicalStaffEntry,
  743. accidentalCalculator, openLyricWords,
  744. tieTimestampListDict,
  745. activeClefs[staffIndex], openTuplets,
  746. openBeams, octaveShiftValue, false, linkedNotes,
  747. sourceStaffEntry);
  748. this.handleVoiceEntryGraceNotes(voiceEntry.graceVoiceEntriesAfter, graphicalStaffEntry.graceStaffEntriesAfter, graphicalStaffEntry, accidentalCalculator, activeClefs[staffIndex], octaveShiftValue, openLyricWords,
  749. tieTimestampListDict,
  750. openTuplets,
  751. openBeams);
  752. }
  753. if (sourceStaffEntry.Instructions.length > 0) {
  754. let clefInstruction: ClefInstruction = <ClefInstruction>sourceStaffEntry.Instructions[0];
  755. this.symbolFactory.createInStaffClef(graphicalStaffEntry, clefInstruction);
  756. }
  757. if (sourceStaffEntry.ChordContainer !== undefined) {
  758. sourceStaffEntry.ParentStaff.ParentInstrument.HasChordSymbols = true;
  759. this.symbolFactory.createChordSymbol(sourceStaffEntry, graphicalStaffEntry, this.graphicalMusicSheet.ParentMusicSheet.Transpose);
  760. }
  761. }
  762. }
  763. if (tieTimestampListDict.length > 0) {
  764. this.handleOpenTies(measure, openBeams,
  765. tieTimestampListDict, activeClefs[staffIndex], openOctaveShifts[staffIndex]);
  766. }
  767. accidentalCalculator.doCalculationsAtEndOfMeasure();
  768. if (sourceMeasure.LastInstructionsStaffEntries[staffIndex] !== undefined) {
  769. let lastStaffEntry: SourceStaffEntry = sourceMeasure.LastInstructionsStaffEntries[staffIndex];
  770. for (let idx: number = 0, len: number = lastStaffEntry.Instructions.length; idx < len; ++idx) {
  771. let abstractNotationInstruction: AbstractNotationInstruction = lastStaffEntry.Instructions[idx];
  772. if (abstractNotationInstruction instanceof ClefInstruction)
  773. activeClefs[staffIndex] = <ClefInstruction>abstractNotationInstruction;
  774. }
  775. }
  776. for (let idx: number = 0, len: number = sourceMeasure.StaffLinkedExpressions[staffIndex].length; idx < len; ++idx) {
  777. let multiExpression: MultiExpression = sourceMeasure.StaffLinkedExpressions[staffIndex][idx];
  778. if (multiExpression.OctaveShiftEnd !== undefined && openOctaveShifts[staffIndex] !== undefined && multiExpression.OctaveShiftEnd === openOctaveShifts[staffIndex].getOpenOctaveShift) {
  779. openOctaveShifts[staffIndex] = undefined;
  780. }
  781. }
  782. if (measure.staffEntries.length === 0) {
  783. let sourceStaffEntry: SourceStaffEntry = new SourceStaffEntry(undefined, staff);
  784. let note: Note = new Note(undefined, sourceStaffEntry, Fraction.createFromFraction(sourceMeasure.Duration), undefined);
  785. let graphicalStaffEntry: GraphicalStaffEntry = this.symbolFactory.createStaffEntry(sourceStaffEntry, measure);
  786. measure.addGraphicalStaffEntry(graphicalStaffEntry);
  787. graphicalStaffEntry.relInMeasureTimestamp = new Fraction(0, 1);
  788. let graphicalNotes: GraphicalNote[] = [];
  789. graphicalStaffEntry.notes.push(graphicalNotes);
  790. let numberOfDots: number = note.calculateNumberOfNeededDots();
  791. let graphicalNote: GraphicalNote = this.symbolFactory.createNote(note, numberOfDots, graphicalStaffEntry, new ClefInstruction(ClefEnum.G, 0, 2));
  792. graphicalNotes.push(graphicalNote);
  793. graphicalStaffEntry.PositionAndShape.ChildElements.push(graphicalNote.PositionAndShape);
  794. }
  795. return measure;
  796. }
  797. private calculatePageLabels(page: GraphicalMusicPage): void {
  798. let relative: PointF2D = new PointF2D();
  799. let firstSystemAbsoluteTopMargin: number = 10;
  800. if (page.MusicSystems.length > 0) {
  801. let firstMusicSystem: MusicSystem = page.MusicSystems[0];
  802. firstSystemAbsoluteTopMargin = firstMusicSystem.PositionAndShape.RelativePosition.y + firstMusicSystem.PositionAndShape.BorderTop;
  803. }
  804. if (this.graphicalMusicSheet.Title !== undefined) {
  805. let title: GraphicalLabel = this.graphicalMusicSheet.Title;
  806. title.PositionAndShape.Parent = page.PositionAndShape;
  807. page.PositionAndShape.ChildElements.push(title.PositionAndShape);
  808. relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth / 2;
  809. relative.y = this.rules.TitleTopDistance + this.rules.SheetTitleHeight;
  810. title.PositionAndShape.RelativePosition = relative;
  811. page.Labels.push(title);
  812. }
  813. if (this.graphicalMusicSheet.Subtitle !== undefined) {
  814. let subtitle: GraphicalLabel = this.graphicalMusicSheet.Subtitle;
  815. subtitle.PositionAndShape.Parent = page.PositionAndShape;
  816. page.PositionAndShape.ChildElements.push(subtitle.PositionAndShape);
  817. relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth / 2;
  818. relative.y = this.rules.TitleTopDistance + this.rules.SheetTitleHeight + this.rules.SheetMinimumDistanceBetweenTitleAndSubtitle;
  819. subtitle.PositionAndShape.RelativePosition = relative;
  820. page.Labels.push(subtitle);
  821. }
  822. if (this.graphicalMusicSheet.Composer !== undefined) {
  823. let composer: GraphicalLabel = this.graphicalMusicSheet.Composer;
  824. composer.PositionAndShape.Parent = page.PositionAndShape;
  825. page.PositionAndShape.ChildElements.push(composer.PositionAndShape);
  826. composer.setLabelPositionAndShapeBorders();
  827. relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth - this.rules.PageRightMargin;
  828. relative.y = firstSystemAbsoluteTopMargin - this.rules.SystemComposerDistance;
  829. composer.PositionAndShape.RelativePosition = relative;
  830. page.Labels.push(composer);
  831. }
  832. if (this.graphicalMusicSheet.Lyricist !== undefined) {
  833. let lyricist: GraphicalLabel = this.graphicalMusicSheet.Lyricist;
  834. lyricist.PositionAndShape.Parent = page.PositionAndShape;
  835. page.PositionAndShape.ChildElements.push(lyricist.PositionAndShape);
  836. lyricist.setLabelPositionAndShapeBorders();
  837. relative.x = this.rules.PageLeftMargin;
  838. relative.y = firstSystemAbsoluteTopMargin - this.rules.SystemComposerDistance;
  839. lyricist.PositionAndShape.RelativePosition = relative;
  840. page.Labels.push(lyricist);
  841. }
  842. }
  843. private checkVoiceEntriesForTechnicalInstructions(voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry): void {
  844. for (let idx: number = 0, len: number = voiceEntry.TechnicalInstructions.length; idx < len; ++idx) {
  845. let technicalInstruction: TechnicalInstruction = voiceEntry.TechnicalInstructions[idx];
  846. this.symbolFactory.createGraphicalTechnicalInstruction(technicalInstruction, graphicalStaffEntry);
  847. }
  848. }
  849. private checkNoteForAccidental(graphicalNote: GraphicalNote, accidentalCalculator: AccidentalCalculator, activeClef: ClefInstruction,
  850. octaveEnum: OctaveEnum, grace: boolean = false): void {
  851. let pitch: Pitch = graphicalNote.sourceNote.Pitch;
  852. let transpose: number = this.graphicalMusicSheet.ParentMusicSheet.Transpose;
  853. if (transpose !== 0 && graphicalNote.sourceNote.ParentStaffEntry.ParentStaff.ParentInstrument.MidiInstrumentId !== MidiInstrument.Percussion) {
  854. pitch = graphicalNote.Transpose(accidentalCalculator.ActiveKeyInstruction, activeClef,
  855. transpose, octaveEnum);
  856. if (graphicalNote.sourceNote.NoteTie !== undefined)
  857. graphicalNote.sourceNote.NoteTie.BaseNoteYPosition = graphicalNote.PositionAndShape.RelativePosition.y;
  858. }
  859. graphicalNote.sourceNote.halfTone = pitch.getHalfTone();
  860. let scalingFactor: number = 1.0;
  861. if (grace)
  862. scalingFactor = this.rules.GraceNoteScalingFactor;
  863. accidentalCalculator.checkAccidental(graphicalNote, pitch, grace, scalingFactor);
  864. }
  865. private createStaffEntryForTieNote(measure: StaffMeasure, absoluteTimestamp: Fraction, openTie: Tie): GraphicalStaffEntry {
  866. let graphicalStaffEntry: GraphicalStaffEntry;
  867. graphicalStaffEntry = this.symbolFactory.createStaffEntry(openTie.Start.ParentStaffEntry, measure);
  868. graphicalStaffEntry.relInMeasureTimestamp = new Fraction(absoluteTimestamp - measure.parentSourceMeasure.AbsoluteTimestamp);
  869. this.resetYPositionForLeadSheet(graphicalStaffEntry.PositionAndShape);
  870. measure.addGraphicalStaffEntry(graphicalStaffEntry);
  871. return graphicalStaffEntry;
  872. }
  873. private updateSkyBottomLines(): void {
  874. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  875. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  876. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  877. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  878. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  879. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  880. this.updateSkyBottomLine(staffLine);
  881. }
  882. }
  883. }
  884. }
  885. private handleStaffEntries(): void {
  886. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MeasureList.length; idx < len; ++idx) {
  887. let measures: StaffMeasure[] = this.graphicalMusicSheet.MeasureList[idx];
  888. for (let idx2: number = 0, len2: number = measures.length; idx2 < len2; ++idx2) {
  889. let measure: StaffMeasure = measures[idx2];
  890. for (let idx3: number = 0, len3: number = measure.staffEntries.length; idx3 < len3; ++idx3) {
  891. let graphicalStaffEntry: GraphicalStaffEntry = measure.staffEntries[idx3];
  892. if (graphicalStaffEntry.parentMeasure !== undefined && graphicalStaffEntry.notes.length > 0 && graphicalStaffEntry.notes[0].length > 0) {
  893. this.layoutVoiceEntries(graphicalStaffEntry);
  894. this.layoutStaffEntry(graphicalStaffEntry);
  895. }
  896. }
  897. }
  898. }
  899. }
  900. private createGraphicalTies(): void {
  901. for (let measureIndex: number = 0; measureIndex < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; measureIndex++) {
  902. let sourceMeasure: SourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[measureIndex];
  903. for (let staffIndex: number = 0; staffIndex < sourceMeasure.CompleteNumberOfStaves; staffIndex++) {
  904. for (let j: number = 0; j < sourceMeasure.VerticalSourceStaffEntryContainers.length; j++) {
  905. if (sourceMeasure.VerticalSourceStaffEntryContainers[j][staffIndex] !== undefined) {
  906. let sourceStaffEntry: SourceStaffEntry = sourceMeasure.VerticalSourceStaffEntryContainers[j][staffIndex];
  907. let startStaffEntry: GraphicalStaffEntry = this.graphicalMusicSheet.findGraphicalStaffEntryFromMeasureList(staffIndex, measureIndex, sourceStaffEntry);
  908. for (let idx: number = 0, len: number = sourceStaffEntry.VoiceEntries.length; idx < len; ++idx) {
  909. let voiceEntry: VoiceEntry = sourceStaffEntry.VoiceEntries[idx];
  910. for (let idx2: number = 0, len2: number = voiceEntry.Notes.length; idx2 < len2; ++idx2) {
  911. let note: Note = voiceEntry.Notes[idx2];
  912. if (note.NoteTie !== undefined) {
  913. let tie: Tie = note.NoteTie;
  914. this.handleTie(tie, startStaffEntry, staffIndex, measureIndex);
  915. }
  916. }
  917. }
  918. }
  919. }
  920. }
  921. }
  922. }
  923. private calculateSkyBottomLines(): void {
  924. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  925. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  926. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  927. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  928. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  929. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  930. this.calculateSkyBottomLine(staffLine);
  931. }
  932. }
  933. }
  934. }
  935. private calculateBeams(): void {
  936. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  937. let musicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  938. for (let idx2: number = 0, len2: number = musicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  939. let musicSystem: MusicSystem = musicPage.MusicSystems[idx2];
  940. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  941. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  942. for (let idx4: number = 0, len4: number = staffLine.Measures.length; idx4 < len4; ++idx4) {
  943. let measure: StaffMeasure = staffLine.Measures[idx4];
  944. for (let idx5: number = 0, len5: number = measure.staffEntries.length; idx5 < len5; ++idx5) {
  945. let staffEntry: GraphicalStaffEntry = measure.staffEntries[idx5];
  946. this.layoutBeams(staffEntry);
  947. }
  948. }
  949. }
  950. }
  951. }
  952. }
  953. private calculateStaffEntryArticulationMarks(): void {
  954. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  955. let page: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  956. for (let idx2: number = 0, len2: number = page.MusicSystems.length; idx2 < len2; ++idx2) {
  957. let system: MusicSystem = page.MusicSystems[idx2];
  958. for (let idx3: number = 0, len3: number = system.StaffLines.length; idx3 < len3; ++idx3) {
  959. let line: StaffLine = system.StaffLines[idx3];
  960. for (let idx4: number = 0, len4: number = line.Measures.length; idx4 < len4; ++idx4) {
  961. let measure: StaffMeasure = line.Measures[idx4];
  962. for (let idx5: number = 0, len5: number = measure.staffEntries.length; idx5 < len5; ++idx5) {
  963. let graphicalStaffEntry: GraphicalStaffEntry = measure.staffEntries[idx5];
  964. for (let idx6: number = 0, len6: number = graphicalStaffEntry.sourceStaffEntry.VoiceEntries.length; idx6 < len6; ++idx6) {
  965. let voiceEntry: VoiceEntry = graphicalStaffEntry.sourceStaffEntry.VoiceEntries[idx6];
  966. if (voiceEntry.Articulations.length > 0)
  967. this.layoutArticulationMarks(voiceEntry.Articulations, voiceEntry, graphicalStaffEntry);
  968. }
  969. }
  970. }
  971. }
  972. }
  973. }
  974. }
  975. private calculateOrnaments(): void {
  976. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  977. let page: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  978. for (let idx2: number = 0, len2: number = page.MusicSystems.length; idx2 < len2; ++idx2) {
  979. let system: MusicSystem = page.MusicSystems[idx2];
  980. for (let idx3: number = 0, len3: number = system.StaffLines.length; idx3 < len3; ++idx3) {
  981. let line: StaffLine = system.StaffLines[idx3];
  982. for (let idx4: number = 0, len4: number = line.Measures.length; idx4 < len4; ++idx4) {
  983. let measure: StaffMeasure = line.Measures[idx4];
  984. for (let idx5: number = 0, len5: number = measure.staffEntries.length; idx5 < len5; ++idx5) {
  985. let graphicalStaffEntry: GraphicalStaffEntry = measure.staffEntries[idx5];
  986. for (let idx6: number = 0, len6: number = graphicalStaffEntry.sourceStaffEntry.VoiceEntries.length; idx6 < len6; ++idx6) {
  987. let voiceEntry: VoiceEntry = graphicalStaffEntry.sourceStaffEntry.VoiceEntries[idx6];
  988. if (voiceEntry.OrnamentContainer !== undefined) {
  989. if (voiceEntry.hasTie() && graphicalStaffEntry.relInMeasureTimestamp !== voiceEntry.Timestamp)
  990. continue;
  991. this.layoutOrnament(voiceEntry.OrnamentContainer, voiceEntry, graphicalStaffEntry);
  992. if (!(this.staffEntriesWithOrnaments.indexOf(graphicalStaffEntry) !== -1))
  993. this.staffEntriesWithOrnaments.push(graphicalStaffEntry);
  994. }
  995. }
  996. }
  997. }
  998. }
  999. }
  1000. }
  1001. }
  1002. private optimizeRestPlacement(): void {
  1003. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  1004. let page: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  1005. for (let idx2: number = 0, len2: number = page.MusicSystems.length; idx2 < len2; ++idx2) {
  1006. let system: MusicSystem = page.MusicSystems[idx2];
  1007. for (let idx3: number = 0, len3: number = system.StaffLines.length; idx3 < len3; ++idx3) {
  1008. let line: StaffLine = system.StaffLines[idx3];
  1009. for (let idx4: number = 0, len4: number = line.Measures.length; idx4 < len4; ++idx4) {
  1010. let measure: StaffMeasure = line.Measures[idx4];
  1011. for (let idx5: number = 0, len5: number = measure.staffEntries.length; idx5 < len5; ++idx5) {
  1012. let graphicalStaffEntry: GraphicalStaffEntry = measure.staffEntries[idx5];
  1013. this.optimizeRestNotePlacement(graphicalStaffEntry, measure);
  1014. }
  1015. }
  1016. }
  1017. }
  1018. }
  1019. }
  1020. private calculateTwoRestNotesPlacementWithCollisionDetection(graphicalStaffEntry: GraphicalStaffEntry): void {
  1021. let firstRestNote: GraphicalNote = graphicalStaffEntry.notes[0][0];
  1022. let secondRestNote: GraphicalNote = graphicalStaffEntry.notes[1][0];
  1023. secondRestNote.PositionAndShape.RelativePosition = new PointF2D(0.0, 2.5);
  1024. graphicalStaffEntry.PositionAndShape.calculateAbsolutePositionsRecursiveWithoutTopelement();
  1025. firstRestNote.PositionAndShape.computeNonOverlappingPositionWithMargin(graphicalStaffEntry.PositionAndShape, ColDirEnum.Up,
  1026. new PointF2D(0.0, secondRestNote.PositionAndShape.RelativePosition.y));
  1027. let relative: PointF2D = firstRestNote.PositionAndShape.RelativePosition;
  1028. relative.y -= 1.0;
  1029. firstRestNote.PositionAndShape.RelativePosition = relative;
  1030. graphicalStaffEntry.PositionAndShape.calculateBoundingBox();
  1031. }
  1032. private calculateRestNotePlacementWithCollisionDetectionFromGraphicalNote(graphicalStaffEntry: GraphicalStaffEntry): void {
  1033. let restNote: GraphicalNote;
  1034. let graphicalNotes: GraphicalNote[];
  1035. if (graphicalStaffEntry.notes[0][0].sourceNote.Pitch === undefined) {
  1036. restNote = graphicalStaffEntry.notes[0][0];
  1037. graphicalNotes = graphicalStaffEntry.notes[1];
  1038. } else {
  1039. graphicalNotes = graphicalStaffEntry.notes[0];
  1040. restNote = graphicalStaffEntry.notes[1][0];
  1041. }
  1042. let collision: boolean = false;
  1043. graphicalStaffEntry.PositionAndShape.calculateAbsolutePositionsRecursiveWithoutTopelement();
  1044. for (let idx: number = 0, len: number = graphicalNotes.length; idx < len; ++idx) {
  1045. let graphicalNote: GraphicalNote = graphicalNotes[idx];
  1046. if (restNote.PositionAndShape.marginCollisionDetection(graphicalNote.PositionAndShape)) {
  1047. collision = true;
  1048. break;
  1049. }
  1050. }
  1051. if (collision) {
  1052. if (restNote.sourceNote.ParentVoiceEntry.ParentVoice instanceof LinkedVoice) {
  1053. let bottomBorder: number = graphicalNotes[0].PositionAndShape.BorderMarginBottom + graphicalNotes[0].PositionAndShape.RelativePosition.y;
  1054. restNote.PositionAndShape.RelativePosition = new PointF2D(0.0, bottomBorder - restNote.PositionAndShape.BorderMarginTop + 0.5);
  1055. } else {
  1056. let last: GraphicalNote = graphicalNotes[graphicalNotes.length-1];
  1057. let topBorder: number = last.PositionAndShape.BorderMarginTop + last.PositionAndShape.RelativePosition.y;
  1058. if (graphicalNotes[0].sourceNote.ParentVoiceEntry.ParentVoice instanceof LinkedVoice) {
  1059. restNote.PositionAndShape.RelativePosition = new PointF2D(0.0, topBorder - restNote.PositionAndShape.BorderMarginBottom - 0.5);
  1060. } else {
  1061. let bottomBorder: number = graphicalNotes[0].PositionAndShape.BorderMarginBottom + graphicalNotes[0].PositionAndShape.RelativePosition.y;
  1062. if (bottomBorder < 2.0)
  1063. restNote.PositionAndShape.RelativePosition = new PointF2D(0.0, bottomBorder - restNote.PositionAndShape.BorderMarginTop + 0.5);
  1064. else restNote.PositionAndShape.RelativePosition = new PointF2D(0.0, topBorder - restNote.PositionAndShape.BorderMarginBottom - 0.0);
  1065. }
  1066. }
  1067. }
  1068. graphicalStaffEntry.PositionAndShape.calculateBoundingBox();
  1069. }
  1070. private calculateTieCurves(): void {
  1071. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  1072. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  1073. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  1074. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  1075. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  1076. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  1077. for (let idx4: number = 0, len5: number = staffLine.Measures.length; idx4 < len5; ++idx4) {
  1078. let measure: StaffMeasure = staffLine.Measures[idx4];
  1079. for (let idx6: number = 0, len6: number = measure.staffEntries.length; idx6 < len6; ++idx6) {
  1080. let staffEntry: GraphicalStaffEntry = measure.staffEntries[idx6];
  1081. let graphicalTies: GraphicalTie[] = staffEntry.GraphicalTies;
  1082. for (let idx7: number = 0, len7: number = graphicalTies.length; idx7 < len7; ++idx7) {
  1083. let graphicalTie: GraphicalTie = graphicalTies[idx7];
  1084. if (graphicalTie.StartNote !== undefined && graphicalTie.StartNote.parentStaffEntry === staffEntry) {
  1085. let tieIsAtSystemBreak: boolean = (graphicalTie.StartNote.parentStaffEntry.parentMeasure.ParentStaffLine !== graphicalTie.EndNote.parentStaffEntry.parentMeasure.ParentStaffLine);
  1086. this.layoutGraphicalTie(graphicalTie, tieIsAtSystemBreak);
  1087. }
  1088. }
  1089. }
  1090. }
  1091. }
  1092. }
  1093. }
  1094. }
  1095. private calculateFingering(): void {
  1096. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  1097. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  1098. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  1099. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  1100. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  1101. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  1102. let skyBottomLineCalculator: SkyBottomLineCalculator = new SkyBottomLineCalculator(this.rules);
  1103. for (let idx4: number = 0, len4: number = staffLine.Measures.length; idx4 < len4; ++idx4) {
  1104. let measure: StaffMeasure = staffLine.Measures[idx4];
  1105. let measureRelativePosition: PointF2D = measure.PositionAndShape.RelativePosition;
  1106. for (let idx5: number = 0, len5: number = measure.staffEntries.length; idx5 < len5; ++idx5) {
  1107. let staffEntry: GraphicalStaffEntry = measure.staffEntries[idx5];
  1108. let hasTechnicalInstruction: boolean = false;
  1109. for (let idx6: number = 0, len6: number = staffEntry.sourceStaffEntry.VoiceEntries.length; idx6 < len6; ++idx6) {
  1110. let ve: VoiceEntry = staffEntry.sourceStaffEntry.VoiceEntries[idx6];
  1111. if (ve.TechnicalInstructions.length > 0) {
  1112. hasTechnicalInstruction = true;
  1113. break;
  1114. }
  1115. }
  1116. if (hasTechnicalInstruction) {
  1117. this.layoutFingering(staffLine, skyBottomLineCalculator, staffEntry, measureRelativePosition);
  1118. }
  1119. }
  1120. }
  1121. }
  1122. }
  1123. }
  1124. }
  1125. private calculateLyricsPosition(): void {
  1126. for (let idx: number = 0, len: number = this.graphicalMusicSheet.ParentMusicSheet.Instruments.length; idx < len; ++idx) {
  1127. let instrument: Instrument = this.graphicalMusicSheet.ParentMusicSheet.Instruments[idx];
  1128. if (instrument.HasLyrics && instrument.LyricVersesNumbers.length > 0)
  1129. instrument.LyricVersesNumbers.sort();
  1130. }
  1131. for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
  1132. let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
  1133. for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
  1134. let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
  1135. for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
  1136. let staffLine: StaffLine = musicSystem.StaffLines[idx3];
  1137. this.calculateSingleStaffLineLyricsPosition(staffLine, staffLine.ParentStaff.ParentInstrument.LyricVersesNumbers);
  1138. }
  1139. }
  1140. }
  1141. }
  1142. private calculateDynamicExpressions(): void {
  1143. for (let i: number = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
  1144. let sourceMeasure: SourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
  1145. for (let j: number = 0; j < sourceMeasure.StaffLinkedExpressions.length; j++) {
  1146. if (this.graphicalMusicSheet.MeasureList[i][j].ParentStaff.ParentInstrument.Visible)
  1147. for (let k: number = 0; k < sourceMeasure.StaffLinkedExpressions[j].length; k++)
  1148. if (sourceMeasure.StaffLinkedExpressions[j][k].InstantaniousDynamic !== undefined || (sourceMeasure.StaffLinkedExpressions[j][k].StartingContinuousDynamic !== undefined && sourceMeasure.StaffLinkedExpressions[j][k].StartingContinuousDynamic.StartMultiExpression === sourceMeasure.StaffLinkedExpressions[j][k] && sourceMeasure.StaffLinkedExpressions[j][k].UnknownList.length === 0)) {
  1149. this.calculateDynamicExpressionsForSingleMultiExpression(sourceMeasure.StaffLinkedExpressions[j][k], i, j);
  1150. }
  1151. }
  1152. }
  1153. }
  1154. private calculateOctaveShifts(): void {
  1155. for (let i: number = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
  1156. let sourceMeasure: SourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
  1157. for (let j: number = 0; j < sourceMeasure.StaffLinkedExpressions.length; j++) {
  1158. if (this.graphicalMusicSheet.MeasureList[i][j].ParentStaff.ParentInstrument.Visible)
  1159. for (let k: number = 0; k < sourceMeasure.StaffLinkedExpressions[j].length; k++)
  1160. if ((sourceMeasure.StaffLinkedExpressions[j][k].OctaveShiftStart !== undefined)) {
  1161. this.calculateSingleOctaveShift(sourceMeasure, sourceMeasure.StaffLinkedExpressions[j][k], i, j);
  1162. }
  1163. }
  1164. }
  1165. }
  1166. private getFirstLeftNotNullStaffEntryFromContainer(horizontalIndex: number, verticalIndex: number, multiStaffInstrument: boolean): GraphicalStaffEntry {
  1167. if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex] !== undefined)
  1168. return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex];
  1169. for (let i: number = horizontalIndex - 1; i >= 0; i--)
  1170. if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex] !== undefined)
  1171. return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex];
  1172. return undefined;
  1173. }
  1174. private getFirstRightNotNullStaffEntryFromContainer(horizontalIndex: number, verticalIndex: number, multiStaffInstrument: boolean): GraphicalStaffEntry {
  1175. if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex] !== undefined)
  1176. return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex];
  1177. for (let i: number = horizontalIndex + 1; i < this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length; i++)
  1178. if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex] !== undefined)
  1179. return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex];
  1180. return undefined;
  1181. }
  1182. private calculateWordRepetitionInstructions(): void {
  1183. for (let i: number = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
  1184. let sourceMeasure: SourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
  1185. for (let idx: number = 0, len: number = sourceMeasure.FirstRepetitionInstructions.length; idx < len; ++idx) {
  1186. let instruction: RepetitionInstruction = sourceMeasure.FirstRepetitionInstructions[idx];
  1187. this.calculateWordRepetitionInstruction(instruction, i);
  1188. }
  1189. for (let idx: number = 0, len: number = sourceMeasure.LastRepetitionInstructions.length; idx < len; ++idx) {
  1190. let instruction: RepetitionInstruction = sourceMeasure.LastRepetitionInstructions[idx];
  1191. this.calculateWordRepetitionInstruction(instruction, i);
  1192. }
  1193. }
  1194. }
  1195. private calculateRepetitionEndings(): void {
  1196. let musicsheet: MusicSheet = this.graphicalMusicSheet.ParentMusicSheet;
  1197. for (let idx: number = 0, len: number = musicsheet.Repetitions.length; idx < len; ++idx) {
  1198. let partListEntry: Repetition = musicsheet.Repetitions[idx];
  1199. this.calcGraphicalRepetitionEndingsRecursively(partListEntry);
  1200. }
  1201. }
  1202. private calculateTempoExpressions(): void {
  1203. for (let i: number = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
  1204. let sourceMeasure: SourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
  1205. for (let j: number = 0; j < sourceMeasure.TempoExpressions.length; j++) {
  1206. this.calculateTempoExpressionsForSingleMultiTempoExpression(sourceMeasure, sourceMeasure.TempoExpressions[j], i);
  1207. }
  1208. }
  1209. }
  1210. private calculateMoodAndUnknownExpressions(): void {
  1211. for (let i: number = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
  1212. let sourceMeasure: SourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
  1213. for (let j: number = 0; j < sourceMeasure.StaffLinkedExpressions.length; j++) {
  1214. if (this.graphicalMusicSheet.MeasureList[i][j].ParentStaff.ParentInstrument.Visible)
  1215. for (let k: number = 0; k < sourceMeasure.StaffLinkedExpressions[j].length; k++)
  1216. if ((sourceMeasure.StaffLinkedExpressions[j][k].MoodList.length > 0) || (sourceMeasure.StaffLinkedExpressions[j][k].UnknownList.length > 0)) {
  1217. this.calculateMoodAndUnknownExpression(sourceMeasure.StaffLinkedExpressions[j][k], i, j);
  1218. }
  1219. }
  1220. }
  1221. }
  1222. }