コード例 #1
0
 private static void DrawNoteGroupOutline(ScoreRendererBase renderer, Quadrangle noteGroupBounds, NoteOrRest element)
 {
     renderer.DrawLine(noteGroupBounds.NW, noteGroupBounds.NE, new Pen(Color.Red), element);
     renderer.DrawLine(noteGroupBounds.NE, noteGroupBounds.SE, new Pen(Color.Red), element);
     renderer.DrawLine(noteGroupBounds.SE, noteGroupBounds.SW, new Pen(Color.Red), element);
     renderer.DrawLine(noteGroupBounds.SW, noteGroupBounds.NW, new Pen(Color.Red), element);
 }
コード例 #2
0
        /// <summary>
        /// Draws of performs additional logic at slur end
        /// </summary>
        /// <param name="renderer">Score renderer</param>
        /// <param name="slur">Slur</param>
        /// <param name="element">Element with a slur</param>
        /// <param name="notePositionY">Y position of element with a slur</param>
        /// <param name="slurStartInfo">Information about slur start point</param>
        /// <param name="slurPlacement">Information about slur placement</param>
        protected override void ProcessSlurEnd(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY, SlurInfo slurStartInfo, VerticalPlacement slurPlacement)
        {
            Point endPoint;
            var   noteheadWidth = element.GetNoteheadWidthPx(renderer);

            if (slurStartInfo.StartPlacement == VerticalPlacement.Above)
            {
                var  xShiftConcerningStemDirectionEnd = noteheadWidth / 2;
                bool hasFlagOrBeam = element.BaseDuration.Denominator > 4;
                endPoint = new Point(scoreService.CursorPositionX + xShiftConcerningStemDirectionEnd,
                                     (element.StemDirection == VerticalDirection.Up ? element.StemEndLocation.Y + (hasFlagOrBeam ? -2 : 0) : notePositionY - 7));
            }
            else if (slurStartInfo.StartPlacement == VerticalPlacement.Below)
            {
                var xShiftConcerningStemDirectionEnd = noteheadWidth / 2;
                endPoint = new Point(scoreService.CursorPositionX + xShiftConcerningStemDirectionEnd, notePositionY + 5);
            }
            else
            {
                throw new Exception("Unsupported placement type.");
            }

            var slurHeight = DetermineSlurHeight(element, slur, slurStartInfo, endPoint);

            for (int i = 0; i < 3; i++) //Draw a few curves one by one to simulate a curve with variable thickness. It will be replaced by a path in future releases.
            {
                var controlPoints = GetBezierControlPoints(slurStartInfo.StartPoint, endPoint, slurStartInfo.StartPlacement, slurHeight + i);
                renderer.DrawBezier(slurStartInfo.StartPoint, controlPoints.Item1, controlPoints.Item2, endPoint, element);
            }

            //DrawSlurFrame(renderer, startPoint, controlPoints.Item1, controlPoints.Item2, endPoint, element);
        }
コード例 #3
0
        /// <summary>
        /// Draws a slur
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="slur"></param>
        /// <param name="element"></param>
        /// <param name="notePositionY"></param>
        public void Draw(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY)
        {
            VerticalPlacement slurPlacement;

            if (slur.Placement.HasValue)
            {
                slurPlacement = slur.Placement.Value;
            }
            else
            {
                slurPlacement = element.StemDirection == VerticalDirection.Up ? VerticalPlacement.Below : VerticalPlacement.Above;
            }

            if (slur.Type == NoteSlurType.Start)
            {
                ProcessSlurStart(renderer, slur, element, notePositionY, GetSlurInfoForWriting(slur.Number), slurPlacement);
            }
            if (slur.Type == NoteSlurType.Stop)
            {
                var slurInfo = GetSlurInfoForReading(slur.Number);
                if (slurInfo == null)
                {
                    return;                     //There is no slur with that number. MusicXml file might be malformed (like in DWOK tom 1, s. 315, nr 24.xml)
                }
                ProcessSlurEnd(renderer, slur, element, notePositionY, slurInfo, slurPlacement);
                measurementService.Slurs.Remove(slur.Number);
            }
        }
