/// <summary> /// Moves rests onto the top and bottom stafflines. Most rests move two gaps from the centre staffline, /// but breve and semibreve rests in the top voice move to a position 1 gap above the top staffline, and /// breve and semibreve rests in the bottom voice move onto the bottom staffline. /// Breve and semibreve rests outside the stafflines have a single, visible "ledgerline". /// </summary> private void MoveRestsOntoOuterStafflines() { for (int voiceIndex = 0; voiceIndex < 2; ++voiceIndex) { foreach (NoteObject noteObject in Voices[voiceIndex].NoteObjects) { RestSymbol rest = noteObject as RestSymbol; if (rest != null) { RestMetrics metrics = (RestMetrics)rest.Metrics; if (voiceIndex == 0) { if (rest.DurationClass == DurationClass.breve || rest.DurationClass == DurationClass.semibreve) { metrics.LedgerlineVisible = true; // only affects breves, semibreves and minims } metrics.Move(0F, this.Gap * -2); } else { if (rest.DurationClass == DurationClass.breve || rest.DurationClass == DurationClass.semibreve) { metrics.Move(0F, this.Gap * 3); } else { metrics.Move(0F, this.Gap * 2); } } } } } }
private void AdjustRestRestCollisions() { List <NoteObject> upperObjects = Voices[0].NoteObjects; List <NoteObject> lowerObjects = Voices[1].NoteObjects; // If a rest in the top voice collides with a rest in the lower voice at the same msPosition, // both rests are moved in gap steps outwards until they no longer overlap. foreach (NoteObject topObject in upperObjects) { RestSymbol topRest = topObject as RestSymbol; if (topRest != null) { RestMetrics upperRestMetrics = topRest.Metrics as RestMetrics; foreach (NoteObject lowerObject in lowerObjects) { RestSymbol lowerRestSymbol = lowerObject as RestSymbol; if (lowerRestSymbol != null) { if (topRest.MsPosition < lowerRestSymbol.MsPosition) { break; } if (topRest.MsPosition == lowerRestSymbol.MsPosition) { RestMetrics lowerRestMetrics = (RestMetrics)lowerRestSymbol.Metrics; float verticalOverlap = lowerRestMetrics.OverlapHeight(upperRestMetrics, 0F); bool moveBottomRest = true; while (verticalOverlap > 0) { float newMinBottom = upperRestMetrics.Bottom - verticalOverlap; if (upperRestMetrics.Bottom > newMinBottom) { if (moveBottomRest) { lowerRestMetrics.LedgerlineVisible = true; // only affects breves, semibreves and minims lowerRestMetrics.Move(0F, Gap); moveBottomRest = false; } else { upperRestMetrics.LedgerlineVisible = true; // only affects breves, semibreves and minims upperRestMetrics.Move(0F, -Gap); moveBottomRest = true; } } verticalOverlap = lowerRestMetrics.OverlapHeight(upperRestMetrics, 0F); } } } } } } }
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); }
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); }
/// <summary> /// There is currently still one bar per system. /// Each voice ends with a barline. /// </summary> protected virtual void ReplaceConsecutiveRestsInBars(int minimumCrotchetDuration) { foreach (SvgSystem system in Systems) { foreach (Staff staff in system.Staves) { if (!(staff is InvisibleOutputStaff)) { foreach (Voice voice in staff.Voices) { Debug.Assert(voice.NoteObjects[voice.NoteObjects.Count - 1] is Barline); // contains lists of consecutive rest indices List <List <int> > restsToReplace = new List <List <int> >(); #region find the consecutive rests List <int> consecRestIndices = new List <int>(); for (int i = 0; i < voice.NoteObjects.Count - 1; i++) { Debug.Assert(!(voice.NoteObjects[i] is Barline)); RestSymbol rest1 = voice.NoteObjects[i] as RestSymbol; RestSymbol rest2 = voice.NoteObjects[i + 1] as RestSymbol; if (rest1 != null && rest2 != null) { if (!consecRestIndices.Contains(i)) { consecRestIndices.Add(i); } consecRestIndices.Add(i + 1); } else { if (consecRestIndices != null && consecRestIndices.Count > 0) { restsToReplace.Add(consecRestIndices); consecRestIndices = new List <int>(); } } } #endregion #region replace the consecutive rests if (restsToReplace.Count > 0) { for (int i = restsToReplace.Count - 1; i >= 0; i--) { List <int> indToReplace = restsToReplace[i]; int msDuration = 0; int msPos = 0; float fontSize = 0F; for (int j = indToReplace.Count - 1; j >= 0; j--) { RestSymbol rest = voice.NoteObjects[indToReplace[j]] as RestSymbol; Debug.Assert(rest != null); msDuration += rest.MsDuration; msPos = rest.MsPosition; fontSize = rest.FontHeight; voice.NoteObjects.RemoveAt(indToReplace[j]); } RestDef umrd = new RestDef(msPos, msDuration); RestSymbol newRest = new RestSymbol(voice, umrd, minimumCrotchetDuration, _pageFormat.MusicFontHeight); newRest.MsPosition = msPos; voice.NoteObjects.Insert(indToReplace[0], newRest); } } #endregion } } } } }
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); } } } } }
public override NoteObject GetNoteObject(Voice voice, int absMsPosition, 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) { if(cautionaryChordDef.NotatedMidiVelocities != null) { CautionaryOutputChordSymbol cautionaryOutputChordSymbol = new CautionaryOutputChordSymbol(voice, cautionaryChordDef, absMsPosition, cautionaryFontHeight); noteObject = cautionaryOutputChordSymbol; } else { CautionaryInputChordSymbol cautionaryInputChordSymbol = new CautionaryInputChordSymbol(voice, cautionaryChordDef, absMsPosition, cautionaryFontHeight); noteObject = cautionaryInputChordSymbol; } } else if(midiChordDef != null) { OutputChordSymbol outputChordSymbol = new OutputChordSymbol(voice, midiChordDef, absMsPosition, minimumCrotchetDuration, musicFontHeight); if(this._coloredVelocities == true) { outputChordSymbol.SetNoteheadColors(); } else if(midiChordDef.NotatedMidiVelocities[0] != currentVelocity) { outputChordSymbol.AddDynamic(midiChordDef.NotatedMidiVelocities[0], currentVelocity); currentVelocity = midiChordDef.NotatedMidiVelocities[0]; } noteObject = outputChordSymbol; } else if(inputChordDef != null) { InputChordSymbol inputChordSymbol = new InputChordSymbol(voice, inputChordDef, absMsPosition, minimumCrotchetDuration, musicFontHeight); noteObject = inputChordSymbol; } else if(restDef != null) { RestSymbol restSymbol = new RestSymbol(voice, iud, absMsPosition, minimumCrotchetDuration, musicFontHeight); noteObject = restSymbol; } else if(clefChangeDef != null) { ClefChangeSymbol clefChangeSymbol = new ClefChangeSymbol(voice, clefChangeDef.ClefType, absMsPosition, cautionaryFontHeight); noteObject = clefChangeSymbol; } return noteObject; }
private void AdjustRestsForVerticalChordCollisions(int restsChannelIndex) { Debug.Assert(restsChannelIndex == 0 || restsChannelIndex == 1); List <NoteObject> restObjects; List <NoteObject> chordObjects; bool shiftRestUp; if (restsChannelIndex == 0) { shiftRestUp = true; restObjects = Voices[0].NoteObjects; chordObjects = Voices[1].NoteObjects; } else { shiftRestUp = false; restObjects = Voices[1].NoteObjects; chordObjects = Voices[0].NoteObjects; } // Move rests in the top voice up by gap increments if they are synchronous with an overlapping chord in the lower voice. // Move rests in the bottom voice down by gap increments if they are synchronous with an overlapping chord in the top voice. foreach (NoteObject restObject in restObjects) { RestSymbol restSymbol = restObject as RestSymbol; if (restSymbol != null) { foreach (NoteObject chordObject in chordObjects) { OutputChordSymbol chordSymbol = chordObject as OutputChordSymbol; if (chordSymbol != null) { if (chordSymbol.MsPosition > restSymbol.MsPosition) { break; } if (chordSymbol.MsPosition == restSymbol.MsPosition) { RestMetrics restMetrics = restSymbol.RestMetrics; ChordMetrics chordMetrics = chordSymbol.ChordMetrics; //float verticalOverlap = chordMetrics.OverlapHeight(restMetrics, Gap / 2F); float verticalOverlap = chordMetrics.OverlapHeight(restMetrics, 0F); if (verticalOverlap > 0) { if (shiftRestUp) { //float newMaxBottom = chordMetrics.Top - Gap; float newMaxBottom = chordMetrics.Top; newMaxBottom += DurationClassDeltaAbove(restSymbol.DurationClass, Gap); while (restMetrics.Bottom > newMaxBottom) { restMetrics.LedgerlineVisible = true; // only affects breves, semibreves and minims restMetrics.Move(0F, -Gap); } break; // to next rest symbol } else { //float newMinTop = chordMetrics.Bottom + Gap; float newMinTop = chordMetrics.Bottom; newMinTop += DurationClassDeltaBelow(restSymbol.DurationClass, Gap); while (restMetrics.Top < newMinTop) { restMetrics.LedgerlineVisible = true; // only affects breves, semibreves and minims restMetrics.Move(0F, Gap); } break; // to next rest symbol } } } } } } } }
public RestMetrics(Graphics graphics, RestSymbol rest, float gap, int numberOfStafflines, float ledgerlineStrokeWidth) : base(rest.DurationClass, true, rest.FontHeight) { float dy = 0; if(numberOfStafflines > 1) dy = gap * (numberOfStafflines / 2); _top = _top + dy; _bottom += dy; _originY += dy; // the staffline on which the rest is aligned _ledgerlineStub = gap * 0.75F; Move((Left - Right) / 2F, 0F); // centre the glyph horizontally switch(rest.DurationClass) { case DurationClass.breve: case DurationClass.semibreve: Move(gap * -0.25F, 0F); if(numberOfStafflines == 1) Move(0F, gap); _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub, ledgerlineStrokeWidth); _ledgerline.AddLedgerline(_originY - gap, 0F); _ledgerline.Move(gap * 0.17F, 0F); _top -= (gap * 1.5F); break; case DurationClass.minim: Move(gap * 0.18F, 0); _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub - (gap * 0.3F), ledgerlineStrokeWidth); _ledgerline.AddLedgerline(_originY, 0F); _bottom += (gap * 1.5F); break; case DurationClass.quaver: _top -= gap * 0.5F; _bottom += gap * 0.5F; break; case DurationClass.semiquaver: _top -= gap * 0.5F; _bottom += gap * 0.5F; break; case DurationClass.threeFlags: _top -= gap * 0.5F; _right += gap * 0.2F; _bottom += gap * 0.5F; _left -= gap * 0.2F; break; case DurationClass.fourFlags: _top -= gap * 0.5F; _right += gap * 0.1F; _bottom += gap * 1.25F; _left -= gap * 0.1F; _originY += gap; break; case DurationClass.fiveFlags: _top -= gap * 1.5F; _right += gap * 0.2F; _bottom += gap * 1.25F; _left -= gap * 0.2F; _originY += gap; break; } }
/// <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; } } }
public RestMetrics(Graphics graphics, RestSymbol rest, float gap, int numberOfStafflines, float ledgerlineStrokeWidth) : base(rest.DurationClass, true, rest.FontHeight) { float dy = 0; if (numberOfStafflines > 1) { dy = gap * (numberOfStafflines / 2); } _top = _top + dy; _bottom += dy; _originY += dy; // the staffline on which the rest is aligned _ledgerlineStub = gap * 0.75F; Move((Left - Right) / 2F, 0F); // centre the glyph horizontally switch (rest.DurationClass) { case DurationClass.breve: case DurationClass.semibreve: Move(gap * -0.25F, 0F); if (numberOfStafflines == 1) { Move(0F, gap); } _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub, ledgerlineStrokeWidth); _ledgerline.AddLedgerline(_originY - gap, 0F); _ledgerline.Move(gap * 0.17F, 0F); _top -= (gap * 1.5F); break; case DurationClass.minim: Move(gap * 0.18F, 0); _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub - (gap * 0.3F), ledgerlineStrokeWidth); _ledgerline.AddLedgerline(_originY, 0F); _bottom += (gap * 1.5F); break; case DurationClass.quaver: _top -= gap * 0.5F; _bottom += gap * 0.5F; break; case DurationClass.semiquaver: _top -= gap * 0.5F; _bottom += gap * 0.5F; break; case DurationClass.threeFlags: _top -= gap * 0.5F; _right += gap * 0.2F; _bottom += gap * 0.5F; _left -= gap * 0.2F; break; case DurationClass.fourFlags: _top -= gap * 0.5F; _right += gap * 0.1F; _bottom += gap * 1.25F; _left -= gap * 0.1F; _originY += gap; break; case DurationClass.fiveFlags: _top -= gap * 1.5F; _right += gap * 0.2F; _bottom += gap * 1.25F; _left -= gap * 0.2F; _originY += gap; break; } }
public RestMetrics(Graphics graphics, RestSymbol rest, double gap, int numberOfStafflines, double ledgerlineStrokeWidth) : base(rest.DurationClass, rest.FontHeight, CSSObjectClass.rest) { double dy = 0; if (numberOfStafflines > 1) { dy = gap * (numberOfStafflines / 2); } _top = _top + dy; _bottom += dy; _originY += dy; // the staffline on which the rest is aligned _ledgerlineStub = gap * 0.75; Move((Left - Right) / 2, 0F); // centre the glyph horizontally CSSObjectClass llBlockClass = CSSObjectClass.ledgerlines; switch (rest.DurationClass) { case DurationClass.breve: case DurationClass.semibreve: Move(gap * -0.25, 0F); if (numberOfStafflines == 1) { Move(0, gap); } _ledgerlineBlockMetrics = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub, ledgerlineStrokeWidth, llBlockClass); _ledgerlineBlockMetrics.AddLedgerline(_originY - gap, 0F); _ledgerlineBlockMetrics.Move(gap * 0.17, 0F); _top -= (gap * 1.5F); break; case DurationClass.minim: Move(gap * 0.18, 0); _ledgerlineBlockMetrics = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub - (gap * 0.3F), ledgerlineStrokeWidth, llBlockClass); _ledgerlineBlockMetrics.AddLedgerline(_originY, 0F); _bottom += (gap * 1.5F); break; case DurationClass.quaver: _top -= gap * 0.5; _bottom += gap * 0.5; break; case DurationClass.semiquaver: _top -= gap * 0.5; _bottom += gap * 0.5; break; case DurationClass.threeFlags: _top -= gap * 0.5; _right += gap * 0.2; _bottom += gap * 0.5; _left -= gap * 0.2; break; case DurationClass.fourFlags: _top -= gap * 0.5; _right += gap * 0.1; _bottom += gap * 1.25; _left -= gap * 0.1; _originY += gap; break; case DurationClass.fiveFlags: _top -= gap * 1.5; _right += gap * 0.2; _bottom += gap * 1.25; _left -= gap * 0.2; _originY += gap; break; } }