예제 #1
0
        private List <float> GetX1sFromChord1(ChordMetrics chord1Metrics, float hairlinePadding)
        {
            List <float>           x1s = new List <float>();
            LedgerlineBlockMetrics upperLedgerlineMetrics = chord1Metrics.UpperLedgerlineBlockMetrics;
            LedgerlineBlockMetrics lowerLedgerlineMetrics = chord1Metrics.LowerLedgerlineBlockMetrics;
            List <HeadMetrics>     headsMetrics           = chord1Metrics.HeadsMetrics;

            Debug.Assert(headsMetrics.Count > 0);

            foreach (HeadMetrics headmetrics in headsMetrics)
            {
                float x1 = headmetrics.Right;
                if (upperLedgerlineMetrics != null &&
                    headmetrics.OriginY >= upperLedgerlineMetrics.Top && headmetrics.OriginY <= upperLedgerlineMetrics.Bottom)
                {
                    x1 = upperLedgerlineMetrics.Right;
                }
                if (lowerLedgerlineMetrics != null &&
                    headmetrics.OriginY >= lowerLedgerlineMetrics.Top && headmetrics.OriginY <= lowerLedgerlineMetrics.Bottom)
                {
                    x1 = lowerLedgerlineMetrics.Right;
                }

                x1s.Add(x1 + hairlinePadding);
            }
            return(x1s);
        }
예제 #2
0
        private List <float> GetX2sFromChord2(List <float> ys, ChordMetrics chord2Metrics, float hairlinePadding)
        {
            List <float>           x2s = new List <float>();
            LedgerlineBlockMetrics c2UpperLedgerlineMetrics = chord2Metrics.UpperLedgerlineBlockMetrics;
            LedgerlineBlockMetrics c2LowerLedgerlineMetrics = chord2Metrics.LowerLedgerlineBlockMetrics;
            List <HeadMetrics>     c2headsMetrics           = chord2Metrics.HeadsMetrics;

            Debug.Assert(c2headsMetrics.Count > 0);
            List <AccidentalMetrics> c2AccidentalsMetrics = chord2Metrics.TopDownAccidentalsMetrics;

            float verticalPadding = hairlinePadding * 4.0f;

            foreach (float y in ys)
            {
                float x2 = float.MaxValue;
                if (c2UpperLedgerlineMetrics != null)
                {
                    if (y >= (c2UpperLedgerlineMetrics.Top - verticalPadding) &&
                        y <= (c2UpperLedgerlineMetrics.Bottom + verticalPadding))
                    {
                        x2 = x2 < c2UpperLedgerlineMetrics.Left ? x2 : c2UpperLedgerlineMetrics.Left;
                    }
                }
                if (c2LowerLedgerlineMetrics != null)
                {
                    if (y >= (c2LowerLedgerlineMetrics.Top - verticalPadding) &&
                        y <= (c2LowerLedgerlineMetrics.Bottom + verticalPadding))
                    {
                        x2 = x2 < c2LowerLedgerlineMetrics.Left ? x2 : c2LowerLedgerlineMetrics.Left;
                    }
                }
                foreach (HeadMetrics headMetrics in c2headsMetrics)
                {
                    if (y >= (headMetrics.Top - verticalPadding) &&
                        y <= (headMetrics.Bottom + verticalPadding))
                    {
                        x2 = x2 < headMetrics.Left ? x2 : headMetrics.Left;
                    }
                }
                foreach (AccidentalMetrics accidentalMetrics in c2AccidentalsMetrics)
                {
                    if (y >= (accidentalMetrics.Top - verticalPadding) &&
                        y <= (accidentalMetrics.Bottom + verticalPadding))
                    {
                        x2 = x2 < accidentalMetrics.Left ? x2 : accidentalMetrics.Left;
                    }
                }
                x2 = x2 < float.MaxValue ? x2 : chord2Metrics.Left;
                x2s.Add(x2 - hairlinePadding);
            }

            float minX = float.MaxValue;

            foreach (float x in x2s)
            {
                minX = minX < x ? minX : x;
            }
            List <float> x2sMinimum = new List <float>();

            foreach (float x in x2s)
            {
                x2sMinimum.Add(minX);
            }

            return(x2sMinimum);
        }
