private OctaveShift CreateContinuedOctavaLine(OctaveShift octaveShift, double gap, System.Drawing.Graphics graphics) { OctaveShift continuedOctaveShiftContinues = null; OctaveShiftExtender octaveShiftExtender = null; foreach (var voice in Voices) { double yMax = Metrics.StafflinesBottom; double yMin = Metrics.StafflinesTop; var noteObjects = voice.NoteObjects; for (var noteObjectIndex = 0; noteObjectIndex < noteObjects.Count; noteObjectIndex++) { if (noteObjects[noteObjectIndex] is OutputChordSymbol chord) { yMax = (yMax > chord.ChordMetrics.Bottom) ? yMax : chord.ChordMetrics.Bottom; yMin = (yMin < chord.ChordMetrics.Top) ? yMin : chord.ChordMetrics.Top; if (chord.EndOctaveShift != null) { // a continuation octaveShiftExtender with endmarker in this staff (= voice). var y = (chord.EndOctaveShift.Orient == Orientation.up) ? yMin : yMax; octaveShiftExtender = new OctaveShiftExtender(chord.EndOctaveShift, graphics, this.Metrics.Left, chord.ChordMetrics.Right, y, gap, true, true); this.Metrics.MetricsList.Add(octaveShiftExtender.Metrics); this.Extenders.Add(octaveShiftExtender); // so that extender.Metrics.WriteSvg(w) will be called correctly continuedOctaveShiftContinues = null; break; } } } if (octaveShiftExtender == null) { // a continuation octaveShiftExtender, with no endmarker, that continues beyond the end of this staff (= voice). var y = (octaveShift.Orient == Orientation.up) ? yMin : yMax; octaveShiftExtender = new OctaveShiftExtender(null, graphics, this.Metrics.Left, Metrics.Right + (gap * 1.1), y, gap, true, false); this.Metrics.MetricsList.Add(octaveShiftExtender.Metrics); this.Extenders.Add(octaveShiftExtender); // so that extender.Metrics.WriteSvg(w) will be called correctly continuedOctaveShiftContinues = octaveShift; } } return(continuedOctaveShiftContinues); }
public OctaveShiftExtender(OctaveShift octaveShift, Graphics graphics, double leftChordLeft, double rightChordRight, double chordsY, double gap, bool isContinuation, bool displayEndMarker) { string text = null; switch (octaveShift.Type) { case OctaveShiftType.down3Oct: text = "3oct"; break; case OctaveShiftType.down2Oct: text = "2oct"; break; case OctaveShiftType.down1Oct: text = "8va"; break; case OctaveShiftType.up1Oct: text = "8va"; // bassa break; case OctaveShiftType.up2Oct: text = "2oct"; // bassa break; case OctaveShiftType.up3Oct: text = "3oct"; // bassa break; } double hLineY = 0; double textY = 0; double textFontHeight = M.PageFormat.OctaveShiftExtenderTextFontHeight; double endMarkerHeight = gap * 0.8; if (octaveShift.Orient == MNX.Common.Orientation.up) { hLineY = chordsY - (gap * 1.3); textY = hLineY + (textFontHeight * 0.6); } else { hLineY = chordsY + (gap * 1.2); textY = hLineY + (gap * 0.1); endMarkerHeight *= -1; } string dashArrayString = (gap / 2).ToString(); // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray TextInfo textInfo = null; if (isContinuation) { text = "(" + text + ")"; textInfo = new TextInfo(text, M.PageFormat.OctaveShiftExtenderTextFontFamily, textFontHeight * 0.9, SVGFontWeight.normal, SVGFontStyle.italic, TextHorizAlign.left); } else { textInfo = new TextInfo(text, M.PageFormat.OctaveShiftExtenderTextFontFamily, textFontHeight, SVGFontWeight.bold, SVGFontStyle.italic, TextHorizAlign.left); } TextMetrics textMetrics = new TextMetrics(CSSObjectClass.octaveShiftExtenderText, graphics, textInfo); textMetrics.Move(leftChordLeft - textMetrics.Left, textY - textMetrics.OriginY); Metrics = new OctaveShiftExtenderMetrics(textMetrics, leftChordLeft, rightChordRight, hLineY, dashArrayString, endMarkerHeight, displayEndMarker); }
internal OctaveShift CreateOctaveShiftExtenders(System.Drawing.Graphics graphics, OctaveShift firstExtenderIsContinuation) { double gap = M.PageFormat.GapVBPX; OctaveShift extenderContinuesOnNextSystem = null; if (firstExtenderIsContinuation != null) { extenderContinuesOnNextSystem = CreateContinuedOctavaLine(firstExtenderIsContinuation, gap, graphics); } if (extenderContinuesOnNextSystem == null) { foreach (var voice in Voices) { var noteObjects = voice.NoteObjects; for (var noteObjectIndex = 0; noteObjectIndex < noteObjects.Count; noteObjectIndex++) { double yMax = Metrics.StafflinesBottom; double yMin = Metrics.StafflinesTop; if (noteObjects[noteObjectIndex] is OutputChordSymbol leftChord && leftChord.OctaveShift != null) { yMax = (yMax > leftChord.ChordMetrics.Bottom) ? yMax : leftChord.ChordMetrics.Bottom; yMin = (yMin < leftChord.ChordMetrics.Top) ? yMin : leftChord.ChordMetrics.Top; OctaveShiftExtender octaveShiftExtender = null; var octaveShift = leftChord.OctaveShift; for (var rightNOIndex = noteObjectIndex; rightNOIndex < noteObjects.Count; rightNOIndex++) { if (noteObjects[rightNOIndex] is OutputChordSymbol rightChord) { yMax = (yMax > rightChord.ChordMetrics.Bottom) ? yMax : rightChord.ChordMetrics.Bottom; yMin = (yMin < rightChord.ChordMetrics.Top) ? yMin : rightChord.ChordMetrics.Top; if (rightChord.EventID == leftChord.OctaveShift.TargetID) { var y = (leftChord.OctaveShift.Orient == Orientation.up) ? yMin : yMax; // an octaveShiftExtender with endmarker, that ends in this voice. octaveShiftExtender = new OctaveShiftExtender(octaveShift, graphics, leftChord.ChordMetrics.Left, rightChord.ChordMetrics.Right, y, gap, false, true); extenderContinuesOnNextSystem = leftChord.OctaveShift; break; } } } if (octaveShiftExtender == null) { var y = (leftChord.OctaveShift.Orient == Orientation.up) ? yMin : yMax; // an octaveShiftExtender, without endmarker, that extends to the right of the system. octaveShiftExtender = new OctaveShiftExtender(octaveShift, graphics, leftChord.ChordMetrics.Left, Metrics.Right + (gap * 1.1), y, gap, false, false); extenderContinuesOnNextSystem = leftChord.OctaveShift; } this.Metrics.MetricsList.Add(octaveShiftExtender.Metrics); // so that the extender will be moved vertically correctly this.Extenders.Add(octaveShiftExtender); // so that extender.Metrics.WriteSvg(w) will be called correctly } } } } return(extenderContinuesOnNextSystem); }