コード例 #4
0
        public static Quadrangle GetBounds(this IEnumerable <Note> notes, ScoreRendererBase renderer)
        {
            if (!notes.Any())
            {
                return(default(Quadrangle));
            }

            var boundsCollection = notes.Select(n => n.GetBounds(renderer)).ToArray();
            var bounds           = new Quadrangle(
                boundsCollection.Last().NE,
                boundsCollection.First().NW,
                boundsCollection.Last().SE,
                boundsCollection.First().SW);
            var lowestB  = bounds.SW.Y > bounds.SE.Y ? bounds.SW.Y : bounds.SE.Y;
            var highestB = bounds.NW.Y < bounds.NE.Y ? bounds.NW.Y : bounds.NE.Y;

            var lowest  = boundsCollection.Max(b => b.SW.Y);
            var highest = boundsCollection.Min(b => b.NW.Y);

            var deltaYL = lowest - lowestB;
            var deltaYH = highest - highestB;

            return(new Quadrangle(
                       new Point(bounds.NE.X, bounds.NE.Y + deltaYH),
                       new Point(bounds.NW.X, bounds.NW.Y + deltaYH),
                       new Point(bounds.SE.X, bounds.SE.Y + deltaYL),
                       new Point(bounds.SW.X, bounds.SW.Y + deltaYL)));
        }
コード例 #5
0
 /// <summary>
 /// For debug purposes. It will be used in slur edit mode in the future.
 /// </summary>
 private void DrawSlurFrame(ScoreRendererBase renderer, Point p1, Point p2, Point p3, Point p4, MusicalSymbol owner)
 {
     renderer.DrawLine(p1, p2, owner);
     renderer.DrawLine(p2, p3, owner);
     renderer.DrawLine(p3, p4, owner);
     renderer.DrawLine(p4, p1, owner);
 }
        public override void Render(PrintSuggestion element, ScoreRendererBase renderer)
        {
            if (element.IsSystemBreak && renderer.Settings.RenderingMode != ScoreRenderingModes.Panorama)
            {
                renderer.BreakSystem(renderer.TenthsToPixels(element.SystemDistance ?? scoreService.CurrentScore.DefaultPageSettings.DefaultSystemDistance ?? 0), element.IsPageBreak);

                MusicalSymbolRenderStrategyBase strategy = new ClefRenderStrategy(scoreService)
                {
                    WasSystemChanged = true
                };
                strategy.Render(scoreService.CurrentClef, renderer);

                strategy = new KeyRenderStrategy(scoreService);
                strategy.Render(scoreService.CurrentKey, renderer);

                //Time signature is not rendered in new line.

                //Render measure number:
                renderer.DrawString((scoreService.CurrentMeasureNo).ToString(), MusicFontStyles.LyricsFont,
                                    new Primitives.Point(0, scoreService.CurrentLinePositions[0] - 25), scoreService.CurrentStaff);
            }

            //Issue #44: Jeśli jesteśmy w trybie panoramy, to trzeba uzupełnić line positions dla pozostałych systemów:
            if (renderer.Settings.RenderingMode == ScoreRenderingModes.Panorama)
            {
                var firstSystem = scoreService.Systems.First();
                foreach (var system in scoreService.Systems)
                {
                    system.BuildStaffFragments(firstSystem.LinePositions.ToDictionary(p => scoreService.CurrentScore.Staves[p.Key - 1], p => p.Value));
                }
            }
        }
コード例 #7
0
 protected override void DragInternal(ScoreRendererBase renderer, Direction draggedElement, DraggingState draggingState, double delta, double smallDelta)
 {
     draggedElement.SuppressEvents    = true;
     draggedElement.Placement         = DirectionPlacementType.Custom;
     draggedElement.SuppressEvents    = false;
     draggedElement.DefaultYPosition += renderer.PixelsToTenths(smallDelta);
 }
