private int GetAboveStaff() { /* Find the topmost note in the chord */ WhiteNote topnote = notedata[notedata.Length - 1].whitenote; /* The stem.End is the note position where the stem ends. * Check if the stem end is higher than the top note. */ if (stem1 != null) { topnote = WhiteNote.Max(topnote, stem1.End); } if (stem2 != null) { topnote = WhiteNote.Max(topnote, stem2.End); } int dist = topnote.Dist(WhiteNote.Top(clef)) * SheetMusic.NoteHeight / 2; int result = 0; if (dist > 0) { result = dist; } /* Check if any accidental symbols extend above the staff */ foreach (AccidSymbol symbol in accidsymbols) { if (symbol.AboveStaff > result) { result = symbol.AboveStaff; } } return(result); }
/** Draw the note letters (A, A#, Bb, etc) next to the note circles. * @param ytop The ylocation (in pixels) where the top of the staff starts. * @param topstaff The white note of the top of the staff. */ public void DrawNoteLetters(Graphics g, Pen pen, int ytop, WhiteNote topstaff) { bool overlap = NotesOverlap(notedata, 0, notedata.Length); pen.Width = 1; foreach (NoteData note in notedata) { if (!note.leftside) { /* There's not enought pixel room to show the letter */ continue; } /* Get the x,y position to draw the note */ int ynote = ytop + topstaff.Dist(note.whitenote) * SheetMusic.NoteHeight / 2; /* Draw the letter to the right side of the note */ int xnote = SheetMusic.NoteWidth + SheetMusic.LineSpace / 4; if (note.duration == NoteDuration.DottedHalf || note.duration == NoteDuration.DottedQuarter || note.duration == NoteDuration.DottedEighth || overlap) { xnote += SheetMusic.NoteWidth / 2; } g.DrawString(NoteName(note.number, note.whitenote), SheetMusic.LetterFont, Brushes.Black, xnote, ynote - SheetMusic.NoteHeight / 2); } }
/** Draw the vertical line of the stem * @param ytop The y location (in pixels) where the top of the staff starts. * @param topstaff The note at the top of the staff. */ private void DrawVerticalLine(Graphics g, Pen pen, int ytop, WhiteNote topstaff) { int xstart; if (side == LeftSide) { xstart = SheetMusic.LineSpace / 4 + 1; } else { xstart = SheetMusic.LineSpace / 4 + SheetMusic.NoteWidth; } if (direction == Up) { int y1 = ytop + topstaff.Dist(bottom) * SheetMusic.NoteHeight / 2 + SheetMusic.NoteHeight / 4; int ystem = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2; g.DrawLine(pen, xstart, y1, xstart, ystem); } else if (direction == Down) { int y1 = ytop + topstaff.Dist(top) * SheetMusic.NoteHeight / 2 + SheetMusic.NoteHeight; if (side == LeftSide) { y1 = y1 - SheetMusic.NoteHeight / 4; } else { y1 = y1 - SheetMusic.NoteHeight / 2; } int ystem = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2 + SheetMusic.NoteHeight; g.DrawLine(pen, xstart, y1, xstart, ystem); } }
/** Draw the black circle notes. * @param ytop The ylocation (in pixels) where the top of the staff starts. * @param topstaff The white note of the top of the staff. */ public void DrawNotes(Graphics g, Pen pen, int ytop, WhiteNote topstaff) { pen.Width = 1; foreach (NoteData note in notedata) { /* Get the x,y position to draw the note */ int ynote = ytop + topstaff.Dist(note.whitenote) * SheetMusic.NoteHeight / 2; int xnote = SheetMusic.LineSpace / 4; if (!note.leftside) { xnote += SheetMusic.NoteWidth; } /* Draw rotated ellipse. You must first translate (0,0) * to the center of the ellipse. */ g.TranslateTransform(xnote + SheetMusic.NoteWidth / 2 + 1, ynote - SheetMusic.LineWidth + SheetMusic.NoteHeight / 2); g.RotateTransform(-45); if (sheetmusic != null) { pen.Color = sheetmusic.NoteColor(note.number); } else { pen.Color = Color.Black; } if (note.duration == NoteDuration.Whole || note.duration == NoteDuration.Half || note.duration == NoteDuration.DottedHalf) { g.DrawEllipse(pen, -SheetMusic.NoteWidth / 2, -SheetMusic.NoteHeight / 2, SheetMusic.NoteWidth, SheetMusic.NoteHeight - 1); g.DrawEllipse(pen, -SheetMusic.NoteWidth / 2, -SheetMusic.NoteHeight / 2 + 1, SheetMusic.NoteWidth, SheetMusic.NoteHeight - 2); g.DrawEllipse(pen, -SheetMusic.NoteWidth / 2, -SheetMusic.NoteHeight / 2 + 1, SheetMusic.NoteWidth, SheetMusic.NoteHeight - 3); } else { Brush brush = Brushes.Black; if (pen.Color != Color.Black) { brush = new SolidBrush(pen.Color); } g.FillEllipse(brush, -SheetMusic.NoteWidth / 2, -SheetMusic.NoteHeight / 2, SheetMusic.NoteWidth, SheetMusic.NoteHeight - 1); if (pen.Color != Color.Black) { brush.Dispose(); } } pen.Color = Color.Black; g.DrawEllipse(pen, -SheetMusic.NoteWidth / 2, -SheetMusic.NoteHeight / 2, SheetMusic.NoteWidth, SheetMusic.NoteHeight - 1); g.RotateTransform(45); g.TranslateTransform(-(xnote + SheetMusic.NoteWidth / 2 + 1), -(ynote - SheetMusic.LineWidth + SheetMusic.NoteHeight / 2)); /* Draw a dot if this is a dotted duration. */ if (note.duration == NoteDuration.DottedHalf || note.duration == NoteDuration.DottedQuarter || note.duration == NoteDuration.DottedEighth) { g.FillEllipse(Brushes.Black, xnote + SheetMusic.NoteWidth + SheetMusic.LineSpace / 3, ynote + SheetMusic.LineSpace / 3, 4, 4); } /* Draw horizontal lines if note is above/below the staff */ WhiteNote top = topstaff.Add(1); int dist = note.whitenote.Dist(top); int y = ytop - SheetMusic.LineWidth; if (dist >= 2) { for (int i = 2; i <= dist; i += 2) { y -= SheetMusic.NoteHeight; g.DrawLine(pen, xnote - SheetMusic.LineSpace / 4, y, xnote + SheetMusic.NoteWidth + SheetMusic.LineSpace / 4, y); } } WhiteNote bottom = top.Add(-8); y = ytop + (SheetMusic.LineSpace + SheetMusic.LineWidth) * 4 - 1; dist = bottom.Dist(note.whitenote); if (dist >= 2) { for (int i = 2; i <= dist; i += 2) { y += SheetMusic.NoteHeight; g.DrawLine(pen, xnote - SheetMusic.LineSpace / 4, y, xnote + SheetMusic.NoteWidth + SheetMusic.LineSpace / 4, y); } } /* End drawing horizontal lines */ } }
LineUpStemEnds(ChordSymbol[] chords) { Stem firstStem = chords[0].Stem; Stem lastStem = chords[chords.Length - 1].Stem; Stem middleStem = chords[1].Stem; if (firstStem.Direction == Stem.Up) { /* Find the highest stem. The beam will either: * - Slant downwards (first stem is highest) * - Slant upwards (last stem is highest) * - Be straight (middle stem is highest) */ WhiteNote top = firstStem.End; foreach (ChordSymbol chord in chords) { top = WhiteNote.Max(top, chord.Stem.End); } if (top == firstStem.End && top.Dist(lastStem.End) >= 2) { firstStem.End = top; middleStem.End = top.Add(-1); lastStem.End = top.Add(-2); } else if (top == lastStem.End && top.Dist(firstStem.End) >= 2) { firstStem.End = top.Add(-2); middleStem.End = top.Add(-1); lastStem.End = top; } else { firstStem.End = top; middleStem.End = top; lastStem.End = top; } } else { /* Find the bottommost stem. The beam will either: * - Slant upwards (first stem is lowest) * - Slant downwards (last stem is lowest) * - Be straight (middle stem is highest) */ WhiteNote bottom = firstStem.End; foreach (ChordSymbol chord in chords) { bottom = WhiteNote.Min(bottom, chord.Stem.End); } if (bottom == firstStem.End && lastStem.End.Dist(bottom) >= 2) { middleStem.End = bottom.Add(1); lastStem.End = bottom.Add(2); } else if (bottom == lastStem.End && firstStem.End.Dist(bottom) >= 2) { middleStem.End = bottom.Add(1); firstStem.End = bottom.Add(2); } else { firstStem.End = bottom; middleStem.End = bottom; lastStem.End = bottom; } } /* All middle stems have the same end */ for (int i = 1; i < chords.Length - 1; i++) { Stem stem = chords[i].Stem; stem.End = middleStem.End; } }
/* Draw a horizontal beam stem, connecting this stem with the Stem pair. * @param ytop The y location (in pixels) where the top of the staff starts. * @param topstaff The note at the top of the staff. */ private void DrawHorizBarStem(Graphics g, Pen pen, int ytop, WhiteNote topstaff) { pen.Width = SheetMusic.NoteHeight / 2; int xstart = 0; int xstart2 = 0; if (side == LeftSide) { xstart = SheetMusic.LineSpace / 4 + 1; } else if (side == RightSide) { xstart = SheetMusic.LineSpace / 4 + SheetMusic.NoteWidth; } if (pair.side == LeftSide) { xstart2 = SheetMusic.LineSpace / 4 + 1; } else if (pair.side == RightSide) { xstart2 = SheetMusic.LineSpace / 4 + SheetMusic.NoteWidth; } if (direction == Up) { int xend = width_to_pair + xstart2; int ystart = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2; int yend = ytop + topstaff.Dist(pair.end) * SheetMusic.NoteHeight / 2; if (duration == NoteDuration.Eighth || duration == NoteDuration.DottedEighth || duration == NoteDuration.Triplet || duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawLine(pen, xstart, ystart, xend, yend); } ystart += SheetMusic.NoteHeight; yend += SheetMusic.NoteHeight; /* A dotted eighth will connect to a 16th note. */ if (duration == NoteDuration.DottedEighth) { int x = xend - SheetMusic.NoteHeight; double slope = (yend - ystart) * 1.0 / (xend - xstart); int y = (int)(slope * (x - xend) + yend); g.DrawLine(pen, x, y, xend, yend); } if (duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawLine(pen, xstart, ystart, xend, yend); } ystart += SheetMusic.NoteHeight; yend += SheetMusic.NoteHeight; if (duration == NoteDuration.ThirtySecond) { g.DrawLine(pen, xstart, ystart, xend, yend); } } else { int xend = width_to_pair + xstart2; int ystart = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2 + SheetMusic.NoteHeight; int yend = ytop + topstaff.Dist(pair.end) * SheetMusic.NoteHeight / 2 + SheetMusic.NoteHeight; if (duration == NoteDuration.Eighth || duration == NoteDuration.DottedEighth || duration == NoteDuration.Triplet || duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawLine(pen, xstart, ystart, xend, yend); } ystart -= SheetMusic.NoteHeight; yend -= SheetMusic.NoteHeight; /* A dotted eighth will connect to a 16th note. */ if (duration == NoteDuration.DottedEighth) { int x = xend - SheetMusic.NoteHeight; double slope = (yend - ystart) * 1.0 / (xend - xstart); int y = (int)(slope * (x - xend) + yend); g.DrawLine(pen, x, y, xend, yend); } if (duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawLine(pen, xstart, ystart, xend, yend); } ystart -= SheetMusic.NoteHeight; yend -= SheetMusic.NoteHeight; if (duration == NoteDuration.ThirtySecond) { g.DrawLine(pen, xstart, ystart, xend, yend); } } pen.Width = 1; }
/** Draw a curvy stem tail. This is only used for single chords, not chord pairs. * @param ytop The y location (in pixels) where the top of the staff starts. * @param topstaff The note at the top of the staff. */ private void DrawCurvyStem(Graphics g, Pen pen, int ytop, WhiteNote topstaff) { pen.Width = 2; int xstart = 0; if (side == LeftSide) { xstart = SheetMusic.LineSpace / 4 + 1; } else { xstart = SheetMusic.LineSpace / 4 + SheetMusic.NoteWidth; } if (direction == Up) { int ystem = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2; if (duration == NoteDuration.Eighth || duration == NoteDuration.DottedEighth || duration == NoteDuration.Triplet || duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawBezier(pen, xstart, ystem, xstart, ystem + 3 * SheetMusic.LineSpace / 2, xstart + SheetMusic.LineSpace * 2, ystem + SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace / 2, ystem + SheetMusic.NoteHeight * 3); } ystem += SheetMusic.NoteHeight; if (duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawBezier(pen, xstart, ystem, xstart, ystem + 3 * SheetMusic.LineSpace / 2, xstart + SheetMusic.LineSpace * 2, ystem + SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace / 2, ystem + SheetMusic.NoteHeight * 3); } ystem += SheetMusic.NoteHeight; if (duration == NoteDuration.ThirtySecond) { g.DrawBezier(pen, xstart, ystem, xstart, ystem + 3 * SheetMusic.LineSpace / 2, xstart + SheetMusic.LineSpace * 2, ystem + SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace / 2, ystem + SheetMusic.NoteHeight * 3); } } else if (direction == Down) { int ystem = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2 + SheetMusic.NoteHeight; if (duration == NoteDuration.Eighth || duration == NoteDuration.DottedEighth || duration == NoteDuration.Triplet || duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawBezier(pen, xstart, ystem, xstart, ystem - SheetMusic.LineSpace, xstart + SheetMusic.LineSpace * 2, ystem - SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace, ystem - SheetMusic.NoteHeight * 2 - SheetMusic.LineSpace / 2); } ystem -= SheetMusic.NoteHeight; if (duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { g.DrawBezier(pen, xstart, ystem, xstart, ystem - SheetMusic.LineSpace, xstart + SheetMusic.LineSpace * 2, ystem - SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace, ystem - SheetMusic.NoteHeight * 2 - SheetMusic.LineSpace / 2); } ystem -= SheetMusic.NoteHeight; if (duration == NoteDuration.ThirtySecond) { g.DrawBezier(pen, xstart, ystem, xstart, ystem - SheetMusic.LineSpace, xstart + SheetMusic.LineSpace * 2, ystem - SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace, ystem - SheetMusic.NoteHeight * 2 - SheetMusic.LineSpace / 2); } } pen.Width = 1; }