OSDN Git Service

#37961 PCとMIDI機器をつなぐケーブルとして「MIDI2.0-USB」を使用している場合に警告を表示する機能を追加。このケーブルを通すと、PCからのMIDI出力...
[dtxmania/dtxmania.git] / DTXMania / コード / ステージ / CActDigit.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using FDK;
7 using System.Drawing;
8 using SharpDX;
9
10 using Rectangle = System.Drawing.Rectangle;
11 using Color = System.Drawing.Color;
12
13 namespace DTXMania
14 {
15         public class CActDigit : CActivity
16         {
17                 Rectangle[] digitRect = new Rectangle[12];
18                 CTexture[] texDigit = new CTexture[12];
19                 Color colorInside;
20                 Color colorEdge;
21                 Color colorGradTop;
22                 Color colorGradBottom;
23                 int pt;
24                 bool bEdge;
25                 bool bGrad;
26
27                 public int MaximumHeight { get; private set; }
28
29                 public CActDigit(Color color, int pt)
30                 {
31                         colorInside = color;
32                         this.pt = pt;
33                 }
34
35                 public CActDigit(Color colorInside, Color colorEdge, int pt)
36                 {
37                         this.colorInside = colorInside;
38                         this.colorEdge = colorEdge;
39                         this.pt = pt;
40                         bEdge = true;
41                 }
42
43                 public CActDigit(Color colorInside, Color colorEdge, Color gradTop, Color gradBottom, int pt)
44                 {
45                         this.colorInside = colorInside;
46                         this.colorEdge = colorEdge;
47                         this.colorGradTop = gradTop;
48                         this.colorGradBottom = gradBottom;
49                         this.pt = pt;
50                         bEdge = true;
51                         bGrad = true;
52                 }
53
54                 public override void OnManagedリソースの作成()
55                 {
56                         string dg = "0123456789";
57
58                         if (b活性化してる)
59                         {
60                                 for (int i = 0; i < texDigit.Length; ++i)
61                                 {
62                                         TextureFactory.tテクスチャの解放(ref texDigit[i]);
63                                 }
64
65                                 using (FontFamily ff = new FontFamily("MS PGothic"))
66                                 {
67                                         using (CPrivateFont cpf = new CPrivateFont(ff, pt, FontStyle.Bold))
68                                         {
69                                                 for (int i = 0; i < 12; ++i)
70                                                 {
71                                                         string sub = ".";
72                                                         if (i < 10)
73                                                         {
74                                                                 sub = dg.Substring(i, 1);
75                                                         }
76                                                         else
77                                                         {
78                                                                 sub = "-";
79                                                         }
80
81                                                         Bitmap x = null;
82                                                         if (bGrad)
83                                                         {
84                                                                 x = cpf.DrawPrivateFont(sub, colorInside, colorEdge, colorGradTop, colorGradBottom);
85                                                         }
86                                                         else if (bEdge)
87                                                         {
88                                                                 x = cpf.DrawPrivateFont(sub, colorInside, colorEdge);
89                                                         }
90                                                         else
91                                                         {
92                                                                 x = cpf.DrawPrivateFont(sub, colorInside);
93                                                         }
94
95                                                         using (Bitmap bmp = x)
96                                                         {
97                                                                 texDigit[i] = TextureFactory.tテクスチャの生成(bmp);
98                                                                 digitRect[i] = MeasureRectangle(bmp);
99                                                                 MaximumHeight = Math.Max(MaximumHeight, digitRect[i].Height);
100                                                         }
101                                                 }
102                                         }
103                                 }
104                                 base.OnManagedリソースの作成();
105                         }
106                 }
107
108                 public override void OnManagedリソースの解放()
109                 {
110                         if (b活性化してる)
111                         {
112                                 for (int i = 0; i < texDigit.Length; ++i)
113                                 {
114                                         TextureFactory.tテクスチャの解放(ref texDigit[i]);
115                                 }
116                                 base.OnManagedリソースの解放();
117                         }
118                 }
119
120                 /// <summary>
121                 /// bmp 内の不透明ピクセルからなる最大の範囲(幅)を得る。
122                 /// CPrivateFont で文字描画前の bmp は透明になっているから透明でないピクセルをなめて実際の幅を得る。
123                 /// (重いので描画処理中には呼ばないこと)
124                 /// </summary>
125                 /// <param name="bmp">計算対象ビットマップ。</param>
126                 /// <returns>有効なピクセルを囲う最小の矩形情報</returns>
127                 private Rectangle MeasureRectangle(Bitmap bmp)
128                 {
129                         int xmin = bmp.Width;
130                         int xmax = -1;
131                         int ymin = bmp.Height;
132                         int ymax = -1;
133                         for (int x = 0; x < bmp.Width; ++x)
134                         {
135                                 for (int y = 0; y < bmp.Height; ++y)
136                                 {
137                                         if (bmp.GetPixel(x, y).A != 0)
138                                         {
139                                                 xmin = Math.Min(xmin, x);
140                                                 xmax = Math.Max(xmax, x);
141                                                 ymin = Math.Min(ymin, y);
142                                                 ymax = Math.Max(ymax, y);
143                                         }
144                                 }
145                         }
146                         return new Rectangle(xmin, ymin, xmax - xmin, ymax - ymin);
147                 }
148
149                 public int Measure(int num)
150                 {
151                         return DrawSub((long)num, 0, 0, false);
152                 }
153
154                 public int Measure(long num)
155                 {
156                         return DrawSub(num, 0, 0, false);
157                 }
158
159                 private int numlen(int n)
160                 {
161                         int ret = 0;
162                         if (n == 0)
163                         {
164                                 ret = 1;
165                         }
166                         while (n > 0)
167                         {
168                                 ++ret;
169                                 n /= 10;
170                         }
171                         return ret;
172                 }
173
174                 public int Measure(double num, int prec)
175                 {
176                         int ret = 0;
177                         int integer = (int)num;
178                         ret += Measure(integer);
179                         // . を足す
180                         ret += digitRect[11].Width;
181
182                         int dec = (int)((num - integer) * Math.Pow(10, prec));
183                         for (int d = 0; d < prec - numlen(dec); ++d)
184                         {
185                                 // 0.007 のような場合で 007 の 00 をカウントする
186                                 ret += digitRect[0].Width;
187                         }
188                         ret += Measure(dec);
189
190                         return ret;
191                 }
192
193                 public void Draw(int num, int x, int y)
194                 {
195                         DrawSub((long)num, x, y);
196                 }
197
198                 public void Draw(long num, int x, int y)
199                 {
200                         DrawSub(num, x, y, true);
201                 }
202
203                 public void Draw(double num, int prec, int x, int y)
204                 {
205                         int integer = (int)num;
206
207                         // 整数部
208                         x += DrawSub(integer, x, y);
209
210                         // . を描画
211                         texDigit[11].t2D描画(CDTXMania.Instance.Device, x, y);
212                         x += digitRect[11].Width;
213
214                         // 小数部
215                         int dec = (int)((num - integer) * Math.Pow(10, prec));
216                         for (int d = 0; d < prec - numlen(dec); ++d)
217                         {
218                                 x += DrawSub(0, x, y, true);
219                         }
220                         DrawSub((int)dec, x, y);
221                 }
222
223                 private int DrawSub(long num, int x = 0, int y = 0, bool draw = true)
224                 {
225                         int ret = 0;
226
227                         List<int> d = new List<int>();
228
229                         if (num < 0)
230                         {
231                                 d.Add(10);
232                                 num -= num;
233                         }
234
235                         if (num > 0)
236                         {
237                                 while (num > 0)
238                                 {
239                                         d.Add((int)(num % 10));
240                                         num /= 10;
241                                 }
242                         }
243                         else if (num == 0)
244                         {
245                                 d.Add(0);
246                         }
247                         d.Reverse();
248
249                         foreach (var t in d)
250                         {
251                                 if (texDigit[t] != null)
252                                 {
253                                         if (draw)
254                                         {
255                                                 texDigit[t].t2D描画(CDTXMania.Instance.Device, x, y, digitRect[t]);
256                                                 x += digitRect[t].Width;
257                                         }
258                                         ret += digitRect[t].Width;
259                                 }
260                         }
261
262                         return ret;
263                 }
264
265         }
266 }