コード例 #8
0
        /// <summary>
        /// Draws of performs additional logic at slur end
        /// </summary>
        /// <param name="renderer">Score renderer</param>
        /// <param name="slur">Slur</param>
        /// <param name="element">Element with a slur</param>
        /// <param name="notePositionY">Y position of element with a slur</param>
        /// <param name="slurStartInfo">Information about slur start point</param>
        /// <param name="slurPlacement">Information about slur placement</param>
        protected override void ProcessSlurEnd(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY, SlurInfo slurStartInfo, VerticalPlacement slurPlacement)
        {
            var absoluteControlPoint = RelativeToAbsolute(renderer, renderer.TenthsToPixels(slur.BezierStartOrEndPoint), notePositionY);
            var absoluteEndPoint     = RelativeToAbsolute(renderer, renderer.TenthsToPixels(slur.BezierControlPoint), notePositionY);

            renderer.DrawBezier(slurStartInfo.StartPoint.X, slurStartInfo.StartPoint.Y,
                                slurStartInfo.BezierStartControlPoint.X, slurStartInfo.BezierStartControlPoint.Y,
                                absoluteControlPoint.X, absoluteControlPoint.Y,
                                absoluteEndPoint.X, absoluteEndPoint.Y, element);
        }
コード例 #9
0
 protected override void DragInternal(ScoreRendererBase renderer, Rest draggedElement, DraggingState draggingState, double delta, double smallDelta)
 {
     if (!draggedElement.DefaultYPosition.HasValue)
     {
         draggedElement.SuppressEvents   = true;
         draggedElement.DefaultYPosition = 0;
         draggedElement.SuppressEvents   = false;
     }
     draggedElement.DefaultYPosition -= renderer.PixelsToTenths(smallDelta);
 }
コード例 #10
0
 private void Draw(Staff staff, ScoreRendererBase renderer, StaffFragment staffFragment, StaffSystem system)
 {
     renderer.DrawLine(0, staffFragment.LinePositions[0], 0, staffFragment.LinePositions[4], staffFragment);
     foreach (double position in staffFragment.LinePositions)
     {
         Point startPoint = new Point(0, position);
         Point endPoint   = new Point(system.Width, position);
         renderer.DrawLine(startPoint, endPoint, new Pen(renderer.Settings.DefaultColor, 1, -1), staffFragment);
     }
 }
コード例 #11
0
        public void PerformOnMeasure(Measure measure, ScoreRendererBase renderer)
        {
            var beamGroupsForThisMeasure = measure.Staff.BeamGroups.Where(bg => bg.Members.Any(m => m.Measure == measure));

            foreach (var beamGroup in beamGroupsForThisMeasure)
            {
                beamGroup.Start = beamGroup.Members.OfType <Note>().First().StemEndLocation;
                beamGroup.End   = beamGroup.Members.OfType <Note>().Last().StemEndLocation;
            }
            PerformOnBeamGroups(beamGroupsForThisMeasure, renderer);
        }
コード例 #12
0
 protected override void DragInternal(ScoreRendererBase renderer, Lyrics draggedElement, DraggingState draggingState, double delta, double smallDelta)
 {
     draggedElement.SuppressEvents = true;
     if (!draggedElement.DefaultYPosition.HasValue)
     {
         draggedElement.DefaultYPosition = renderer.PixelsToTenths(-30);
     }
     draggedElement.DefaultYPosition += renderer.PixelsToTenths(smallDelta);
     draggedElement.SuppressEvents    = false;
     draggedElement.InvalidateMeasure();
 }