예제 #3
0
        /// <summary>
        /// The accidental is at the correct height (accidental.OriginY == head.OriginY), 
        /// but it has not yet been added to this.MetricsList, or used to set this chord's Boundary.
        /// The accidental is now moved left, such that it does not overlap noteheads, stem, ledgerlines or accidentals.
        /// It is added to this.MetricsList after this function returns.
        /// </summary>
        private void MoveAccidentalLeft(AccidentalMetrics accidentalMetrics, List<HeadMetrics> topDownHeadsMetrics,
            StemMetrics stemMetrics,
            LedgerlineBlockMetrics upperLedgerlineBlockMetrics, LedgerlineBlockMetrics lowerLedgerlineBlockMetrics,
            List<AccidentalMetrics> existingAccidentalsMetrics)
        {
            #region move left of ledgerline block
            if(upperLedgerlineBlockMetrics != null)
            {
                MoveAccidentalLeftOfLedgerlineBlock(accidentalMetrics, upperLedgerlineBlockMetrics);
            }
            if(lowerLedgerlineBlockMetrics != null)
            {
                MoveAccidentalLeftOfLedgerlineBlock(accidentalMetrics, lowerLedgerlineBlockMetrics);
            }
            #endregion
            #region move left of noteheads
            float topRange = accidentalMetrics.OriginY - (_gap * 1.51F);
            float bottomRange = accidentalMetrics.OriginY + (_gap * 1.51F);
            foreach(HeadMetrics head in topDownHeadsMetrics)
            {
                if(head.OriginY > topRange && head.OriginY < bottomRange && head.Overlaps(accidentalMetrics))
                {
                    float extraHorizontalSpace = 0;
                    if(accidentalMetrics.ID_Type == "b")
                        extraHorizontalSpace = accidentalMetrics.FontHeight * -0.03F;

                    accidentalMetrics.Move(head.Left - extraHorizontalSpace - accidentalMetrics.Right, 0);
                }
            }
            #endregion
            #region move left of stem (can be in another chord)
            if(stemMetrics != null)
            {
                // Note that the length of the stem is ignored here.
                float maxRight = stemMetrics.Left - stemMetrics.StrokeWidth;
                if(maxRight < accidentalMetrics.Right)
                    accidentalMetrics.Move(maxRight - accidentalMetrics.Right, 0F);
            }
            #endregion
            #region move accidental left of existing accidentals
            MoveLeftOfExistingAccidentals(existingAccidentalsMetrics, 0, accidentalMetrics);
            #endregion
        }
예제 #4
0
        private void MoveAccidentalLeftOfLedgerlineBlock(AccidentalMetrics accidentalM, LedgerlineBlockMetrics ledgerlineBlockM)
        {
            Debug.Assert(accidentalM != null && ledgerlineBlockM != null);

            //float top = ledgerlineBlockM.Top - (_gap * 0.51F);
            //float bottom = ledgerlineBlockM.Bottom + (_gap * 0.51F);
            float top = ledgerlineBlockM.Top - (_gap * 1.01F);
            float bottom = ledgerlineBlockM.Bottom + (_gap * 1.01F);
            if(accidentalM.OriginY > top && accidentalM.OriginY < bottom)
                accidentalM.Move(ledgerlineBlockM.Left - accidentalM.Right, 0F);
        }
예제 #5
0
        private LedgerlineBlockMetrics CreateLowerLedgerlineBlock(List<HeadMetrics> topDownHeadsMetrics, float limbLength, float strokeWidth)
        {
            Debug.Assert(topDownHeadsMetrics != null);
            float minLeftX = float.MaxValue;
            float maxRightX = float.MinValue;
            foreach(HeadMetrics head in topDownHeadsMetrics)
            {
                if(head.OriginY >= _gap * _nStafflines)
                {
                    minLeftX = minLeftX < head.LeftStemX ? minLeftX : head.LeftStemX;
                    maxRightX = maxRightX > head.RightStemX ? maxRightX : head.RightStemX;
                }
            }
            float leftX = minLeftX - limbLength;
            float rightX = maxRightX + limbLength;
            Metrics bottomHeadMetrics = topDownHeadsMetrics[topDownHeadsMetrics.Count - 1];
            LedgerlineBlockMetrics lowerLedgerlineBlockMetrics = null;
            if(bottomHeadMetrics.OriginY > (_gap * 4.75))
            {
                lowerLedgerlineBlockMetrics = new LedgerlineBlockMetrics(leftX, rightX, strokeWidth); // contains no ledgerlines

                float bottomLedgerlineY = bottomHeadMetrics.OriginY;
                if((bottomLedgerlineY % _gap) > 0)
                {
                    bottomLedgerlineY -= (_gap / 2F);
                }
                for(float y = (_gap * _nStafflines); y <= bottomLedgerlineY; y += _gap)
                {
                    lowerLedgerlineBlockMetrics.AddLedgerline(y, _gap);
                }
            }
            return lowerLedgerlineBlockMetrics;
        }
