private void PaintBeamHelper(float cx, float cy, ICanvas canvas, BeamingHelper h) { if (h.Beats[0].GraceType != GraceType.None) return; var useBeams = Stave.GetSetting("use-beams", false); // check if we need to paint simple footer if (useBeams && h.Beats.Count == 1) { PaintFooter(cx, cy, canvas, h); } else { PaintBar(cx, cy, canvas, h); } }
public BarHelpers(Bar bar) { BeamHelpers = new FastList <FastList <BeamingHelper> >(); BeamHelperLookup = new FastList <FastDictionary <int, BeamingHelper> >(); TupletHelpers = new FastList <FastList <TupletHelper> >(); BeamingHelper currentBeamHelper = null; TupletHelper currentTupletHelper = null; if (bar != null) { for (int i = 0, j = bar.Voices.Count; i < j; i++) { var v = bar.Voices[i]; BeamHelpers.Add(new FastList <BeamingHelper>()); BeamHelperLookup.Add(new FastDictionary <int, BeamingHelper>()); TupletHelpers.Add(new FastList <TupletHelper>()); for (int k = 0, l = v.Beats.Count; k < l; k++) { var b = v.Beats[k]; var forceNewTupletHelper = false; // if a new beaming helper was started, we close our tuplet grouping as well if (!b.IsRest) { // try to fit beam to current beamhelper if (currentBeamHelper == null || !currentBeamHelper.CheckBeat(b)) { if (currentBeamHelper != null) { currentBeamHelper.Finish(); forceNewTupletHelper = currentBeamHelper.Beats.Count > 1; } else { forceNewTupletHelper = true; } // if not possible, create the next beaming helper currentBeamHelper = new BeamingHelper(bar.Staff); currentBeamHelper.CheckBeat(b); BeamHelpers[v.Index].Add(currentBeamHelper); } } if (b.HasTuplet) { // try to fit tuplet to current tuplethelper // TODO: register tuplet overflow var previousBeat = b.PreviousBeat; // don't group if the previous beat isn't in the same voice if (previousBeat != null && previousBeat.Voice != b.Voice) { previousBeat = null; } // if a new beaming helper was started, we close our tuplet grouping as well if (forceNewTupletHelper && currentTupletHelper != null) { currentTupletHelper.Finish(); } if (previousBeat == null || currentTupletHelper == null || !currentTupletHelper.Check(b)) { currentTupletHelper = new TupletHelper(v.Index); currentTupletHelper.Check(b); TupletHelpers[v.Index].Add(currentTupletHelper); } } BeamHelperLookup[v.Index][b.Index] = currentBeamHelper; } if (currentBeamHelper != null) { currentBeamHelper.Finish(); } if (currentTupletHelper != null) { currentTupletHelper.Finish(); } currentBeamHelper = null; currentTupletHelper = null; } } }
private void PaintFooter(float cx, float cy, ICanvas canvas, BeamingHelper h) { var beat = h.Beats[0]; var isGrace = beat.GraceType != GraceType.None; var scaleMod = isGrace ? NoteHeadGlyph.GraceScale : 1; // // draw line // var stemSize = GetFooterStemSize(h.ShortestDuration); var beatLineX = h.GetBeatLineX(beat) + Scale; var direction = h.Direction; var topY = GetScoreY(GetNoteLine(beat.MaxNote)); var bottomY = GetScoreY(GetNoteLine(beat.MinNote)); float beamY; float fingeringY; if (direction == BeamDirection.Down) { bottomY += stemSize * scaleMod; beamY = bottomY; fingeringY = cy + Y + bottomY; } else { topY -= stemSize * scaleMod; beamY = topY; fingeringY = cy + Y + topY; } PaintFingering(canvas, beat, cx + X + beatLineX, direction, fingeringY); if (beat.Duration == Duration.Whole || beat.Duration == Duration.DoubleWhole) { return; } canvas.BeginPath(); canvas.MoveTo(cx + X + beatLineX, cy + Y + topY); canvas.LineTo(cx + X + beatLineX, cy + Y + bottomY); canvas.Stroke(); if (isGrace) { var graceSizeY = 15 * Scale; var graceSizeX = 12 * Scale; canvas.BeginPath(); if (direction == BeamDirection.Down) { canvas.MoveTo(cx + X + beatLineX - (graceSizeX / 2), cy + Y + bottomY - graceSizeY); canvas.LineTo(cx + X + beatLineX + (graceSizeX / 2), cy + Y + bottomY); } else { canvas.MoveTo(cx + X + beatLineX - (graceSizeX / 2), cy + Y + topY + graceSizeY); canvas.LineTo(cx + X + beatLineX + (graceSizeX / 2), cy + Y + topY); } canvas.Stroke(); } // // Draw beam // if (beat.Duration > Duration.Quarter) { var glyph = new BeamGlyph(beatLineX - Scale / 2f, beamY, beat.Duration, direction, isGrace); glyph.Renderer = this; glyph.DoLayout(); glyph.Paint(cx + X, cy + Y, canvas); } }
private void PaintBeamHelper(float cx, float cy, ICanvas canvas, BeamingHelper h) { canvas.Color = h.Voice.Index == 0 ? Resources.MainGlyphColor : Resources.SecondaryGlyphColor; // check if we need to paint simple footer if (h.Beats.Count == 1) { PaintFooter(cx, cy, canvas, h); } else { PaintBar(cx, cy, canvas, h); } }
private void PaintBar(float cx, float cy, ICanvas canvas, BeamingHelper h) { for (int i = 0, j = h.Beats.Count; i < j; i++) { var beat = h.Beats[i]; // // draw line // var beatLineX = h.GetBeatLineX(beat) + Scale; var direction = h.Direction; var y1 = cy + Y + (direction == BeamDirection.Up ? GetScoreY(GetNoteLine(beat.MinNote)) : GetScoreY(GetNoteLine(beat.MaxNote))); var y2 = cy + Y + CalculateBeamY(h, beatLineX); canvas.BeginPath(); canvas.MoveTo(cx + X + beatLineX, y1); canvas.LineTo(cx + X + beatLineX, y2); canvas.Stroke(); float fingeringY = y2; if (direction == BeamDirection.Down) { fingeringY += canvas.Font.Size * 2f; } else if (i != 0) { fingeringY -= canvas.Font.Size * 1.5f; } PaintFingering(canvas, beat, cx + X + beatLineX, direction, fingeringY); var brokenBarOffset = 6 * Scale; var barSpacing = 6 * Scale; var barSize = 3 * Scale; var barCount = beat.Duration.GetIndex() - 2; var barStart = cy + Y; if (direction == BeamDirection.Down) { barSpacing = -barSpacing; barSize = -barSize; } for (var barIndex = 0; barIndex < barCount; barIndex++) { float barStartX; float barEndX; float barStartY; float barEndY; var barY = barStart + (barIndex * barSpacing); // // Bar to Next? // if (i < h.Beats.Count - 1) { // full bar? if (IsFullBarJoin(beat, h.Beats[i + 1], barIndex)) { barStartX = beatLineX; barEndX = h.GetBeatLineX(h.Beats[i + 1]) + Scale; } // broken bar? else if (i == 0 || !IsFullBarJoin(h.Beats[i - 1], beat, barIndex)) { barStartX = beatLineX; barEndX = barStartX + brokenBarOffset; } else { continue; } barStartY = barY + CalculateBeamY(h, barStartX); barEndY = barY + CalculateBeamY(h, barEndX); PaintSingleBar(canvas, cx + X + barStartX, barStartY, cx + X + barEndX, barEndY, barSize); } // // Broken Bar to Previous? // else if (i > 0 && !IsFullBarJoin(beat, h.Beats[i - 1], barIndex)) { barStartX = beatLineX - brokenBarOffset; barEndX = beatLineX; barStartY = barY + CalculateBeamY(h, barStartX); barEndY = barY + CalculateBeamY(h, barEndX); PaintSingleBar(canvas, cx + X + barStartX, barStartY, cx + X + barEndX, barEndY, barSize); } } } }
private float GetStemSize(BeamingHelper helper) { return helper.Beats.Count == 1 ? GetFooterStemSize(helper.ShortestDuration) : GetBarStemSize(helper.ShortestDuration); }
private float CalculateBeamY(BeamingHelper h, float x) { var stemSize = GetStemSize(h); return h.CalculateBeamY(stemSize, Scale, x, Scale, n => GetScoreY(GetNoteLine(n))); }
private float CalculateBeamY(BeamingHelper h, float x) { var correction = NoteHeadGlyph.NoteHeadHeight / 2; var stemSize = GetStemSize(h.MaxDuration); return h.CalculateBeamY(stemSize, Scale, x, Scale, n => GetScoreY(GetNoteLine(n), correction - 1)); }
private void PaintBeamHelper(float cx, float cy, ICanvas canvas, BeamingHelper h) { // check if we need to paint simple footer if (h.Beats.Count == 1) { PaintFooter(cx, cy, canvas, h); } else { PaintBar(cx, cy, canvas, h); } }
public BarHelpers(Bar bar) { BeamHelpers = new FastList<FastList<BeamingHelper>>(); BeamHelperLookup = new FastList<FastDictionary<int, BeamingHelper>>(); TupletHelpers = new FastList<FastList<TupletHelper>>(); BeamingHelper currentBeamHelper = null; TupletHelper currentTupletHelper = null; for (int i = 0, j = bar.Voices.Count; i < j; i++) { var v = bar.Voices[i]; BeamHelpers.Add(new FastList<BeamingHelper>()); BeamHelperLookup.Add(new FastDictionary<int, BeamingHelper>()); TupletHelpers.Add(new FastList<TupletHelper>()); for (int k = 0, l = v.Beats.Count; k < l; k++) { var b = v.Beats[k]; var newBeamingHelper = false; if (!b.IsRest) { // try to fit beam to current beamhelper if (currentBeamHelper == null || !currentBeamHelper.CheckBeat(b)) { // if not possible, create the next beaming helper currentBeamHelper = new BeamingHelper(bar.Track); currentBeamHelper.CheckBeat(b); BeamHelpers[v.Index].Add(currentBeamHelper); newBeamingHelper = true; } } if (b.HasTuplet) { // try to fit tuplet to current tuplethelper // TODO: register tuplet overflow var previousBeat = b.PreviousBeat; // don't group if the previous beat isn't in the same voice if (previousBeat != null && previousBeat.Voice != b.Voice) previousBeat = null; // if a new beaming helper was started, we close our tuplet grouping as well if (newBeamingHelper && currentTupletHelper != null) { currentTupletHelper.Finish(); } if (previousBeat == null || currentTupletHelper == null || !currentTupletHelper.Check(b)) { currentTupletHelper = new TupletHelper(v.Index); currentTupletHelper.Check(b); TupletHelpers[v.Index].Add(currentTupletHelper); } } BeamHelperLookup[v.Index][b.Index] = currentBeamHelper; } currentBeamHelper = null; currentTupletHelper = null; } }
private void PaintFooter(float cx, float cy, ICanvas canvas, BeamingHelper h) { var beat = h.Beats[0]; if (beat.Duration == Duration.Whole || beat.Duration == Duration.DoubleWhole) { return; } // // draw line // var beatLineX = h.GetBeatLineX(beat) + Scale; const float topY = 0; var bottomY = Height; float beamY = _direction == BeamDirection.Down ? bottomY : topY; canvas.BeginPath(); canvas.MoveTo(cx + X + beatLineX, cy + Y + topY); canvas.LineTo(cx + X + beatLineX, cy + Y + bottomY); canvas.Stroke(); // // Draw beam // var glyph = new BeamGlyph(beatLineX, beamY, beat.Duration, _direction, false); glyph.Renderer = this; glyph.DoLayout(); glyph.Paint(cx + X, cy + Y, canvas); }
private void PaintBar(float cx, float cy, ICanvas canvas, BeamingHelper h) { for (int i = 0, j = h.Beats.Count; i < j; i++) { var beat = h.Beats[i]; if (h.HasBeatLineX(beat)) { // // draw line // var beatLineX = h.GetBeatLineX(beat) + Scale; var y1 = cy + Y; var y2 = cy + Y + Height; canvas.BeginPath(); canvas.MoveTo(cx + X + beatLineX, y1); canvas.LineTo(cx + X + beatLineX, y2); canvas.Stroke(); var brokenBarOffset = (6 * Scale); var barSpacing = (6 * Scale); var barSize = (3 * Scale); var barCount = beat.Duration.GetIndex() - 2; var barStart = cy + Y; if (_direction == BeamDirection.Down) { barSpacing = -barSpacing; barStart += Height; } for (int barIndex = 0; barIndex < barCount; barIndex++) { float barStartX; float barEndX; float barStartY; float barEndY; var barY = barStart + (barIndex * barSpacing); // // Broken Bar to Next // if (h.Beats.Count == 1) { barStartX = beatLineX; barEndX = beatLineX + brokenBarOffset; barStartY = barY; barEndY = barY; PaintSingleBar(canvas, cx + X + barStartX, barStartY, cx + X + barEndX, barEndY, barSize); } // // Bar to Next? // else if (i < h.Beats.Count - 1) { // full bar? if (IsFullBarJoin(beat, h.Beats[i + 1], barIndex)) { barStartX = beatLineX; barEndX = h.GetBeatLineX(h.Beats[i + 1]) + Scale; } // broken bar? else if (i == 0 || !IsFullBarJoin(h.Beats[i - 1], beat, barIndex)) { barStartX = beatLineX; barEndX = barStartX + brokenBarOffset; } else { continue; } barStartY = barY; barEndY = barY; PaintSingleBar(canvas, cx + X + barStartX, barStartY, cx + X + barEndX, barEndY, barSize); } // // Broken Bar to Previous? // else if (i > 0 && !IsFullBarJoin(beat, h.Beats[i - 1], barIndex)) { barStartX = beatLineX - brokenBarOffset; barEndX = beatLineX; barStartY = barY; barEndY = barY; PaintSingleBar(canvas, cx + X + barStartX, barStartY, cx + X + barEndX, barEndY, barSize); } } } } }
private void PaintBeamHelper(float cx, float cy, ICanvas canvas, BeamingHelper h) { if (h.Beats[0].GraceType != GraceType.None) return; // check if we need to paint simple footer if (h.Beats.Count == 1) { PaintFooter(cx, cy, canvas, h); } else { PaintBar(cx, cy, canvas, h); } }