コード例 #13
0
 public void PerformOnStaff(Staff staff, ScoreRendererBase renderer)
 {
     foreach (var system in scoreService.Systems)
     {
         if (system.LinePositions == null)
         {
             continue;
         }
         var staffFragment = system.Staves[scoreService.CurrentStaffNo - 1];
         Draw(staff, renderer, staffFragment, system);
     }
 }
コード例 #14
0
        private void Draw(Staff staff, ScoreRendererBase renderer, StaffFragment staffFragment, StaffSystem system, Pen staffLinePen, double?staffLineWidth)
        {
            renderer.DrawLine(0, staffFragment.LinePositions[0], 0, staffFragment.LinePositions[4], staffLinePen, staffFragment);
            var endPositionX = staffLineWidth ?? CalculateStaffLineWidth(staff, system, renderer.Settings);

            foreach (double linePositionY in staffFragment.LinePositions)
            {
                Point startPoint = new Point(0, linePositionY);
                Point endPoint   = new Point(endPositionX, linePositionY);
                renderer.DrawLine(startPoint, endPoint, staffLinePen, staffFragment);
            }
        }
コード例 #15
0
        public void PerformOnScore(Score score, ScoreRendererBase renderer)
        {
#if DemoVersion
            foreach (var location in new[] {
                new Point(0, 0),
                new Point(renderer.ScoreInformation.Systems.Max(s => s.Width) - 30, 0)
            })
            {
                renderer.DrawString("DEMO", MusicFontStyles.LyricsFont, location, Color.Red, MusicalSymbol.Null);
            }
#endif
        }
コード例 #16
0
        private void DrawBracket(StaffSystem system, Part part, ScoreRendererBase renderer)
        {
            if (system.LinePositions == null)
            {
                return;
            }
            var location = new Point(-30, system.LinePositions[1][0]);
            var size     = new Size(25, system.LinePositions[part.Staves.Count][4] - system.LinePositions[1][0]);

            renderer.DrawStringInBounds(renderer.Settings.CurrentFont.LeftBracket, Model.Fonts.MusicFontStyles.MusicFont, location, size,
                                        renderer.Settings.DefaultColor, part.Staves.First());
        }
コード例 #17
0
        protected override void DragInternal(ScoreRendererBase renderer, Note draggedElement, DraggingState draggingState, double delta, double smallDelta)
        {
            int midiPitch = draggingState.MidiPitchOnStartDragging + (int)(delta / 2);

            draggedElement.SuppressEvents = true;
            draggedElement.ApplyMidiPitch(midiPitch);                 //TODO: Wstawianie kasownika, jeśli jest znak przykluczowy, a obniżyliśmy o pół tonu
            //TODO: Ustalanie kierunku ogonka. Sprawdzić czy gdzieś to nie jest już zrobione, np. w PSAMie

            DetermineStemDirection(draggedElement);

            draggedElement.SuppressEvents = false;
            draggedElement.InvalidateMeasure();
        }
コード例 #18
0
 private Tuple <double, double> GetBraceLocationXAndWidth(ScoreRendererBase renderer)
 {
     if (renderer.IsSMuFLFont && renderer.Settings.MusicFontProfile.SMuFLMetadata != null)
     {
         var bounds = renderer.Settings.MusicFontProfile.SMuFLMetadata.GlyphBBoxes.Brace;
         var width  = (bounds.BBoxNe[0] + bounds.BBoxSw[0]) * 3; //TODO: Sprawdzić czemu Brace ma tak mały bounding box w SMuFL
         return(new Tuple <double, double>(renderer.LinespacesToPixels(bounds.BBoxSw[0] * -3 - width), renderer.LinespacesToPixels(width)));
     }
     else
     {
         return(new Tuple <double, double>(-17.5, 15));
     }
 }
コード例 #19
0
 public double GetNoteheadWidthLs(ScoreRendererBase renderer)
 {
     if (renderer.IsSMuFLFont)
     {
         if (renderer.Settings.MusicFontProfile.SMuFLMetadata == null)
         {
             return(1.18);
         }
         var bounds = GetSMuFLNoteheadBounds(this, renderer.Settings.MusicFontProfile.SMuFLMetadata);
         return(bounds.BBoxNe[0] - bounds.BBoxSw[0]);
     }
     return(IsGraceNote || IsCueNote ? 0.6 : 1.1);
 }
