/// <summary> /// Creates a TopEdge by inverting the bottomEdge /// </summary> public TopEdge(BottomEdge bottomEdge) : base() { foreach (HLine line in bottomEdge.Lines) { HLine fLine = new HLine(line.Left, line.Right, -line.Y); Lines.Add(fLine); } }
/// <summary> /// Returns the (minimum) vertical distance to the bottom edge above. /// This top edge and the bottom edge above belong to two diferent objects, for example two staves or two systems. /// The returned value is positive if this top edge is completely below the bottomEdge argument. /// </summary> /// <param name="currentMinDist"></param> /// <param name="rightEdge"></param> /// <returns></returns> public double DistanceToEdgeAbove(BottomEdge bottomEdge) { double minDist = double.MaxValue; HashSet <double> allLeftXs = AllLeftXsInBothEdges(bottomEdge); foreach (double leftX in allLeftXs) { double bottomEdgeYatLeftX = bottomEdge.YatX(leftX); double topEdgeYatLeftX = this.YatX(leftX); double dist = topEdgeYatLeftX - bottomEdgeYatLeftX; minDist = minDist < dist ? minDist : dist; } return(minDist); }
/// <summary> /// Returns the (minimum) vertical distance to the bottom edge above. /// This top edge and the bottom edge above belong to two diferent objects, for example two staves or two systems. /// The returned value is positive if this top edge is completely below the bottomEdge argument. /// </summary> /// <param name="currentMinDist"></param> /// <param name="rightEdge"></param> /// <returns></returns> public float DistanceToEdgeAbove(BottomEdge bottomEdge) { float minDist = float.MaxValue; HashSet <float> allLeftXs = AllLeftXsInBothEdges(bottomEdge); foreach (float leftX in allLeftXs) { float bottomEdgeYatLeftX = bottomEdge.YatX(leftX); float topEdgeYatLeftX = this.YatX(leftX); float dist = topEdgeYatLeftX - bottomEdgeYatLeftX; minDist = minDist < dist ? minDist : dist; } return(minDist); }
private HashSet <double> AllLeftXsInBothEdges(BottomEdge bottomEdge) { HashSet <double> allXs = new HashSet <double>(); foreach (HLine ht in Lines) { allXs.Add(ht.Left); } foreach (HLine ht in bottomEdge.Lines) { if (!allXs.Contains(ht.Left)) { allXs.Add(ht.Left); } } return(allXs); }
private BottomEdge GetBottomEdge(int upperStaffIndex, int topVisibleStaffIndex, float pageWidth, float gap) { BottomEdge bottomEdge = null; for(int i = upperStaffIndex; i >= topVisibleStaffIndex; --i) { Staff staff = Staves[i]; if(!(staff is HiddenOutputStaff) && staff.Metrics != null) { bottomEdge = new BottomEdge(staff, 0F, pageWidth, gap); break; } } return bottomEdge; }
private void WriteConnectors(SvgWriter w, int systemNumber, PageFormat pageFormat) { List<bool> barlineContinuesDownList = pageFormat.BarlineContinuesDownList; int topVisibleStaffIndex = TopUnHiddenStaffIndex(); Debug.Assert(barlineContinuesDownList[barlineContinuesDownList.Count - 1] == false); Barline barline = null; bool isFirstBarline = true; for(int staffIndex = topVisibleStaffIndex; staffIndex < Staves.Count; staffIndex++) { Staff staff = Staves[staffIndex]; if(staff.Metrics != null) { Voice voice = staff.Voices[0]; float barlinesTop = staff.Metrics.StafflinesTop; float barlinesBottom = staff.Metrics.StafflinesBottom; #region set barlinesTop, barlinesBottom switch(staff.NumberOfStafflines) { case 1: barlinesTop -= (staff.Gap * 1.5F); barlinesBottom += (staff.Gap * 1.5F); break; case 2: case 3: case 4: barlinesTop -= staff.Gap; barlinesBottom += staff.Gap; break; default: break; } #endregion set barlinesTop, barlinesBottom #region draw barlines down from staves if(staffIndex < Staves.Count - 1) { //TopEdge topEdge = new TopEdge(Staves[staffIndex + 1], 0F, pageFormat.Right); TopEdge topEdge = GetTopEdge(staffIndex + 1, pageFormat.Right); if(topEdge != null) { BottomEdge bottomEdge = new BottomEdge(staff, 0F, pageFormat.Right, pageFormat.Gap); isFirstBarline = true; for(int i = 0; i < voice.NoteObjects.Count; ++i) { NoteObject noteObject = voice.NoteObjects[i]; barline = noteObject as Barline; if(barline != null) { // draw grouping barlines between staves if(barlineContinuesDownList[staffIndex - topVisibleStaffIndex] || isFirstBarline) { float top = bottomEdge.YatX(barline.Metrics.OriginX); float bottom = topEdge.YatX(barline.Metrics.OriginX); bool isLastNoteObject = (i == (voice.NoteObjects.Count - 1)); barline.WriteSVG(w, top, bottom, pageFormat.BarlineStrokeWidth, pageFormat.StafflineStemStrokeWidth, isLastNoteObject, true); isFirstBarline = false; } } } } } #endregion } } }
private HashSet<float> AllLeftXsInBothEdges(BottomEdge bottomEdge) { HashSet<float> allXs = new HashSet<float>(); foreach(HLine ht in Lines) { allXs.Add(ht.Left); } foreach(HLine ht in bottomEdge.Lines) { if(!allXs.Contains(ht.Left)) { allXs.Add(ht.Left); } } return allXs; }
/// <summary> /// Returns the (minimum) vertical distance to the bottom edge above. /// This top edge and the bottom edge above belong to two diferent objects, for example two staves or two systems. /// The returned value is positive if this top edge is completely below the bottomEdge argument. /// </summary> /// <param name="currentMinDist"></param> /// <param name="rightEdge"></param> /// <returns></returns> public float DistanceToEdgeAbove(BottomEdge bottomEdge) { float minDist = float.MaxValue; HashSet<float> allLeftXs = AllLeftXsInBothEdges(bottomEdge); foreach(float leftX in allLeftXs) { float bottomEdgeYatLeftX = bottomEdge.YatX(leftX); float topEdgeYatLeftX = this.YatX(leftX); float dist = topEdgeYatLeftX - bottomEdgeYatLeftX; minDist = minDist < dist ? minDist : dist; } return minDist; }
/// <summary> /// Creates a TopEdge by inverting the bottomEdge /// </summary> public TopEdge(BottomEdge bottomEdge) : base() { foreach(HLine line in bottomEdge.Lines) { HLine fLine = new HLine(line.Left, line.Right, -line.Y); Lines.Add(fLine); } }
private void JustifyVertically(float pageWidth, float gap) { int topVisibleStaffIndex = TopVisibleStaffIndex(); Debug.Assert(Staves[topVisibleStaffIndex].Metrics.StafflinesTop == 0); if((topVisibleStaffIndex + 1) < Staves.Count)// There must be at least one visible staff (an InputStaff). { for(int i = (topVisibleStaffIndex + 1); i < Staves.Count; ++i) { BottomEdge bottomEdge = new BottomEdge(Staves[i - 1], 0F, pageWidth, gap); TopEdge topEdge = new TopEdge(Staves[i], 0F, pageWidth); float separation = topEdge.DistanceToEdgeAbove(bottomEdge); float dy = gap - separation; // limit stafflineHeight to multiples of pageFormat.Gap so that stafflines // are not displayed as thick grey lines. dy = dy - (dy % gap) + gap; // the minimum space bewteen stafflines is gap pixels. if(dy > 0F) { for(int j = i; j < Staves.Count; ++j) { Staves[j].Metrics.Move(0F, dy); } this.Metrics.StafflinesBottom += dy; } } } this.Metrics = new SystemMetrics(); foreach(Staff staff in Staves) { if(!(staff is InvisibleOutputStaff)) this.Metrics.Add(staff.Metrics); } Debug.Assert(this.Metrics.StafflinesTop == 0); }