RenderForm.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using KaraokeRenderPoc.Karaoke;
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Drawing.Text;
  6. using System.Windows.Forms;
  7. namespace KaraokeRenderPoc
  8. {
  9. public partial class RenderForm : Form
  10. {
  11. private KaraokeLyric _karaoke;
  12. public RenderForm()
  13. {
  14. InitializeComponent();
  15. InputTextBox.Text = Properties.Resources.Example;
  16. }
  17. private void ParseButton_Click(object sender, EventArgs e)
  18. {
  19. _karaoke = new KaraokeLyric(InputTextBox.Lines);
  20. PositionTrackBar.Maximum = _karaoke.Length;
  21. }
  22. private void PositionTrackBar_Scroll(object sender, EventArgs e)
  23. {
  24. RenderPictureBox.Invalidate();
  25. }
  26. private void RenderPictureBox_Paint(object sender, PaintEventArgs e)
  27. {
  28. var g = e.Graphics;
  29. g.CompositingMode = CompositingMode.SourceOver;
  30. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  31. g.PixelOffsetMode = PixelOffsetMode.HighQuality;
  32. g.SmoothingMode = SmoothingMode.HighQuality;
  33. g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
  34. g.PageUnit = GraphicsUnit.Pixel;
  35. var top = 400;
  36. var correctWidth = -25f;
  37. var readyOutlineColor = Color.Black;
  38. var readyFillColor = Color.White;
  39. var singOutlineColor = Color.White;
  40. var singFillColor = Color.Blue;
  41. var timelinePosition = PositionTrackBar.Value;
  42. if (_karaoke != null)
  43. {
  44. var index = _karaoke.GetSentenceIndex(timelinePosition);
  45. var sentence = _karaoke.Sentences[index];
  46. using var rubyFont = new Font("方正准圆_GBK", 20, FontStyle.Bold);
  47. using var textFont = new Font("方正准圆_GBK", 40, FontStyle.Bold);
  48. var left = 0f;
  49. foreach (var word in sentence.Words)
  50. {
  51. var rubySize = g.MeasureString(word.Ruby, rubyFont);//g.MeasureDisplayString(word.Ruby, rubyFont);//TextRenderer.MeasureText(g, word.Ruby, rubyFont); //
  52. var textSize = g.MeasureString(word.Text, textFont);//g.MeasureDisplayString(word.Text, textFont);//TextRenderer.MeasureText(g, word.Text, textFont); //
  53. var maxWidth = Math.Max(rubySize.Width, textSize.Width);
  54. //g.DrawRectangle(Pens.Red, left, top, rubySize.Width, rubyFont.Height);
  55. //g.DrawRectangle(Pens.Red, left, top + rubyFont.Height, textSize.Width, textFont.Height);
  56. if (word.StartPosition <= timelinePosition && word.EndPosition >= timelinePosition)
  57. {
  58. var percent = ((float)timelinePosition - word.StartPosition) / word.Duration;
  59. var singWidth = maxWidth * percent;
  60. var readyWidth = maxWidth - singWidth;
  61. g.SetClip(new RectangleF(left, top, singWidth, rubyFont.Height + textFont.Height));
  62. g.DrawKaraoke(word.Ruby, rubyFont, new RectangleF(left, top, maxWidth, rubyFont.Height), singOutlineColor, singFillColor);
  63. g.DrawKaraoke(word.Text, textFont, new RectangleF(left, top + rubyFont.Height, maxWidth, textFont.Height), singOutlineColor, singFillColor);
  64. g.SetClip(new RectangleF(left + singWidth, top, readyWidth, rubyFont.Height + textFont.Height));
  65. g.DrawKaraoke(word.Ruby, rubyFont, new RectangleF(left, top, maxWidth, rubyFont.Height), readyOutlineColor, readyFillColor);
  66. g.DrawKaraoke(word.Text, textFont, new RectangleF(left, top + rubyFont.Height, maxWidth, textFont.Height), readyOutlineColor, readyFillColor);
  67. g.ResetClip();
  68. }
  69. else if (word.EndPosition < timelinePosition)
  70. {
  71. g.DrawKaraoke(word.Ruby, rubyFont, new RectangleF(left, top, maxWidth, rubyFont.Height), singOutlineColor, singFillColor);
  72. g.DrawKaraoke(word.Text, textFont, new RectangleF(left, top + rubyFont.Height, maxWidth, textFont.Height), singOutlineColor, singFillColor);
  73. }
  74. else
  75. {
  76. g.DrawKaraoke(word.Ruby, rubyFont, new RectangleF(left, top, maxWidth, rubySize.Height), readyOutlineColor, readyFillColor);
  77. g.DrawKaraoke(word.Text, textFont, new RectangleF(left, top + rubyFont.Height, maxWidth, textSize.Height), readyOutlineColor, readyFillColor);
  78. }
  79. left += correctWidth + maxWidth;
  80. }
  81. }
  82. }
  83. }
  84. internal static class ExtensionMethods
  85. {
  86. public static void DrawKaraoke(this Graphics g, string s, Font f, RectangleF rectangle, Color outline, Color fill, int outlineWidth = 1)
  87. {
  88. using var path = new GraphicsPath();
  89. {
  90. using var alignment = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Near };
  91. path.AddString(s, f.FontFamily, (int)f.Style, f.Size, rectangle, alignment);
  92. }
  93. using var fillBrush = new SolidBrush(fill);
  94. g.FillPath(fillBrush, path);
  95. using var outlinePen = new Pen(outline, outlineWidth);
  96. g.DrawPath(outlinePen, path);
  97. }
  98. }
  99. }