コード例 #20
0
 /// <summary>
 /// Applies AddBracketsFinishingTouch to the score.
 /// </summary>
 /// <param name="score">Score</param>
 /// <param name="renderer">Score renderer</param>
 public void PerformOnScore(Score score, ScoreRendererBase renderer)
 {
     foreach (var part in score.Parts)
     {
         if (part.Staves.Count < 2)
         {
             continue;
         }
         foreach (var system in score.Systems)
         {
             DrawBracket(system, part, renderer);
         }
     }
 }
コード例 #21
0
        private void DrawBracket(StaffSystem system, Part part, ScoreRendererBase renderer)
        {
            if (system.LinePositions == null)
            {
                return;
            }

            var locationXAndWidth = GetBraceLocationXAndWidth(renderer);

            var location = new Point(locationXAndWidth.Item1, system.LinePositions[1][0]);
            var size     = new Size(locationXAndWidth.Item2, system.LinePositions[part.Staves.Count][4] - system.LinePositions[1][0]);

            renderer.DrawCharacterInBounds(renderer.Settings.MusicFontProfile.MusicFont.BraceLeft, Model.Fonts.MusicFontStyles.MusicFont, location, size,
                                           renderer.Settings.DefaultColor, part.Staves.First());
        }
コード例 #22
0
        /// <summary>
        /// Applies DrawLinesBetweenStavesFinishingTouch to the score.
        /// </summary>
        /// <param name="score">Score</param>
        /// <param name="renderer">Score renderer</param>
        public void PerformOnScore(Score score, ScoreRendererBase renderer)
        {
            var lightPen   = new Pen(renderer.Settings.DefaultColor, 1);
            var thickPen   = new Pen(renderer.Settings.DefaultColor, 3);
            var defaultPen = new Pen(renderer.Settings.DefaultColor, renderer.Settings.DefaultStaffLineThickness);


            for (var i = 0; i < scoreService.CurrentScore.Staves.Count - 1; i++)
            {
                var staff      = scoreService.CurrentScore.Staves[i];
                var barlinePen = renderer.CreatePenFromDefaults(staff, "thinBarlineThickness", s => s.DefaultBarlineThickness);
                foreach (var system in scoreService.CurrentScore.Systems)
                {
                    if (renderer.Settings.RenderingMode == ScoreRenderingModes.SinglePage)
                    {
                        var page       = staff.Score.Pages.FirstOrDefault(p => p.Systems.Contains(system));
                        var pageNumber = page == null ? -1 : staff.Score.Pages.IndexOf(page) + 1;
                        if (pageNumber != renderer.Settings.CurrentPage)
                        {
                            continue;
                        }
                    }

                    if (system.LinePositions == null)
                    {
                        continue;
                    }
                    var staffFragment = system.Staves[i];
                    if (!system.LinePositions.ContainsKey(i + 1) || !system.LinePositions.ContainsKey(i + 2))
                    {
                        continue;
                    }
                    renderer.DrawLine(0, system.LinePositions[i + 1][4], 0, system.LinePositions[i + 2][0], barlinePen, staffFragment);
                    foreach (var measure in staff.Measures.Where(m => m.Barline != null && m.System == system))
                    {
                        if (measure.Barline?.Style == BarlineStyle.LightHeavy)
                        {
                            renderer.DrawLine(measure.BarlineLocationX - 6, system.LinePositions[i + 1][4], measure.BarlineLocationX - 6, system.LinePositions[i + 2][0], lightPen, measure.Barline);
                            renderer.DrawLine(measure.BarlineLocationX - 1.5, system.LinePositions[i + 1][4], measure.BarlineLocationX - 1.5, system.LinePositions[i + 2][0], thickPen, measure.Barline);
                        }
                        else if (measure.Barline?.Style != BarlineStyle.None)
                        {
                            renderer.DrawLine(measure.BarlineLocationX, system.LinePositions[i + 1][4], measure.BarlineLocationX, system.LinePositions[i + 2][0], barlinePen, measure.Barline);
                        }
                    }
                }
            }
        }
