import { GraphicalMeasure } from "./GraphicalMeasure" ; import { GraphicalMusicPage } from "./GraphicalMusicPage" ; import { EngravingRules } from "./EngravingRules" ; import { RhythmInstruction } from "../VoiceData/Instructions/RhythmInstruction" ; import { KeyInstruction } from "../VoiceData/Instructions/KeyInstruction" ; import { ClefInstruction } from "../VoiceData/Instructions/ClefInstruction" ; import { SourceMeasure } from "../VoiceData/SourceMeasure" ; import { MusicSystem } from "./MusicSystem" ; import { BoundingBox } from "./BoundingBox" ; import { Staff } from "../VoiceData/Staff" ; import { Instrument } from "../Instrument" ; import { PointF2D } from "../../Common/DataObjects/PointF2D" ; import { StaffLine } from "./StaffLine" ; import { GraphicalLine } from "./GraphicalLine" ; import { SourceStaffEntry } from "../VoiceData/SourceStaffEntry" ; import { AbstractNotationInstruction } from "../VoiceData/Instructions/AbstractNotationInstruction" ; import { SystemLinesEnum } from "./SystemLinesEnum" ; import { GraphicalMusicSheet } from "./GraphicalMusicSheet" ; import { MusicSheetCalculator } from "./MusicSheetCalculator" ; import { MidiInstrument } from "../VoiceData/Instructions/ClefInstruction" ; import { CollectionUtil } from "../../Util/CollectionUtil" ; import { SystemLinePosition } from "./SystemLinePosition" ; export class MusicSystemBuilder { protected measureList : GraphicalMeasure [ ] [ ] ; protected graphicalMusicSheet : GraphicalMusicSheet ; protected currentSystemParams : SystemBuildParameters ; protected numberOfVisibleStaffLines : number ; protected rules : EngravingRules ; protected measureListIndex : number ; protected musicSystems : MusicSystem [ ] = [ ] ; /**
     * Does the mapping from the currently visible staves to the global staff-list of the music sheet.
     */ protected visibleStaffIndices : number [ ] ; protected activeRhythm : RhythmInstruction [ ] ; protected activeKeys : KeyInstruction [ ] ; protected activeClefs : ClefInstruction [ ] ; protected globalSystemIndex : number = 0 ; protected leadSheet : boolean = false ; public initialize ( graphicalMusicSheet , measureList , numberOfStaffLines ) { this . leadSheet = graphicalMusicSheet . LeadSheet ; this . graphicalMusicSheet = graphicalMusicSheet ; this . rules = this . graphicalMusicSheet . ParentMusicSheet . Rules ; this . measureList = measureList ; this . numberOfVisibleStaffLines = numberOfStaffLines ; this . activeRhythm = new Array ( this . numberOfVisibleStaffLines ) ; this . activeKeys = new Array ( this . numberOfVisibleStaffLines ) ; this . activeClefs = new Array ( this . numberOfVisibleStaffLines ) ; this . initializeActiveInstructions ( this . measureList [ 0 ] ) ; } public buildMusicSystems ( ) { const systemMaxWidth = this . getFullPageSystemWidth ( ) ; let prevMeasureEndsPart = false ; this . measureListIndex = 0 ; this . currentSystemParams = new SystemBuildParameters ( ) ; this . currentSystemParams . currentSystem = this . initMusicSystem ( ) ; while ( this . measureListIndex < this . measureList . length ) { const graphicalMeasures = this . measureList [ this . measureListIndex ] ; if ( ! graphicalMeasures || ! graphicalMeasures [ 0 ] ) { this . measureListIndex ++ ; continue ; } for ( let idx = 0 , len = graphicalMeasures . length ; idx < len ; ++ idx ) { graphicalMeasures [ idx ] . resetLayout ( ) ; } const sourceMeasure = graphicalMeasures [ 0 ] . parentSourceMeasure ; const sourceMeasureEndsPart = sourceMeasure . HasEndLine ; const sourceMeasureBreaksSystem = sourceMeasureEndsPart && this . rules . NewPartAndSystemAfterFinalBarline ; const isSystemStartMeasure = this . currentSystemParams . IsSystemStartMeasure ( ) ; sourceMeasure . IsSystemStartMeasure = isSystemStartMeasure ; const isFirstSourceMeasure = sourceMeasure === this . graphicalMusicSheet . ParentMusicSheet . getFirstSourceMeasure ( ) ; let currentMeasureBeginInstructionsWidth = this . rules . MeasureLeftMargin ; let currentMeasureEndInstructionsWidth = 0 ; const measureStartLine = this . getMeasureStartLine ( ) ; currentMeasureBeginInstructionsWidth += this . getLineWidth ( graphicalMeasures [ 0 ] , measureStartLine , isSystemStartMeasure ) ; if ( ! this . leadSheet ) { let forceShowRhythm = false ; if ( prevMeasureEndsPart && this . rules . ShowRhythmAgainAfterPartEndOrFinalBarline ) { forceShowRhythm = true ; } currentMeasureBeginInstructionsWidth += this . addBeginInstructions ( graphicalMeasures , isSystemStartMeasure , isFirstSourceMeasure || forceShowRhythm ) ; currentMeasureEndInstructionsWidth += this . addEndInstructions ( graphicalMeasures ) ; } let currentMeasureVarWidth = 0 ; for ( let i = 0 ; i < this . numberOfVisibleStaffLines ; i ++ ) { currentMeasureVarWidth = Math . max ( currentMeasureVarWidth , graphicalMeasures [ i ] . minimumStaffEntriesWidth ) ; } const measureEndLine = this . getMeasureEndLine ( ) ; currentMeasureEndInstructionsWidth += this . getLineWidth ( graphicalMeasures [ 0 ] , measureEndLine , isSystemStartMeasure ) ; let nextMeasureBeginInstructionWidth = this . rules . MeasureLeftMargin ; let nextSourceMeasure = undefined ; if ( this . measureListIndex + 1 < this . measureList . length ) { const nextGraphicalMeasures = this . measureList [ this . measureListIndex + 1 ] ; nextSourceMeasure = nextGraphicalMeasures [ 0 ] ?. parentSourceMeasure ; if ( nextSourceMeasure ?. hasBeginInstructions ( ) ) { nextMeasureBeginInstructionWidth += this . addBeginInstructions ( nextGraphicalMeasures , false , false ) ; } } let totalMeasureWidth = currentMeasureBeginInstructionsWidth + currentMeasureEndInstructionsWidth + currentMeasureVarWidth ; if ( graphicalMeasures [ 0 ] ?. parentSourceMeasure ?. multipleRestMeasures ) { totalMeasureWidth = this . rules . MultipleRestMeasureDefaultWidth ; } const measureFitsInSystem = this . currentSystemParams . currentWidth + totalMeasureWidth + nextMeasureBeginInstructionWidth < systemMaxWidth ; const doXmlPageBreak = this . rules . NewPageAtXMLNewPageAttribute && sourceMeasure . printNewPageXml ; const doXmlLineBreak = doXmlPageBreak || ( this . rules . NewSystemAtXMLNewSystemAttribute && sourceMeasure . printNewSystemXml ) ; if ( isSystemStartMeasure || ( measureFitsInSystem && ! doXmlLineBreak ) ) { this . addMeasureToSystem ( graphicalMeasures , measureStartLine , measureEndLine , totalMeasureWidth , currentMeasureBeginInstructionsWidth , currentMeasureVarWidth , currentMeasureEndInstructionsWidth ) ; this . updateActiveClefs ( sourceMeasure , graphicalMeasures ) ; this . measureListIndex ++ ; if ( sourceMeasureBreaksSystem ) { if ( this . rules . MaxSystemToDrawNumber === this . musicSystems . length ) { this . finalizeCurrentSystem ( graphicalMeasures , ! this . rules . StretchLastSystemLine , false ) ; return this . musicSystems ; } this . finalizeCurrentAndCreateNewSystem ( graphicalMeasures , ! this . rules . StretchLastSystemLine , false ) ; } prevMeasureEndsPart = sourceMeasureEndsPart ; } else { if ( this . rules . MaxSystemToDrawNumber === this . musicSystems . length ) { this . finalizeCurrentSystem ( graphicalMeasures , false , true , doXmlPageBreak ) ; return this . musicSystems ; } this . finalizeCurrentAndCreateNewSystem ( graphicalMeasures , false , true , doXmlPageBreak ) ; } } if ( this . currentSystemParams . systemMeasures . length > 0 ) { if ( this . rules . MaxSystemToDrawNumber === this . musicSystems . length ) { this . finalizeCurrentSystem ( this . measureList [ this . measureList . length - 1 ] , ! this . rules . StretchLastSystemLine , false ) ; return this . musicSystems ; } this . finalizeCurrentAndCreateNewSystem ( this . measureList [ this . measureList . length - 1 ] , ! this . rules . StretchLastSystemLine , false ) ; } return this . musicSystems ; } /**
     * calculates the y positions of the staff lines within a system and
     * furthermore the y positions of the systems themselves.
     */ public calculateSystemYLayout ( ) { for ( const musicSystem of this . musicSystems ) { this . optimizeDistanceBetweenStaffLines ( musicSystem ) ; } this . calculateMusicSystemsRelativePositions ( ) ; } param graphicalMeasures param width param beginInstrWidth param endInstrWidth protected setMeasureWidth ( graphicalMeasures , width , beginInstrWidth , endInstrWidth ) { for ( let idx = 0 , len = graphicalMeasures . length ; idx < len ; ++ idx ) { const measure = graphicalMeasures [ idx ] ; measure . setWidth ( width ) ; if ( beginInstrWidth > 0 ) { measure . beginInstructionsWidth = beginInstrWidth ; } if ( endInstrWidth > 0 ) { measure . endInstructionsWidth = endInstrWidth ; } } } param measures param isPartEndingSystem protected finalizeCurrentAndCreateNewSystem ( measures , systemEndsPart = false , checkExtraInstructionMeasure = true , startNewPage = false ) { this . finalizeCurrentSystem ( measures , systemEndsPart , checkExtraInstructionMeasure , startNewPage ) ; this . currentSystemParams = new SystemBuildParameters ( ) ; if ( measures !== undefined && this . measureListIndex < this . measureList . length ) { this . currentSystemParams . currentSystem = this . initMusicSystem ( ) ; } } protected finalizeCurrentSystem ( measures , systemEndsPart = false , checkExtraInstructionMeasure = true , startNewPage = false ) { this . currentSystemParams . currentSystem . breaksPage = startNewPage ; this . adaptRepetitionLineWithIfNeeded ( ) ; if ( measures !== undefined && checkExtraInstructionMeasure ) { this . checkAndCreateExtraInstructionMeasure ( measures ) ; } this . stretchMusicSystem ( systemEndsPart ) ; } /**
     * If a line repetition is ending and a new line repetition is starting at the end of the system,
     * the double repetition line has to be split into two: one at the currently ending system and
     * one at the next system.
     * (this should be refactored at some point to not use a combined end/start line but always separated lines)
     */ protected adaptRepetitionLineWithIfNeeded ( ) { const systemMeasures = this . currentSystemParams . systemMeasures ; if ( systemMeasures . length >= 1 ) { const measures = this . currentSystemParams . currentSystem . GraphicalMeasures [ this . currentSystemParams . currentSystem . GraphicalMeasures . length - 1 ] ; let diff = 0.0 ; const measureParams = systemMeasures [ systemMeasures . length - 1 ] ; if ( measureParams . endLine === SystemLinesEnum . DotsBoldBoldDots ) { measureParams . endLine = SystemLinesEnum . DotsThinBold ; diff = measures [ 0 ] . getLineWidth ( SystemLinesEnum . DotsBoldBoldDots ) / 2 - measures [ 0 ] . getLineWidth ( SystemLinesEnum . DotsThinBold ) ; } this . currentSystemParams . currentSystemFixWidth -= diff ; for ( let idx = 0 , len = measures . length ; idx < len ; ++ idx ) { const measure = measures [ idx ] ; measure . endInstructionsWidth -= diff ; } } } protected addMeasureToSystem ( graphicalMeasures , measureStartLine , measureEndLine , totalMeasureWidth , currentMeasureBeginInstructionsWidth , currentVarWidth , currentMeasureEndInstructionsWidth ) { this . currentSystemParams . systemMeasures . push ( { beginLine : measureStartLine , endLine : measureEndLine } ) ; this . setMeasureWidth ( graphicalMeasures , totalMeasureWidth , currentMeasureBeginInstructionsWidth , currentMeasureEndInstructionsWidth ) ; this . addStaveMeasuresToSystem ( graphicalMeasures ) ; this . currentSystemParams . currentWidth += totalMeasureWidth ; this . currentSystemParams . currentSystemFixWidth += currentMeasureBeginInstructionsWidth + currentMeasureEndInstructionsWidth ; this . currentSystemParams . currentSystemVarWidth += currentVarWidth ; this . currentSystemParams . systemMeasureIndex ++ ; } returns { MusicSystem } protected initMusicSystem ( ) { const musicSystem = MusicSheetCalculator . symbolFactory . createMusicSystem ( this . globalSystemIndex ++ , this . rules ) ; this . musicSystems . push ( musicSystem ) ; this . layoutSystemStaves ( musicSystem ) ; musicSystem . createMusicSystemLabel ( this . rules . InstrumentLabelTextHeight , this . rules . SystemLabelsRightMargin , this . rules . LabelMarginBorderFactor , this . musicSystems . length === 1 ) ; return musicSystem ; } returns { number } protected getFullPageSystemWidth ( ) { return this . graphicalMusicSheet . ParentMusicSheet . pageWidth - this . rules . PageLeftMargin - this . rules . PageRightMargin - this . rules . SystemLeftMargin - this . rules . SystemRightMargin ; } protected layoutSystemStaves ( musicSystem ) { const systemWidth = this . getFullPageSystemWidth ( ) ; const boundingBox = musicSystem . PositionAndShape ; boundingBox . BorderLeft = 0.0 ; boundingBox . BorderRight = systemWidth ; boundingBox . BorderTop = 0.0 ; const staffList = [ ] ; const instruments = this . graphicalMusicSheet . ParentMusicSheet . Instruments ; for ( let idx = 0 , len = instruments . length ; idx < len ; ++ idx ) { const instrument = instruments [ idx ] ; if ( ! instrument . Visible || instrument . Voices . length === 0 ) { continue ; } for ( let idx2 = 0 , len2 = instrument . Staves . length ; idx2 < len2 ; ++ idx2 ) { const staff = instrument . Staves [ idx2 ] ; staffList . push ( staff ) ; } } let multiLyrics = false ; if ( this . leadSheet ) { for ( let idx = 0 , len = staffList . length ; idx < len ; ++ idx ) { const staff = staffList [ idx ] ; if ( staff . ParentInstrument . LyricVersesNumbers . length > 1 ) { multiLyrics = true ; break ; } } } let yOffsetSum = 0 ; for ( let i = 0 ; i < staffList . length ; i ++ ) { this . addStaffLineToMusicSystem ( musicSystem , yOffsetSum , staffList [ i ] ) ; yOffsetSum += this . rules . StaffHeight ; if ( i + 1 < staffList . length ) { let yOffset = 0 ; if ( this . leadSheet && ! multiLyrics ) { yOffset = 2.5 ; } else { if ( staffList [ i ] . ParentInstrument === staffList [ i + 1 ] . ParentInstrument ) { yOffset = this . rules . BetweenStaffDistance ; } else { yOffset = this . rules . StaffDistance ; } } yOffsetSum += yOffset ; } } boundingBox . BorderBottom = yOffsetSum ; } param musicSystem param relativeYPosition param staff protected addStaffLineToMusicSystem ( musicSystem , relativeYPosition , staff ) { if ( musicSystem ) { const staffLine = MusicSheetCalculator . symbolFactory . createStaffLine ( musicSystem , staff ) ; musicSystem . StaffLines . push ( staffLine ) ; const boundingBox = staffLine . PositionAndShape ; const relativePosition = new PointF2D ( ) ; relativePosition . x = 0.0 ; boundingBox . BorderRight = musicSystem . PositionAndShape . Size . width ; relativePosition . y = relativeYPosition ; boundingBox . RelativePosition = relativePosition ; boundingBox . BorderLeft = 0.0 ; boundingBox . BorderTop = 0.0 ; boundingBox . BorderBottom = this . rules . StaffHeight ; for ( let i = 0 ; i < 5 ; i ++ ) { const start = new PointF2D ( ) ; start . x = 0.0 ; start . y = i * this . rules . StaffHeight / 4 ; const end = new PointF2D ( ) ; end . x = staffLine . PositionAndShape . Size . width ; end . y = i * this . rules . StaffHeight / 4 ; if ( this . leadSheet ) { start . y = end . y = 0 ; } staffLine . StaffLines [ i ] = new GraphicalLine ( start , end , this . rules . StaffLineWidth ) ; } } } param measureList protected initializeActiveInstructions ( measureList ) { const firstSourceMeasure = this . graphicalMusicSheet . ParentMusicSheet . getFirstSourceMeasure ( ) ; if ( firstSourceMeasure ) { this . visibleStaffIndices = this . graphicalMusicSheet . getVisibleStavesIndicesFromSourceMeasure ( measureList ) ; for ( let i = 0 , len = this . visibleStaffIndices . length ; i < len ; i ++ ) { const staffIndex = this . visibleStaffIndices [ i ] ; const graphicalMeasure = this . graphicalMusicSheet . getGraphicalMeasureFromSourceMeasureAndIndex ( firstSourceMeasure , staffIndex ) ; this . activeClefs [ i ] = < ClefInstruction > firstSourceMeasure . FirstInstructionsStaffEntries [ staffIndex ] . Instructions [ 0 ] ; const firstKeyInstruction = < KeyInstruction > firstSourceMeasure . FirstInstructionsStaffEntries [ staffIndex ] . Instructions [ 1 ] ; if ( firstKeyInstruction ) { let keyInstruction = KeyInstruction . copy ( firstKeyInstruction ) ; keyInstruction = this . transposeKeyInstruction ( keyInstruction , graphicalMeasure ) ; this . activeKeys [ i ] = keyInstruction ; } const firstRhythmInstruction = < RhythmInstruction > firstSourceMeasure . FirstInstructionsStaffEntries [ staffIndex ] . Instructions [ 2 ] ; this . activeRhythm [ i ] = firstRhythmInstruction ; } } } protected transposeKeyInstruction ( keyInstruction , graphicalMeasure ) { const transposeHalftones = graphicalMeasure . getTransposedHalftones ( ) ; if ( transposeHalftones !== keyInstruction . isTransposedBy && graphicalMeasure . ParentStaff . ParentInstrument . MidiInstrumentId !== MidiInstrument . Percussion && MusicSheetCalculator . transposeCalculator !== undefined ) { MusicSheetCalculator . transposeCalculator . transposeKey ( keyInstruction , transposeHalftones ) ; } return keyInstruction ; } param measures param isSystemFirstMeasure param isFirstSourceMeasure returns { number } protected addBeginInstructions ( measures , isSystemFirstMeasure , isFirstSourceMeasure ) { const measureCount = measures . length ; if ( measureCount === 0 ) { return 0 ; } let totalBeginInstructionLengthX = 0.0 ; const sourceMeasure = measures [ 0 ] . parentSourceMeasure ; for ( let idx = 0 ; idx < measureCount ; ++ idx ) { const measure = measures [ idx ] ; const staffIndex = this . visibleStaffIndices [ idx ] ; const beginInstructionsStaffEntry = sourceMeasure . FirstInstructionsStaffEntries [ staffIndex ] ; const beginInstructionLengthX = this . AddInstructionsAtMeasureBegin ( beginInstructionsStaffEntry , measure , idx , isFirstSourceMeasure , isSystemFirstMeasure ) ; totalBeginInstructionLengthX = Math . max ( totalBeginInstructionLengthX , beginInstructionLengthX ) ; } return totalBeginInstructionLengthX ; } param measures returns { number } protected addEndInstructions ( measures ) { const measureCount = measures . length ; if ( measureCount === 0 ) { return 0 ; } let totalEndInstructionLengthX = 0.5 ; const sourceMeasure = measures [ 0 ] . parentSourceMeasure ; for ( let idx = 0 ; idx < measureCount ; idx ++ ) { const measure = measures [ idx ] ; const staffIndex = this . visibleStaffIndices [ idx ] ; const endInstructionsStaffEntry = sourceMeasure . LastInstructionsStaffEntries [ staffIndex ] ; const endInstructionLengthX = this . addInstructionsAtMeasureEnd ( endInstructionsStaffEntry , measure , measures ) ; totalEndInstructionLengthX = Math . max ( totalEndInstructionLengthX , endInstructionLengthX ) ; } return totalEndInstructionLengthX ; } protected AddInstructionsAtMeasureBegin ( firstEntry , measure , visibleStaffIdx , isFirstSourceMeasure , isSystemStartMeasure ) { let instructionsLengthX = 0 ; let currentClef = undefined ; let currentKey = undefined ; let currentRhythm = undefined ; if ( firstEntry ) { for ( let idx = 0 , len = firstEntry . Instructions . length ; idx < len ; ++ idx ) { const abstractNotationInstruction = firstEntry . Instructions [ idx ] ; if ( abstractNotationInstruction instanceof ClefInstruction ) { currentClef = < ClefInstruction > abstractNotationInstruction ; } else if ( abstractNotationInstruction instanceof KeyInstruction ) { currentKey = < KeyInstruction > abstractNotationInstruction ; } else if ( abstractNotationInstruction instanceof RhythmInstruction ) { currentRhythm = < RhythmInstruction > abstractNotationInstruction ; } } } if ( isSystemStartMeasure ) { if ( ! currentClef ) { currentClef = this . activeClefs [ visibleStaffIdx ] ; } if ( ! currentKey ) { currentKey = KeyInstruction . copy ( this . activeKeys [ visibleStaffIdx ] ) ; } if ( isFirstSourceMeasure && ! currentRhythm ) { currentRhythm = this . activeRhythm [ visibleStaffIdx ] ; } } let clefAdded = false ; let keyAdded = false ; let rhythmAdded = false ; if ( currentClef ) { measure . addClefAtBegin ( currentClef ) ; clefAdded = true ; } else { currentClef = this . activeClefs [ visibleStaffIdx ] ; } if ( currentKey ) { currentKey = this . transposeKeyInstruction ( currentKey , measure ) ; const previousKey = isSystemStartMeasure ? undefined : this . activeKeys [ visibleStaffIdx ] ; measure . addKeyAtBegin ( currentKey , previousKey , currentClef ) ; keyAdded = true ; } if ( currentRhythm !== undefined && currentRhythm . PrintObject && this . rules . RenderTimeSignatures ) { let printRhythm = true ; const pickupMeasureIndex = measure . MeasureNumber - 1 ; const measureIndex = pickupMeasureIndex - this . rules . MinMeasureToDrawIndex ; if ( measure . MeasureNumber - 1 >= 0 && this . measureList [ measureIndex ] ) { const previousMeasureList = this . measureList [ measureIndex ] ; const previousMeasure = previousMeasureList [ 0 ] ?. parentSourceMeasure ; if ( previousMeasure ?. ImplicitMeasure && previousMeasure ?. RhythmPrinted ) { printRhythm = false ; } } if ( printRhythm ) { measure . addRhythmAtBegin ( currentRhythm ) ; measure . parentSourceMeasure . RhythmPrinted = currentRhythm ; rhythmAdded = true ; } } if ( clefAdded || keyAdded || rhythmAdded ) { instructionsLengthX += measure . beginInstructionsWidth ; if ( rhythmAdded ) { instructionsLengthX += this . rules . RhythmRightMargin ; } } return instructionsLengthX ; } protected addInstructionsAtMeasureEnd ( lastEntry , measure , measures ) { if ( ! lastEntry || ! lastEntry . Instructions || lastEntry . Instructions . length === 0 ) { return 0 ; } for ( let idx = 0 , len = lastEntry . Instructions . length ; idx < len ; ++ idx ) { const abstractNotationInstruction = lastEntry . Instructions [ idx ] ; if ( abstractNotationInstruction instanceof ClefInstruction ) { const activeClef = < ClefInstruction > abstractNotationInstruction ; measure . addClefAtEnd ( activeClef ) ; for ( const otherVerticalMeasure of measures ) { if ( otherVerticalMeasure !== measure ) { otherVerticalMeasure . addClefAtEnd ( activeClef , false ) ; } } } } return this . rules . MeasureRightMargin + measure . endInstructionsWidth ; } param measure param graphicalMeasures protected updateActiveClefs ( measure , graphicalMeasures ) { for ( let visStaffIdx = 0 , len = graphicalMeasures . length ; visStaffIdx < len ; visStaffIdx ++ ) { const staffIndex = this . visibleStaffIndices [ visStaffIdx ] ; const firstEntry = measure . FirstInstructionsStaffEntries [ staffIndex ] ; if ( firstEntry ) { for ( let idx = 0 , len2 = firstEntry . Instructions . length ; idx < len2 ; ++ idx ) { const abstractNotationInstruction = firstEntry . Instructions [ idx ] ; if ( abstractNotationInstruction instanceof ClefInstruction ) { this . activeClefs [ visStaffIdx ] = < ClefInstruction > abstractNotationInstruction ; } else if ( abstractNotationInstruction instanceof KeyInstruction ) { this . activeKeys [ visStaffIdx ] = < KeyInstruction > abstractNotationInstruction ; } else if ( abstractNotationInstruction instanceof RhythmInstruction ) { this . activeRhythm [ visStaffIdx ] = < RhythmInstruction > abstractNotationInstruction ; } } } const entries = measure . getEntriesPerStaff ( staffIndex ) ; for ( let idx = 0 , len2 = entries . length ; idx < len2 ; ++ idx ) { const staffEntry = entries [ idx ] ; if ( staffEntry . Instructions ) { for ( let idx2 = 0 , len3 = staffEntry . Instructions . length ; idx2 < len3 ; ++ idx2 ) { const abstractNotationInstruction = staffEntry . Instructions [ idx2 ] ; if ( abstractNotationInstruction instanceof ClefInstruction ) { this . activeClefs [ visStaffIdx ] = < ClefInstruction > abstractNotationInstruction ; } } } } const lastEntry = measure . LastInstructionsStaffEntries [ staffIndex ] ; if ( lastEntry ) { const instructions = lastEntry . Instructions ; for ( let idx = 0 , len3 = instructions . length ; idx < len3 ; ++ idx ) { const abstractNotationInstruction = instructions [ idx ] ; if ( abstractNotationInstruction instanceof ClefInstruction ) { this . activeClefs [ visStaffIdx ] = < ClefInstruction > abstractNotationInstruction ; } } } } } param measures protected checkAndCreateExtraInstructionMeasure ( measures ) { const firstStaffEntries = measures [ 0 ] . parentSourceMeasure . FirstInstructionsStaffEntries ; const visibleInstructionEntries = [ ] ; for ( let idx = 0 , len = measures . length ; idx < len ; ++ idx ) { const measure = measures [ idx ] ; visibleInstructionEntries . push ( firstStaffEntries [ measure . ParentStaff . idInMusicSheet ] ) ; } let maxMeasureWidth = 0 ; for ( let visStaffIdx = 0 , len = visibleInstructionEntries . length ; visStaffIdx < len ; ++ visStaffIdx ) { const sse = visibleInstructionEntries [ visStaffIdx ] ; if ( ! sse ) { continue ; } const instructions = sse . Instructions ; let keyInstruction = undefined ; let rhythmInstruction = undefined ; for ( let idx2 = 0 , len2 = instructions . length ; idx2 < len2 ; ++ idx2 ) { const instruction = instructions [ idx2 ] ; if ( instruction instanceof KeyInstruction && ( < KeyInstruction > instruction ) . Key !== this . activeKeys [ visStaffIdx ] . Key ) { keyInstruction = < KeyInstruction > instruction ; } if ( instruction instanceof RhythmInstruction && ( < RhythmInstruction > instruction ) !== this . activeRhythm [ visStaffIdx ] ) { rhythmInstruction = < RhythmInstruction > instruction ; } } if ( keyInstruction !== undefined || rhythmInstruction ) { const measureWidth = this . addExtraInstructionMeasure ( visStaffIdx , keyInstruction , rhythmInstruction ) ; maxMeasureWidth = Math . max ( maxMeasureWidth , measureWidth ) ; } } if ( maxMeasureWidth > 0 ) { this . currentSystemParams . systemMeasures . push ( { beginLine : SystemLinesEnum . None , endLine : SystemLinesEnum . None , } ) ; this . currentSystemParams . currentWidth += maxMeasureWidth ; this . currentSystemParams . currentSystemFixWidth += maxMeasureWidth ; } } protected addExtraInstructionMeasure ( visStaffIdx , keyInstruction , rhythmInstruction ) { const currentSystem = this . currentSystemParams . currentSystem ; const measures = [ ] ; const measure = MusicSheetCalculator . symbolFactory . createExtraGraphicalMeasure ( currentSystem . StaffLines [ visStaffIdx ] ) ; measures . push ( measure ) ; if ( keyInstruction ) { measure . addKeyAtBegin ( keyInstruction , this . activeKeys [ visStaffIdx ] , this . activeClefs [ visStaffIdx ] ) ; } if ( rhythmInstruction !== undefined && rhythmInstruction . PrintObject ) { measure . addRhythmAtBegin ( rhythmInstruction ) ; } measure . PositionAndShape . BorderLeft = 0.0 ; measure . PositionAndShape . BorderTop = 0.0 ; measure . PositionAndShape . BorderBottom = this . rules . StaffHeight ; const width = this . rules . MeasureLeftMargin + measure . beginInstructionsWidth + this . rules . MeasureRightMargin ; measure . PositionAndShape . BorderRight = width ; currentSystem . StaffLines [ visStaffIdx ] . Measures . push ( measure ) ; return width ; } param graphicalMeasures protected addStaveMeasuresToSystem ( graphicalMeasures ) { if ( graphicalMeasures [ 0 ] ) { const gmeasures = [ ] ; for ( let i = 0 ; i < graphicalMeasures . length ; i ++ ) { gmeasures . push ( graphicalMeasures [ i ] ) ; } const currentSystem = this . currentSystemParams . currentSystem ; for ( let visStaffIdx = 0 ; visStaffIdx < this . numberOfVisibleStaffLines ; visStaffIdx ++ ) { const measure = gmeasures [ visStaffIdx ] ; currentSystem . StaffLines [ visStaffIdx ] . Measures . push ( measure ) ; measure . ParentStaffLine = currentSystem . StaffLines [ visStaffIdx ] ; } currentSystem . AddGraphicalMeasures ( gmeasures ) ; } } returns { SystemLinesEnum } protected getMeasureStartLine ( ) { const thisMeasureBeginsLineRep = this . thisMeasureBeginsLineRepetition ( ) ; if ( thisMeasureBeginsLineRep ) { const isSystemStartMeasure = this . currentSystemParams . IsSystemStartMeasure ( ) ; const isGlobalFirstMeasure = this . measureListIndex === 0 ; if ( this . previousMeasureEndsLineRepetition ( ) && ! isSystemStartMeasure ) { return SystemLinesEnum . DotsBoldBoldDots ; } if ( ! isGlobalFirstMeasure ) { return SystemLinesEnum . BoldThinDots ; } } return SystemLinesEnum . None ; } protected getMeasureEndLine ( ) { let sourceMeasure = undefined ; try { sourceMeasure = this . measureList [ this . measureListIndex ] [ 0 ] . parentSourceMeasure ; if ( this . rules . RenderMultipleRestMeasures && sourceMeasure . multipleRestMeasures > 1 ) { const newIndex = Math . min ( this . graphicalMusicSheet . ParentMusicSheet . SourceMeasures . length - 1 , sourceMeasure . measureListIndex + sourceMeasure . multipleRestMeasures - 1 ) ; sourceMeasure = this . graphicalMusicSheet . ParentMusicSheet . SourceMeasures [ newIndex ] ; } } finally { } if ( this . nextMeasureBeginsLineRepetition ( ) && this . thisMeasureEndsLineRepetition ( ) ) { return SystemLinesEnum . DotsBoldBoldDots ; } if ( this . thisMeasureEndsLineRepetition ( ) ) { return SystemLinesEnum . DotsThinBold ; } if ( this . nextMeasureHasKeyInstructionChange ( ) || this . thisMeasureEndsWordRepetition ( ) || this . nextMeasureBeginsWordRepetition ( ) ) { return SystemLinesEnum . DoubleThin ; } if ( ! sourceMeasure ) { return SystemLinesEnum . SingleThin ; } if ( sourceMeasure . endingBarStyleEnum !== undefined ) { return sourceMeasure . endingBarStyleEnum ; } return SystemLinesEnum . SingleThin ; } param measure param systemLineEnum param isSystemStartMeasure returns { number } protected getLineWidth ( measure , systemLineEnum , isSystemStartMeasure ) { let width = measure . getLineWidth ( systemLineEnum ) ; if ( systemLineEnum === SystemLinesEnum . DotsBoldBoldDots ) { width /= 2 ; } if ( isSystemStartMeasure && systemLineEnum === SystemLinesEnum . BoldThinDots ) { width += this . rules . DistanceBetweenLastInstructionAndRepetitionBarline ; } return width ; } protected previousMeasureEndsLineRepetition ( ) { if ( this . measureListIndex === 0 ) { return false ; } for ( let idx = 0 , len = this . measureList [ this . measureListIndex - 1 ] . length ; idx < len ; ++ idx ) { const measure = this . measureList [ this . measureListIndex - 1 ] [ idx ] ; if ( measure . endsWithLineRepetition ( ) ) { return true ; } } return false ; } returns { boolean } protected thisMeasureBeginsLineRepetition ( ) { for ( let idx = 0 , len = this . measureList [ this . measureListIndex ] . length ; idx < len ; ++ idx ) { const measure = this . measureList [ this . measureListIndex ] [ idx ] ; if ( measure . beginsWithLineRepetition ( ) ) { return true ; } } return false ; } returns { boolean } protected nextMeasureBeginsLineRepetition ( ) { const nextMeasureIndex = this . measureListIndex + 1 ; if ( nextMeasureIndex >= this . graphicalMusicSheet . ParentMusicSheet . SourceMeasures . length || ! this . measureList [ nextMeasureIndex ] ) { return false ; } for ( let idx = 0 , len = this . measureList [ nextMeasureIndex ] . length ; idx < len ; ++ idx ) { const measure = this . measureList [ nextMeasureIndex ] [ idx ] ; if ( measure . beginsWithLineRepetition ( ) ) { return true ; } } return false ; } returns { boolean } protected thisMeasureEndsLineRepetition ( ) { for ( let idx = 0 , len = this . measureList [ this . measureListIndex ] . length ; idx < len ; ++ idx ) { const measure = this . measureList [ this . measureListIndex ] [ idx ] ; if ( measure . endsWithLineRepetition ( ) ) { return true ; } } return false ; } returns { boolean } protected nextMeasureBeginsWordRepetition ( ) { const nextMeasureIndex = this . measureListIndex + 1 ; if ( nextMeasureIndex >= this . graphicalMusicSheet . ParentMusicSheet . SourceMeasures . length || nextMeasureIndex > this . measureList . length - 1 ) { return false ; } for ( let idx = 0 , len = this . measureList [ nextMeasureIndex ] . length ; idx < len ; ++ idx ) { const measure = this . measureList [ nextMeasureIndex ] [ idx ] ; if ( measure . beginsWithWordRepetition ( ) ) { return true ; } } return false ; } returns { boolean } protected thisMeasureEndsWordRepetition ( ) { for ( let idx = 0 , len = this . measureList [ this . measureListIndex ] . length ; idx < len ; ++ idx ) { const measure = this . measureList [ this . measureListIndex ] [ idx ] ; if ( measure . endsWithWordRepetition ( ) ) { return true ; } } return false ; } returns { boolean } protected nextMeasureHasKeyInstructionChange ( ) { return this . getNextMeasureKeyInstruction ( ) !== undefined ; } protected getNextMeasureKeyInstruction ( ) { if ( this . measureListIndex < this . measureList . length - 1 ) { for ( let visIndex = 0 ; visIndex < this . measureList [ this . measureListIndex ] . length ; visIndex ++ ) { const sourceMeasure = this . measureList [ this . measureListIndex + 1 ] [ visIndex ] ?. parentSourceMeasure ; if ( ! sourceMeasure ) { return undefined ; } return sourceMeasure . getKeyInstruction ( this . visibleStaffIndices [ visIndex ] ) ; } } return undefined ; } param systemFixWidth param systemVarWidth returns { number } protected calculateXScalingFactor ( systemFixWidth , systemVarWidth ) { if ( Math . abs ( systemVarWidth - 0 ) < 0.00001 || Math . abs ( systemFixWidth - 0 ) < 0.00001 ) { return 1.0 ; } const currentSystem = this . currentSystemParams . currentSystem ; const systemEndX = currentSystem . StaffLines [ 0 ] . PositionAndShape . Size . width ; const scalingFactor = ( systemEndX - systemFixWidth ) / systemVarWidth ; return scalingFactor ; } param systemEndsPart protected stretchMusicSystem ( systemEndsPart ) { let scalingFactor = this . calculateXScalingFactor ( this . currentSystemParams . currentSystemFixWidth , this . currentSystemParams . currentSystemVarWidth ) ; if ( systemEndsPart ) { scalingFactor = Math . min ( scalingFactor , this . rules . LastSystemMaxScalingFactor ) ; } const currentSystem = this . currentSystemParams . currentSystem ; for ( let visStaffIdx = 0 , len = currentSystem . StaffLines . length ; visStaffIdx < len ; ++ visStaffIdx ) { const staffLine = currentSystem . StaffLines [ visStaffIdx ] ; let currentXPosition = 0.0 ; for ( let measureIndex = 0 ; measureIndex < staffLine . Measures . length ; measureIndex ++ ) { const measure = staffLine . Measures [ measureIndex ] ; measure . setPositionInStaffline ( currentXPosition ) ; const beginInstructionsWidth = measure . beginInstructionsWidth ; measure . setWidth ( beginInstructionsWidth + measure . minimumStaffEntriesWidth * scalingFactor + measure . endInstructionsWidth ) ; if ( measureIndex < this . currentSystemParams . systemMeasures . length ) { const startLine = this . currentSystemParams . systemMeasures [ measureIndex ] . beginLine ; const lineWidth = measure . getLineWidth ( SystemLinesEnum . BoldThinDots ) ; switch ( startLine ) { case SystemLinesEnum . BoldThinDots : let xPosition = currentXPosition ; if ( measureIndex === 0 ) { xPosition = currentXPosition + measure . beginInstructionsWidth - lineWidth ; } currentSystem . createVerticalLineForMeasure ( xPosition , lineWidth , startLine , SystemLinePosition . MeasureBegin , measureIndex , measure ) ; break ; default : } } measure . staffEntriesScaleFactor = scalingFactor ; measure . layoutSymbols ( ) ; const nextMeasureHasRepStartLine = measureIndex + 1 < this . currentSystemParams . systemMeasures . length && this . currentSystemParams . systemMeasures [ measureIndex + 1 ] . beginLine === SystemLinesEnum . BoldThinDots ; if ( ! nextMeasureHasRepStartLine ) { let endLine = SystemLinesEnum . SingleThin ; if ( measureIndex < this . currentSystemParams . systemMeasures . length ) { endLine = this . currentSystemParams . systemMeasures [ measureIndex ] . endLine ; } const lineWidth = measure . getLineWidth ( endLine ) ; let xPos = measure . PositionAndShape . RelativePosition . x + measure . PositionAndShape . BorderRight - lineWidth ; if ( endLine === SystemLinesEnum . DotsBoldBoldDots ) { xPos -= lineWidth / 2 ; } currentSystem . createVerticalLineForMeasure ( xPos , lineWidth , endLine , SystemLinePosition . MeasureEnd , measureIndex , measure ) ; } currentXPosition = measure . PositionAndShape . RelativePosition . x + measure . PositionAndShape . BorderRight ; } } if ( systemEndsPart ) { this . decreaseMusicSystemBorders ( ) ; } } /**
     * If the last [[MusicSystem]] doesn't need stretching, then this method decreases the System's Width,
     * the [[StaffLine]]'s Width and the 5 [[StaffLine]]s length.
     */ protected decreaseMusicSystemBorders ( ) { const currentSystem = this . currentSystemParams . currentSystem ; const bb = CollectionUtil . last ( currentSystem . StaffLines [ 0 ] . Measures ) . PositionAndShape ; const width = bb . RelativePosition . x + bb . Size . width ; for ( let idx = 0 , len = currentSystem . StaffLines . length ; idx < len ; ++ idx ) { const staffLine = currentSystem . StaffLines [ idx ] ; staffLine . PositionAndShape . BorderRight = width ; for ( let idx2 = 0 , len2 = staffLine . StaffLines . length ; idx2 < len2 ; ++ idx2 ) { const graphicalLine = staffLine . StaffLines [ idx2 ] ; graphicalLine . End = new PointF2D ( width , graphicalLine . End . y ) ; } } currentSystem . PositionAndShape . BorderRight = width + this . currentSystemParams . maxLabelLength + this . rules . SystemLabelsRightMargin ; } param musicSystem param index param value protected updateStaffLinesRelativePosition ( musicSystem , index , value ) { for ( let i = index ; i < musicSystem . StaffLines . length ; i ++ ) { musicSystem . StaffLines [ i ] . PositionAndShape . RelativePosition . y = value ; } musicSystem . PositionAndShape . BorderBottom += value ; } returns { GraphicalMusicPage } protected createMusicPage ( ) { const page = new GraphicalMusicPage ( this . graphicalMusicSheet ) ; this . graphicalMusicSheet . MusicPages . push ( page ) ; page . PageNumber = this . graphicalMusicSheet . MusicPages . length ; page . PositionAndShape . BorderLeft = 0.0 ; page . PositionAndShape . BorderRight = this . graphicalMusicSheet . ParentMusicSheet . pageWidth ; page . PositionAndShape . BorderTop = 0.0 ; page . PositionAndShape . BorderBottom = this . rules . PageHeight ; page . PositionAndShape . RelativePosition = new PointF2D ( 0.0 , 0.0 ) ; return page ; } protected addSystemToPage ( page , system ) { page . MusicSystems . push ( system ) ; system . Parent = page ; } param musicSystem protected optimizeDistanceBetweenStaffLines ( musicSystem ) { if ( ! musicSystem . checkStaffEntriesForStaffEntryLink ( ) ) { for ( let i = 0 ; i < musicSystem . StaffLines . length - 1 ; i ++ ) { const upperBottomLine = musicSystem . StaffLines [ i ] . BottomLine ; const lowerSkyLine = musicSystem . StaffLines [ i + 1 ] . SkyLine ; let maxDistance = 0 ; for ( let j = 0 ; j < upperBottomLine . length ; j ++ ) { const bottomLineValue = upperBottomLine [ j ] ; const startIdx = Math . max ( 0 , j - 6 ) ; const endIdx = Math . min ( lowerSkyLine . length - 1 , j + 6 ) ; let skylineValue = 0 ; for ( let lowerIdx = startIdx ; lowerIdx <= endIdx ; lowerIdx ++ ) { skylineValue = Math . min ( skylineValue , lowerSkyLine [ lowerIdx ] ) ; } const distance = bottomLineValue - skylineValue ; maxDistance = Math . max ( distance , maxDistance ) ; } maxDistance += this . rules . MinSkyBottomDistBetweenStaves ; maxDistance = Math . max ( maxDistance , this . rules . StaffHeight + this . rules . MinimumStaffLineDistance ) ; const lowerStafflineYPos = maxDistance + musicSystem . StaffLines [ i ] . PositionAndShape . RelativePosition . y ; this . updateStaffLinesRelativePosition ( musicSystem , i + 1 , lowerStafflineYPos ) ; } } const firstStaffLine = musicSystem . StaffLines [ 0 ] ; musicSystem . PositionAndShape . BorderTop = firstStaffLine . PositionAndShape . RelativePosition . y + firstStaffLine . PositionAndShape . BorderTop ; const lastStaffLine = musicSystem . StaffLines [ musicSystem . StaffLines . length - 1 ] ; musicSystem . PositionAndShape . BorderBottom = lastStaffLine . PositionAndShape . RelativePosition . y + lastStaffLine . PositionAndShape . BorderBottom ; } /** Calculates the relative Positions of all MusicSystems.
     *
     */ protected calculateMusicSystemsRelativePositions ( ) { let currentPage = this . createMusicPage ( ) ; let currentYPosition = 0 ; let currentSystem = this . musicSystems [ 0 ] ; let timesPageCouldntFitSingleSystem = 0 ; for ( let i = 0 ; i < this . musicSystems . length ; i ++ ) { currentSystem = this . musicSystems [ i ] ; if ( currentPage . MusicSystems . length === 0 ) { this . addSystemToPage ( currentPage , currentSystem ) ; if ( this . rules . CompactMode ) { currentYPosition = this . rules . PageTopMarginNarrow ; } else { currentYPosition = this . rules . PageTopMargin ; } if ( this . graphicalMusicSheet . MusicPages . length === 1 ) { if ( this . rules . RenderTitle ) { currentYPosition += this . rules . TitleTopDistance + this . rules . SheetTitleHeight + this . rules . TitleBottomDistance ; } } const relativePosition = new PointF2D ( this . rules . PageLeftMargin + this . rules . SystemLeftMargin , currentYPosition ) ; currentSystem . PositionAndShape . RelativePosition = relativePosition ; if ( currentYPosition + currentSystem . PositionAndShape . BorderBottom > this . rules . PageHeight - this . rules . PageBottomMargin ) { timesPageCouldntFitSingleSystem ++ ; if ( timesPageCouldntFitSingleSystem <= 4 ) { console . log ( `warning: could not fit a single system on page ${ currentPage . PageNumber }` + ` and measure number ${ currentSystem . GraphicalMeasures [ 0 ] [ 0 ] . MeasureNumber }.
                            The PageFormat may be too small for this sheet."
                            Will not give further warnings for all pages, only total.` ) ; } } } else { const previousSystem = this . musicSystems [ i - 1 ] ; const prevSystemLastStaffline = previousSystem . StaffLines [ previousSystem . StaffLines . length - 1 ] ; const prevSystemLastStaffLineBB = prevSystemLastStaffline . PositionAndShape ; let distance = this . findRequiredDistanceWithSkyBottomLine ( previousSystem , currentSystem ) ; distance += this . rules . MinSkyBottomDistBetweenSystems ; distance = Math . max ( distance , this . rules . MinimumDistanceBetweenSystems + prevSystemLastStaffline . StaffHeight ) ; const newYPosition = currentYPosition + prevSystemLastStaffLineBB . RelativePosition . y + distance ; const currSystemBottomYPos = newYPosition + currentSystem . PositionAndShape . BorderMarginBottom ; const doXmlPageBreak = this . rules . NewPageAtXMLNewPageAttribute && previousSystem . breaksPage ; if ( ! doXmlPageBreak && ( currSystemBottomYPos < this . rules . PageHeight - this . rules . PageBottomMargin ) ) { this . addSystemToPage ( currentPage , currentSystem ) ; currentYPosition = newYPosition ; const relativePosition = new PointF2D ( this . rules . PageLeftMargin + this . rules . SystemLeftMargin , currentYPosition ) ; currentSystem . PositionAndShape . RelativePosition = relativePosition ; } else { currentPage = this . createMusicPage ( ) ; i -= 1 ; continue ; } } } if ( timesPageCouldntFitSingleSystem > 0 ) { console . log ( `total amount of pages that couldn't fit a single music system: ${ timesPageCouldntFitSingleSystem } of ${ currentPage . PageNumber }` ) ; } } param upperSystem param lowerSystem private findRequiredDistanceWithSkyBottomLine ( upperSystem , lowerSystem ) { const upperSystemLastStaffLine = upperSystem . StaffLines [ upperSystem . StaffLines . length - 1 ] ; const lowerSystemFirstStaffLine = lowerSystem . StaffLines [ 0 ] ; const upperBottomLineArray = upperSystemLastStaffLine . BottomLine ; const lowerSkyLineArray = lowerSystemFirstStaffLine . SkyLine ; const upperStaffLineBB = upperSystemLastStaffLine . PositionAndShape ; const lowerStaffLineBB = lowerSystemFirstStaffLine . PositionAndShape ; const skylinePixelWidth = 1 / this . rules . SamplingUnit ; let maxDistance = 0 ; for ( let upperIdx = 0 ; upperIdx < upperBottomLineArray . length ; upperIdx ++ ) { const bottomLineValue = upperBottomLineArray [ upperIdx ] ; const lowerCenterIdx = upperIdx + Math . round ( ( upperStaffLineBB . RelativePosition . x - lowerStaffLineBB . RelativePosition . x ) * skylinePixelWidth ) ; if ( lowerCenterIdx < 0 ) { continue ; } if ( lowerCenterIdx >= lowerSkyLineArray . length ) { break ; } const startIdx = Math . max ( 0 , lowerCenterIdx - 6 ) ; const endIdx = Math . min ( lowerSkyLineArray . length - 1 , lowerCenterIdx + 6 ) ; let skylineValue = 0 ; for ( let lowerIdx = startIdx ; lowerIdx <= endIdx ; lowerIdx ++ ) { skylineValue = Math . min ( skylineValue , lowerSkyLineArray [ lowerIdx ] ) ; } const distance = bottomLineValue - skylineValue ; maxDistance = Math . max ( distance , maxDistance ) ; } if ( maxDistance === 0 ) { maxDistance = upperStaffLineBB . BorderBottom - lowerStaffLineBB . BorderTop ; } return maxDistance ; } } export class SystemBuildParameters { public currentSystem : MusicSystem ; public systemMeasures : MeasureBuildParameters [ ] = [ ] ; public systemMeasureIndex : number = 0 ; public currentWidth : number = 0 ; public currentSystemFixWidth : number = 0 ; public currentSystemVarWidth : number = 0 ; public maxLabelLength : number = 0 ; public IsSystemStartMeasure ( ) { return this . systemMeasureIndex === 0 ; } } export class MeasureBuildParameters { public beginLine : SystemLinesEnum ; public endLine : SystemLinesEnum ; }