Exemplo n.º 1
0
        private void PaintTupletHelper(float cx, float cy, ICanvas canvas, TupletHelper h)
        {
            var res = Resources;
            var oldAlign = canvas.TextAlign;
            canvas.TextAlign = TextAlign.Center;
            // check if we need to paint simple footer
            if (h.Beats.Count == 1 || !h.IsFull)
            {
                for (int i = 0, j = h.Beats.Count; i < j; i++)
                {
                    var beat = h.Beats[i];
                    var beamingHelper = Helpers.BeamHelperLookup[h.VoiceIndex][beat.Index];
                    if (beamingHelper == null) continue;
                    var direction = beamingHelper.Direction;

                    var tupletX = beamingHelper.GetBeatLineX(beat) + Scale;
                    var tupletY = cy + Y + CalculateBeamY(beamingHelper, tupletX);

                    var offset = direction == BeamDirection.Up
                                ? res.EffectFont.Size * 1.8f
                                : -3 * Scale;

                    canvas.Font = res.EffectFont;
                    canvas.FillText(h.Tuplet.ToString(), cx + X + tupletX, tupletY - offset);
                }
            }
            else
            {
                var firstBeat = h.Beats[0];
                var lastBeat = h.Beats[h.Beats.Count - 1];

                var firstBeamingHelper = Helpers.BeamHelperLookup[h.VoiceIndex][firstBeat.Index];
                var lastBeamingHelper = Helpers.BeamHelperLookup[h.VoiceIndex][lastBeat.Index];
                if (firstBeamingHelper != null && lastBeamingHelper != null)
                {
                    var direction = firstBeamingHelper.Direction;

                    //
                    // Calculate the overall area of the tuplet bracket

                    var startX = firstBeamingHelper.GetBeatLineX(firstBeat) + Scale;
                    var endX = lastBeamingHelper.GetBeatLineX(lastBeat) + Scale;

                    //
                    // Calculate how many space the text will need
                    canvas.Font = res.EffectFont;
                    var s = h.Tuplet.ToString();
                    var sw = canvas.MeasureText(s);
                    var sp = 3 * Scale;

                    //
                    // Calculate the offsets where to break the bracket
                    var middleX = (startX + endX) / 2;
                    var offset1X = middleX - sw / 2 - sp;
                    var offset2X = middleX + sw / 2 + sp;

                    //
                    // calculate the y positions for our bracket

                    var startY = CalculateBeamY(firstBeamingHelper, startX);
                    var offset1Y = CalculateBeamY(firstBeamingHelper, offset1X);
                    var middleY = CalculateBeamY(firstBeamingHelper, middleX);
                    var offset2Y = CalculateBeamY(lastBeamingHelper, offset2X);
                    var endY = CalculateBeamY(lastBeamingHelper, endX);

                    var offset = 10 * Scale;
                    var size = 5 * Scale;
                    if (direction == BeamDirection.Down)
                    {
                        offset *= -1;
                        size *= -1;
                    }

                    //
                    // draw the bracket
                    canvas.BeginPath();
                    canvas.MoveTo(cx + X + startX, (int)(cy + Y + startY - offset));
                    canvas.LineTo(cx + X + startX, (int)(cy + Y + startY - offset - size));
                    canvas.LineTo(cx + X + offset1X, (int)(cy + Y + offset1Y - offset - size));
                    canvas.Stroke();

                    canvas.BeginPath();
                    canvas.MoveTo(cx + X + offset2X, (int)(cy + Y + offset2Y - offset - size));
                    canvas.LineTo(cx + X + endX, (int)(cy + Y + endY - offset - size));
                    canvas.LineTo(cx + X + endX, (int)(cy + Y + endY - offset));
                    canvas.Stroke();

                    //
                    // Draw the string
                    canvas.FillText(s, cx + X + middleX, cy + Y + middleY - offset - size - res.EffectFont.Size);
                }
            }
            canvas.TextAlign = oldAlign;
        }
Exemplo n.º 2
0
        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;
                }
            }
        }
Exemplo n.º 3
0
        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;
            }
        }