コード例 #23
0
        /// <summary>
        /// Draws or performs additional logic at slur start
        /// </summary>
        /// <param name="renderer">Score renderer</param>
        /// <param name="slur">Slur</param>
        /// <param name="element">Element with a slur</param>
        /// <param name="notePositionY"></param>
        /// <param name="slurStartInfo">Information about slur start point</param>
        /// <param name="slurPlacement">Information about slur placement</param>
        protected override void ProcessSlurStart(ScoreRendererBase renderer, Slur slur, Note element, double notePositionY, SlurInfo slurStartInfo, VerticalPlacement slurPlacement)
        {
            slurStartInfo.StartPlacement          = slurPlacement;
            slurStartInfo.StartPointStemDirection = element.StemDirection;
            var polihymniaFix = renderer.LinespacesToPixels(element.GetNoteheadWidthLs(renderer) * 0.5);

            if (slurPlacement == VerticalPlacement.Above)
            {
                bool hasFlagOrBeam = element.BaseDuration.Denominator > 4;  //If note has a flag or beam start the slur above the note. If not, start a bit to the right and down.
                var  xShiftConcerningStemDirectionStart = slurStartInfo.StartPointStemDirection == VerticalDirection.Up ? (hasFlagOrBeam ? 5 : 10) : 1;
                slurStartInfo.StartPoint = new Point(scoreService.CursorPositionX + xShiftConcerningStemDirectionStart + polihymniaFix, element.StemDirection == VerticalDirection.Down ? notePositionY - 7 : element.StemEndLocation.Y + (hasFlagOrBeam ? -3 : 8));
            }
            else
            {
                slurStartInfo.StartPoint = new Point(scoreService.CursorPositionX + 3 + polihymniaFix, notePositionY + 5);
            }
        }
コード例 #24
0
        private void PerformOnBeamGroups(IEnumerable <BeamGroup> beamGroups, ScoreRendererBase renderer)
        {
            foreach (var beamGroup in beamGroups)
            {
                Note previousNote = null;
                foreach (var member in beamGroup.Members)
                {
                    var currentNote = member as Note;
                    if (currentNote == null)
                    {
                        continue;
                    }

                    var beamPen = renderer.CreatePenFromDefaults(currentNote, "beamThickness", s => s.DefaultBeamThickness);
                    beamPen.Color = currentNote.CoalesceColor(renderer);
                    var beamSpacing = renderer.GetEngravingDefault("beamSpacing") ?? beamPen.Thickness * 0.6;

                    var beamNumber = 1;
                    foreach (var beamType in currentNote.BeamList)
                    {
                        var beamOffset = (beamPen.Thickness + beamSpacing) * (beamNumber - 1) * (currentNote.StemDirection == VerticalDirection.Up ? 1 : -1);

                        var stemEnd = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, currentNote.StemEndLocation.X - beamGroup.Start.X);
                        currentNote.StemStartLocation = stemEnd;
                        if (beamType == NoteBeamType.ForwardHook || beamType == NoteBeamType.BackwardHook)
                        {
                            var hookLength = beamType == NoteBeamType.ForwardHook ? 6 : -6;
                            var hookEnd    = stemEnd.TranslateByAngleOld(beamGroup.Angle, hookLength);
                            renderer.DrawLine(stemEnd.Translate(0, beamOffset), hookEnd.Translate(0, beamOffset),
                                              beamPen, beamGroup);
                        }
                        else if (previousNote != null && beamType != NoteBeamType.Single && previousNote.BeamList.Count >= beamNumber)
                        {
                            var stemEnd1 = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, previousNote.StemEndLocation.X - beamGroup.Start.X);
                            renderer.DrawLine(stemEnd1.Translate(0, beamOffset), stemEnd.Translate(0, beamOffset),
                                              beamPen, beamGroup);
                        }
                        beamNumber++;
                    }

                    previousNote = currentNote;
                }
            }
        }
        public void PerformOnScore(Score score, ScoreRendererBase renderer)
        {
            if (!Debugger.IsAttached)
            {
                return;
            }

            foreach (var system in score.Systems)
            {
                foreach (var staffFragment in system.Staves)
                {
                    var elementsOnThisFragment = staffFragment.Staff?.Elements?.Where(e => e.Measure.System == system).ToArray() ?? new MusicalSymbol[0];
                    if (elementsOnThisFragment.Length > 0)
                    {
                        staffFragment.ActualRenderingTime = TimeSpan.FromTicks(elementsOnThisFragment.Sum(e => e.ActualRenderingTime.Ticks));
                    }
                }
            }
        }
