MusicSystemBuilder.js 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. "use strict";
  2. var GraphicalMusicPage_1 = require("./GraphicalMusicPage");
  3. var RhythmInstruction_1 = require("../VoiceData/Instructions/RhythmInstruction");
  4. var KeyInstruction_1 = require("../VoiceData/Instructions/KeyInstruction");
  5. var ClefInstruction_1 = require("../VoiceData/Instructions/ClefInstruction");
  6. var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
  7. var GraphicalLine_1 = require("./GraphicalLine");
  8. var SystemLinesEnum_1 = require("./SystemLinesEnum");
  9. var MusicSheetCalculator_1 = require("./MusicSheetCalculator");
  10. var ClefInstruction_2 = require("../VoiceData/Instructions/ClefInstruction");
  11. var collectionUtil_1 = require("../../Util/collectionUtil");
  12. var SystemLinePosition_1 = require("./SystemLinePosition");
  13. var MusicSystemBuilder = (function () {
  14. function MusicSystemBuilder() {
  15. this.globalSystemIndex = 0;
  16. this.leadSheet = false;
  17. }
  18. MusicSystemBuilder.prototype.initialize = function (graphicalMusicSheet, measureList, numberOfStaffLines, symbolFactory) {
  19. this.leadSheet = graphicalMusicSheet.LeadSheet;
  20. this.graphicalMusicSheet = graphicalMusicSheet;
  21. this.rules = this.graphicalMusicSheet.ParentMusicSheet.rules;
  22. this.measureList = measureList;
  23. this.symbolFactory = symbolFactory;
  24. this.currentMusicPage = this.createMusicPage();
  25. this.currentPageHeight = 0.0;
  26. this.numberOfVisibleStaffLines = numberOfStaffLines;
  27. this.activeRhythm = new Array(this.numberOfVisibleStaffLines);
  28. this.activeKeys = new Array(this.numberOfVisibleStaffLines);
  29. this.activeClefs = new Array(this.numberOfVisibleStaffLines);
  30. this.initializeActiveInstructions(this.measureList[0]);
  31. };
  32. MusicSystemBuilder.prototype.buildMusicSystems = function () {
  33. var previousMeasureEndsSystem = false;
  34. var systemMaxWidth = this.getFullPageSystemWidth();
  35. this.measureListIndex = 0;
  36. this.currentSystemParams = new SystemBuildParameters();
  37. this.currentSystemParams.currentSystem = this.initMusicSystem();
  38. this.layoutSystemStaves();
  39. this.currentSystemParams.currentSystem.createMusicSystemLabel(this.rules.InstrumentLabelTextHeight, this.rules.SystemLabelsRightMargin, this.rules.LabelMarginBorderFactor);
  40. this.currentPageHeight += this.currentSystemParams.currentSystem.PositionAndShape.RelativePosition.y;
  41. var numberOfMeasures = 0;
  42. for (var idx = 0, len = this.measureList.length; idx < len; ++idx) {
  43. if (this.measureList[idx].length > 0) {
  44. numberOfMeasures++;
  45. }
  46. }
  47. while (this.measureListIndex < numberOfMeasures) {
  48. var staffMeasures = this.measureList[this.measureListIndex];
  49. for (var idx = 0, len = staffMeasures.length; idx < len; ++idx) {
  50. staffMeasures[idx].resetLayout();
  51. }
  52. var sourceMeasure = staffMeasures[0].parentSourceMeasure;
  53. var sourceMeasureEndsSystem = sourceMeasure.BreakSystemAfter;
  54. var isSystemStartMeasure = this.currentSystemParams.IsSystemStartMeasure();
  55. var isFirstSourceMeasure = sourceMeasure === this.graphicalMusicSheet.ParentMusicSheet.getFirstSourceMeasure();
  56. var currentMeasureBeginInstructionsWidth = this.rules.MeasureLeftMargin;
  57. var currentMeasureEndInstructionsWidth = 0;
  58. var measureStartLine = this.getMeasureStartLine();
  59. currentMeasureBeginInstructionsWidth += this.getLineWidth(staffMeasures[0], measureStartLine, isSystemStartMeasure);
  60. if (!this.leadSheet) {
  61. currentMeasureBeginInstructionsWidth += this.addBeginInstructions(staffMeasures, isSystemStartMeasure, isFirstSourceMeasure);
  62. currentMeasureEndInstructionsWidth += this.addEndInstructions(staffMeasures);
  63. }
  64. var currentMeasureVarWidth = 0;
  65. for (var i = 0; i < this.numberOfVisibleStaffLines; i++) {
  66. currentMeasureVarWidth = Math.max(currentMeasureVarWidth, staffMeasures[i].minimumStaffEntriesWidth);
  67. }
  68. var measureEndLine = this.getMeasureEndLine();
  69. currentMeasureEndInstructionsWidth += this.getLineWidth(staffMeasures[0], measureEndLine, isSystemStartMeasure);
  70. var nextMeasureBeginInstructionWidth = this.rules.MeasureLeftMargin;
  71. if (this.measureListIndex + 1 < this.measureList.length) {
  72. var nextStaffMeasures = this.measureList[this.measureListIndex + 1];
  73. var nextSourceMeasure = nextStaffMeasures[0].parentSourceMeasure;
  74. if (nextSourceMeasure.hasBeginInstructions()) {
  75. nextMeasureBeginInstructionWidth += this.addBeginInstructions(nextStaffMeasures, false, false);
  76. }
  77. }
  78. var totalMeasureWidth = currentMeasureBeginInstructionsWidth + currentMeasureEndInstructionsWidth + currentMeasureVarWidth;
  79. var measureFitsInSystem = this.currentSystemParams.currentWidth + totalMeasureWidth + nextMeasureBeginInstructionWidth < systemMaxWidth;
  80. if (isSystemStartMeasure || measureFitsInSystem) {
  81. this.addMeasureToSystem(staffMeasures, measureStartLine, measureEndLine, totalMeasureWidth, currentMeasureBeginInstructionsWidth, currentMeasureVarWidth, currentMeasureEndInstructionsWidth);
  82. this.updateActiveClefs(sourceMeasure, staffMeasures);
  83. this.measureListIndex++;
  84. }
  85. else {
  86. this.finalizeCurrentAndCreateNewSystem(staffMeasures, previousMeasureEndsSystem);
  87. }
  88. previousMeasureEndsSystem = sourceMeasureEndsSystem;
  89. }
  90. this.finalizeCurrentAndCreateNewSystem(this.measureList[this.measureList.length - 1], true);
  91. };
  92. MusicSystemBuilder.prototype.setMeasureWidth = function (staffMeasures, width, beginInstrWidth, endInstrWidth) {
  93. for (var idx = 0, len = staffMeasures.length; idx < len; ++idx) {
  94. var measure = staffMeasures[idx];
  95. measure.setWidth(width);
  96. if (beginInstrWidth > 0) {
  97. measure.beginInstructionsWidth = beginInstrWidth;
  98. }
  99. if (endInstrWidth > 0) {
  100. measure.endInstructionsWidth = endInstrWidth;
  101. }
  102. }
  103. };
  104. MusicSystemBuilder.prototype.finalizeCurrentAndCreateNewSystem = function (measures, isPartEndingSystem) {
  105. if (isPartEndingSystem === void 0) { isPartEndingSystem = false; }
  106. this.adaptRepetitionLineWithIfNeeded();
  107. if (!isPartEndingSystem) {
  108. this.checkAndCreateExtraInstructionMeasure(measures);
  109. }
  110. this.stretchMusicSystem(isPartEndingSystem);
  111. if (this.currentPageHeight + this.currentSystemParams.currentSystem.PositionAndShape.Size.height + this.rules.SystemDistance <= this.rules.PageHeight) {
  112. this.currentPageHeight += this.currentSystemParams.currentSystem.PositionAndShape.Size.height + this.rules.SystemDistance;
  113. if (this.currentPageHeight + this.currentSystemParams.currentSystem.PositionAndShape.Size.height
  114. + this.rules.SystemDistance >= this.rules.PageHeight) {
  115. this.currentMusicPage = this.createMusicPage();
  116. this.currentPageHeight = this.rules.PageTopMargin + this.rules.TitleTopDistance;
  117. }
  118. }
  119. else {
  120. this.currentMusicPage = this.createMusicPage();
  121. this.currentPageHeight = this.rules.PageTopMargin + this.rules.TitleTopDistance;
  122. }
  123. this.currentSystemParams = new SystemBuildParameters();
  124. if (this.measureListIndex < this.measureList.length) {
  125. this.currentSystemParams.currentSystem = this.initMusicSystem();
  126. this.layoutSystemStaves();
  127. }
  128. };
  129. MusicSystemBuilder.prototype.adaptRepetitionLineWithIfNeeded = function () {
  130. var systemMeasures = this.currentSystemParams.systemMeasures;
  131. if (systemMeasures.length >= 1) {
  132. var measures = this.currentSystemParams.currentSystem.GraphicalMeasures[this.currentSystemParams.currentSystem.GraphicalMeasures.length - 1];
  133. var measureParams = systemMeasures[systemMeasures.length - 1];
  134. var diff = 0.0;
  135. if (measureParams.endLine === SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) {
  136. measureParams.endLine = SystemLinesEnum_1.SystemLinesEnum.DotsThinBold;
  137. diff = measures[0].getLineWidth(SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) / 2 - measures[0].getLineWidth(SystemLinesEnum_1.SystemLinesEnum.DotsThinBold);
  138. }
  139. this.currentSystemParams.currentSystemFixWidth -= diff;
  140. for (var idx = 0, len = measures.length; idx < len; ++idx) {
  141. var measure = measures[idx];
  142. measure.endInstructionsWidth -= diff;
  143. }
  144. }
  145. };
  146. MusicSystemBuilder.prototype.addMeasureToSystem = function (staffMeasures, measureStartLine, measureEndLine, totalMeasureWidth, currentMeasureBeginInstructionsWidth, currentVarWidth, currentMeasureEndInstructionsWidth) {
  147. this.currentSystemParams.systemMeasures.push({ beginLine: measureStartLine, endLine: measureEndLine });
  148. this.setMeasureWidth(staffMeasures, totalMeasureWidth, currentMeasureBeginInstructionsWidth, currentMeasureEndInstructionsWidth);
  149. this.addStaveMeasuresToSystem(staffMeasures);
  150. this.currentSystemParams.currentWidth += totalMeasureWidth;
  151. this.currentSystemParams.currentSystemFixWidth += currentMeasureBeginInstructionsWidth + currentMeasureEndInstructionsWidth;
  152. this.currentSystemParams.currentSystemVarWidth += currentVarWidth;
  153. this.currentSystemParams.systemMeasureIndex++;
  154. };
  155. MusicSystemBuilder.prototype.createMusicPage = function () {
  156. var page = new GraphicalMusicPage_1.GraphicalMusicPage(this.graphicalMusicSheet);
  157. this.graphicalMusicSheet.MusicPages.push(page);
  158. page.PositionAndShape.BorderLeft = 0.0;
  159. page.PositionAndShape.BorderRight = this.graphicalMusicSheet.ParentMusicSheet.pageWidth;
  160. page.PositionAndShape.BorderTop = 0.0;
  161. page.PositionAndShape.BorderBottom = this.rules.PageHeight;
  162. page.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, 0.0);
  163. return page;
  164. };
  165. MusicSystemBuilder.prototype.initMusicSystem = function () {
  166. var musicSystem = this.symbolFactory.createMusicSystem(this.currentMusicPage, this.globalSystemIndex++);
  167. this.currentMusicPage.MusicSystems.push(musicSystem);
  168. var boundingBox = musicSystem.PositionAndShape;
  169. this.currentMusicPage.PositionAndShape.ChildElements.push(boundingBox);
  170. return musicSystem;
  171. };
  172. MusicSystemBuilder.prototype.getFullPageSystemWidth = function () {
  173. return this.currentMusicPage.PositionAndShape.Size.width - this.rules.PageLeftMargin
  174. - this.rules.PageRightMargin - this.rules.SystemLeftMargin - this.rules.SystemRightMargin;
  175. };
  176. MusicSystemBuilder.prototype.layoutSystemStaves = function () {
  177. var systemWidth = this.getFullPageSystemWidth();
  178. var musicSystem = this.currentSystemParams.currentSystem;
  179. var boundingBox = musicSystem.PositionAndShape;
  180. boundingBox.BorderLeft = 0.0;
  181. boundingBox.BorderRight = systemWidth;
  182. boundingBox.BorderTop = 0.0;
  183. var staffList = [];
  184. var instruments = this.graphicalMusicSheet.ParentMusicSheet.Instruments;
  185. for (var idx = 0, len = instruments.length; idx < len; ++idx) {
  186. var instrument = instruments[idx];
  187. if (instrument.Voices.length === 0 || !instrument.Visible) {
  188. continue;
  189. }
  190. for (var idx2 = 0, len2 = instrument.Staves.length; idx2 < len2; ++idx2) {
  191. var staff = instrument.Staves[idx2];
  192. staffList.push(staff);
  193. }
  194. }
  195. var multiLyrics = false;
  196. if (this.leadSheet) {
  197. for (var idx = 0, len = staffList.length; idx < len; ++idx) {
  198. var staff = staffList[idx];
  199. if (staff.ParentInstrument.LyricVersesNumbers.length > 1) {
  200. multiLyrics = true;
  201. break;
  202. }
  203. }
  204. }
  205. var yOffsetSum = 0;
  206. for (var i = 0; i < staffList.length; i++) {
  207. this.addStaffLineToMusicSystem(musicSystem, yOffsetSum, staffList[i]);
  208. yOffsetSum += this.rules.StaffHeight;
  209. if (i + 1 < staffList.length) {
  210. var yOffset = 0;
  211. if (this.leadSheet && !multiLyrics) {
  212. yOffset = 2.5;
  213. }
  214. else {
  215. if (staffList[i].ParentInstrument === staffList[i + 1].ParentInstrument) {
  216. yOffset = this.rules.BetweenStaffDistance;
  217. }
  218. else {
  219. yOffset = this.rules.StaffDistance;
  220. }
  221. }
  222. yOffsetSum += yOffset;
  223. }
  224. }
  225. boundingBox.BorderBottom = yOffsetSum;
  226. };
  227. MusicSystemBuilder.prototype.addStaffLineToMusicSystem = function (musicSystem, relativeYPosition, staff) {
  228. if (musicSystem !== undefined) {
  229. var staffLine = this.symbolFactory.createStaffLine(musicSystem, staff);
  230. musicSystem.StaffLines.push(staffLine);
  231. var boundingBox = staffLine.PositionAndShape;
  232. musicSystem.PositionAndShape.ChildElements.push(boundingBox);
  233. var relativePosition = new PointF2D_1.PointF2D();
  234. if (musicSystem.Parent.MusicSystems[0] === musicSystem && musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
  235. relativePosition.x = this.rules.FirstSystemMargin;
  236. }
  237. else {
  238. relativePosition.x = 0.0;
  239. }
  240. relativePosition.y = relativeYPosition;
  241. boundingBox.RelativePosition = relativePosition;
  242. if (musicSystem.Parent.MusicSystems[0] === musicSystem && musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
  243. boundingBox.BorderRight = musicSystem.PositionAndShape.Size.width - this.rules.FirstSystemMargin;
  244. }
  245. else {
  246. boundingBox.BorderRight = musicSystem.PositionAndShape.Size.width;
  247. }
  248. boundingBox.BorderLeft = 0.0;
  249. boundingBox.BorderTop = 0.0;
  250. boundingBox.BorderBottom = this.rules.StaffHeight;
  251. for (var i = 0; i < 5; i++) {
  252. var start = new PointF2D_1.PointF2D();
  253. start.x = 0.0;
  254. start.y = i * this.rules.StaffHeight / 4;
  255. var end = new PointF2D_1.PointF2D();
  256. end.x = staffLine.PositionAndShape.Size.width;
  257. end.y = i * this.rules.StaffHeight / 4;
  258. if (this.leadSheet) {
  259. start.y = end.y = 0;
  260. }
  261. staffLine.StaffLines[i] = new GraphicalLine_1.GraphicalLine(start, end, this.rules.StaffLineWidth);
  262. }
  263. }
  264. };
  265. MusicSystemBuilder.prototype.initializeActiveInstructions = function (measureList) {
  266. var firstSourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.getFirstSourceMeasure();
  267. if (firstSourceMeasure !== undefined) {
  268. this.visibleStaffIndices = this.graphicalMusicSheet.getVisibleStavesIndecesFromSourceMeasure(measureList);
  269. for (var i = 0, len = this.visibleStaffIndices.length; i < len; i++) {
  270. var staffIndex = this.visibleStaffIndices[i];
  271. var graphicalMeasure = this.graphicalMusicSheet.getGraphicalMeasureFromSourceMeasureAndIndex(firstSourceMeasure, staffIndex);
  272. this.activeClefs[i] = firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[0];
  273. var keyInstruction = KeyInstruction_1.KeyInstruction.copy(firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[1]);
  274. keyInstruction = this.transposeKeyInstruction(keyInstruction, graphicalMeasure);
  275. this.activeKeys[i] = keyInstruction;
  276. this.activeRhythm[i] = firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[2];
  277. }
  278. }
  279. };
  280. MusicSystemBuilder.prototype.transposeKeyInstruction = function (keyInstruction, graphicalMeasure) {
  281. if (this.graphicalMusicSheet.ParentMusicSheet.Transpose !== 0
  282. && graphicalMeasure.ParentStaff.ParentInstrument.MidiInstrumentId !== ClefInstruction_2.MidiInstrument.Percussion
  283. && MusicSheetCalculator_1.MusicSheetCalculator.transposeCalculator !== undefined) {
  284. MusicSheetCalculator_1.MusicSheetCalculator.transposeCalculator.transposeKey(keyInstruction, this.graphicalMusicSheet.ParentMusicSheet.Transpose);
  285. }
  286. return keyInstruction;
  287. };
  288. MusicSystemBuilder.prototype.addBeginInstructions = function (measures, isSystemFirstMeasure, isFirstSourceMeasure) {
  289. var measureCount = measures.length;
  290. if (measureCount === 0) {
  291. return 0;
  292. }
  293. var totalBeginInstructionLengthX = 0.0;
  294. var sourceMeasure = measures[0].parentSourceMeasure;
  295. for (var idx = 0; idx < measureCount; ++idx) {
  296. var measure = measures[idx];
  297. var staffIndex = this.visibleStaffIndices[idx];
  298. var beginInstructionsStaffEntry = sourceMeasure.FirstInstructionsStaffEntries[staffIndex];
  299. var beginInstructionLengthX = this.AddInstructionsAtMeasureBegin(beginInstructionsStaffEntry, measure, idx, isFirstSourceMeasure, isSystemFirstMeasure);
  300. totalBeginInstructionLengthX = Math.max(totalBeginInstructionLengthX, beginInstructionLengthX);
  301. }
  302. return totalBeginInstructionLengthX;
  303. };
  304. MusicSystemBuilder.prototype.addEndInstructions = function (measures) {
  305. var measureCount = measures.length;
  306. if (measureCount === 0) {
  307. return 0;
  308. }
  309. var totalEndInstructionLengthX = 0.5;
  310. var sourceMeasure = measures[0].parentSourceMeasure;
  311. for (var idx = 0; idx < measureCount; idx++) {
  312. var measure = measures[idx];
  313. var staffIndex = this.visibleStaffIndices[idx];
  314. var endInstructionsStaffEntry = sourceMeasure.LastInstructionsStaffEntries[staffIndex];
  315. var endInstructionLengthX = this.addInstructionsAtMeasureEnd(endInstructionsStaffEntry, measure);
  316. totalEndInstructionLengthX = Math.max(totalEndInstructionLengthX, endInstructionLengthX);
  317. }
  318. return totalEndInstructionLengthX;
  319. };
  320. MusicSystemBuilder.prototype.AddInstructionsAtMeasureBegin = function (firstEntry, measure, visibleStaffIdx, isFirstSourceMeasure, isSystemStartMeasure) {
  321. var instructionsLengthX = 0;
  322. var currentClef = undefined;
  323. var currentKey = undefined;
  324. var currentRhythm = undefined;
  325. if (firstEntry !== undefined) {
  326. for (var idx = 0, len = firstEntry.Instructions.length; idx < len; ++idx) {
  327. var abstractNotationInstruction = firstEntry.Instructions[idx];
  328. if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
  329. currentClef = abstractNotationInstruction;
  330. }
  331. else if (abstractNotationInstruction instanceof KeyInstruction_1.KeyInstruction) {
  332. currentKey = abstractNotationInstruction;
  333. }
  334. else if (abstractNotationInstruction instanceof RhythmInstruction_1.RhythmInstruction) {
  335. currentRhythm = abstractNotationInstruction;
  336. }
  337. }
  338. }
  339. if (isSystemStartMeasure) {
  340. if (currentClef === undefined) {
  341. currentClef = this.activeClefs[visibleStaffIdx];
  342. }
  343. if (currentKey === undefined) {
  344. currentKey = this.activeKeys[visibleStaffIdx];
  345. }
  346. if (isFirstSourceMeasure && currentRhythm === undefined) {
  347. currentRhythm = this.activeRhythm[visibleStaffIdx];
  348. }
  349. }
  350. var clefAdded = false;
  351. var keyAdded = false;
  352. var rhythmAdded = false;
  353. if (currentClef !== undefined) {
  354. measure.addClefAtBegin(currentClef);
  355. clefAdded = true;
  356. }
  357. else {
  358. currentClef = this.activeClefs[visibleStaffIdx];
  359. }
  360. if (currentKey !== undefined) {
  361. currentKey = this.transposeKeyInstruction(currentKey, measure);
  362. var previousKey = isSystemStartMeasure ? undefined : this.activeKeys[visibleStaffIdx];
  363. measure.addKeyAtBegin(currentKey, previousKey, currentClef);
  364. keyAdded = true;
  365. }
  366. if (currentRhythm !== undefined) {
  367. measure.addRhythmAtBegin(currentRhythm);
  368. rhythmAdded = true;
  369. }
  370. if (clefAdded || keyAdded || rhythmAdded) {
  371. instructionsLengthX += measure.beginInstructionsWidth;
  372. if (rhythmAdded) {
  373. instructionsLengthX += this.rules.RhythmRightMargin;
  374. }
  375. }
  376. return instructionsLengthX;
  377. };
  378. MusicSystemBuilder.prototype.addInstructionsAtMeasureEnd = function (lastEntry, measure) {
  379. if (lastEntry === undefined || lastEntry.Instructions === undefined || lastEntry.Instructions.length === 0) {
  380. return 0;
  381. }
  382. for (var idx = 0, len = lastEntry.Instructions.length; idx < len; ++idx) {
  383. var abstractNotationInstruction = lastEntry.Instructions[idx];
  384. if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
  385. var activeClef = abstractNotationInstruction;
  386. measure.addClefAtEnd(activeClef);
  387. }
  388. }
  389. return this.rules.MeasureRightMargin + measure.endInstructionsWidth;
  390. };
  391. MusicSystemBuilder.prototype.updateActiveClefs = function (measure, staffMeasures) {
  392. for (var visStaffIdx = 0, len = staffMeasures.length; visStaffIdx < len; visStaffIdx++) {
  393. var staffIndex = this.visibleStaffIndices[visStaffIdx];
  394. var firstEntry = measure.FirstInstructionsStaffEntries[staffIndex];
  395. if (firstEntry !== undefined) {
  396. for (var idx = 0, len2 = firstEntry.Instructions.length; idx < len2; ++idx) {
  397. var abstractNotationInstruction = firstEntry.Instructions[idx];
  398. if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
  399. this.activeClefs[visStaffIdx] = abstractNotationInstruction;
  400. }
  401. else if (abstractNotationInstruction instanceof KeyInstruction_1.KeyInstruction) {
  402. this.activeKeys[visStaffIdx] = abstractNotationInstruction;
  403. }
  404. else if (abstractNotationInstruction instanceof RhythmInstruction_1.RhythmInstruction) {
  405. this.activeRhythm[visStaffIdx] = abstractNotationInstruction;
  406. }
  407. }
  408. }
  409. var entries = measure.getEntriesPerStaff(staffIndex);
  410. for (var idx = 0, len2 = entries.length; idx < len2; ++idx) {
  411. var staffEntry = entries[idx];
  412. if (staffEntry.Instructions !== undefined) {
  413. for (var idx2 = 0, len3 = staffEntry.Instructions.length; idx2 < len3; ++idx2) {
  414. var abstractNotationInstruction = staffEntry.Instructions[idx2];
  415. if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
  416. this.activeClefs[visStaffIdx] = abstractNotationInstruction;
  417. }
  418. }
  419. }
  420. }
  421. var lastEntry = measure.LastInstructionsStaffEntries[staffIndex];
  422. if (lastEntry !== undefined) {
  423. var instructions = lastEntry.Instructions;
  424. for (var idx = 0, len3 = instructions.length; idx < len3; ++idx) {
  425. var abstractNotationInstruction = instructions[idx];
  426. if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
  427. this.activeClefs[visStaffIdx] = abstractNotationInstruction;
  428. }
  429. }
  430. }
  431. }
  432. };
  433. MusicSystemBuilder.prototype.checkAndCreateExtraInstructionMeasure = function (measures) {
  434. var firstStaffEntries = measures[0].parentSourceMeasure.FirstInstructionsStaffEntries;
  435. var visibleInstructionEntries = [];
  436. for (var idx = 0, len = measures.length; idx < len; ++idx) {
  437. var measure = measures[idx];
  438. visibleInstructionEntries.push(firstStaffEntries[measure.ParentStaff.idInMusicSheet]);
  439. }
  440. var maxMeasureWidth = 0;
  441. for (var visStaffIdx = 0, len = visibleInstructionEntries.length; visStaffIdx < len; ++visStaffIdx) {
  442. var sse = visibleInstructionEntries[visStaffIdx];
  443. if (sse === undefined) {
  444. continue;
  445. }
  446. var instructions = sse.Instructions;
  447. var keyInstruction = undefined;
  448. var rhythmInstruction = undefined;
  449. for (var idx2 = 0, len2 = instructions.length; idx2 < len2; ++idx2) {
  450. var instruction = instructions[idx2];
  451. if (instruction instanceof KeyInstruction_1.KeyInstruction && instruction.Key !== this.activeKeys[visStaffIdx].Key) {
  452. keyInstruction = instruction;
  453. }
  454. if (instruction instanceof RhythmInstruction_1.RhythmInstruction && instruction !== this.activeRhythm[visStaffIdx]) {
  455. rhythmInstruction = instruction;
  456. }
  457. }
  458. if (keyInstruction !== undefined || rhythmInstruction !== undefined) {
  459. var measureWidth = this.addExtraInstructionMeasure(visStaffIdx, keyInstruction, rhythmInstruction);
  460. maxMeasureWidth = Math.max(maxMeasureWidth, measureWidth);
  461. }
  462. }
  463. if (maxMeasureWidth > 0) {
  464. this.currentSystemParams.systemMeasures.push({
  465. beginLine: SystemLinesEnum_1.SystemLinesEnum.None,
  466. endLine: SystemLinesEnum_1.SystemLinesEnum.None,
  467. });
  468. this.currentSystemParams.currentWidth += maxMeasureWidth;
  469. this.currentSystemParams.currentSystemFixWidth += maxMeasureWidth;
  470. }
  471. };
  472. MusicSystemBuilder.prototype.addExtraInstructionMeasure = function (visStaffIdx, keyInstruction, rhythmInstruction) {
  473. var currentSystem = this.currentSystemParams.currentSystem;
  474. var measures = [];
  475. var measure = this.symbolFactory.createExtraStaffMeasure(currentSystem.StaffLines[visStaffIdx]);
  476. measures.push(measure);
  477. if (keyInstruction !== undefined) {
  478. measure.addKeyAtBegin(keyInstruction, this.activeKeys[visStaffIdx], this.activeClefs[visStaffIdx]);
  479. }
  480. if (rhythmInstruction !== undefined) {
  481. measure.addRhythmAtBegin(rhythmInstruction);
  482. }
  483. measure.PositionAndShape.BorderLeft = 0.0;
  484. measure.PositionAndShape.BorderTop = 0.0;
  485. measure.PositionAndShape.BorderBottom = this.rules.StaffHeight;
  486. var width = this.rules.MeasureLeftMargin + measure.beginInstructionsWidth + this.rules.MeasureRightMargin;
  487. measure.PositionAndShape.BorderRight = width;
  488. currentSystem.StaffLines[visStaffIdx].Measures.push(measure);
  489. measure.ParentStaffLine = currentSystem.StaffLines[visStaffIdx];
  490. currentSystem.StaffLines[visStaffIdx].PositionAndShape.ChildElements.push(measure.PositionAndShape);
  491. return width;
  492. };
  493. MusicSystemBuilder.prototype.addStaveMeasuresToSystem = function (staffMeasures) {
  494. if (staffMeasures[0] !== undefined) {
  495. var gmeasures = [];
  496. for (var i = 0; i < staffMeasures.length; i++) {
  497. gmeasures.push(staffMeasures[i]);
  498. }
  499. var currentSystem = this.currentSystemParams.currentSystem;
  500. for (var visStaffIdx = 0; visStaffIdx < this.numberOfVisibleStaffLines; visStaffIdx++) {
  501. var measure = gmeasures[visStaffIdx];
  502. currentSystem.StaffLines[visStaffIdx].Measures.push(measure);
  503. measure.ParentStaffLine = currentSystem.StaffLines[visStaffIdx];
  504. currentSystem.StaffLines[visStaffIdx].PositionAndShape.ChildElements.push(measure.PositionAndShape);
  505. }
  506. currentSystem.AddStaffMeasures(gmeasures);
  507. }
  508. };
  509. MusicSystemBuilder.prototype.getMeasureStartLine = function () {
  510. var thisMeasureBeginsLineRep = this.thisMeasureBeginsLineRepetition();
  511. if (thisMeasureBeginsLineRep) {
  512. var isSystemStartMeasure = this.currentSystemParams.IsSystemStartMeasure();
  513. var isGlobalFirstMeasure = this.measureListIndex === 0;
  514. if (this.previousMeasureEndsLineRepetition() && !isSystemStartMeasure) {
  515. return SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots;
  516. }
  517. if (!isGlobalFirstMeasure) {
  518. return SystemLinesEnum_1.SystemLinesEnum.BoldThinDots;
  519. }
  520. }
  521. return SystemLinesEnum_1.SystemLinesEnum.None;
  522. };
  523. MusicSystemBuilder.prototype.getMeasureEndLine = function () {
  524. if (this.nextMeasureBeginsLineRepetition() && this.thisMeasureEndsLineRepetition()) {
  525. return SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots;
  526. }
  527. if (this.thisMeasureEndsLineRepetition()) {
  528. return SystemLinesEnum_1.SystemLinesEnum.DotsThinBold;
  529. }
  530. if (this.measureListIndex === this.measureList.length - 1 || this.measureList[this.measureListIndex][0].parentSourceMeasure.endsPiece) {
  531. return SystemLinesEnum_1.SystemLinesEnum.ThinBold;
  532. }
  533. if (this.nextMeasureHasKeyInstructionChange() || this.thisMeasureEndsWordRepetition() || this.nextMeasureBeginsWordRepetition()) {
  534. return SystemLinesEnum_1.SystemLinesEnum.DoubleThin;
  535. }
  536. return SystemLinesEnum_1.SystemLinesEnum.SingleThin;
  537. };
  538. MusicSystemBuilder.prototype.getLineWidth = function (measure, systemLineEnum, isSystemStartMeasure) {
  539. var width = measure.getLineWidth(systemLineEnum);
  540. if (systemLineEnum === SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) {
  541. width /= 2;
  542. }
  543. if (isSystemStartMeasure && systemLineEnum === SystemLinesEnum_1.SystemLinesEnum.BoldThinDots) {
  544. width += this.rules.DistanceBetweenLastInstructionAndRepetitionBarline;
  545. }
  546. return width;
  547. };
  548. MusicSystemBuilder.prototype.previousMeasureEndsLineRepetition = function () {
  549. if (this.measureListIndex === 0) {
  550. return false;
  551. }
  552. for (var idx = 0, len = this.measureList[this.measureListIndex - 1].length; idx < len; ++idx) {
  553. var measure = this.measureList[this.measureListIndex - 1][idx];
  554. if (measure.endsWithLineRepetition()) {
  555. return true;
  556. }
  557. }
  558. return false;
  559. };
  560. MusicSystemBuilder.prototype.thisMeasureBeginsLineRepetition = function () {
  561. for (var idx = 0, len = this.measureList[this.measureListIndex].length; idx < len; ++idx) {
  562. var measure = this.measureList[this.measureListIndex][idx];
  563. if (measure.beginsWithLineRepetition()) {
  564. return true;
  565. }
  566. }
  567. return false;
  568. };
  569. MusicSystemBuilder.prototype.nextMeasureBeginsLineRepetition = function () {
  570. var nextMeasureIndex = this.measureListIndex + 1;
  571. if (nextMeasureIndex >= this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length) {
  572. return false;
  573. }
  574. for (var idx = 0, len = this.measureList[nextMeasureIndex].length; idx < len; ++idx) {
  575. var measure = this.measureList[nextMeasureIndex][idx];
  576. if (measure.beginsWithLineRepetition()) {
  577. return true;
  578. }
  579. }
  580. return false;
  581. };
  582. MusicSystemBuilder.prototype.thisMeasureEndsLineRepetition = function () {
  583. for (var idx = 0, len = this.measureList[this.measureListIndex].length; idx < len; ++idx) {
  584. var measure = this.measureList[this.measureListIndex][idx];
  585. if (measure.endsWithLineRepetition()) {
  586. return true;
  587. }
  588. }
  589. return false;
  590. };
  591. MusicSystemBuilder.prototype.nextMeasureBeginsWordRepetition = function () {
  592. var nextMeasureIndex = this.measureListIndex + 1;
  593. if (nextMeasureIndex >= this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length) {
  594. return false;
  595. }
  596. for (var idx = 0, len = this.measureList[nextMeasureIndex].length; idx < len; ++idx) {
  597. var measure = this.measureList[nextMeasureIndex][idx];
  598. if (measure.beginsWithWordRepetition()) {
  599. return true;
  600. }
  601. }
  602. return false;
  603. };
  604. MusicSystemBuilder.prototype.thisMeasureEndsWordRepetition = function () {
  605. for (var idx = 0, len = this.measureList[this.measureListIndex].length; idx < len; ++idx) {
  606. var measure = this.measureList[this.measureListIndex][idx];
  607. if (measure.endsWithWordRepetition()) {
  608. return true;
  609. }
  610. }
  611. return false;
  612. };
  613. MusicSystemBuilder.prototype.nextMeasureHasKeyInstructionChange = function () {
  614. return this.getNextMeasureKeyInstruction() !== undefined;
  615. };
  616. MusicSystemBuilder.prototype.getNextMeasureKeyInstruction = function () {
  617. if (this.measureListIndex < this.measureList.length - 1) {
  618. for (var visIndex = 0; visIndex < this.measureList[this.measureListIndex].length; visIndex++) {
  619. var sourceMeasure = this.measureList[this.measureListIndex + 1][visIndex].parentSourceMeasure;
  620. if (sourceMeasure === undefined) {
  621. return undefined;
  622. }
  623. return sourceMeasure.getKeyInstruction(this.visibleStaffIndices[visIndex]);
  624. }
  625. }
  626. return undefined;
  627. };
  628. MusicSystemBuilder.prototype.calculateXScalingFactor = function (systemFixWidth, systemVarWidth) {
  629. if (Math.abs(systemVarWidth - 0) < 0.00001 || Math.abs(systemFixWidth - 0) < 0.00001) {
  630. return 1.0;
  631. }
  632. var systemEndX;
  633. var currentSystem = this.currentSystemParams.currentSystem;
  634. systemEndX = currentSystem.StaffLines[0].PositionAndShape.Size.width;
  635. var scalingFactor = (systemEndX - systemFixWidth) / systemVarWidth;
  636. return scalingFactor;
  637. };
  638. MusicSystemBuilder.prototype.stretchMusicSystem = function (isPartEndingSystem) {
  639. var scalingFactor = this.calculateXScalingFactor(this.currentSystemParams.currentSystemFixWidth, this.currentSystemParams.currentSystemVarWidth);
  640. if (isPartEndingSystem) {
  641. scalingFactor = Math.min(scalingFactor, this.rules.LastSystemMaxScalingFactor);
  642. }
  643. var currentSystem = this.currentSystemParams.currentSystem;
  644. for (var visStaffIdx = 0, len = currentSystem.StaffLines.length; visStaffIdx < len; ++visStaffIdx) {
  645. var staffLine = currentSystem.StaffLines[visStaffIdx];
  646. var currentXPosition = 0.0;
  647. for (var measureIndex = 0; measureIndex < staffLine.Measures.length; measureIndex++) {
  648. var measure = staffLine.Measures[measureIndex];
  649. measure.setPositionInStaffline(currentXPosition);
  650. measure.setWidth(measure.beginInstructionsWidth + measure.minimumStaffEntriesWidth * scalingFactor + measure.endInstructionsWidth);
  651. if (measureIndex < this.currentSystemParams.systemMeasures.length) {
  652. var startLine = this.currentSystemParams.systemMeasures[measureIndex].beginLine;
  653. var lineWidth = measure.getLineWidth(SystemLinesEnum_1.SystemLinesEnum.BoldThinDots);
  654. switch (startLine) {
  655. case SystemLinesEnum_1.SystemLinesEnum.BoldThinDots:
  656. var xPosition = currentXPosition;
  657. if (measureIndex === 0) {
  658. xPosition = currentXPosition + measure.beginInstructionsWidth - lineWidth;
  659. }
  660. currentSystem.createVerticalLineForMeasure(xPosition, lineWidth, startLine, SystemLinePosition_1.SystemLinePosition.MeasureBegin, measureIndex, measure);
  661. break;
  662. default:
  663. }
  664. }
  665. measure.staffEntriesScaleFactor = scalingFactor;
  666. measure.layoutSymbols();
  667. var nextMeasureHasRepStartLine = measureIndex + 1 < this.currentSystemParams.systemMeasures.length
  668. && this.currentSystemParams.systemMeasures[measureIndex + 1].beginLine === SystemLinesEnum_1.SystemLinesEnum.BoldThinDots;
  669. if (!nextMeasureHasRepStartLine) {
  670. var endLine = SystemLinesEnum_1.SystemLinesEnum.SingleThin;
  671. if (measureIndex < this.currentSystemParams.systemMeasures.length) {
  672. endLine = this.currentSystemParams.systemMeasures[measureIndex].endLine;
  673. }
  674. var lineWidth = measure.getLineWidth(endLine);
  675. var xPos = measure.PositionAndShape.RelativePosition.x + measure.PositionAndShape.BorderRight - lineWidth;
  676. if (endLine === SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) {
  677. xPos -= lineWidth / 2;
  678. }
  679. currentSystem.createVerticalLineForMeasure(xPos, lineWidth, endLine, SystemLinePosition_1.SystemLinePosition.MeasureEnd, measureIndex, measure);
  680. }
  681. currentXPosition = measure.PositionAndShape.RelativePosition.x + measure.PositionAndShape.BorderRight;
  682. }
  683. }
  684. if (isPartEndingSystem) {
  685. this.decreaseMusicSystemBorders();
  686. }
  687. };
  688. MusicSystemBuilder.prototype.decreaseMusicSystemBorders = function () {
  689. var currentSystem = this.currentSystemParams.currentSystem;
  690. var bb = collectionUtil_1.CollectionUtil.last(currentSystem.StaffLines[0].Measures).PositionAndShape;
  691. var width = bb.RelativePosition.x + bb.Size.width;
  692. for (var idx = 0, len = currentSystem.StaffLines.length; idx < len; ++idx) {
  693. var staffLine = currentSystem.StaffLines[idx];
  694. staffLine.PositionAndShape.BorderRight = width;
  695. for (var idx2 = 0, len2 = staffLine.StaffLines.length; idx2 < len2; ++idx2) {
  696. var graphicalLine = staffLine.StaffLines[idx2];
  697. graphicalLine.End = new PointF2D_1.PointF2D(width, graphicalLine.End.y);
  698. }
  699. }
  700. currentSystem.PositionAndShape.BorderRight = width + this.currentSystemParams.maxLabelLength + this.rules.SystemLabelsRightMargin;
  701. };
  702. return MusicSystemBuilder;
  703. }());
  704. exports.MusicSystemBuilder = MusicSystemBuilder;
  705. var SystemBuildParameters = (function () {
  706. function SystemBuildParameters() {
  707. this.systemMeasures = [];
  708. this.systemMeasureIndex = 0;
  709. this.currentWidth = 0;
  710. this.currentSystemFixWidth = 0;
  711. this.currentSystemVarWidth = 0;
  712. this.maxLabelLength = 0;
  713. }
  714. SystemBuildParameters.prototype.IsSystemStartMeasure = function () {
  715. return this.systemMeasureIndex === 0;
  716. };
  717. return SystemBuildParameters;
  718. }());
  719. exports.SystemBuildParameters = SystemBuildParameters;
  720. var MeasureBuildParameters = (function () {
  721. function MeasureBuildParameters() {
  722. }
  723. return MeasureBuildParameters;
  724. }());
  725. exports.MeasureBuildParameters = MeasureBuildParameters;