OSDN Git Service

#xxxxx CPrivateFont (とCPrivateFastFont) に以下の修正を適用。
[dtxmania/dtxmania.git] / DTXMania / コード / 全体 / CPrivateFastFont.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Runtime.InteropServices;
4 using System.Text;
5 using System.Drawing;
6 using System.Drawing.Drawing2D;
7 using System.Diagnostics;
8
9 namespace DTXMania
10 {
11         /// <summary>
12         /// 高速描画版のCPrivateFontクラス。
13         /// といっても、一度レンダリングした結果をキャッシュして使いまわしているだけ。
14         /// </summary>
15         public class CPrivateFastFont : CPrivateFont
16         {
17                 /// <summary>
18                 /// キャッシュ容量
19                 /// </summary>
20                 private const int MAXCACHESIZE = 128;
21
22                 private struct FontCache
23                 {
24                         // public Font font;
25                         public string drawstr;
26                         public DrawMode drawmode;
27                         public Color fontColor;
28                         public Color edgeColor;
29                         public Color gradationTopColor;
30                         public Color gradationBottomColor;
31                         public Bitmap bmp;
32                         public Rectangle rectStrings;
33                         public Point ptOrigin;
34                 }
35                 private List<FontCache> listFontCache;
36
37
38                 #region [ コンストラクタ ]
39                 public CPrivateFastFont(FontFamily fontfamily, float pt, FontStyle style)
40                 {
41                         Initialize(null, null, fontfamily, pt, style);
42                 }
43                 public CPrivateFastFont(FontFamily fontfamily, float pt)
44                 {
45                         Initialize(null, null, fontfamily, pt, FontStyle.Regular);
46                 }
47                 public CPrivateFastFont(string fontpath, float pt, FontStyle style)
48                 {
49                         Initialize(fontpath, null, null, pt, style);
50                 }
51                 public CPrivateFastFont(string fontpath, float pt)
52                 {
53                         Initialize(fontpath, null, null, pt, FontStyle.Regular);
54                 }
55                 public CPrivateFastFont()
56                 {
57                         throw new ArgumentException("CPrivateFastFont: 引数があるコンストラクタを使用してください。");
58                 }
59                 #endregion
60                 #region [ コンストラクタから呼ばれる初期化処理 ]
61                 protected new void Initialize(string fontpath, string baseFontPath, FontFamily fontfamily, float pt, FontStyle style)
62                 {
63                         this.bDispose完了済み_CPrivateFastFont = false;
64                         this.listFontCache = new List<FontCache>();
65                         base.Initialize(fontpath, baseFontPath, fontfamily, pt, style);
66                 }
67                 #endregion
68
69
70                 #region [ DrawPrivateFontのオーバーロード群 ]
71                 /// <summary>
72                 /// 文字列を描画したテクスチャを返す
73                 /// </summary>
74                 /// <param name="drawstr">描画文字列</param>
75                 /// <param name="fontColor">描画色</param>
76                 /// <returns>描画済テクスチャ</returns>
77                 public new Bitmap DrawPrivateFont(string drawstr, Color fontColor)
78                 {
79                         return DrawPrivateFont(drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White);
80                 }
81
82                 /// <summary>
83                 /// 文字列を描画したテクスチャを返す
84                 /// </summary>
85                 /// <param name="drawstr">描画文字列</param>
86                 /// <param name="fontColor">描画色</param>
87                 /// <param name="edgeColor">縁取色</param>
88                 /// <returns>描画済テクスチャ</returns>
89                 public new Bitmap DrawPrivateFont(string drawstr, Color fontColor, Color edgeColor)
90                 {
91                         return DrawPrivateFont(drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White);
92                 }
93
94                 /// <summary>
95                 /// 文字列を描画したテクスチャを返す
96                 /// </summary>
97                 /// <param name="drawstr">描画文字列</param>
98                 /// <param name="fontColor">描画色</param>
99                 /// <param name="gradationTopColor">グラデーション 上側の色</param>
100                 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
101                 /// <returns>描画済テクスチャ</returns>
102                 //public new Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )
103                 //{
104                 //    return DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );
105                 //}
106
107                 /// <summary>
108                 /// 文字列を描画したテクスチャを返す
109                 /// </summary>
110                 /// <param name="drawstr">描画文字列</param>
111                 /// <param name="fontColor">描画色</param>
112                 /// <param name="edgeColor">縁取色</param>
113                 /// <param name="gradationTopColor">グラデーション 上側の色</param>
114                 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
115                 /// <returns>描画済テクスチャ</returns>
116                 public new Bitmap DrawPrivateFont(string drawstr, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradataionBottomColor)
117                 {
118                         return DrawPrivateFont(drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor);
119                 }
120
121 #if こちらは使わない // (Bitmapではなく、CTextureを返す版)
122                 /// <summary>
123                 /// 文字列を描画したテクスチャを返す
124                 /// </summary>
125                 /// <param name="drawstr">描画文字列</param>
126                 /// <param name="fontColor">描画色</param>
127                 /// <returns>描画済テクスチャ</returns>
128                 public CTexture DrawPrivateFont( string drawstr, Color fontColor )
129                 {
130                         Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White );
131                         return TextureFactory.tテクスチャの生成( bmp, false );
132                 }
133
134                 /// <summary>
135                 /// 文字列を描画したテクスチャを返す
136                 /// </summary>
137                 /// <param name="drawstr">描画文字列</param>
138                 /// <param name="fontColor">描画色</param>
139                 /// <param name="edgeColor">縁取色</param>
140                 /// <returns>描画済テクスチャ</returns>
141                 public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor )
142                 {
143                         Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White );
144                         return TextureFactory.tテクスチャの生成( bmp, false );
145                 }
146
147                 /// <summary>
148                 /// 文字列を描画したテクスチャを返す
149                 /// </summary>
150                 /// <param name="drawstr">描画文字列</param>
151                 /// <param name="fontColor">描画色</param>
152                 /// <param name="gradationTopColor">グラデーション 上側の色</param>
153                 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
154                 /// <returns>描画済テクスチャ</returns>
155                 //public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )
156                 //{
157                 //    Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );
158                 //        return TextureFactory.tテクスチャの生成( bmp, false );
159                 //}
160
161                 /// <summary>
162                 /// 文字列を描画したテクスチャを返す
163                 /// </summary>
164                 /// <param name="drawstr">描画文字列</param>
165                 /// <param name="fontColor">描画色</param>
166                 /// <param name="edgeColor">縁取色</param>
167                 /// <param name="gradationTopColor">グラデーション 上側の色</param>
168                 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
169                 /// <returns>描画済テクスチャ</returns>
170                 public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor,  Color gradationTopColor, Color gradataionBottomColor )
171                 {
172                         Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor );
173                         return TextureFactory.tテクスチャの生成( bmp, false );
174                 }
175 #endif
176                 #endregion
177
178                 protected new Bitmap DrawPrivateFont(string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradationBottomColor)
179                 {
180                         #region [ 以前レンダリングしたことのある文字列/フォントか? (キャッシュにヒットするか?) ]
181                         int index = listFontCache.FindIndex(
182                                 delegate (FontCache fontcache)
183                                 {
184                                         return (
185                                                 drawstr == fontcache.drawstr &&
186                                                 drawmode == fontcache.drawmode &&
187                                                 fontColor == fontcache.fontColor &&
188                                                 edgeColor == fontcache.edgeColor &&
189                                                 gradationTopColor == fontcache.gradationTopColor &&
190                                                 gradationBottomColor == fontcache.gradationBottomColor
191                                         // _font == fontcache.font
192                                         );
193                                 }
194                         );
195                         #endregion
196                         if (index < 0)
197                         {
198                                 // キャッシュにヒットせず。
199                                 #region [ レンダリングして、キャッシュに登録 ]
200                                 FontCache fc = new FontCache();
201                                 fc.bmp = base.DrawPrivateFont(drawstr, drawmode, fontColor, edgeColor, gradationTopColor, gradationBottomColor);
202                                 fc.drawstr = drawstr;
203                                 fc.drawmode = drawmode;
204                                 fc.fontColor = fontColor;
205                                 fc.edgeColor = edgeColor;
206                                 fc.gradationTopColor = gradationTopColor;
207                                 fc.gradationBottomColor = gradationBottomColor;
208                                 fc.rectStrings = RectStrings;
209                                 fc.ptOrigin = PtOrigin;
210                                 listFontCache.Add(fc);
211                                 // Debug.WriteLine( drawstr + ": Cacheにヒットせず。(cachesize=" + listFontCache.Count + ")" );
212                                 #endregion
213                                 #region [ もしキャッシュがあふれたら、最も古いキャッシュを破棄する ]
214                                 if (listFontCache.Count > MAXCACHESIZE)
215                                 {
216                                         // Debug.WriteLine( "Cache溢れ。" + listFontCache[ 0 ].drawstr + " を解放します。" );
217                                         if (listFontCache[0].bmp != null)
218                                         {
219                                                 listFontCache[0].bmp.Dispose();
220                                         }
221                                         listFontCache.RemoveAt(0);
222                                 }
223                                 #endregion
224
225                                 // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。
226                                 return (Bitmap)listFontCache[listFontCache.Count - 1].bmp.Clone();
227                         }
228                         else
229                         {
230                                 // Debug.WriteLine( drawstr + ": Cacheにヒット!! index=" + index );
231                                 #region [ キャッシュにヒット。レンダリングは行わず、キャッシュ内のデータを返して終了。]
232                                 RectStrings = listFontCache[index].rectStrings;
233                                 PtOrigin = listFontCache[index].ptOrigin;
234                                 // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。
235                                 return (Bitmap)listFontCache[index].bmp.Clone();
236                                 #endregion
237                         }
238                 }
239
240                 #region [ IDisposable 実装 ]
241                 //-----------------
242                 public new void Dispose()
243                 {
244                         if (!this.bDispose完了済み_CPrivateFastFont)
245                         {
246                                 if (listFontCache != null)
247                                 {
248                                         //Debug.WriteLine( "Disposing CPrivateFastFont()" );
249                                         #region [ キャッシュしている画像を破棄する ]
250                                         foreach (FontCache bc in listFontCache)
251                                         {
252                                                 if (bc.bmp != null)
253                                                 {
254                                                         bc.bmp.Dispose();
255                                                 }
256                                         }
257                                         #endregion
258                                         listFontCache.Clear();
259                                         listFontCache = null;
260                                 }
261                                 this.bDispose完了済み_CPrivateFastFont = true;
262                         }
263                         base.Dispose();
264                 }
265                 //-----------------
266                 #endregion
267
268                 #region [ private ]
269                 //-----------------
270                 protected bool bDispose完了済み_CPrivateFastFont;
271                 //-----------------
272                 #endregion
273         }
274 }