internal void AddSlurTemplate(double slurBeginX, double slurBeginY, double slurEndX, double slurEndY, double gap, bool isOver, double endAngle) { // The SVG scale is such that there is no problem using integers here. double dyControl = gap * 3; double dxControl = dyControl / Math.Tan(endAngle); double x1 = slurBeginX; double y1 = slurBeginY; double x4 = slurEndX; double y4 = slurEndY; SlurTemplate slurTemplate = null; double shortSlurMaxWidth = gap * 20; // 5 staff heights double shortSlurMinWidth = gap * 9.5; // 4.4 is shortTieMaxWidth double width = x4 - x1; if (width <= shortSlurMaxWidth) { if (width <= shortSlurMinWidth) { double factor = width / shortSlurMinWidth; dxControl *= factor; dyControl *= factor; } // short (=two-point) slur template // standard Bezier points var p1 = new Point((int)x1, (int)y1); var p2 = (isOver) ? new Point((int)(x1 + dxControl), (int)(y1 - dyControl)) : new Point((int)(x1 + dxControl), (int)(y1 + dyControl)); var p4 = new Point((int)x4, (int)y4); var p3 = (isOver) ? new Point((int)(x4 - dxControl), (int)(y4 - dyControl)) : new Point((int)(x4 - dxControl), (int)(y4 + dyControl)); slurTemplate = new SlurTemplate(p1, p2, p3, p4, gap, isOver); } else { // long (=three-point) slur template var p1 = new Point((int)x1, (int)y1); var c1 = (isOver) ? new Point((int)(x1 + dxControl), (int)(y1 - dyControl)) : new Point((int)(x1 + dxControl), (int)(y1 + dyControl)); var p3 = new Point((int)x4, (int)y4); var c3 = (isOver) ? new Point((int)(x4 - dxControl), (int)(y4 - dyControl)) : new Point((int)(x4 - dxControl), (int)(y4 + dyControl)); var p2 = new Point((int)((x1 + x4) / 2), (int)((y1 + c1.Y) / 2)); var c2 = new Point((p1.X + p2.X) / 2, p2.Y); slurTemplate = new SlurTemplate(p1, c1, c2, p2, c3, p3, gap, isOver); } ChordMetrics.SlurTemplates.Add(slurTemplate); // So that the slurTemplate will be written to SVG. ChordMetrics.AddSlurTieMetrics((SlurTieMetrics)slurTemplate.Metrics); // So that the tie will be moved vertically with the system. }
/// <summary> /// Tie templates have similar point and control point structures as a slurs, except that /// 1. they are both horizontal and symmetric. /// 2. the maximum width of a short tie is twice the width of a tie hook. /// 3. long slurs have three points on the slur, long ties have four points on the tie. /// </summary> /// <param name="tieTemplateBeginX"></param> /// <param name="tieBeginY"></param> /// <param name="tieTemplateEndX"></param> /// <param name="tieTemplateY"></param> /// <param name="gap"></param> /// <param name="isOver"></param> internal void AddTieTemplate(double tieTemplateBeginX, double tieTemplateEndX, double tieTemplateY, double gap, bool isOver) { // The SVG scale is such that there should be no problem using integers here. TieTemplate tieTemplate = null; double p1x = tieTemplateBeginX; double p1y = tieTemplateY; double p2x = tieTemplateEndX; double p2y = tieTemplateY; double shortTieMaxWidth = gap * 10; double veryShortTieMaxWidth = gap * 3.45; double width = p2x - p1x; double deltaControl; // the x and y distance between an end-point on the template and its related control point. if (width <= shortTieMaxWidth) { deltaControl = (width <= veryShortTieMaxWidth) ? width / 3 : gap * 1.15; var p1 = new Point((int)p1x, (int)p1y); var c1 = (isOver) ? new Point((int)(p1x + deltaControl), (int)(p1y - deltaControl)) : new Point((int)(p1x + deltaControl), (int)(p1y + deltaControl)); var p2 = new Point((int)p2x, (int)p2y); var c2 = (isOver) ? new Point((int)(p2x - deltaControl), (int)(p2y - deltaControl)) : new Point((int)(p2x - deltaControl), (int)(p2y + deltaControl)); tieTemplate = new ShortTieTemplate(p1, c1, c2, p2, gap, isOver); } else { deltaControl = (gap * 0.85); // long tie template var p1 = new Point((int)p1x, (int)p1y); var c1 = (isOver) ? new Point((int)(p1x + deltaControl), (int)(p1y - deltaControl)) : new Point((int)(p1x + deltaControl), (int)(p1y + deltaControl)); var tc = new Point(c1.X + (int)(deltaControl / 2), c1.Y); var tp = new Point((int)(p1x + (p2x - p1x) / 2), c1.Y); var c2 = (isOver) ? new Point((int)(p2x - deltaControl), (int)(p2y - deltaControl)) : new Point((int)(p2x - deltaControl), (int)(p2y + deltaControl)); var p2 = new Point((int)p2x, (int)p2y); tieTemplate = new LongTieTemplate(p1, c1, tc, tp, c2, p2, gap, isOver); } ChordMetrics.TieTemplates.Add(tieTemplate); // So that the slurTemplate will be written to SVG. ChordMetrics.AddSlurTieMetrics((SlurTieMetrics)tieTemplate.Metrics); // So that the tie will be moved vertically with the system. }