Пример #1
0
        internal void FinalizeBeamBlock(double rightBarlineX)
        {
            M.Assert(this.BeamBlock != null);
            M.Assert(this.BeamBlockDef != null);

            BeamBlock.FinalizeBeamBlock(BeamBlockDef, rightBarlineX);
        }
Пример #2
0
        public ChordMetrics(System.Drawing.Graphics graphics, ChordSymbol chord, VerticalDir voiceStemDirection, float gap, float stemStrokeWidthVBPX)
            : base()
        {
            _top = float.MaxValue;
            _right = float.MinValue;
            _bottom = float.MinValue;
            _left = float.MaxValue;
            _drawObjects = chord.DrawObjects;

            _gap = gap;

            // The _objectType is written to the SVG file as a group name, but is otherwise not used.
            if(chord is CautionaryChordSymbol)
                _objectType = "cautionary chord";
            else
                _objectType = "chord";

            GetStaffParameters(chord); // sets _clef to the most recent clef, and _nStafflines.

            // For each component, find its characterID, deltaX and deltaY re the chord's origin.
            // The chord's x-origin is the centre of the outermost notehead.
            // (deltaX of the outermost notehead is 0.)
            // The chord's y-origin is the top line of the staff.
            // (deltaY of a notehead on the top line of the staff is 0.)

            if(chord.BeamBlock != null && chord.BeamBlock.Chords[0] == chord)
                this.BeamBlock = chord.BeamBlock;

            SetHeadsMetrics(chord, stemStrokeWidthVBPX);
            if(chord.Stem.Draw) // false for cautionary chords
                SetStemAndFlags(chord, _headsMetricsTopDown, stemStrokeWidthVBPX);

            // if the chord is part of a beamGroup, the stem tips are all at one height here.

            // These objects are created with originX and originY at 0,0 (the chord's origin).
            CreateLedgerlineAndAccidentalMetrics(chord.FontHeight, chord.HeadsTopDown, _headsMetricsTopDown, stemStrokeWidthVBPX);
            CautionaryChordSymbol cautionaryChordSymbol = chord as CautionaryChordSymbol;
            if(cautionaryChordSymbol != null)
            {
                CreateCautionaryBracketsMetrics(cautionaryChordSymbol);
            }
            else
            {
                bool dynamicIsBelow;
                bool ornamentIsBelow;
                _lyricMetrics = NewLyricMetrics(chord.Voice.StemDirection, graphics, gap);

                GetRelativePositions(chord.Voice.StemDirection, _lyricMetrics, out ornamentIsBelow, out dynamicIsBelow);
                _ornamentMetrics = NewOrnamentMetrics(graphics, gap, ornamentIsBelow);

                _dynamicMetrics = NewDynamicMetrics(gap, dynamicIsBelow);

                MoveAuxilliaries(chord.Stem.Direction, gap);
            }

            SetExternalBoundary();
        }
Пример #3
0
        /// <summary>
        /// Adjusts the heights of stem tips attached to beam blocks in staves which have 2 voices.
        /// The stem tips are moved vertically (all to the same height) to take account of chords in the other
        /// voice which would otherwise collide with the beamBlock.
        /// This is done so that account can be taken of the stems and auxilliaries when justifying horizontally.
        /// The BeamBlocks themselves are finalized later, at which point the stem tips are moved again.
        /// </summary>
        public void AdjustBeamedStemHeights(int voiceIndex)
        {
            Debug.Assert(Voices.Count == 2);
            Debug.Assert(voiceIndex == 0 || voiceIndex == 1);
            Debug.Assert(Voices[0].StemDirection == VerticalDir.up);
            Debug.Assert(Voices[1].StemDirection == VerticalDir.down);

            int adjustVoiceIndex = 0;
            int otherVoiceIndex  = 1;

            if (voiceIndex == 1)
            {
                adjustVoiceIndex = 1;
                otherVoiceIndex  = 0;
            }
            foreach (ChordSymbol chordSymbol in Voices[adjustVoiceIndex].ChordSymbols)
            {
                if (chordSymbol.BeamBlock != null)
                {
                    BeamBlock          beamBlock      = chordSymbol.BeamBlock;
                    List <ChordSymbol> enclosedChords = beamBlock.EnclosedChords(Voices[otherVoiceIndex]);
                    foreach (ChordSymbol chord in beamBlock.Chords)
                    {
                        foreach (ChordSymbol otherChord in enclosedChords)
                        {
                            chord.ChordMetrics.AdjustStemLengthAndFlagBlock(chord.DurationClass, chord.FontHeight, otherChord.ChordMetrics.HeadsMetrics);
                        }
                    }
                    if (adjustVoiceIndex == 0)
                    {
                        float minStemTip = float.MaxValue;
                        foreach (ChordSymbol beamedChord in beamBlock.Chords)
                        {
                            minStemTip = minStemTip < beamedChord.ChordMetrics.StemMetrics.Top ? minStemTip : beamedChord.ChordMetrics.StemMetrics.Top;
                        }
                        foreach (ChordSymbol beamedChord in beamBlock.Chords)
                        {
                            beamedChord.ChordMetrics.MoveOuterStemTip(minStemTip, VerticalDir.up);
                        }
                    }
                    else
                    {
                        float maxStemTip = float.MinValue;
                        foreach (ChordSymbol beamedChord in beamBlock.Chords)
                        {
                            maxStemTip = maxStemTip > beamedChord.ChordMetrics.StemMetrics.Bottom ? maxStemTip : beamedChord.ChordMetrics.StemMetrics.Bottom;
                        }
                        foreach (ChordSymbol beamedChord in beamBlock.Chords)
                        {
                            beamedChord.ChordMetrics.MoveOuterStemTip(maxStemTip, VerticalDir.down);
                        }
                    }
                }
            }
        }