예제 #6
0
        private LedgerlineBlockMetrics CreateUpperLedgerlineBlock(List<HeadMetrics> topDownHeadsMetrics, float limbLength, float strokeWidth)
        {
            Debug.Assert(topDownHeadsMetrics != null);
            #region upper ledgerline block
            float minLeftX = float.MaxValue;
            float maxRightX = float.MinValue;
            foreach(HeadMetrics head in topDownHeadsMetrics)
            {
                if(head.OriginY <= _gap * 0.75F)
                {
                    minLeftX = minLeftX < head.LeftStemX ? minLeftX : head.LeftStemX;
                    maxRightX = maxRightX > head.RightStemX ? maxRightX : head.RightStemX;
                }
            }
            float left = minLeftX - limbLength;
            float right = maxRightX + limbLength;
            Metrics topHeadMetrics = topDownHeadsMetrics[0];
            LedgerlineBlockMetrics upperLedgerlineBlockMetrics = null;
            if(topHeadMetrics.OriginY < -(_gap * 0.75F))
            {
                upperLedgerlineBlockMetrics = new LedgerlineBlockMetrics(left, right, strokeWidth); // contains no ledgerlines

                float topLedgerlineY = topHeadMetrics.OriginY;
                if((topLedgerlineY % _gap) < 0)
                {
                    topLedgerlineY += (_gap / 2F);
                }
                for(float y = topLedgerlineY; y < 0; y += _gap)
                {
                    upperLedgerlineBlockMetrics.AddLedgerline(y, _gap);
                }
            }
            #endregion upper ledgerline block
            return upperLedgerlineBlockMetrics;
        }
예제 #7
0
        private void CreateLedgerlineAndAccidentalMetrics(float fontHeight, List<Head> topDownHeads, List<HeadMetrics> topDownHeadsMetrics, float ledgerlineStemStrokeWidth)
        {
            float limbLength = (topDownHeadsMetrics[0].RightStemX - topDownHeadsMetrics[0].LeftStemX) / 2F; // change to taste later
            _upperLedgerlineBlockMetrics = CreateUpperLedgerlineBlock(topDownHeadsMetrics, limbLength, ledgerlineStemStrokeWidth);
            _lowerLedgerlineBlockMetrics = CreateLowerLedgerlineBlock(topDownHeadsMetrics, limbLength, ledgerlineStemStrokeWidth);

            List<AccidentalMetrics> existingAccidentalsMetrics = new List<AccidentalMetrics>();
            for(int i = 0; i < topDownHeads.Count; i++)
            {
                HeadMetrics headMetrics = topDownHeadsMetrics[i];
                Head head = topDownHeads[i];
                if(head.DisplayAccidental == DisplayAccidental.force)
                {
                    AccidentalMetrics accidentalMetrics = new AccidentalMetrics(head, fontHeight, _gap);
                    accidentalMetrics.Move(headMetrics.OriginX, headMetrics.OriginY);
                    MoveAccidentalLeft(accidentalMetrics, topDownHeadsMetrics, _stemMetrics,
                        _upperLedgerlineBlockMetrics, _lowerLedgerlineBlockMetrics,
                        existingAccidentalsMetrics);
                    existingAccidentalsMetrics.Add(accidentalMetrics);
                    if(_topDownAccidentalsMetrics == null)
                        _topDownAccidentalsMetrics = new List<AccidentalMetrics>();
                    this._topDownAccidentalsMetrics.Add(accidentalMetrics);
                }
            }
        }