コード例 #26
0
        public void PerformOnStaff(Staff staff, ScoreRendererBase renderer)
        {
            var staffLinePen = renderer.CreatePenFromDefaults(staff, "staffLineThickness", s => s.DefaultStaffLineThickness);

            staffLinePen.ZIndex = -1;

            var staffLineWidth = renderer.Settings.IsMusicPaperMode && scoreService.Systems.Any() ?
                                 (double?)scoreService.Systems.Max(s => CalculateStaffLineWidth(staff, s, renderer.Settings)) : null;

            foreach (var system in scoreService.Systems)
            {
                if (system.LinePositions == null)
                {
                    continue;
                }
                var staffFragment = system.Staves[scoreService.CurrentStaffNo - 1];
                Draw(staff, renderer, staffFragment, system, staffLinePen, staffLineWidth);
            }
        }
コード例 #27
0
        public Quadrangle GetBounds(ScoreRendererBase renderer)
        {
            var upperY = TextBlockLocation.Y < StemEndLocation.Y || StemEndLocation.Y == 0 ? TextBlockLocation.Y : StemEndLocation.Y;
            var lowerY = TextBlockLocation.Y > StemEndLocation.Y || StemEndLocation.Y == 0 ? TextBlockLocation.Y : StemEndLocation.Y;
            var leftX  = TextBlockLocation.X < StemEndLocation.X || StemEndLocation.X == 0 ? TextBlockLocation.X : StemEndLocation.X;
            var rightX = TextBlockLocation.X > StemEndLocation.X || StemEndLocation.X == 0 ? TextBlockLocation.X : StemEndLocation.X;

            if (StemDirection == VerticalDirection.Down)
            {
                rightX += GetNoteheadWidthPx(renderer);
            }

            return(new Quadrangle(
                       new Point(rightX, upperY),
                       new Point(leftX, upperY),
                       new Point(rightX, lowerY),
                       new Point(leftX, lowerY)
                       ));
        }