Пример #4
0
        private void MoveFramedTextAboveBeamBlock(Metrics framedTextMetrics, BeamBlock beamBlock)
        {
            double padding = Gap * 1.5;

            double verticalOverlap = beamBlock.OverlapHeight(framedTextMetrics, padding);

            if (verticalOverlap > 0)
            {
                verticalOverlap = (verticalOverlap > padding) ? verticalOverlap : padding;
                framedTextMetrics.Move(0, -verticalOverlap);
            }
        }
Пример #5
0
        private StemMetrics NewStemMetrics(
            List<HeadMetrics> topDownHeadsMetrics, 
            VerticalDir stemDirection, 
            float fontHeight, 
            Metrics flagsBlockMetrics,
            BeamBlock beamBlock,
            float strokeWidth)
        {
            HeadMetrics outerNotehead = FindOuterNotehead(topDownHeadsMetrics, stemDirection);
            HeadMetrics innerNotehead = FindInnerNotehead(topDownHeadsMetrics, stemDirection);
            string noteheadID = outerNotehead.ID_Type;
            NoteheadStemPositions_px nspPX = CLichtFontMetrics.ClichtNoteheadStemPositionsDictPX[noteheadID];
            float outerNoteheadAlignmentY = (outerNotehead.Bottom + outerNotehead.Top) / 2F;
            float innerNoteheadAlignmentY = (innerNotehead.Bottom + innerNotehead.Top) / 2F;
            float delta = _gap * 0.1F;
            float octave = (_gap * 3.5F) + delta; // a little more than 1 octave
            float sixth = (_gap * 2.5F) + delta; // a little more than 1 sixth

            float top = 0F;
            float bottom = 0F;
            float x = 0F;
            if(stemDirection == VerticalDir.up)
            {
                x = outerNotehead.RightStemX - (strokeWidth / 2);
                bottom = outerNoteheadAlignmentY + (nspPX.RightStemY_px * fontHeight);
                if(beamBlock != null)
                {
                    top = beamBlock.DefaultStemTipY;
                }
                else
                {
                    if(flagsBlockMetrics != null)
                    {
                        top = flagsBlockMetrics.Top;
                    }
                    else
                        top = innerNoteheadAlignmentY - octave;

                    if(top > (_gap * 2))
                    {
                        top = (_gap * 2) - delta;
                    }
                }
            }
            else // stem is down
            {
                x = outerNotehead.LeftStemX + (strokeWidth / 2);
                top = outerNoteheadAlignmentY + (nspPX.LeftStemY_px * fontHeight);
                if(beamBlock != null)
                {
                    bottom = beamBlock.DefaultStemTipY;
                }
                else
                {
                    if(flagsBlockMetrics != null)
                    {
                        bottom = flagsBlockMetrics.Bottom;
                    }
                    else
                        bottom = innerNoteheadAlignmentY + octave;

                    if(bottom < (_gap * 2))
                    {
                        bottom = (_gap * 2) + delta;
                    }
                }
            }

            StemMetrics stemMetrics = new StemMetrics(top, x, bottom, strokeWidth, stemDirection);
            return stemMetrics;
        }
Пример #6
0
        /// <summary>
        /// Returns the stem which the otherChordTopDownHeadsMetrics would have if their duration class was crotchet.
        /// DummyStemMetrics are used when aligning synchronous chords.
        /// </summary>
        private StemMetrics DummyStemMetrics(
            List<HeadMetrics> otherChordTopDownHeadsMetrics,
            VerticalDir stemDirection,
            float fontHeight,
            Metrics flagsBlockMetrics,
            BeamBlock beamBlock,
            float strokeWidth)
        {
            List<HeadMetrics> tempTopDownHeadsMetrics = new List<HeadMetrics>();
            foreach(HeadMetrics headMetrics in otherChordTopDownHeadsMetrics)
            {
                HeadMetrics newHeadMetrics = new HeadMetrics(headMetrics, DurationClass.crotchet);
                tempTopDownHeadsMetrics.Add(newHeadMetrics);
            }

            return NewStemMetrics(tempTopDownHeadsMetrics, stemDirection, fontHeight, flagsBlockMetrics, beamBlock, strokeWidth);
        }