예제 #8
0
 private LedgerlineBlockMetrics CombinedLedgerlineBlockMetrics(LedgerlineBlockMetrics lbm1, LedgerlineBlockMetrics lbm2,
     float staffLineStemStrokeWidth)
 {
     LedgerlineBlockMetrics ledgerlineBlockMetrics = null;
     float top = float.MaxValue;
     float right = float.MaxValue;
     float bottom = float.MaxValue;
     float left = float.MaxValue;
     if(lbm1 != null && lbm2 != null)
     {
         top = lbm1.Top < lbm2.Top ? lbm1.Top : lbm2.Top;
         right = lbm1.Right > lbm2.Right ? lbm1.Right : lbm2.Right;
         bottom = lbm1.Bottom > lbm2.Bottom ? lbm1.Bottom : lbm2.Bottom;
         left = lbm1.Left < lbm2.Left ? lbm1.Left : lbm2.Left;
     }
     else if(lbm1 != null)
     {
         top = lbm1.Top;
         right = lbm1.Right;
         bottom = lbm1.Bottom;
         left = lbm1.Left;
     }
     else if(lbm2 != null)
     {
         top = lbm2.Top;
         right = lbm2.Right;
         bottom = lbm2.Bottom;
         left = lbm2.Left;
     }
     if(top != float.MaxValue)
     {
         ledgerlineBlockMetrics = new LedgerlineBlockMetrics(left, right, staffLineStemStrokeWidth);
         ledgerlineBlockMetrics.SetTop(top);
         ledgerlineBlockMetrics.SetBottom(bottom);
     }
     return ledgerlineBlockMetrics;
 }
예제 #9
0
파일: Metrics.cs 프로젝트: notator/Moritz
        public RestMetrics(Graphics graphics, RestSymbol rest, float gap, int numberOfStafflines, float ledgerlineStrokeWidth)
            : base(rest.DurationClass, true, rest.FontHeight)
        {
            float dy = 0;
            if(numberOfStafflines > 1)
                dy = gap * (numberOfStafflines / 2);

            _top = _top + dy;
            _bottom += dy;
            _originY += dy; // the staffline on which the rest is aligned
            _ledgerlineStub = gap * 0.75F;
            Move((Left - Right) / 2F, 0F); // centre the glyph horizontally
            switch(rest.DurationClass)
            {
                case DurationClass.breve:
                case DurationClass.semibreve:
                    Move(gap * -0.25F, 0F);
                    if(numberOfStafflines == 1)
                        Move(0F, gap);
                    _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub, ledgerlineStrokeWidth);
                    _ledgerline.AddLedgerline(_originY - gap, 0F);
                    _ledgerline.Move(gap * 0.17F, 0F);
                    _top -= (gap * 1.5F);
                    break;
                case DurationClass.minim:
                    Move(gap * 0.18F, 0);
                    _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub - (gap * 0.3F), ledgerlineStrokeWidth);
                    _ledgerline.AddLedgerline(_originY, 0F);
                    _bottom += (gap * 1.5F);
                    break;
                case DurationClass.quaver:
                    _top -= gap * 0.5F;
                    _bottom += gap * 0.5F;
                    break;
                case DurationClass.semiquaver:
                    _top -= gap * 0.5F;
                    _bottom += gap * 0.5F;
                    break;
                case DurationClass.threeFlags:
                    _top -= gap * 0.5F;
                    _right += gap * 0.2F;
                    _bottom += gap * 0.5F;
                    _left -= gap * 0.2F;
                    break;
                case DurationClass.fourFlags:
                    _top -= gap * 0.5F;
                    _right += gap * 0.1F;
                    _bottom += gap * 1.25F;
                    _left -= gap * 0.1F;
                    _originY += gap;
                    break;
                case DurationClass.fiveFlags:
                    _top -= gap * 1.5F;
                    _right += gap * 0.2F;
                    _bottom += gap * 1.25F;
                    _left -= gap * 0.2F;
                    _originY += gap;
                    break;
            }
        }
