StringMeasure.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.Windows.Forms;
  5. using MinorShift.Emuera;
  6. using MinorShift._Library;
  7. namespace NTERA.Game.Display
  8. {
  9. /// <summary>
  10. /// テキスト長計測装置
  11. /// 1819 必要になるたびにCreateGraphicsする方式をやめてあらかじめGraphicsを用意しておくことにする
  12. /// </summary>
  13. public sealed class StringMeasure : IDisposable
  14. {
  15. public StringMeasure()
  16. {
  17. textDrawingMode = Config.TextDrawingMode;
  18. layoutSize = new Size(Config.WindowX * 2, Config.LineHeight);
  19. layoutRect = new RectangleF(0, 0, Config.WindowX * 2, Config.LineHeight);
  20. fontDisplaySize = Config.Font.Size / 2 * 1.04f;//実際には指定したフォントより若干幅をとる?
  21. //bmp = new Bitmap(Config.WindowX, Config.LineHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
  22. bmp = new Bitmap(16, 16, PixelFormat.Format32bppArgb);
  23. graph = Graphics.FromImage(bmp);
  24. if (textDrawingMode == TextDrawingMode.WINAPI)
  25. GDI.GdiMesureTextStart(graph);
  26. }
  27. readonly TextDrawingMode textDrawingMode;
  28. readonly StringFormat sf = new StringFormat(StringFormatFlags.MeasureTrailingSpaces);
  29. readonly CharacterRange[] ranges = { new CharacterRange(0, 1) };
  30. readonly Size layoutSize;
  31. readonly RectangleF layoutRect;
  32. readonly float fontDisplaySize;
  33. readonly Graphics graph;
  34. readonly Bitmap bmp;
  35. public int GetDisplayLength(string s, Font font)
  36. {
  37. if (string.IsNullOrEmpty(s))
  38. return 0;
  39. if (textDrawingMode == TextDrawingMode.GRAPHICS)
  40. {
  41. if (s.Contains("\t"))
  42. s = s.Replace("\t", " ");
  43. ranges[0].Length = s.Length;
  44. //CharacterRange[] ranges = new CharacterRange[] { new CharacterRange(0, s.Length) };
  45. sf.SetMeasurableCharacterRanges(ranges);
  46. Region[] regions = graph.MeasureCharacterRanges(s, font, layoutRect, sf);
  47. RectangleF rectF = regions[0].GetBounds(graph);
  48. //return (int)rectF.Width;//プロポーショナルでなくても数ピクセルずれる
  49. return (int)((int)((rectF.Width - 1) / fontDisplaySize + 0.95f) * fontDisplaySize);
  50. }
  51. if (textDrawingMode == TextDrawingMode.TEXTRENDERER)
  52. {
  53. Size size = TextRenderer.MeasureText(graph, s, font, layoutSize, TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix);
  54. //Size size = TextRenderer.MeasureText(g, s, StaticConfig.Font);
  55. return size.Width;
  56. }
  57. else// if (StaticConfig.TextDrawingMode == TextDrawingMode.WINAPI)
  58. {
  59. Size size = GDI.MeasureText(s, font);
  60. return size.Width;
  61. }
  62. //来るわけがない
  63. //else
  64. // throw new ExeEE("描画モード不明");
  65. }
  66. bool disposed;
  67. public void Dispose()
  68. {
  69. if (disposed)
  70. return;
  71. disposed = true;
  72. if (textDrawingMode == TextDrawingMode.WINAPI)
  73. GDI.GdiMesureTextEnd(graph);
  74. graph.Dispose();
  75. bmp.Dispose();
  76. sf.Dispose();
  77. }
  78. }
  79. }