|
@@ -49,12 +49,13 @@ import {Staff} from "../VoiceData/Staff";
|
|
|
import {OctaveShift} from "../VoiceData/Expressions/ContinuousExpressions/OctaveShift";
|
|
|
import * as log from "loglevel";
|
|
|
import Dictionary from "typescript-collections/dist/lib/Dictionary";
|
|
|
-import {GraphicalLyricEntry} from "./GraphicalLyricEntry";
|
|
|
-import {GraphicalLyricWord} from "./GraphicalLyricWord";
|
|
|
-import {GraphicalLine} from "./GraphicalLine";
|
|
|
-import {Label} from "../Label";
|
|
|
+import { GraphicalLyricEntry } from "./GraphicalLyricEntry";
|
|
|
+import { GraphicalLyricWord } from "./GraphicalLyricWord";
|
|
|
+import { GraphicalLine } from "./GraphicalLine";
|
|
|
+import { Label } from "../Label";
|
|
|
import { GraphicalVoiceEntry } from "./GraphicalVoiceEntry";
|
|
|
import { VerticalSourceStaffEntryContainer } from "../VoiceData/VerticalSourceStaffEntryContainer";
|
|
|
+import { SkyBottomLineCalculator } from "./SkyBottomLineCalculator";
|
|
|
|
|
|
/**
|
|
|
* Class used to do all the calculations in a MusicSheet, which in the end populates a GraphicalMusicSheet.
|
|
@@ -178,11 +179,6 @@ export abstract class MusicSheetCalculator {
|
|
|
// create new MusicSystems and StaffLines (as many as necessary) and populate them with Measures from measureList
|
|
|
this.calculateMusicSystems();
|
|
|
|
|
|
- this.formatMeasures();
|
|
|
-
|
|
|
- // calculate all LyricWords Positions
|
|
|
- this.calculateLyricsPosition();
|
|
|
-
|
|
|
// Add some white space at the end of the piece:
|
|
|
this.graphicalMusicSheet.MusicPages[0].PositionAndShape.BorderMarginBottom += 9;
|
|
|
|
|
@@ -214,6 +210,44 @@ export abstract class MusicSheetCalculator {
|
|
|
protected formatMeasures(): void {
|
|
|
throw new Error("abstract, not implemented");
|
|
|
}
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// This method calculates the relative Positions of all MusicSystems.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="graphicalMusicPage"></param>
|
|
|
+ protected calculateMusicSystemsRelativePositions(graphicalMusicPage: GraphicalMusicPage): void {
|
|
|
+ // xPosition is always fix
|
|
|
+ let relativePosition: PointF2D = new PointF2D(this.rules.PageLeftMargin + this.rules.SystemLeftMargin, 0);
|
|
|
+
|
|
|
+ // first System is handled extra
|
|
|
+ const firstMusicSystem: MusicSystem = graphicalMusicPage.MusicSystems[0];
|
|
|
+ if (graphicalMusicPage === graphicalMusicPage.Parent.MusicPages[0]) {
|
|
|
+ relativePosition.y = this.rules.PageTopMargin + this.rules.TitleTopDistance + this.rules.SheetTitleHeight +
|
|
|
+ this.rules.TitleBottomDistance;
|
|
|
+ } else {
|
|
|
+ relativePosition.y = this.rules.PageTopMargin + this.rules.TitleTopDistance;
|
|
|
+ }
|
|
|
+ firstMusicSystem.PositionAndShape.RelativePosition = relativePosition;
|
|
|
+
|
|
|
+ for (let i: number = 1; i < graphicalMusicPage.MusicSystems.length; i++) {
|
|
|
+ const musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[i];
|
|
|
+ relativePosition = new PointF2D(this.rules.PageLeftMargin + this.rules.SystemLeftMargin, 0);
|
|
|
+
|
|
|
+ // find optimum distance between Systems
|
|
|
+ const previousSystem: MusicSystem = graphicalMusicPage.MusicSystems[i - 1];
|
|
|
+ const lastPreviousStaffLine: StaffLine = previousSystem.StaffLines[previousSystem.StaffLines.length - 1];
|
|
|
+ const distance: number = (lastPreviousStaffLine.SkyBottomLineCalculator.getBottomLineMax() - this.rules.StaffHeight) +
|
|
|
+ Math.abs(musicSystem.StaffLines[0].SkyBottomLineCalculator.getSkyLineMin()) +
|
|
|
+ this.rules.MinimumAllowedDistanceBetweenSystems;
|
|
|
+
|
|
|
+ relativePosition.y = previousSystem.PositionAndShape.RelativePosition.y +
|
|
|
+ lastPreviousStaffLine.PositionAndShape.RelativePosition.y +
|
|
|
+ this.rules.StaffHeight + Math.max(this.rules.SystemDistance, distance);
|
|
|
+
|
|
|
+ musicSystem.PositionAndShape.RelativePosition = relativePosition;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Calculates the x layout of the staff entries within the staff measures belonging to one source measure.
|
|
|
* All staff entries are x-aligned throughout all the measures.
|
|
@@ -223,6 +257,43 @@ export abstract class MusicSheetCalculator {
|
|
|
throw new Error("abstract, not implemented");
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * This method checks the distances between two System's StaffLines and if needed, shifts the lower down.
|
|
|
+ * @param musicSystem
|
|
|
+ */
|
|
|
+ protected optimizeDistanceBetweenStaffLines(musicSystem: MusicSystem): void {
|
|
|
+ musicSystem.PositionAndShape.calculateAbsolutePositionsRecursive(0, 0);
|
|
|
+
|
|
|
+ // don't perform any y-spacing in case of a StaffEntryLink (in both StaffLines)
|
|
|
+ if (!musicSystem.checkStaffEntriesForStaffEntryLink()) {
|
|
|
+ for (let i: number = 0; i < musicSystem.StaffLines.length - 1; i++) {
|
|
|
+ const upperBottomLine: number = musicSystem.StaffLines[i].SkyBottomLineCalculator.getBottomLineMax();
|
|
|
+ // TODO: Lower skyline should add to offset when there are items above the line. Currently no test
|
|
|
+ // file available
|
|
|
+ // const lowerSkyLine: number = Math.min(...musicSystem.StaffLines[i + 1].SkyLine);
|
|
|
+ if (Math.abs(upperBottomLine) > this.rules.MinimumStaffLineDistance) {
|
|
|
+ // Remove staffheight from offset. As it results in huge distances
|
|
|
+ const offset: number = Math.abs(upperBottomLine) + this.rules.MinimumStaffLineDistance - this.rules.StaffHeight;
|
|
|
+ this.updateStaffLinesRelativePosition(musicSystem, i + 1, offset);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method updates the System's StaffLine's RelativePosition (starting from the given index).
|
|
|
+ * @param musicSystem
|
|
|
+ * @param index
|
|
|
+ * @param value
|
|
|
+ */
|
|
|
+ protected updateStaffLinesRelativePosition(musicSystem: MusicSystem, index: number, value: number): void {
|
|
|
+ for (let i: number = index; i < musicSystem.StaffLines.length; i++) {
|
|
|
+ musicSystem.StaffLines[i].PositionAndShape.RelativePosition.y += value;
|
|
|
+ }
|
|
|
+
|
|
|
+ musicSystem.PositionAndShape.BorderBottom += value;
|
|
|
+ }
|
|
|
+
|
|
|
protected calculateSystemYLayout(): void {
|
|
|
throw new Error("abstract, not implemented");
|
|
|
}
|
|
@@ -271,19 +342,19 @@ export abstract class MusicSheetCalculator {
|
|
|
throw new Error("abstract, not implemented");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * Adds a technical instruction at the given staff entry.
|
|
|
- * @param technicalInstructions
|
|
|
- * @param voiceEntry
|
|
|
- * @param staffEntry
|
|
|
- */
|
|
|
- protected handleVoiceEntryTechnicalInstructions(technicalInstructions: TechnicalInstruction[],
|
|
|
- voiceEntry: VoiceEntry, staffEntry: GraphicalStaffEntry): void {
|
|
|
- throw new Error("abstract, not implemented");
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * Adds a technical instruction at the given staff entry.
|
|
|
+ * @param technicalInstructions
|
|
|
+ * @param voiceEntry
|
|
|
+ * @param staffEntry
|
|
|
+ */
|
|
|
+ protected handleVoiceEntryTechnicalInstructions(technicalInstructions: TechnicalInstruction[],
|
|
|
+ voiceEntry: VoiceEntry, staffEntry: GraphicalStaffEntry): void {
|
|
|
+ throw new Error("abstract, not implemented");
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- protected handleTuplet(graphicalNote: GraphicalNote, tuplet: Tuplet, openTuplets: Tuplet[]): void {
|
|
|
+ protected handleTuplet(graphicalNote: GraphicalNote, tuplet: Tuplet, openTuplets: Tuplet[]): void {
|
|
|
throw new Error("abstract, not implemented");
|
|
|
}
|
|
|
|
|
@@ -322,72 +393,68 @@ export abstract class MusicSheetCalculator {
|
|
|
!measure.parentSourceMeasure.ImplicitMeasure) {
|
|
|
if (measure.MeasureNumber !== 1 ||
|
|
|
(measure.MeasureNumber === 1 && measure !== staffLine.Measures[0])) {
|
|
|
- this.calculateSingleMeasureNumberPlacement(measure, staffLine, musicSystem);
|
|
|
- }
|
|
|
+ this.calculateSingleMeasureNumberPlacement(measure, staffLine, musicSystem);
|
|
|
+ }
|
|
|
currentMeasureNumber = measure.MeasureNumber;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// This method calculates a single MeasureNumberLabel and adds it to the graphical label list of the music system
|
|
|
- /// </summary>
|
|
|
- /// <param name="measure"></param>
|
|
|
- /// <param name="staffLine"></param>
|
|
|
- /// <param name="musicSystem"></param>
|
|
|
- private calculateSingleMeasureNumberPlacement(measure: GraphicalMeasure, staffLine: StaffLine, musicSystem: MusicSystem): void {
|
|
|
- const labelNumber: string = measure.MeasureNumber.toString();
|
|
|
- const graphicalLabel: GraphicalLabel = new GraphicalLabel(new Label(labelNumber), this.rules.MeasureNumberLabelHeight,
|
|
|
- TextAlignment.LeftBottom);
|
|
|
- // FIXME: Change if Skyline is available
|
|
|
- // const skyBottomLineCalculator: SkyBottomLineCalculator = new SkyBottomLineCalculator(this.rules);
|
|
|
-
|
|
|
- // calculate LabelBoundingBox and set PSI parent
|
|
|
- graphicalLabel.setLabelPositionAndShapeBorders();
|
|
|
- graphicalLabel.PositionAndShape.Parent = musicSystem.PositionAndShape;
|
|
|
-
|
|
|
- // calculate relative Position
|
|
|
- const relativeX: number = staffLine.PositionAndShape.RelativePosition.x +
|
|
|
- measure.PositionAndShape.RelativePosition.x - graphicalLabel.PositionAndShape.BorderMarginLeft;
|
|
|
- let relativeY: number;
|
|
|
-
|
|
|
- // and the corresponding SkyLine indeces
|
|
|
- // tslint:disable-next-line:no-unused-variable
|
|
|
- let start: number = relativeX;
|
|
|
- // tslint:disable-next-line:no-unused-variable
|
|
|
- let end: number = relativeX - graphicalLabel.PositionAndShape.BorderLeft + graphicalLabel.PositionAndShape.BorderMarginRight;
|
|
|
-
|
|
|
- // take into account the InstrumentNameLabel's at the beginning of the first MusicSystem
|
|
|
- if (staffLine === musicSystem.StaffLines[0] && musicSystem === musicSystem.Parent.MusicSystems[0]) {
|
|
|
- start -= staffLine.PositionAndShape.RelativePosition.x;
|
|
|
- end -= staffLine.PositionAndShape.RelativePosition.x;
|
|
|
- }
|
|
|
-
|
|
|
- // get the minimum corresponding SkyLine value
|
|
|
- // FIXME: Change if Skyline is available
|
|
|
- // const skyLineMinValue: number = skyBottomLineCalculator.getSkyLineMinInRange(staffLine, start, end);
|
|
|
- const skyLineMinValue: number = 0;
|
|
|
-
|
|
|
- if (measure === staffLine.Measures[0]) {
|
|
|
- // must take into account possible MusicSystem Bracket's
|
|
|
- let minBracketTopBorder: number = 0;
|
|
|
- if (musicSystem.GroupBrackets.length > 0) {
|
|
|
- for (const groupBracket of musicSystem.GroupBrackets) {
|
|
|
- minBracketTopBorder = Math.min(minBracketTopBorder, groupBracket.PositionAndShape.BorderTop);
|
|
|
- }
|
|
|
+ /// <summary>
|
|
|
+ /// This method calculates a single MeasureNumberLabel and adds it to the graphical label list of the music system
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="measure"></param>
|
|
|
+ /// <param name="staffLine"></param>
|
|
|
+ /// <param name="musicSystem"></param>
|
|
|
+ private calculateSingleMeasureNumberPlacement(measure: GraphicalMeasure, staffLine: StaffLine, musicSystem: MusicSystem): void {
|
|
|
+ const labelNumber: string = measure.MeasureNumber.toString();
|
|
|
+ const graphicalLabel: GraphicalLabel = new GraphicalLabel(new Label(labelNumber), this.rules.MeasureNumberLabelHeight,
|
|
|
+ TextAlignment.LeftBottom);
|
|
|
+
|
|
|
+ const skyBottomLineCalculator: SkyBottomLineCalculator = staffLine.SkyBottomLineCalculator;
|
|
|
+
|
|
|
+ // calculate LabelBoundingBox and set PSI parent
|
|
|
+ graphicalLabel.setLabelPositionAndShapeBorders();
|
|
|
+ graphicalLabel.PositionAndShape.Parent = musicSystem.PositionAndShape;
|
|
|
+
|
|
|
+ // calculate relative Position
|
|
|
+ const relativeX: number = staffLine.PositionAndShape.RelativePosition.x +
|
|
|
+ measure.PositionAndShape.RelativePosition.x - graphicalLabel.PositionAndShape.BorderMarginLeft;
|
|
|
+ let relativeY: number;
|
|
|
+
|
|
|
+ // and the corresponding SkyLine indeces
|
|
|
+ let start: number = relativeX;
|
|
|
+ let end: number = relativeX - graphicalLabel.PositionAndShape.BorderLeft + graphicalLabel.PositionAndShape.BorderMarginRight;
|
|
|
+
|
|
|
+ // take into account the InstrumentNameLabel's at the beginning of the first MusicSystem
|
|
|
+ if (staffLine === musicSystem.StaffLines[0] && musicSystem === musicSystem.Parent.MusicSystems[0]) {
|
|
|
+ start -= staffLine.PositionAndShape.RelativePosition.x;
|
|
|
+ end -= staffLine.PositionAndShape.RelativePosition.x;
|
|
|
+ }
|
|
|
+
|
|
|
+ // get the minimum corresponding SkyLine value
|
|
|
+ const skyLineMinValue: number = skyBottomLineCalculator.getSkyLineMinInRange(start, end);
|
|
|
+
|
|
|
+ if (measure === staffLine.Measures[0]) {
|
|
|
+ // must take into account possible MusicSystem Bracket's
|
|
|
+ let minBracketTopBorder: number = 0;
|
|
|
+ if (musicSystem.GroupBrackets.length > 0) {
|
|
|
+ for (const groupBracket of musicSystem.GroupBrackets) {
|
|
|
+ minBracketTopBorder = Math.min(minBracketTopBorder, groupBracket.PositionAndShape.BorderTop);
|
|
|
}
|
|
|
- relativeY = Math.min(skyLineMinValue, minBracketTopBorder);
|
|
|
- } else {
|
|
|
- relativeY = skyLineMinValue;
|
|
|
}
|
|
|
+ relativeY = Math.min(skyLineMinValue, minBracketTopBorder);
|
|
|
+ } else {
|
|
|
+ relativeY = skyLineMinValue;
|
|
|
+ }
|
|
|
|
|
|
- relativeY = Math.min(0, relativeY);
|
|
|
+ relativeY = Math.min(0, relativeY);
|
|
|
|
|
|
- graphicalLabel.PositionAndShape.RelativePosition = new PointF2D(relativeX, relativeY);
|
|
|
- // FIXME: Change if Skyline is available
|
|
|
- // skyBottomLineCalculator.updateSkyLineInRange(staffLine, start, end, relativeY + graphicalLabel.PositionAndShape.BorderMarginTop);
|
|
|
- musicSystem.MeasureNumberLabels.push(graphicalLabel);
|
|
|
- }
|
|
|
+ graphicalLabel.PositionAndShape.RelativePosition = new PointF2D(relativeX, relativeY);
|
|
|
+
|
|
|
+ skyBottomLineCalculator.updateSkyLineInRange(start, end, relativeY + graphicalLabel.PositionAndShape.BorderMarginTop);
|
|
|
+ musicSystem.MeasureNumberLabels.push(graphicalLabel);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Calculate the shape (Bézier curve) for this tie.
|
|
@@ -398,8 +465,6 @@ export abstract class MusicSheetCalculator {
|
|
|
throw new Error("abstract, not implemented");
|
|
|
}
|
|
|
|
|
|
- // FIXME: There are several HACKS in this function to make multiline lyrics work without the skyline.
|
|
|
- // These need to be reverted once the skyline is available
|
|
|
/**
|
|
|
* Calculate the Lyrics YPositions for a single [[StaffLine]].
|
|
|
* @param staffLine
|
|
@@ -407,11 +472,9 @@ export abstract class MusicSheetCalculator {
|
|
|
*/
|
|
|
protected calculateSingleStaffLineLyricsPosition(staffLine: StaffLine, lyricVersesNumber: number[]): GraphicalStaffEntry[] {
|
|
|
let numberOfVerses: number = 0;
|
|
|
- // FIXME: There is no class SkyBottomLineCalculator -> Fix value
|
|
|
- // TODO make lyric offset dynamic (also see above)
|
|
|
- let lyricsStartYPosition: number = this.rules.StaffHeight + this.rules.LyricsYOffsetToStaffHeight; // Add offset to prevent collision
|
|
|
+ let lyricsStartYPosition: number = this.rules.StaffHeight; // Add offset to prevent collision
|
|
|
const lyricsStaffEntriesList: GraphicalStaffEntry[] = [];
|
|
|
- // const skyBottomLineCalculator: SkyBottomLineCalculator = new SkyBottomLineCalculator(this.rules);
|
|
|
+ const skyBottomLineCalculator: SkyBottomLineCalculator = staffLine.SkyBottomLineCalculator;
|
|
|
|
|
|
// first find maximum Ycoordinate for the whole StaffLine
|
|
|
let len: number = staffLine.Measures.length;
|
|
@@ -427,7 +490,7 @@ export abstract class MusicSheetCalculator {
|
|
|
|
|
|
// Position of Staffentry relative to StaffLine
|
|
|
const staffEntryPositionX: number = staffEntry.PositionAndShape.RelativePosition.x +
|
|
|
- measureRelativePosition.x;
|
|
|
+ measureRelativePosition.x;
|
|
|
|
|
|
let minMarginLeft: number = Number.MAX_VALUE;
|
|
|
let maxMarginRight: number = Number.MAX_VALUE;
|
|
@@ -440,19 +503,17 @@ export abstract class MusicSheetCalculator {
|
|
|
}
|
|
|
|
|
|
// check BottomLine in this range and take the maximum between the two values
|
|
|
- // FIXME: There is no class SkyBottomLineCalculator -> Fix value
|
|
|
- // float bottomLineMax = skyBottomLineCalculator.getBottomLineMaxInRange(staffLine, minMarginLeft, maxMarginRight);
|
|
|
- const bottomLineMax: number = 0.0;
|
|
|
+ const bottomLineMax: number = skyBottomLineCalculator.getBottomLineMaxInRange(minMarginLeft, maxMarginRight)
|
|
|
+ + this.rules.StaffHeight;
|
|
|
lyricsStartYPosition = Math.max(lyricsStartYPosition, bottomLineMax);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- let maxPosition: number = 4.0;
|
|
|
+ let maxPosition: number = 0;
|
|
|
// iterate again through the Staffentries with LyricEntries
|
|
|
len = lyricsStaffEntriesList.length;
|
|
|
- for (let idx: number = 0; idx < len; ++idx) {
|
|
|
- const staffEntry: GraphicalStaffEntry = lyricsStaffEntriesList[idx];
|
|
|
+ for (const staffEntry of lyricsStaffEntriesList) {
|
|
|
// set LyricEntryLabel RelativePosition
|
|
|
for (let i: number = 0; i < staffEntry.LyricsEntries.length; i++) {
|
|
|
const lyricEntry: GraphicalLyricEntry = staffEntry.LyricsEntries[i];
|
|
@@ -462,10 +523,10 @@ export abstract class MusicSheetCalculator {
|
|
|
// eg verseNumbers: 2,3,4,6 => 1,2,3,4
|
|
|
const verseNumber: number = lyricEntry.GetLyricsEntry.VerseNumber;
|
|
|
const sortedLyricVerseNumberIndex: number = lyricVersesNumber.indexOf(verseNumber);
|
|
|
- const firstPosition: number = lyricsStartYPosition + this.rules.LyricsHeight;
|
|
|
+ const firstPosition: number = lyricsStartYPosition + this.rules.LyricsHeight + this.rules.VerticalBetweenLyricsDistance;
|
|
|
|
|
|
// Y-position calculated according to aforementioned mapping
|
|
|
- let position: number = firstPosition + (this.rules.VerticalBetweenLyricsDistance + this.rules.LyricsHeight) * (sortedLyricVerseNumberIndex);
|
|
|
+ let position: number = firstPosition + (this.rules.VerticalBetweenLyricsDistance + this.rules.LyricsHeight) * sortedLyricVerseNumberIndex;
|
|
|
if (this.leadSheet) {
|
|
|
position = 3.4 + (this.rules.VerticalBetweenLyricsDistance + this.rules.LyricsHeight) * (sortedLyricVerseNumberIndex);
|
|
|
}
|
|
@@ -476,41 +537,11 @@ export abstract class MusicSheetCalculator {
|
|
|
|
|
|
// update BottomLine (on the whole StaffLine's length)
|
|
|
if (lyricsStaffEntriesList.length > 0) {
|
|
|
- /**
|
|
|
- * HACK START
|
|
|
- */
|
|
|
- let additionalPageLength: number = 0;
|
|
|
- maxPosition -= this.rules.StaffHeight;
|
|
|
- let iterator: StaffLine = staffLine.NextStaffLine;
|
|
|
- let systemMaxCount: number = 0;
|
|
|
- while (iterator !== undefined) {
|
|
|
- iterator.PositionAndShape.RelativePosition.y += maxPosition;
|
|
|
- iterator = iterator.NextStaffLine;
|
|
|
- systemMaxCount += maxPosition;
|
|
|
- additionalPageLength += maxPosition;
|
|
|
- }
|
|
|
- // Special care for single line systems
|
|
|
- if (systemMaxCount !== 0) {
|
|
|
- systemMaxCount -= this.rules.BetweenStaffDistance;
|
|
|
- let systemIterator: MusicSystem = staffLine.ParentMusicSystem.NextSystem;
|
|
|
- while (systemIterator !== undefined) {
|
|
|
- systemIterator.PositionAndShape.RelativePosition.y += systemMaxCount;
|
|
|
- systemIterator = systemIterator.NextSystem;
|
|
|
- additionalPageLength += systemMaxCount;
|
|
|
- }
|
|
|
- staffLine.ParentMusicSystem.Parent.PositionAndShape.BorderBottom += additionalPageLength;
|
|
|
- // Update the instrument labels
|
|
|
- }
|
|
|
- staffLine.ParentMusicSystem.setMusicSystemLabelsYPosition();
|
|
|
- /**
|
|
|
- * HACK END
|
|
|
- */
|
|
|
- // const endX: number = staffLine.PositionAndShape.Size.width;
|
|
|
- // const startX: number = lyricsStaffEntriesList[0].PositionAndShape.RelativePosition.x +
|
|
|
- // lyricsStaffEntriesList[0].PositionAndShape.BorderMarginLeft +
|
|
|
- // lyricsStaffEntriesList[0].parentMeasure.PositionAndShape.RelativePosition.x;
|
|
|
- // FIXME: There is no class SkyBottomLineCalculator. This call should update the positions according to the last run
|
|
|
- // skyBottomLineCalculator.updateBottomLineInRange(staffLine, startX, endX, maxPosition);
|
|
|
+ const endX: number = staffLine.PositionAndShape.Size.width;
|
|
|
+ const startX: number = lyricsStaffEntriesList[0].PositionAndShape.RelativePosition.x +
|
|
|
+ lyricsStaffEntriesList[0].PositionAndShape.BorderMarginLeft +
|
|
|
+ lyricsStaffEntriesList[0].parentMeasure.PositionAndShape.RelativePosition.x;
|
|
|
+ skyBottomLineCalculator.updateBottomLineInRange(startX, endX, maxPosition);
|
|
|
}
|
|
|
return lyricsStaffEntriesList;
|
|
|
}
|
|
@@ -674,9 +705,6 @@ export abstract class MusicSheetCalculator {
|
|
|
if (!this.leadSheet) {
|
|
|
this.calculateOrnaments();
|
|
|
}
|
|
|
- // update Sky- and BottomLine with borderValues 0.0 and 4.0 respectively
|
|
|
- // (must also come after Slurs)
|
|
|
- this.updateSkyBottomLines();
|
|
|
// calculate StaffEntry ChordSymbols
|
|
|
this.calculateChordSymbols();
|
|
|
if (!this.leadSheet) {
|
|
@@ -698,6 +726,11 @@ export abstract class MusicSheetCalculator {
|
|
|
this.calculateTempoExpressions();
|
|
|
}
|
|
|
|
|
|
+ this.formatMeasures();
|
|
|
+
|
|
|
+ // calculate all LyricWords Positions
|
|
|
+ this.calculateLyricsPosition();
|
|
|
+
|
|
|
// update all StaffLine's Borders
|
|
|
// create temporary Object, just to call the methods (in order to avoid declaring them static)
|
|
|
for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
|
|
@@ -710,10 +743,11 @@ export abstract class MusicSheetCalculator {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- // calculate Comments for each Staffline
|
|
|
- this.calculateComments();
|
|
|
+
|
|
|
// Y-spacing
|
|
|
this.calculateSystemYLayout();
|
|
|
+ // calculate Comments for each Staffline
|
|
|
+ this.calculateComments();
|
|
|
// calculate marked Areas for Systems
|
|
|
this.calculateMarkedAreas();
|
|
|
|
|
@@ -755,21 +789,12 @@ export abstract class MusicSheetCalculator {
|
|
|
if (graphicalMusicPage === this.graphicalMusicSheet.MusicPages[0]) {
|
|
|
this.calculatePageLabels(graphicalMusicPage);
|
|
|
}
|
|
|
+
|
|
|
// calculate TopBottom Borders for all elements recursively
|
|
|
graphicalMusicPage.PositionAndShape.calculateTopBottomBorders();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- protected updateSkyBottomLine(staffLine: StaffLine): void {
|
|
|
- //log.debug("updateSkyBottomLine not implemented");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- protected calculateSkyBottomLine(staffLine: StaffLine): void {
|
|
|
- //log.debug("calculateSkyBottomLine not implemented");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
protected calculateMarkedAreas(): void {
|
|
|
//log.debug("calculateMarkedAreas not implemented");
|
|
|
return;
|
|
@@ -1366,7 +1391,7 @@ export abstract class MusicSheetCalculator {
|
|
|
let octaveShiftValue: OctaveEnum = OctaveEnum.NONE;
|
|
|
if (openOctaveShifts[staffIndex] !== undefined) {
|
|
|
const octaveShiftParams: OctaveShiftParams = openOctaveShifts[staffIndex];
|
|
|
- if (octaveShiftParams.getAbsoluteStartTimestamp.lte(sourceStaffEntry.AbsoluteTimestamp) &&
|
|
|
+ if (octaveShiftParams.getAbsoluteStartTimestamp.lte(sourceStaffEntry.AbsoluteTimestamp) &&
|
|
|
sourceStaffEntry.AbsoluteTimestamp.lte(octaveShiftParams.getAbsoluteEndTimestamp)) {
|
|
|
octaveShiftValue = octaveShiftParams.getOpenOctaveShift.Type;
|
|
|
}
|
|
@@ -1425,9 +1450,9 @@ export abstract class MusicSheetCalculator {
|
|
|
// if there are no staffEntries in this measure, create a rest for the whole measure:
|
|
|
if (measure.staffEntries.length === 0) {
|
|
|
const sourceStaffEntry: SourceStaffEntry = new SourceStaffEntry(
|
|
|
- new VerticalSourceStaffEntryContainer( measure.parentSourceMeasure,
|
|
|
- measure.parentSourceMeasure.AbsoluteTimestamp,
|
|
|
- measure.parentSourceMeasure.CompleteNumberOfStaves),
|
|
|
+ new VerticalSourceStaffEntryContainer(measure.parentSourceMeasure,
|
|
|
+ measure.parentSourceMeasure.AbsoluteTimestamp,
|
|
|
+ measure.parentSourceMeasure.CompleteNumberOfStaves),
|
|
|
staff);
|
|
|
const voiceEntry: VoiceEntry = new VoiceEntry(new Fraction(0, 1), staff.Voices[0], sourceStaffEntry);
|
|
|
const note: Note = new Note(voiceEntry, sourceStaffEntry, Fraction.createFromFraction(sourceMeasure.Duration), undefined);
|
|
@@ -1437,10 +1462,10 @@ export abstract class MusicSheetCalculator {
|
|
|
graphicalStaffEntry.relInMeasureTimestamp = voiceEntry.Timestamp;
|
|
|
const gve: GraphicalVoiceEntry = MusicSheetCalculator.symbolFactory.createVoiceEntry(voiceEntry, graphicalStaffEntry);
|
|
|
graphicalStaffEntry.graphicalVoiceEntries.push(gve);
|
|
|
- const graphicalNote: GraphicalNote = MusicSheetCalculator.symbolFactory.createNote( note,
|
|
|
- gve,
|
|
|
- new ClefInstruction(),
|
|
|
- OctaveEnum.NONE, undefined);
|
|
|
+ const graphicalNote: GraphicalNote = MusicSheetCalculator.symbolFactory.createNote(note,
|
|
|
+ gve,
|
|
|
+ new ClefInstruction(),
|
|
|
+ OctaveEnum.NONE, undefined);
|
|
|
gve.notes.push(graphicalNote);
|
|
|
}
|
|
|
return measure;
|
|
@@ -1459,18 +1484,18 @@ export abstract class MusicSheetCalculator {
|
|
|
accidentalCalculator.checkAccidental(graphicalNote, pitch);
|
|
|
}
|
|
|
|
|
|
- private updateSkyBottomLines(): void {
|
|
|
- for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
|
|
|
- const graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
|
|
|
- for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
|
|
|
- const musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
|
|
|
- for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
|
|
|
- const staffLine: StaffLine = musicSystem.StaffLines[idx3];
|
|
|
- this.updateSkyBottomLine(staffLine);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // // needed to disable linter, as it doesn't recognize the existing usage of this method.
|
|
|
+ // // ToDo: check if a newer version doesn't have the problem.
|
|
|
+ // /* tslint:disable:no-unused-variable */
|
|
|
+ // private createStaffEntryForTieNote(measure: StaffMeasure, absoluteTimestamp: Fraction, openTie: Tie): GraphicalStaffEntry {
|
|
|
+ // /* tslint:enable:no-unused-variable */
|
|
|
+ // let graphicalStaffEntry: GraphicalStaffEntry;
|
|
|
+ // graphicalStaffEntry = MusicSheetCalculator.symbolFactory.createStaffEntry(openTie.Start.ParentStaffEntry, measure);
|
|
|
+ // graphicalStaffEntry.relInMeasureTimestamp = Fraction.minus(absoluteTimestamp, measure.parentSourceMeasure.AbsoluteTimestamp);
|
|
|
+ // this.resetYPositionForLeadSheet(graphicalStaffEntry.PositionAndShape);
|
|
|
+ // measure.addGraphicalStaffEntryAtTimestamp(graphicalStaffEntry);
|
|
|
+ // return graphicalStaffEntry;
|
|
|
+ // }
|
|
|
|
|
|
private handleStaffEntries(): void {
|
|
|
for (let idx: number = 0, len: number = this.graphicalMusicSheet.MeasureList.length; idx < len; ++idx) {
|
|
@@ -1490,13 +1515,10 @@ export abstract class MusicSheetCalculator {
|
|
|
}
|
|
|
|
|
|
private calculateSkyBottomLines(): void {
|
|
|
- for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
|
|
|
- const graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
|
|
|
- for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
|
|
|
- const musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
|
|
|
- for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
|
|
|
- const staffLine: StaffLine = musicSystem.StaffLines[idx3];
|
|
|
- this.calculateSkyBottomLine(staffLine);
|
|
|
+ for (const graphicalMusicPage of this.graphicalMusicSheet.MusicPages) {
|
|
|
+ for (const musicSystem of graphicalMusicPage.MusicSystems) {
|
|
|
+ for (const staffLine of musicSystem.StaffLines) {
|
|
|
+ staffLine.SkyBottomLineCalculator.calculateLines();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1739,11 +1761,11 @@ export abstract class MusicSheetCalculator {
|
|
|
if (lyricEntry.StaffEntryParent.parentMeasure.ParentStaffLine === nextLyricEntry.StaffEntryParent.parentMeasure.ParentStaffLine) {
|
|
|
// start- and End margins from the text Labels
|
|
|
const startX: number = startStaffEntry.parentMeasure.PositionAndShape.RelativePosition.x +
|
|
|
- startStaffEntry.PositionAndShape.RelativePosition.x +
|
|
|
- lyricEntry.GraphicalLabel.PositionAndShape.BorderMarginRight;
|
|
|
+ startStaffEntry.PositionAndShape.RelativePosition.x +
|
|
|
+ lyricEntry.GraphicalLabel.PositionAndShape.BorderMarginRight;
|
|
|
const endX: number = endStaffentry.parentMeasure.PositionAndShape.RelativePosition.x +
|
|
|
- endStaffentry.PositionAndShape.RelativePosition.x +
|
|
|
- nextLyricEntry.GraphicalLabel.PositionAndShape.BorderMarginLeft;
|
|
|
+ endStaffentry.PositionAndShape.RelativePosition.x +
|
|
|
+ nextLyricEntry.GraphicalLabel.PositionAndShape.BorderMarginLeft;
|
|
|
const y: number = lyricEntry.GraphicalLabel.PositionAndShape.RelativePosition.y;
|
|
|
let numberOfDashes: number = 1;
|
|
|
if ((endX - startX) > this.rules.BetweenSyllabelMaximumDistance) {
|
|
@@ -1774,7 +1796,7 @@ export abstract class MusicSheetCalculator {
|
|
|
|
|
|
// calculate Dashes for the second StaffLine (only if endStaffEntry isn't the first StaffEntry of the StaffLine)
|
|
|
if (!(endStaffentry === endStaffentry.parentMeasure.staffEntries[0] &&
|
|
|
- endStaffentry.parentMeasure === endStaffentry.parentMeasure.ParentStaffLine.Measures[0])) {
|
|
|
+ endStaffentry.parentMeasure === endStaffentry.parentMeasure.ParentStaffLine.Measures[0])) {
|
|
|
const secondStartX: number = nextStaffLine.Measures[0].staffEntries[0].PositionAndShape.RelativePosition.x;
|
|
|
const secondEndX: number = endStaffentry.parentMeasure.PositionAndShape.RelativePosition.x +
|
|
|
endStaffentry.PositionAndShape.RelativePosition.x +
|
|
@@ -1852,8 +1874,8 @@ export abstract class MusicSheetCalculator {
|
|
|
let endStaffLine: StaffLine = undefined;
|
|
|
const staffIndex: number = startStaffEntry.parentMeasure.ParentStaff.idInMusicSheet;
|
|
|
for (let index: number = startStaffEntry.parentVerticalContainer.Index + 1;
|
|
|
- index < this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length;
|
|
|
- ++index) {
|
|
|
+ index < this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length;
|
|
|
+ ++index) {
|
|
|
const gse: GraphicalStaffEntry = this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[index].StaffEntries[staffIndex];
|
|
|
if (gse === undefined) {
|
|
|
continue;
|
|
@@ -1900,7 +1922,7 @@ export abstract class MusicSheetCalculator {
|
|
|
}
|
|
|
// second Underscore in the endStaffLine until endStaffEntry (if endStaffEntry isn't the first StaffEntry of the StaffLine))
|
|
|
if (!(endStaffEntry === endStaffEntry.parentMeasure.staffEntries[0] &&
|
|
|
- endStaffEntry.parentMeasure === endStaffEntry.parentMeasure.ParentStaffLine.Measures[0])) {
|
|
|
+ endStaffEntry.parentMeasure === endStaffEntry.parentMeasure.ParentStaffLine.Measures[0])) {
|
|
|
const secondStartX: number = endStaffLine.Measures[0].staffEntries[0].PositionAndShape.RelativePosition.x;
|
|
|
const secondEndX: number = endStaffEntry.parentMeasure.PositionAndShape.RelativePosition.x +
|
|
|
endStaffEntry.PositionAndShape.RelativePosition.x +
|
|
@@ -1935,21 +1957,21 @@ export abstract class MusicSheetCalculator {
|
|
|
* @param {number} y
|
|
|
* @returns {number}
|
|
|
*/
|
|
|
- private calculateRightAndLeftDashesForLyricWord (staffLine: StaffLine, startX: number, endX: number, y: number): number {
|
|
|
- const leftDash: GraphicalLabel = new GraphicalLabel (new Label ("-"), this.rules.LyricsHeight, TextAlignment.CenterBottom);
|
|
|
+ private calculateRightAndLeftDashesForLyricWord(staffLine: StaffLine, startX: number, endX: number, y: number): number {
|
|
|
+ const leftDash: GraphicalLabel = new GraphicalLabel(new Label("-"), this.rules.LyricsHeight, TextAlignment.CenterBottom);
|
|
|
leftDash.setLabelPositionAndShapeBorders();
|
|
|
staffLine.LyricsDashes.push(leftDash);
|
|
|
if (this.staffLinesWithLyricWords.indexOf(staffLine) === -1) {
|
|
|
this.staffLinesWithLyricWords.push(staffLine);
|
|
|
}
|
|
|
leftDash.PositionAndShape.Parent = staffLine.PositionAndShape;
|
|
|
- const leftDashRelative: PointF2D = new PointF2D (startX, y);
|
|
|
+ const leftDashRelative: PointF2D = new PointF2D(startX, y);
|
|
|
leftDash.PositionAndShape.RelativePosition = leftDashRelative;
|
|
|
- const rightDash: GraphicalLabel = new GraphicalLabel (new Label ("-"), this.rules.LyricsHeight, TextAlignment.CenterBottom);
|
|
|
+ const rightDash: GraphicalLabel = new GraphicalLabel(new Label("-"), this.rules.LyricsHeight, TextAlignment.CenterBottom);
|
|
|
rightDash.setLabelPositionAndShapeBorders();
|
|
|
staffLine.LyricsDashes.push(rightDash);
|
|
|
rightDash.PositionAndShape.Parent = staffLine.PositionAndShape;
|
|
|
- const rightDashRelative: PointF2D = new PointF2D (endX, y);
|
|
|
+ const rightDashRelative: PointF2D = new PointF2D(endX, y);
|
|
|
rightDash.PositionAndShape.RelativePosition = rightDashRelative;
|
|
|
return (rightDash.PositionAndShape.RelativePosition.x - leftDash.PositionAndShape.RelativePosition.x);
|
|
|
}
|
|
@@ -1962,8 +1984,8 @@ export abstract class MusicSheetCalculator {
|
|
|
for (let k: number = 0; k < sourceMeasure.StaffLinkedExpressions[j].length; k++) {
|
|
|
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)
|
|
|
+ sourceMeasure.StaffLinkedExpressions[j][k].StartingContinuousDynamic.StartMultiExpression ===
|
|
|
+ sourceMeasure.StaffLinkedExpressions[j][k] && sourceMeasure.StaffLinkedExpressions[j][k].UnknownList.length === 0)
|
|
|
) {
|
|
|
this.calculateDynamicExpressionsForSingleMultiExpression(sourceMeasure.StaffLinkedExpressions[j][k], i, j);
|
|
|
}
|
|
@@ -2071,13 +2093,13 @@ export abstract class MusicSheetCalculator {
|
|
|
if (hasLink) {
|
|
|
// in case of StaffEntryLink don't check mainVoice / linkedVoice
|
|
|
if (voiceEntry === voiceEntry.ParentSourceStaffEntry.VoiceEntries[0]) {
|
|
|
- // set stem up:
|
|
|
- voiceEntry.StemDirection = StemDirectionType.Up;
|
|
|
- return;
|
|
|
+ // set stem up:
|
|
|
+ voiceEntry.StemDirection = StemDirectionType.Up;
|
|
|
+ return;
|
|
|
} else {
|
|
|
- // set stem down:
|
|
|
- voiceEntry.StemDirection = StemDirectionType.Down;
|
|
|
- return;
|
|
|
+ // set stem down:
|
|
|
+ voiceEntry.StemDirection = StemDirectionType.Down;
|
|
|
+ return;
|
|
|
}
|
|
|
} else {
|
|
|
if (voiceEntry.ParentVoice instanceof LinkedVoice) {
|