/// <summary> /// Writes out an SVG Voice /// </summary> /// <param name="w"></param> public virtual void WriteSVG(SvgWriter w, bool staffIsVisible) { for (int i = 0; i < NoteObjects.Count; ++i) { NoteObject noteObject = NoteObjects[i]; Barline barline = noteObject as Barline; if (staffIsVisible && barline != null) { bool isLastNoteObject = (i == (NoteObjects.Count - 1)); float top = Staff.Metrics.StafflinesTop; float bottom = Staff.Metrics.StafflinesBottom; PageFormat pageFormat = Staff.SVGSystem.Score.PageFormat; float barlineStrokeWidth = pageFormat.BarlineStrokeWidth; float stafflineStrokeWidth = pageFormat.StafflineStemStrokeWidth; barline.WriteSVG(w, top, bottom, barlineStrokeWidth, stafflineStrokeWidth, isLastNoteObject, false); } ChordSymbol chordSymbol = noteObject as ChordSymbol; if (chordSymbol != null) { chordSymbol.WriteSVG(w, staffIsVisible); } else { // if this is the first barline, the staff name and (maybe) barnumber will be written. noteObject.WriteSVG(w, staffIsVisible); } } }
public void Add(NoteObject noteObject) { if (noteObject is DurationSymbol durationSymbol) { M.Assert(_absMsPosition == durationSymbol.AbsMsPosition); } _noteObjects.Add(noteObject); }
public void Add(NoteObject noteObject) { DurationSymbol durationSymbol = noteObject as DurationSymbol; if (durationSymbol != null && _msPosition != durationSymbol.MsPosition) { throw new InvalidOperationException("Attempt to add a non-synchronous DurationSymbol to a MomentSymbol."); } _noteObjects.Add(noteObject); }
/// <summary> /// There is still one system per bar. /// Each VoiceDef begins with an MNXCommon.Clef (taking small clefs into account). /// An Exception will be thrown if a SmallClefDef is found on the lower voiceDef in a staff in the systems input. /// Small clefs (if there are any) are copied from the top to the bottom voice (if there is one) on each staff. /// Small clefs on lower voices on a staff have IsVisible set to false. /// </summary> /// <param name="systems"></param> public void ConvertVoiceDefsToNoteObjects(List <SvgSystem> systems) { byte[] currentChannelVelocities = new byte[systems[0].Staves.Count]; var topVoiceSmallClefs = new List <SmallClef>(); int systemAbsMsPos = 0; for (int systemIndex = 0; systemIndex < systems.Count; ++systemIndex) { SvgSystem system = systems[systemIndex]; system.AbsStartMsPosition = systemAbsMsPos; int msPositionReVoiceDef = 0; for (int staffIndex = 0; staffIndex < system.Staves.Count; ++staffIndex) { Staff staff = system.Staves[staffIndex]; msPositionReVoiceDef = 0; topVoiceSmallClefs.Clear(); for (int voiceIndex = 0; voiceIndex < staff.Voices.Count; ++voiceIndex) { Voice voice = staff.Voices[voiceIndex]; voice.VoiceDef.AgglomerateRests(); msPositionReVoiceDef = 0; List <IUniqueDef> iuds = voice.VoiceDef.UniqueDefs; M.Assert(iuds[0] is ClefDef || iuds[0] is MNX.Common.Clef); /** <-------------- **/ for (int iudIndex = 0; iudIndex < iuds.Count; ++iudIndex) { IUniqueDef iud = voice.VoiceDef.UniqueDefs[iudIndex]; int absMsPosition = systemAbsMsPos + msPositionReVoiceDef; NoteObject noteObject = SymbolSet.GetNoteObject(voice, absMsPosition, iud, iudIndex, ref currentChannelVelocities[staffIndex]); if (noteObject is SmallClef smallClef) { if (voiceIndex == 0) { if (staff.Voices.Count > 1) { topVoiceSmallClefs.Add(smallClef); } } else { throw new Exception("SmallClefs may not be defined for a lower voice. They will be copied from the top voice"); } } if (iud is IUniqueSplittableChordDef iscd && iscd.MsDurationToNextBarline != null) { msPositionReVoiceDef += (int)iscd.MsDurationToNextBarline; }
private void AddNoteObject(NoteObject noteObject) { DurationSymbol durationSymbol = noteObject as DurationSymbol; if (durationSymbol != null && _noteObjects.Count > 0) { Debug.Assert(durationSymbol.MsPosition == _msPosition); Debug.Assert(durationSymbol.Voice.Staff == _noteObjects[0].Voice.Staff); } _noteObjects.Add(noteObject); }
/// <summary> /// returns /// -1 if metrics is entirely to the left of the fixedNoteObject; /// 0 if metrics overlaps the fixedNoteObject; /// 1 if metrics is entirely to the right of the fixedNoteObject; /// </summary> /// <returns></returns> private int OverlapsHorizontally(Metrics metrics, NoteObject fixedNoteObject) { int rval = 0; Metrics fixedMetrics = fixedNoteObject.Metrics; if (metrics.Right < fixedMetrics.Left) { rval = -1; } else if (metrics.Left > fixedMetrics.Right) { rval = 1; } return(rval); }
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); }
/// <summary> /// Move paddedMetrics above the fixedNoteObject if it is not already. /// </summary> private void MovePaddedMetricsAboveNoteObject(PaddedMetrics paddedMetrics, NoteObject fixedNoteObject) { double verticalOverlap = 0; if (fixedNoteObject.Metrics is ChordMetrics chordMetrics) { verticalOverlap = chordMetrics.OverlapHeight(paddedMetrics, 0F); } else if (fixedNoteObject.Metrics is RestMetrics restMetrics) { verticalOverlap = restMetrics.OverlapHeight(paddedMetrics, 0F); } else if (!(fixedNoteObject is Barline)) { verticalOverlap = fixedNoteObject.Metrics.OverlapHeight(paddedMetrics, 0F); } if (verticalOverlap > 0) { verticalOverlap = (verticalOverlap > paddedMetrics.BottomPadding) ? verticalOverlap : paddedMetrics.BottomPadding; paddedMetrics.Move(0, -verticalOverlap); } }
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); }
public NoteObjectMoment(NoteObject noteObject, int msPosition) { _msPosition = msPosition; AddNoteObject(noteObject); }
public abstract Metrics NoteObjectMetrics(Graphics graphics, NoteObject noteObject, VerticalDir voiceStemDirection, double gap, PageFormat pageFormat, string currentClefType);
private void GetStaffParameters(NoteObject rootObject) { // If a staff has two voices, both should contain the same clefs. // The clefs are, however, different objects in the two voices: // clef.IsVisible may be true in one voice and false in the other one. Voice voice = rootObject.Voice; _staffOriginY = voice.Staff.Metrics.StafflinesTop; _nStafflines = voice.Staff.NumberOfStafflines; foreach(NoteObject noteObject in voice.NoteObjects) { ClefSymbol cs = noteObject as ClefSymbol; if(cs != null) _clef = cs; if(noteObject == rootObject) break; } }
public abstract Metrics NoteObjectMetrics(Graphics graphics, NoteObject noteObject, VerticalDir voiceStemDirection, float gap, float storkeWidth);
public void Add(NoteObject noteObject) { DurationSymbol durationSymbol = noteObject as DurationSymbol; if(durationSymbol != null && _absMsPosition != durationSymbol.AbsMsPosition) throw new InvalidOperationException("Attempt to add a non-synchronous DurationSymbol to a MomentSymbol."); _noteObjects.Add(noteObject); }
private void AddNoteObject(NoteObject noteObject) { DurationSymbol durationSymbol = noteObject as DurationSymbol; if(durationSymbol != null && _noteObjects.Count > 0) { Debug.Assert(durationSymbol.AbsMsPosition == _absMsPosition); Debug.Assert(durationSymbol.Voice.Staff == _noteObjects[0].Voice.Staff); } if(noteObject is ClefSymbol) { } _noteObjects.Add(noteObject); }
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; CautionaryOutputChordSymbol cautionaryOutputChordSymbol = noteObject as CautionaryOutputChordSymbol; CautionaryInputChordSymbol cautionaryInputChordSymbol = noteObject as CautionaryInputChordSymbol; 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(cautionaryOutputChordSymbol != null) { returnMetrics = new ChordMetrics(graphics, cautionaryOutputChordSymbol, voiceStemDirection, gap, strokeWidth); } else if(cautionaryInputChordSymbol != null) { returnMetrics = new ChordMetrics(graphics, cautionaryInputChordSymbol, 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; }
/// <summary> /// Writes out an SVG Voice /// The following NoteObject types are only written if voiceIndex == 0: /// Barline, Clef, SmallClef, KeySignature, TimeSignature. /// </summary> /// <param name="w"></param> public virtual void WriteSVG(SvgWriter w, int voiceIndex, List <CarryMsgs> carryMsgsPerChannel, bool graphicsOnly) { bool suppressEndOfScoreBarline = false; for (int i = 0; i < NoteObjects.Count; ++i) { NoteObject noteObject = NoteObjects[i]; if (noteObject is Barline barline && voiceIndex == 0) { bool isLastNoteObject = (i == (NoteObjects.Count - 1)); double top = Staff.Metrics.StafflinesTop; double bottom = Staff.Metrics.StafflinesBottom; if (barline.IsVisible && !suppressEndOfScoreBarline) { barline.WriteSVG(w, top, bottom, isLastNoteObject, true); } barline.WriteDrawObjectsSVG(w); } if (noteObject is CautionaryChordSymbol cautionaryChordSymbol) { cautionaryChordSymbol.WriteSVG(w); } if (noteObject is OutputChordSymbol outputChordSymbol) { M.Assert(carryMsgsPerChannel != null); outputChordSymbol.WriteSVG(w, this.MidiChannel, carryMsgsPerChannel[this.MidiChannel], graphicsOnly); } if (noteObject is OutputRestSymbol outputRestSymbol) { M.Assert(carryMsgsPerChannel != null); outputRestSymbol.WriteSVG(w, this.MidiChannel, carryMsgsPerChannel[this.MidiChannel], graphicsOnly); } if (noteObject is Clef clef && voiceIndex == 0) { if (clef.Metrics != null) { // if this is the first barline, the staff name and (maybe) barnumber will be written. ClefMetrics cm = clef.Metrics as ClefMetrics; clef.WriteSVG(w, cm.ClefID, cm.OriginX, cm.OriginY); } } if (noteObject is SmallClef smallClef && voiceIndex == 0) { if (smallClef.Metrics != null) { SmallClefMetrics scm = smallClef.Metrics as SmallClefMetrics; smallClef.WriteSVG(w, scm.ClefID, scm.OriginX, scm.OriginY); } } if (noteObject is KeySignature keySignature && voiceIndex == 0) { keySignature.WriteSVG(w, keySignature.Fifths.ToString(), keySignature.Metrics.OriginX, keySignature.Metrics.OriginY); } if (noteObject is TimeSignature timeSignature && voiceIndex == 0) { timeSignature.WriteSVG(w, timeSignature.Signature, timeSignature.Metrics.OriginX, timeSignature.Metrics.OriginY); } if (noteObject is RepeatSymbol repeatSymbol && voiceIndex == 0) { bool isLastNoteObject = (i == (NoteObjects.Count - 1)); double top = Staff.Metrics.StafflinesTop; double bottom = Staff.Metrics.StafflinesBottom; repeatSymbol.WriteSVG(w, top, bottom, isLastNoteObject, true); suppressEndOfScoreBarline = (i == (NoteObjects.Count - 2)); } } }
/// <summary> /// There is still one system per bar. /// </summary> /// <param name="systems"></param> public void ConvertVoiceDefsToNoteObjects(List <SvgSystem> systems) { byte[] currentChannelVelocities = new byte[systems[0].Staves.Count]; List <ClefChangeDef> voice0ClefChangeDefs = new List <ClefChangeDef>(); List <ClefChangeDef> voice1ClefChangeDefs = new List <ClefChangeDef>(); for (int systemIndex = 0; systemIndex < systems.Count; ++systemIndex) { SvgSystem system = systems[systemIndex]; int visibleStaffIndex = -1; for (int staffIndex = 0; staffIndex < system.Staves.Count; ++staffIndex) { Staff staff = system.Staves[staffIndex]; if (!(staff is InvisibleOutputStaff)) { visibleStaffIndex++; } voice0ClefChangeDefs.Clear(); voice1ClefChangeDefs.Clear(); for (int voiceIndex = 0; voiceIndex < staff.Voices.Count; ++voiceIndex) { Voice voice = staff.Voices[voiceIndex]; float musicFontHeight = (voice is OutputVoice) ? _pageFormat.MusicFontHeight : _pageFormat.MusicFontHeight * _pageFormat.InputStavesSizeFactor; if (!(staff is InvisibleOutputStaff)) { Debug.Assert(_pageFormat.ClefsList[visibleStaffIndex] != null); voice.NoteObjects.Add(new ClefSymbol(voice, _pageFormat.ClefsList[visibleStaffIndex], musicFontHeight)); } bool firstLmdd = true; if (staff is InputStaff) { InputVoice inputVoice = staff.Voices[voiceIndex] as InputVoice; if (systemIndex == 0) { InputVoiceDef inputVoiceDef = inputVoice.VoiceDef as InputVoiceDef; inputVoice.SetMidiChannel(inputVoiceDef.MidiChannel, systemIndex); } } foreach (IUniqueDef iud in voice.VoiceDef.UniqueDefs) { NoteObject noteObject = SymbolSet.GetNoteObject(voice, iud, firstLmdd, ref currentChannelVelocities[staffIndex], musicFontHeight); ClefChangeSymbol clefChangeSymbol = noteObject as ClefChangeSymbol; if (clefChangeSymbol != null) { if (voiceIndex == 0) { voice0ClefChangeDefs.Add(iud as ClefChangeDef); } else { voice1ClefChangeDefs.Add(iud as ClefChangeDef); } } voice.NoteObjects.Add(noteObject); firstLmdd = false; } } if (voice0ClefChangeDefs.Count > 0 || voice1ClefChangeDefs.Count > 0) { // the main clef on this staff in the next system SetNextSystemClefType(staffIndex, voice0ClefChangeDefs, voice1ClefChangeDefs); } if (staff.Voices.Count == 2) { InsertInvisibleClefChangeSymbols(staff.Voices, voice0ClefChangeDefs, voice1ClefChangeDefs); CheckClefTypes(staff.Voices); StandardSymbolSet standardSymbolSet = SymbolSet as StandardSymbolSet; if (standardSymbolSet != null) { standardSymbolSet.ForceNaturalsInSynchronousChords(staff); } } } } }