private void DrawScaleFormulaIntervals(IGenericDrawingSurface g, int offsetX, int startY, ScaleItem scale, ColorValue fontColor)
        {
            string scaleIntervals = _guitarModel.GetScaleIntervals();

            g.DrawString(offsetX + 2, startY + 11, "Intervals:", BasicFontSizePt, fontColor);
            g.DrawString(offsetX + 40, startY + 11, scaleIntervals, BasicFontSizePt, fontColor);
        }
        private void DrawScaleNoteList(IGenericDrawingSurface g, int offsetX, int startY, ScaleItem scale, ColorValue fontColor)
        {
            string scaleNotes = "";
            int    notePos    = 0;

            try
            {
                for (int i = 0; i < scale.ScaleIntervals.Length; i++)
                {
                    if (scale.ScaleIntervals[i])
                    {
                        notePos++;

                        scaleNotes += NoteManager.GetNoteName(scale.GetNoteAtSequencePosition(notePos, NoteManager.GetNoteByName(_guitarModel.SelectedKey)), true);
                        scaleNotes += "  ";
                    }
                }
            }
            catch (Exception)
            {
                System.Diagnostics.Debug.WriteLine("Exception: Couldn't resolve note name at one or more scale position");
            }

            g.DrawString(offsetX + 2, startY + 18, "Notes:", BasicFontSizePt, fontColor);
            g.DrawString(offsetX + 40, startY + 18, scaleNotes, BasicFontSizePt, fontColor);
        }
        private double DrawFrettedNote(IGenericDrawingSurface g, int numString, int timePos, int numFret, Note note, double previousNoteXPos, double groupNoteSpacing)
        {
            double vspacing = 3;

            //calc position of this note, based on end of previous note
            double xNotePos = measureX + groupNoteSpacing;

            double noteDisplayWidth = GetNoteDisplayWidth(note, groupNoteSpacing);

            //if previous note drawn in measure, start from there
            if (previousNoteXPos > measureX)
            {
                xNotePos = previousNoteXPos;
            }

            double yNotePos = (measureY + (numString * stringSpacing));// -(fontSize * 0.5);

            //draw masking rectangle behind text to improve readability
            double notationWidth = (numFret.ToString().Length *(fontSize * 0.75));

            g.FillRectangle(xNotePos, yNotePos + (fontSize * 0.5), notationWidth, (fontSize), ColorPreset.Background, ColorPreset.Background);

            //draw fret number on string
            g.DrawString(xNotePos, yNotePos + (fontSize * 0.5), numFret.ToString(), fontSize);

            //draw notations
            if (note.Notations != null)
            {
                //draw slur start
                if (note.Notations.IsSlurStart)
                {
                    g.DrawArc(xNotePos + vspacing, yNotePos - vspacing, groupNoteSpacing, true);
                }

                if (note.Notations.IsSlideStart)
                {
                    g.DrawLine((xNotePos + fontSize), (yNotePos + fontSize), (xNotePos + groupNoteSpacing), (yNotePos + fontSize), 2, ColorPreset.Foreground);
                }

                if (note.Notations.Technical.IsVibrato)
                {
                    double x1            = xNotePos + vspacing;
                    double y1            = measureY - STANDARD_STRINGSPACING;
                    string vibratoString = "~";

                    for (int i = 0; i < note.Duration; i++)
                    {
                        vibratoString += "~";
                    }

                    g.DrawString(x1, y1, vibratoString, STANDARD_FONTSIZE * 2);
                }
            }

            xNotePos += noteDisplayWidth;
            return(xNotePos);
        }
        private void DrawRest(IGenericDrawingSurface g, int timePos, Note note)
        {
            int leftPadding = 4;

            double xRestPos = leftPadding + (measureX + ((timePos - 1) * noteSpacing));
            double yRestPos = 30;

            g.DrawString(xRestPos, yRestPos, "r");

            if (note.IsDotted)
            {
                g.DrawString(xRestPos + 10, yRestPos, "dotted");
            }
        }
        private void DrawFretNumbers(int numberFrets, IGenericDrawingSurface g, int startX, int startY, ColorValue defaultCanvasFontColor)
        {
            for (int fretNum = 0; fretNum <= numberFrets; fretNum++)
            {
                int fretX = startX + GuitarString.FretNumberToClientX(fretNum, _guitarModel, 0);

                if (_guitarModel.GuitarModelSettings.EnableDisplacedFingeringMarkers)
                {
                    if (fretNum > 0)
                    {
                        var posL = fretX - GuitarString.FretNumberToClientX(fretNum - 1, _guitarModel, 0);
                        fretX -= posL / 2;
                    }
                    else
                    {
                        fretX -= 5; //displace 0 fret by 5
                    }
                }
                else
                {
                    //offset x by half of text width
                    fretX -= ((BasicFontSizePt / 3) * fretNum.ToString().Length);
                }

                g.DrawString(fretX, startY + 2, fretNum.ToString(), BasicFontSizePt, defaultCanvasFontColor);
            }
        }
        public void DrawGuitarString(GuitarString s, int startY, int offsetX, IGenericDrawingSurface g)
        {
            String strNote = "";
            int    startX  = offsetX;

            //draw string
            int fretboardWidth = s.GetFretboardWidth(_guitarModel, s.StringNumber);
            int fanScaleMM     = (int)_guitarModel.MultiScaleFanFactor;

            if (_guitarModel.IsMultiScale)
            {
                startX        += (s.StringNumber * fanScaleMM);
                fretboardWidth = fretboardWidth - (s.StringNumber * fanScaleMM * 2);
            }

            if (_guitarModel.GuitarModelSettings.EnableDiagramStrings)
            {
                var stringThickness = 0.3 + ((_guitarModel.NumberOfStrings - s.StringNumber) * 0.1);

                g.DrawLine(startX, startY - 0.5, startX + fretboardWidth, startY - 0.5, stringThickness, ColorPalette[ThemeColorPreset.Foreground]);
                g.DrawLine(startX, startY, startX + fretboardWidth, startY, stringThickness, ColorPalette[ThemeColorPreset.MutedForeground]);
            }

            for (int fretNum = 0; fretNum <= _guitarModel.GuitarModelSettings.NumberFrets; fretNum++)
            {
                int tmpVal = fretNum + (int)s.OpenTuning.SelectedNote;
                int octave = 1;
                if (tmpVal > 11)
                {
                    tmpVal = tmpVal - 12;
                    octave++;
                }
                if (tmpVal > 11)
                {
                    tmpVal = tmpVal - 12;
                    octave++;
                }

                int sclVal = (fretNum - (int)_guitarModel.GuitarModelSettings.ScaleManager.CurrentKey) + (int)s.OpenTuning.SelectedNote;
                if (sclVal < 0)
                {
                    sclVal = sclVal + 12;
                }
                if (sclVal > 11)
                {
                    sclVal = sclVal - 12;
                }
                if (sclVal > 11)
                {
                    sclVal = sclVal - 12;
                }

                if (sclVal < 0)
                {
                    System.Diagnostics.Debug.WriteLine(sclVal);
                }

                if (_guitarModel.SelectedScale.ScaleIntervals[sclVal] == true)
                {
                    if (fretNum <= _guitarModel.GuitarModelSettings.NumberFrets)
                    {
                        ColorValue strokeColor = ColorPalette[ThemeColorPreset.Foreground];
                        ColorValue fillColor   = ColorPalette[ThemeColorPreset.Foreground];

                        if (fretNum == 0)
                        {
                            //fret zero has empty circle marker
                            fillColor = ColorPalette[ThemeColorPreset.Subtle];
                        }

                        if ((Note)tmpVal == _guitarModel.GetKey())
                        {
                            //root note has accent colour border
                            strokeColor = ColorPalette[ThemeColorPreset.Accent];
                        }

                        if (_guitarModel.GuitarModelSettings.EnableDisplacedFingeringMarkers)
                        {
                            //displace marker to place behind fret

                            if (fretNum > 0)
                            {
                                var posL = startX - GuitarString.FretNumberToClientX(fretNum - 1, _guitarModel, s.StringNumber);
                                startX -= posL / 2;
                                startX += (_guitarModel.GuitarModelSettings.MarkerSize / 2);
                            }
                            else
                            {
                                //fret 0, displace marker behind nut
                                startX = startX - (_guitarModel.GuitarModelSettings.MarkerSize / 2);
                            }
                        }

                        var currentNote = new NoteItem
                        {
                            Note         = (Note)tmpVal,
                            X            = startX - (_guitarModel.GuitarModelSettings.MarkerSize / 2),
                            Y            = startY - (_guitarModel.GuitarModelSettings.MarkerSize / 2),
                            FretNumber   = fretNum,
                            StringNumber = s.StringNumber,
                            Octave       = octave
                        };

                        _noteList.Add(currentNote);


                        if (_hightlightedNotes.Any(n => n.Note == currentNote.Note && n.StringNumber == currentNote.StringNumber && n.Octave == currentNote.Octave))
                        {
                            // highlight

                            g.FillEllipse(startX - (_guitarModel.GuitarModelSettings.MarkerSize / 2), startY - (_guitarModel.GuitarModelSettings.MarkerSize / 2), _guitarModel.GuitarModelSettings.MarkerSize, _guitarModel.GuitarModelSettings.MarkerSize, ColorPalette[ThemeColorPreset.MutedBackground], new ColorValue(255, 255, 255, 255));
                        }

                        //draw note marker centered behind fret
                        if (_guitarModel.GuitarModelSettings.EnableNoteColours == true)
                        {
                            var noteColor = NoteManager.GetNoteColour((Note)tmpVal, 2);
                            if (_hightlightedNotes.Any())
                            {
                                noteColor.A = 128;
                            }
                            g.FillEllipse(startX - (_guitarModel.GuitarModelSettings.MarkerSize / 2), startY - (_guitarModel.GuitarModelSettings.MarkerSize / 2), _guitarModel.GuitarModelSettings.MarkerSize, _guitarModel.GuitarModelSettings.MarkerSize, ColorPalette[ThemeColorPreset.MutedBackground], noteColor);
                        }
                        else
                        {
                            g.FillEllipse(startX - (_guitarModel.GuitarModelSettings.MarkerSize / 2), startY - (_guitarModel.GuitarModelSettings.MarkerSize / 2), _guitarModel.GuitarModelSettings.MarkerSize, _guitarModel.GuitarModelSettings.MarkerSize, fillColor, strokeColor);
                        }

                        //if enabled, draw note name/sequence number
                        if (_guitarModel.GuitarModelSettings.EnableDiagramNoteNames || _guitarModel.GuitarModelSettings.EnableDiagramNoteSequence || _guitarModel.GuitarModelSettings.EnableDiagramScaleIntervals)
                        {
                            if (_guitarModel.GuitarModelSettings.EnableDiagramNoteNames)
                            {
                                strNote = NoteManager.GetNoteName((Note)tmpVal, _guitarModel.GuitarModelSettings.EnableDiagramNoteNamesSharp);
                            }
                            if (_guitarModel.GuitarModelSettings.EnableDiagramNoteSequence)
                            {
                                strNote = "" + _guitarModel.GuitarModelSettings.ScaleManager.CurrentScale.GetSequenceNumberInScale(sclVal);
                            }
                            if (_guitarModel.GuitarModelSettings.EnableDiagramScaleIntervals)
                            {
                                strNote = "" + _guitarModel.GuitarModelSettings.ScaleManager.CurrentScale.GetIntervalNameInScale(sclVal);
                            }

                            double markerFontSize = BasicFontSizePt;
                            double labelX         = startX - (_guitarModel.GuitarModelSettings.MarkerSize * 0.45);
                            double labelY         = startY - (markerFontSize * 0.3);
                            if (strNote.Length == 1)
                            {
                                labelX += markerFontSize * 0.3;
                                g.DrawString(labelX + 0.5, labelY + 0.5, strNote, markerFontSize, ColorPalette[ThemeColorPreset.TextShadow]); //shadow
                                g.DrawString(labelX, labelY, strNote, markerFontSize, ColorPalette[ThemeColorPreset.ForegroundText]);
                            }
                            else
                            {
                                labelX += markerFontSize * 0.2;
                                labelY += markerFontSize * 0.1;
                                g.DrawString(labelX + 0.5, labelY + 0.5, strNote, markerFontSize * .8, ColorPalette[ThemeColorPreset.TextShadow]);
                                g.DrawString(labelX, labelY, strNote, markerFontSize * .8, ColorPalette[ThemeColorPreset.ForegroundText]);
                            }
                        }
                    }
                }

                startX = offsetX + GuitarString.FretNumberToClientX(fretNum + 1, _guitarModel, s.StringNumber);
            }
        }
        public override void Render(IGenericDrawingSurface canvas)
        {
            if (EnableRendering == false)
            {
                return;
            }

            //select and init rendering surface type
            IGenericDrawingSurface g = InitialiseDrawingSurface(canvas);

            int numberOfStrings = _guitarModel.GuitarModelSettings.CurrentTuning.NumberStrings;
            int numberFrets     = _guitarModel.GuitarModelSettings.NumberFrets;

            int startX = PaddingLeft;
            int startY = PaddingTop;

            _noteList = new List <NoteItem>();

            ColorValue defaultCanvasFontColor = ColorPalette[ThemeColorPreset.Foreground];

            int fboardWidth = GuitarString.FretNumberToClientX(_guitarModel.GuitarModelSettings.NumberFrets, _guitarModel, 0);

            int fboardHeight = _guitarModel.GuitarModelSettings.StringSpacing * (numberOfStrings - 1);

            if (_guitarModel.GuitarModelSettings.EnableFretboardBackgroundFill)
            {
                // optional background fretboard fill
                g.FillRectangle(startX, startY + _guitarModel.GuitarModelSettings.StringSpacing, fboardWidth, fboardHeight, ColorPalette[ThemeColorPreset.Background], ColorPalette[ThemeColorPreset.Subtle]);
            }

            //draw frets..
            DrawFrets(numberOfStrings, g, startX, startY);

            //draw strings (and note markers)..
            startY = PaddingTop + (_guitarModel.GuitarModelSettings.StringSpacing * numberOfStrings);
            startY = DrawGuitarStrings(numberOfStrings, g, PaddingLeft, startY);

            //draw fret numbers
            if (_guitarModel.GuitarModelSettings.EnableFretNumbers)
            {
                startX = PaddingLeft;
                startY = PaddingTop + 5 + _guitarModel.GuitarModelSettings.StringSpacing * (numberOfStrings);

                DrawFretNumbers(numberFrets, g, startX, startY, defaultCanvasFontColor);
            }

            //show scale intervals & notes
            var scale = _guitarModel.SelectedScale;

            DrawScaleFormulaIntervals(g, PaddingLeft + 4, startY, scale, defaultCanvasFontColor);
            DrawScaleNoteList(g, PaddingLeft + 4, startY, scale, defaultCanvasFontColor);

            if (IsExportMode)
            {
                //draw copyright/watermark (for exported images)
                g.DrawString(PaddingLeft + 5, startY + 10, "Generated by Guitar Toolkit - Copyright " + System.DateTime.Now.Year + " Soundshed.com");
            }

            startX = 0;
            startY = 10;

            //draw scale title
            if (_guitarModel.GuitarModelSettings.EnableDiagramTitle)
            {
                var title = _guitarModel.GetDiagramTitle();
                g.DrawString(startX, startY, title, 8, defaultCanvasFontColor);
            }
        }
        public override void Render(IGenericDrawingSurface canvas)
        {
            if (EnableRendering == false)
            {
                return;
            }
            if (CurrentChordDiagrams == null)
            {
                return;
            }

            DrawingColor    = ColorPalette[ThemeColorPreset.Foreground];
            BackgroundColor = ColorPalette[ThemeColorPreset.Background];

            IGenericDrawingSurface g = InitialiseDrawingSurface(canvas, 800, 1024);

            int startX = GENERAL_PADDING;
            int startY = GENERAL_PADDING;

            int stringSpacing       = STRING_SPACING;
            int fretSpacing         = FRET_SPACING;
            int fretMarkerSize      = FRET_MARKERSIZE;
            int numFrets            = NUMBER_OF_FRETS;
            int fontSize            = FONT_SIZE;
            int fretBoardWidth      = (stringSpacing * (GuitarModel.NumberOfStrings - 1));
            int minFretboardBoxSize = (stringSpacing * 5); //allow min fretboard spacing of 6 strings width
            int chordsPerRow        = ChordsPerRow;
            int rowY         = startY;
            int titleSpacing = fontSize * 2;

            int rowChordCount = 0;
            int xPos, yPos;

            foreach (ChordDiagram CurrentChordDiagram in CurrentChordDiagrams)
            {
                if (rowChordCount >= chordsPerRow)
                {
                    //start new row
                    rowY += (titleSpacing * 2) + (numFrets * fretSpacing);

                    xPos = startX;
                    yPos = rowY;

                    rowChordCount = 0;
                }
                else
                {
                    //start next chord on same row
                    if (rowChordCount > 0)
                    {
                        //next chord position in row is based on fretboardwidth +padding
                        xPos = startX +
                               (rowChordCount *
                                (fretBoardWidth < minFretboardBoxSize ? minFretboardBoxSize : fretBoardWidth) + (rowChordCount * stringSpacing)
                               );
                        //+ (rowChordCount * stringSpacing) + stringSpacing;
                    }
                    else
                    {
                        xPos = startX;
                    }

                    yPos = rowY;
                }

                //draw chord name
                g.DrawString(xPos, yPos, CurrentChordDiagram.ChordName, fontSize, DrawingColor);
                yPos += fontSize * 2;

                //draw nut (if chord starts at fret 0)
                g.DrawLine(xPos, yPos, xPos + fretBoardWidth, yPos, 2D, DrawingColor);

                //draw strings
                for (int i = 0; i < GuitarModel.NumberOfStrings; i++)
                {
                    double currentX = xPos + (i * stringSpacing);
                    g.DrawLine(currentX, yPos, currentX, yPos + (numFrets * fretSpacing), 1, DrawingColor);
                }

                //draw frets
                for (int i = 0; i <= numFrets; i++)
                {
                    double currentY = yPos + (i * fretSpacing);
                    g.DrawLine(xPos, currentY, xPos + fretBoardWidth, currentY, 1, DrawingColor);
                }

                //draw fretted notes per string
                for (int i = 0; i < GuitarModel.NumberOfStrings; i++)
                {
                    double currentX = xPos + (i * stringSpacing) - (fretMarkerSize / 2); //position marker centred on string

                    if (CurrentChordDiagram.FrettedStrings[i] != null)
                    {
                        int    fret     = CurrentChordDiagram.FrettedStrings[i].Fret;
                        double currentY = yPos + (fret * fretSpacing) - (fretSpacing / 2) - (fretMarkerSize / 2); //position marker centered between frets or behind nut

                        if (fret == 0)
                        {
                            g.FillEllipse(currentX, currentY, fretMarkerSize, fretMarkerSize, ColorPalette[ThemeColorPreset.MutedForeground], DrawingColor);
                        }
                        else
                        {
                            g.FillEllipse(currentX, currentY, fretMarkerSize, fretMarkerSize, DrawingColor, DrawingColor);
                        }
                    }
                    else
                    {
                        //string not played
                        g.DrawString(currentX, yPos - (fretSpacing / 2) - (fretMarkerSize / 2), "x", DrawingColor);
                    }
                }

                rowChordCount++; //move to next chord in list
            }
        }