예제 #10
0
        public RestMetrics(Graphics graphics, RestSymbol rest, float gap, int numberOfStafflines, float ledgerlineStrokeWidth)
            : base(rest.DurationClass, true, rest.FontHeight)
        {
            float dy = 0;

            if (numberOfStafflines > 1)
            {
                dy = gap * (numberOfStafflines / 2);
            }

            _top            = _top + dy;
            _bottom        += dy;
            _originY       += dy;          // the staffline on which the rest is aligned
            _ledgerlineStub = gap * 0.75F;
            Move((Left - Right) / 2F, 0F); // centre the glyph horizontally
            switch (rest.DurationClass)
            {
            case DurationClass.breve:
            case DurationClass.semibreve:
                Move(gap * -0.25F, 0F);
                if (numberOfStafflines == 1)
                {
                    Move(0F, gap);
                }
                _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub, ledgerlineStrokeWidth);
                _ledgerline.AddLedgerline(_originY - gap, 0F);
                _ledgerline.Move(gap * 0.17F, 0F);
                _top -= (gap * 1.5F);
                break;

            case DurationClass.minim:
                Move(gap * 0.18F, 0);
                _ledgerline = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub - (gap * 0.3F), ledgerlineStrokeWidth);
                _ledgerline.AddLedgerline(_originY, 0F);
                _bottom += (gap * 1.5F);
                break;

            case DurationClass.quaver:
                _top    -= gap * 0.5F;
                _bottom += gap * 0.5F;
                break;

            case DurationClass.semiquaver:
                _top    -= gap * 0.5F;
                _bottom += gap * 0.5F;
                break;

            case DurationClass.threeFlags:
                _top    -= gap * 0.5F;
                _right  += gap * 0.2F;
                _bottom += gap * 0.5F;
                _left   -= gap * 0.2F;
                break;

            case DurationClass.fourFlags:
                _top     -= gap * 0.5F;
                _right   += gap * 0.1F;
                _bottom  += gap * 1.25F;
                _left    -= gap * 0.1F;
                _originY += gap;
                break;

            case DurationClass.fiveFlags:
                _top     -= gap * 1.5F;
                _right   += gap * 0.2F;
                _bottom  += gap * 1.25F;
                _left    -= gap * 0.2F;
                _originY += gap;
                break;
            }
        }
예제 #11
0
        public RestMetrics(Graphics graphics, RestSymbol rest, double gap, int numberOfStafflines, double ledgerlineStrokeWidth)
            : base(rest.DurationClass, rest.FontHeight, CSSObjectClass.rest)
        {
            double dy = 0;

            if (numberOfStafflines > 1)
            {
                dy = gap * (numberOfStafflines / 2);
            }

            _top            = _top + dy;
            _bottom        += dy;
            _originY       += dy;         // the staffline on which the rest is aligned
            _ledgerlineStub = gap * 0.75;
            Move((Left - Right) / 2, 0F); // centre the glyph horizontally
            CSSObjectClass llBlockClass = CSSObjectClass.ledgerlines;

            switch (rest.DurationClass)
            {
            case DurationClass.breve:
            case DurationClass.semibreve:
                Move(gap * -0.25, 0F);
                if (numberOfStafflines == 1)
                {
                    Move(0, gap);
                }
                _ledgerlineBlockMetrics = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub, ledgerlineStrokeWidth, llBlockClass);
                _ledgerlineBlockMetrics.AddLedgerline(_originY - gap, 0F);
                _ledgerlineBlockMetrics.Move(gap * 0.17, 0F);
                _top -= (gap * 1.5F);
                break;

            case DurationClass.minim:
                Move(gap * 0.18, 0);
                _ledgerlineBlockMetrics = new LedgerlineBlockMetrics(Left - _ledgerlineStub, Right + _ledgerlineStub - (gap * 0.3F), ledgerlineStrokeWidth, llBlockClass);
                _ledgerlineBlockMetrics.AddLedgerline(_originY, 0F);
                _bottom += (gap * 1.5F);
                break;

            case DurationClass.quaver:
                _top    -= gap * 0.5;
                _bottom += gap * 0.5;
                break;

            case DurationClass.semiquaver:
                _top    -= gap * 0.5;
                _bottom += gap * 0.5;
                break;

            case DurationClass.threeFlags:
                _top    -= gap * 0.5;
                _right  += gap * 0.2;
                _bottom += gap * 0.5;
                _left   -= gap * 0.2;
                break;

            case DurationClass.fourFlags:
                _top     -= gap * 0.5;
                _right   += gap * 0.1;
                _bottom  += gap * 1.25;
                _left    -= gap * 0.1;
                _originY += gap;
                break;

            case DurationClass.fiveFlags:
                _top     -= gap * 1.5;
                _right   += gap * 0.2;
                _bottom  += gap * 1.25;
                _left    -= gap * 0.2;
                _originY += gap;
                break;
            }
        }