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 CautionaryOutputChordSymbol) _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); ChordSymbol cautionaryChordSymbol = chord as CautionaryOutputChordSymbol; if(cautionaryChordSymbol == null) { cautionaryChordSymbol = chord as CautionaryInputChordSymbol; } 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 = NewCLichtDynamicMetrics(gap, dynamicIsBelow); MoveAuxilliaries(chord.Stem.Direction, gap); } SetExternalBoundary(); }
/// <summary> /// returns null if there is no dynamic text in _drawObjects /// </summary> /// <param name="gap"></param> /// <param name="dynamicIsBelow"></param> /// <returns></returns> private DynamicMetrics NewCLichtDynamicMetrics(float gap, bool dynamicIsBelow) { List<string> clichtDynamics = new List<string>() { "Ø", "∏", "π", "p", "P", "F", "f", "ƒ", "Ï", "Î" }; Text dynamicText = null; foreach(DrawObject drawObject in _drawObjects) { Text text = drawObject as Text; if(text != null) { Debug.Assert(text.TextInfo != null); Debug.Assert(!String.IsNullOrEmpty(text.TextInfo.Text)); Debug.Assert(!String.IsNullOrEmpty(text.TextInfo.FontFamily)); if(text.TextInfo.FontFamily == "CLicht" && clichtDynamics.Contains(text.TextInfo.Text)) { dynamicText = text; break; } } } _dynamicMetrics = null; if(dynamicText != null) { dynamicText.Metrics = new DynamicMetrics(gap, dynamicText.TextInfo, dynamicIsBelow); _dynamicMetrics = (DynamicMetrics)dynamicText.Metrics; } return (DynamicMetrics)_dynamicMetrics; }