コード例 #28
0
        private void PerformOnBeamGroups(IEnumerable <BeamGroup> beamGroups, ScoreRendererBase renderer)
        {
            foreach (var beamGroup in beamGroups)
            {
                Note previousNote = null;
                foreach (var member in beamGroup.Members)
                {
                    var currentNote = member as Note;
                    if (currentNote == null)
                    {
                        continue;
                    }

                    var beamNumber = 1;
                    foreach (var beamType in currentNote.BeamList)
                    {
                        var beamOffset = 28 + 4 * (beamNumber - 1) * (currentNote.StemDirection == VerticalDirection.Up ? 1 : -1);
                        var stemEnd    = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, currentNote.StemEndLocation.X - beamGroup.Start.X);
                        currentNote.StemStartLocation = stemEnd;
                        if (beamType == NoteBeamType.ForwardHook || beamType == NoteBeamType.BackwardHook)
                        {
                            var hookLength = beamType == NoteBeamType.ForwardHook ? 6 : -6;
                            var hookEnd    = stemEnd.TranslateByAngle(beamGroup.Angle, hookLength);
                            renderer.DrawLine(stemEnd.Translate(0, beamOffset), hookEnd.Translate(0, beamOffset), new Pen {
                                Thickness = 2, Color = currentNote.CoalesceColor(renderer)
                            }, beamGroup);
                        }
                        else if (previousNote != null && beamType != NoteBeamType.Single && previousNote.BeamList.Count >= beamNumber)
                        {
                            var stemEnd1 = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, previousNote.StemEndLocation.X - beamGroup.Start.X);
                            renderer.DrawLine(stemEnd1.Translate(0, beamOffset), stemEnd.Translate(0, beamOffset), new Pen {
                                Thickness = 2, Color = currentNote.CoalesceColor(renderer)
                            }, beamGroup);
                        }
                        beamNumber++;
                    }

                    previousNote = currentNote;
                }
            }
        }
コード例 #29
0
        private void DiscoverBeamGroups(Staff staff, ScoreRendererBase renderer)
        {
            staff.BeamGroups.Clear();
            BeamGroup beamGroup = null;

            foreach (var nr in staff.Elements.OfType <NoteOrRest>())
            {
                var note = nr as Note;
                if (note != null && note.BeamList.Any())
                {
                    if (note.BeamList.Count == 1 && note.BeamList[0] == NoteBeamType.Single)
                    {
                        continue;                                                                      //Problem with beams in chords
                    }
                    if (note.BeamList.First() == NoteBeamType.Start)
                    {
                        beamGroup       = new BeamGroup(staff);
                        beamGroup.Start = note.StemEndLocation;
                        staff.BeamGroups.Add(beamGroup);
                    }
                    if (beamGroup != null)
                    {
                        beamGroup.Members.Add(nr);
                    }
                    if (note.BeamList.First() == NoteBeamType.End)
                    {
                        if (beamGroup == null)
                        {
                            renderer.Exceptions.Add(new ScoreException(note, $"Encountered beam group end without corresponding beam group start."));
                        }
                        else
                        {
                            beamGroup.End = note.StemEndLocation;
                            beamGroup     = null;
                        }
                    }
                }
            }
        }
コード例 #30
0
        protected override void DragInternal(ScoreRendererBase renderer, BeamGroup draggedElement, DraggingState draggingState, double delta, double smallDelta)
        {
            if (draggedElement.Members.OfType <Note>().Count() < 2)
            {
                return;
            }
            var firstElement = draggedElement.Members.OfType <Note>().First();
            var lastElement  = draggedElement.Members.OfType <Note>().Last();

            firstElement.SuppressEvents = true;
            lastElement.SuppressEvents  = true;

            if (!firstElement.HasCustomStemEndPosition)
            {
                firstElement.StemDefaultY             = renderer.PixelsToTenths(firstElement.StemEndLocation.Y - firstElement.TextBlockLocation.Y);
                firstElement.HasCustomStemEndPosition = true;
            }
            if (!lastElement.HasCustomStemEndPosition)
            {
                lastElement.StemDefaultY             = renderer.PixelsToTenths(lastElement.StemEndLocation.Y - firstElement.TextBlockLocation.Y);
                lastElement.HasCustomStemEndPosition = true;
            }

            firstElement.StemDefaultY -= smallDelta;
            lastElement.StemDefaultY  -= smallDelta;

            foreach (var element in draggedElement.Members.OfType <Note>())
            {
                element.SuppressEvents = true;
                NoteDraggingStrategy.DetermineStemDirection(element);
                element.SuppressEvents = false;
            }

            firstElement.SuppressEvents = false;
            lastElement.SuppressEvents  = false;
            draggedElement.InvalidateMeasure();
        }