private void AddExtendersAtTheEndsOfStaves(List <Staff> staves, float rightMarginPos, float gap, float extenderStrokeWidth, float hairlinePadding, SvgSystem nextSystem) { for (int staffIndex = 0; staffIndex < staves.Count; ++staffIndex) { Staff staff = staves[staffIndex]; if (!(staff is InvisibleOutputStaff)) { for (int voiceIndex = 0; voiceIndex < staff.Voices.Count; ++voiceIndex) { Voice voice = staff.Voices[voiceIndex]; List <NoteObject> noteObjects = voice.NoteObjects; ChordSymbol lastChord = null; RestSymbol lastRest = null; CautionaryChordSymbol cautionary = null; for (int index = noteObjects.Count - 1; index >= 0; --index) { lastChord = noteObjects[index] as ChordSymbol; lastRest = noteObjects[index] as RestSymbol; cautionary = noteObjects[index] as CautionaryChordSymbol; if (cautionary != null) { cautionary.Visible = false; // a CautionaryChordSymbol is a ChordSymbol, but we have not found a real one yet. } else if (lastChord != null || lastRest != null) { break; } } if (lastChord != null && lastChord.MsDurationToNextBarline != null) { List <float> x1s = GetX1sFromChord1(lastChord.ChordMetrics, hairlinePadding); List <float> x2s; List <float> ys = lastChord.ChordMetrics.HeadsOriginYs; if (nextSystem != null && FirstDurationSymbolOnNextSystemIsCautionary(nextSystem.Staves[staffIndex].Voices[voiceIndex])) { x2s = GetEqualFloats(rightMarginPos + gap, x1s.Count); } else { x2s = GetEqualFloats(rightMarginPos, x1s.Count); } lastChord.ChordMetrics.NoteheadExtendersMetrics = CreateExtenders(x1s, x2s, ys, extenderStrokeWidth, gap, true); } } } } }
public override NoteObject GetNoteObject(Voice voice, IUniqueDef iud, bool firstDefInVoice, ref byte currentVelocity, float musicFontHeight) { NoteObject noteObject = null; CautionaryChordDef cautionaryChordDef = iud as CautionaryChordDef; MidiChordDef midiChordDef = iud as MidiChordDef; InputChordDef inputChordDef = iud as InputChordDef; RestDef restDef = iud as RestDef; ClefChangeDef clefChangeDef = iud as ClefChangeDef; PageFormat pageFormat = voice.Staff.SVGSystem.Score.PageFormat; float cautionaryFontHeight = pageFormat.CautionaryNoteheadsFontHeight; int minimumCrotchetDuration = pageFormat.MinimumCrotchetDuration; if (cautionaryChordDef != null && firstDefInVoice) { CautionaryChordSymbol cautionaryChordSymbol = new CautionaryChordSymbol(voice, cautionaryChordDef, cautionaryFontHeight); noteObject = cautionaryChordSymbol; } else if (midiChordDef != null) { OutputChordSymbol outputChordSymbol = new OutputChordSymbol(voice, midiChordDef, minimumCrotchetDuration, musicFontHeight); if (midiChordDef.MidiVelocity != currentVelocity) { outputChordSymbol.AddDynamic(midiChordDef.MidiVelocity, currentVelocity); currentVelocity = midiChordDef.MidiVelocity; } noteObject = outputChordSymbol; } else if (inputChordDef != null) { InputChordSymbol inputChordSymbol = new InputChordSymbol(voice, inputChordDef, minimumCrotchetDuration, musicFontHeight); noteObject = inputChordSymbol; } else if (restDef != null) { RestSymbol restSymbol = new RestSymbol(voice, iud, minimumCrotchetDuration, musicFontHeight); noteObject = restSymbol; } else if (clefChangeDef != null) { ClefChangeSymbol clefChangeSymbol = new ClefChangeSymbol(voice, clefChangeDef.ClefType, cautionaryFontHeight, ((IUniqueDef)iud).MsPosition); noteObject = clefChangeSymbol; } return(noteObject); }
/// <summary> /// Returns the first chordSymbol or restSymbol after the first cautionaryChordSymbol. /// If there are cautionaryChordSymbols between the first and the returned chordSymbol or restSymbol, they are rendered invisible. /// If there is a barline immediately preceding the durationSymbol that would otherwise be returned, the barline is returned. /// Null is returned if no further chordSymbol or RestSymbol is found in the noteObjects. /// </summary> /// <param name="noteObjects"></param> /// <returns></returns> private NoteObject GetFollowingChordRestOrBarlineSymbol(List <NoteObject> noteObjects) { NoteObject noteObjectToReturn = null; bool firstCautionaryChordSymbolFound = false; for (int i = 0; i < noteObjects.Count; ++i) { NoteObject noteObject = noteObjects[i]; if (firstCautionaryChordSymbolFound == false && noteObject is CautionaryChordSymbol) { firstCautionaryChordSymbolFound = true; continue; } if (firstCautionaryChordSymbolFound) { CautionaryChordSymbol followingCautionary = noteObject as CautionaryChordSymbol; if (followingCautionary != null) { followingCautionary.Visible = false; continue; } if (noteObject is ChordSymbol) { noteObjectToReturn = noteObject; } if (noteObject is RestSymbol) { noteObjectToReturn = noteObject; } } if (noteObjectToReturn != null) // a ChordSymbol or a RestSymbol (not a CautionaryChordSymbol) { Barline barline = noteObjects[i - 1] as Barline; if (barline != null) { noteObjectToReturn = barline; } break; } } return(noteObjectToReturn); }
public override Metrics NoteObjectMetrics(Graphics graphics, NoteObject noteObject, VerticalDir voiceStemDirection, float gap, float strokeWidth) { Metrics returnMetrics = null; ClefSymbol clef = noteObject as ClefSymbol; Barline barline = noteObject as Barline; CautionaryChordSymbol cautionaryChordSymbol = noteObject as CautionaryChordSymbol; ChordSymbol chord = noteObject as ChordSymbol; RestSymbol rest = noteObject as RestSymbol; if (barline != null) { returnMetrics = new BarlineMetrics(graphics, barline, gap); } else if (clef != null) { if (clef.ClefType != "n") { returnMetrics = new ClefMetrics(clef, gap); } } else if (cautionaryChordSymbol != null) { returnMetrics = new ChordMetrics(graphics, cautionaryChordSymbol, voiceStemDirection, gap, strokeWidth); } else if (chord != null) { returnMetrics = new ChordMetrics(graphics, chord, voiceStemDirection, gap, strokeWidth); } else if (rest != null) { // All rests are originally created on the centre line. // They are moved vertically later, if they are on a 2-Voice staff. returnMetrics = new RestMetrics(graphics, rest, gap, noteObject.Voice.Staff.NumberOfStafflines, strokeWidth); } return(returnMetrics); }
private List <float> GetCautionaryRightExtenderX2s(CautionaryChordSymbol cautionaryChordSymbol1, List <NoteObject> noteObjects, List <float> x1s, List <float> ys, float hairlinePadding) { List <float> x2s = new List <float>(); NoteObject no2 = GetFollowingChordRestOrBarlineSymbol(noteObjects); Barline barline = no2 as Barline; ChordSymbol chord2 = no2 as ChordSymbol; RestSymbol rest2 = no2 as RestSymbol; if (barline != null) { float x2 = barline.Metrics.OriginX; x2s = GetEqualFloats(x2, x1s.Count); } else if (chord2 != null) { x2s = GetX2sFromChord2(ys, chord2.ChordMetrics, hairlinePadding); } else if (rest2 != null) { float x2 = rest2.Metrics.Left - hairlinePadding; x2s = GetEqualFloats(x2, x1s.Count); } else // no2 == null { Debug.Assert(no2 == null); // This voice has no further chords or rests, // so draw extenders to the right margin. // extend to the right margin PageFormat pageFormat = cautionaryChordSymbol1.Voice.Staff.SVGSystem.Score.PageFormat; float rightMarginPos = pageFormat.RightMarginPos; float gap = pageFormat.Gap; x2s = GetEqualFloats(rightMarginPos + gap, ys.Count); } return(x2s); }
private void AddExtendersInStaves(List <Staff> staves, float extenderStrokeWidth, float gap, float hairlinePadding) { foreach (Staff staff in staves) { if (!(staff is InvisibleOutputStaff)) { foreach (Voice voice in staff.Voices) { List <NoteObject> noteObjects = voice.NoteObjects; int index = 0; while (index < noteObjects.Count - 1) { // noteObjects.Count - 1 because index is immediately incremented when a continuing // chord or rest is found, and it should always be less than noteObjects.Count. ChordSymbol chord1 = noteObjects[index] as ChordSymbol; if (chord1 != null) { List <float> x1s = GetX1sFromChord1(chord1.ChordMetrics, hairlinePadding); List <float> x2s = null; List <float> ys = null; ++index; if (chord1.MsDurationToNextBarline != null) { while (index < noteObjects.Count) { CautionaryChordSymbol cautionaryChordSymbol = noteObjects[index] as CautionaryChordSymbol; ChordSymbol chord2 = noteObjects[index] as ChordSymbol; RestSymbol rest2 = noteObjects[index] as RestSymbol; if (cautionaryChordSymbol != null) { cautionaryChordSymbol.Visible = false; } else if (chord2 != null) { ys = chord1.ChordMetrics.HeadsOriginYs; x2s = GetX2sFromChord2(ys, chord2.ChordMetrics, hairlinePadding); break; } else if (rest2 != null) { float x2 = rest2.Metrics.Left - hairlinePadding; ys = chord1.ChordMetrics.HeadsOriginYs; x2s = GetEqualFloats(x2, x1s.Count); break; } ++index; } if (x2s != null && ys != null) { bool hasContinuingBeamBlock = ((chord1.BeamBlock != null) && (chord1.BeamBlock.Chords[chord1.BeamBlock.Chords.Count - 1] != chord1)); if (hasContinuingBeamBlock) { Debug.Assert(true); } Barline barline = noteObjects[index - 1] as Barline; if (barline != null) { float x2 = barline.Metrics.OriginX; x2s = GetEqualFloats(x2, x1s.Count); } bool drawExtender = false; if (chord1.DurationClass > DurationClass.semiquaver) { drawExtender = true; } if (chord1.DurationClass < DurationClass.crotchet && hasContinuingBeamBlock) { drawExtender = false; } chord1.ChordMetrics.NoteheadExtendersMetrics = CreateExtenders(x1s, x2s, ys, extenderStrokeWidth, gap, drawExtender); } } } else { ++index; } } } } } }
private void AddExtendersAtTheBeginningsofStaves(List <Staff> staves, float rightMarginPos, float gap, float extenderStrokeWidth, float hairlinePadding) { foreach (Staff staff in staves) { if (!(staff is InvisibleOutputStaff)) { foreach (Voice voice in staff.Voices) { List <NoteObject> noteObjects = voice.NoteObjects; ClefSymbol firstClef = null; CautionaryChordSymbol cautionaryChordSymbol = null; ChordSymbol firstChord = null; RestSymbol firstRest = null; for (int index = 0; index < noteObjects.Count; ++index) { if (firstClef == null) { firstClef = noteObjects[index] as ClefSymbol; } if (cautionaryChordSymbol == null) { cautionaryChordSymbol = noteObjects[index] as CautionaryChordSymbol; } if (firstChord == null) { firstChord = noteObjects[index] as ChordSymbol; } if (firstRest == null) { firstRest = noteObjects[index] as RestSymbol; } if (firstClef != null && (cautionaryChordSymbol != null || firstChord != null || firstRest != null)) { break; } } if (firstClef != null && cautionaryChordSymbol != null) { // create brackets List <CautionaryBracketMetrics> cbMetrics = cautionaryChordSymbol.ChordMetrics.CautionaryBracketsMetrics; Debug.Assert(cbMetrics.Count == 2); Metrics clefMetrics = firstClef.Metrics; // extender left of cautionary List <float> ys = cautionaryChordSymbol.ChordMetrics.HeadsOriginYs; List <float> x1s = GetEqualFloats(clefMetrics.Right - (hairlinePadding * 2), ys.Count); List <float> x2s = GetEqualFloats(cbMetrics[0].Left, ys.Count); for (int i = 0; i < x2s.Count; ++i) { if ((x2s[i] - x1s[i]) < gap) { x1s[i] = x2s[i] - gap; } } cautionaryChordSymbol.ChordMetrics.NoteheadExtendersMetricsBefore = CreateExtenders(x1s, x2s, ys, extenderStrokeWidth, gap, true); // extender right of cautionary x1s = GetEqualFloats(cbMetrics[1].Right, ys.Count); x2s = GetCautionaryRightExtenderX2s(cautionaryChordSymbol, voice.NoteObjects, x1s, ys, hairlinePadding); cautionaryChordSymbol.ChordMetrics.NoteheadExtendersMetrics = CreateExtenders(x1s, x2s, ys, extenderStrokeWidth, gap, true); } } } } }
private void CreateCautionaryBracketsMetrics(CautionaryChordSymbol chord) { PageFormat pageFormat = chord.Voice.Staff.SVGSystem.Score.PageFormat; float gap = pageFormat.Gap; float padding = pageFormat.StafflineStemStrokeWidth; float strokeWidth = pageFormat.StafflineStemStrokeWidth; float top, left, bottom, right; GetAccidentalsAndHeadsBox(out top, out right, out bottom, out left, gap, padding); float leftBracketLeft = left - (gap / 2F); float rightBracketRight = right + (gap / 2F); // the left bracket CautionaryBracketMetrics leftBracketMetrics = new CautionaryBracketMetrics(true, top, left, bottom, leftBracketLeft, strokeWidth); // the right bracket CautionaryBracketMetrics rightBracketMetrics = new CautionaryBracketMetrics(false, top, rightBracketRight, bottom, right, strokeWidth); _cautionaryBracketsMetrics = new List<CautionaryBracketMetrics>(); this._cautionaryBracketsMetrics.Add(leftBracketMetrics); this._cautionaryBracketsMetrics.Add(rightBracketMetrics); }
/// <summary> /// Sets Chord.Stem.Direction for each chord. /// Chords are beamed together, duration classes permitting, unless a rest or clef intervenes. /// If a barline intervenes, and beamsCrossBarlines is true, the chords are beamed together. /// If a barline intervenes, and beamsCrossBarlines is false, the beam is broken. /// </summary> public void SetChordStemDirectionsAndCreateBeamBlocks(PageFormat pageFormat) { List <ChordSymbol> chordsBeamedTogether = new List <ChordSymbol>(); ClefSymbol currentClef = null; bool breakGroup = false; ChordSymbol lastChord = null; foreach (ChordSymbol cs in ChordSymbols) { lastChord = cs; } foreach (NoteObject noteObject in NoteObjects) { CautionaryChordSymbol cautionaryChord = noteObject as CautionaryChordSymbol; ChordSymbol chord = noteObject as ChordSymbol; RestSymbol rest = noteObject as RestSymbol; ClefSymbol clef = noteObject as ClefSymbol; Barline barline = noteObject as Barline; if (cautionaryChord != null) { continue; } if (chord != null) { if (chord.DurationClass == DurationClass.cautionary || chord.DurationClass == DurationClass.breve || chord.DurationClass == DurationClass.semibreve || chord.DurationClass == DurationClass.minim || chord.DurationClass == DurationClass.crotchet) { if (currentClef != null) { if (this.StemDirection == VerticalDir.none) { chord.Stem.Direction = chord.DefaultStemDirection(currentClef); } else { chord.Stem.Direction = this.StemDirection; } } breakGroup = true; } else { chordsBeamedTogether.Add(chord); if (chord.Stem.BeamContinues) // this is true by default { breakGroup = false; } else { breakGroup = true; } } } if (chordsBeamedTogether.Count > 0) { if (rest != null) { if (rest.LocalCautionaryChordDef == null) { breakGroup = true; } } if (clef != null) { breakGroup = true; } if (barline != null && !pageFormat.BeamsCrossBarlines) { breakGroup = true; } if (chord == lastChord) { breakGroup = true; } } if (chordsBeamedTogether.Count > 0 && breakGroup) { if (currentClef != null) { if (chordsBeamedTogether.Count == 1) { if (this.StemDirection == VerticalDir.none) { chordsBeamedTogether[0].Stem.Direction = chordsBeamedTogether[0].DefaultStemDirection(currentClef); } else { chordsBeamedTogether[0].Stem.Direction = this.StemDirection; } } else if (chordsBeamedTogether.Count > 1) { float beamThickness = pageFormat.BeamThickness; float beamStrokeThickness = pageFormat.StafflineStemStrokeWidth; if (this is InputVoice) { beamThickness *= pageFormat.InputStavesSizeFactor; beamStrokeThickness *= pageFormat.InputStavesSizeFactor; } chordsBeamedTogether[0].BeamBlock = new BeamBlock(currentClef, chordsBeamedTogether, this.StemDirection, beamThickness, beamStrokeThickness); } } chordsBeamedTogether.Clear(); } if (clef != null) { currentClef = clef; } } }