2 using System.Collections.Generic;
\r
5 using System.Runtime.InteropServices;
\r
6 using System.Drawing;
\r
7 using System.Drawing.Drawing2D;
\r
8 using System.Diagnostics;
\r
15 /// プライベートフォントでの描画を扱うクラス。
\r
17 /// <exception cref="FileNotFoundException">フォントファイルが見つからない時に例外発生</exception>
\r
18 /// <exception cref="ArgumentException">スタイル指定不正時に例外発生</exception>
\r
21 /// CPrivateFont prvFont = new CPrivateFont( CSkin.Path( @"Graphics\fonts\mplus-1p-bold.ttf" ), 36 ); // プライベートフォント
\r
23 /// CPrivateFont prvFont = new CPrivateFont( new FontFamily("MS UI Gothic"), 36, FontStyle.Bold ); // システムフォント
\r
25 /// Bitmap bmp = prvFont.DrawPrivateFont( "ABCDE", Color.White, Color.Black ); // フォント色=白、縁の色=黒の例。縁の色は省略可能
\r
27 /// Bitmap bmp = prvFont.DrawPrivateFont( "ABCDE", Color.White, Color.Black, Color.Yellow, Color.OrangeRed ); // 上下グラデーション(Yellow→OrangeRed)
\r
29 /// CTexture ctBmp = CDTXMania.tテクスチャの生成( bmp, false );
\r
30 /// ctBMP.t2D描画( ~~~ );
\r
34 /// 任意のフォントでのレンダリングは結構負荷が大きいので、なるべkなら描画フレーム毎にフォントを再レンダリングするようなことはせず、
\r
35 /// 一旦レンダリングしたものを描画に使い回すようにしてください。
\r
36 /// また、長い文字列を与えると、返されるBitmapも横長になります。この横長画像をそのままテクスチャとして使うと、
\r
37 /// 古いPCで問題を発生させやすいです。これを回避するには、一旦Bitmapとして取得したのち、256pixや512pixで分割して
\r
38 /// テクスチャに定義するようにしてください。
\r
40 public class CPrivateFont : IDisposable
\r
43 public CPrivateFont( FontFamily fontfamily, int pt, FontStyle style )
\r
45 Initialize( null, fontfamily, pt, style );
\r
47 public CPrivateFont( FontFamily fontfamily, int pt )
\r
49 Initialize( null, fontfamily, pt, FontStyle.Regular );
\r
51 public CPrivateFont( string fontpath, int pt, FontStyle style )
\r
53 Initialize( fontpath, null, pt, style );
\r
55 public CPrivateFont( string fontpath, int pt )
\r
57 Initialize( fontpath, null, pt, FontStyle.Regular );
\r
59 public CPrivateFont()
\r
61 //throw new ArgumentException("CPrivateFont: 引数があるコンストラクタを使用してください。");
\r
65 protected void Initialize( string fontpath, FontFamily fontfamily, int pt, FontStyle style )
\r
68 this._fontfamily = null;
\r
71 this._rectStrings = new Rectangle( 0, 0, 0, 0 );
\r
72 this._ptOrigin = new Point( 0, 0 );
\r
73 this.bDispose完了済み = false;
\r
75 if ( fontfamily != null )
\r
77 this._fontfamily = fontfamily;
\r
83 this._pfc = new System.Drawing.Text.PrivateFontCollection(); //PrivateFontCollectionオブジェクトを作成する
\r
84 this._pfc.AddFontFile( fontpath ); //PrivateFontCollectionにフォントを追加する
\r
86 catch ( System.IO.FileNotFoundException )
\r
88 Trace.TraceError( "プライベートフォントの追加に失敗しました。({0})", fontpath );
\r
89 throw new FileNotFoundException( "プライベートフォントの追加に失敗しました。({0})", Path.GetFileName( fontpath ) );
\r
93 //foreach ( FontFamily ff in pfc.Families )
\r
95 // Debug.WriteLine( "fontname=" + ff.Name );
\r
96 // if ( ff.Name == Path.GetFileNameWithoutExtension( fontpath ) )
\r
98 // _fontfamily = ff;
\r
102 //if ( _fontfamily == null )
\r
104 // Trace.TraceError( "プライベートフォントの追加後、検索に失敗しました。({0})", fontpath );
\r
107 _fontfamily = _pfc.Families[ 0 ];
\r
110 // 指定されたフォントスタイルが適用できない場合は、フォント内で定義されているスタイルから候補を選んで使用する
\r
111 // 何もスタイルが使えないようなフォントなら、例外を出す。
\r
112 if ( !_fontfamily.IsStyleAvailable( style ) )
\r
114 FontStyle[] FS = { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Underline, FontStyle.Strikeout };
\r
115 style = FontStyle.Regular | FontStyle.Bold | FontStyle.Italic | FontStyle.Underline | FontStyle.Strikeout; // null非許容型なので、代わりに全盛をNGワードに設定
\r
116 foreach ( FontStyle ff in FS )
\r
118 if ( this._fontfamily.IsStyleAvailable( ff ) )
\r
121 Trace.TraceWarning( "フォント{0}へのスタイル指定を、{1}に変更しました。", Path.GetFileName( fontpath ), style.ToString() );
\r
125 if ( style == ( FontStyle.Regular | FontStyle.Bold | FontStyle.Italic | FontStyle.Underline | FontStyle.Strikeout ) )
\r
127 throw new ArgumentException( "フォント{0}は適切なスタイルを選択できず、使用できません。", Path.GetFileName( fontpath ) );
\r
130 this._font = new Font( this._fontfamily, pt, style ); //PrivateFontCollectionの先頭のフォントのFontオブジェクトを作成する
\r
134 protected enum DrawMode
\r
141 #region [ DrawPrivateFontのオーバーロード群 ]
\r
143 /// 文字列を描画したテクスチャを返す
\r
145 /// <param name="drawstr">描画文字列</param>
\r
146 /// <param name="fontColor">描画色</param>
\r
147 /// <returns>描画済テクスチャ</returns>
\r
148 public Bitmap DrawPrivateFont( string drawstr, Color fontColor )
\r
150 return DrawPrivateFont( drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White );
\r
154 /// 文字列を描画したテクスチャを返す
\r
156 /// <param name="drawstr">描画文字列</param>
\r
157 /// <param name="fontColor">描画色</param>
\r
158 /// <param name="edgeColor">縁取色</param>
\r
159 /// <returns>描画済テクスチャ</returns>
\r
160 public Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor )
\r
162 return DrawPrivateFont( drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White );
\r
166 /// 文字列を描画したテクスチャを返す
\r
168 /// <param name="drawstr">描画文字列</param>
\r
169 /// <param name="fontColor">描画色</param>
\r
170 /// <param name="gradationTopColor">グラデーション 上側の色</param>
\r
171 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
\r
172 /// <returns>描画済テクスチャ</returns>
\r
173 //public Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )
\r
175 // return DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );
\r
179 /// 文字列を描画したテクスチャを返す
\r
181 /// <param name="drawstr">描画文字列</param>
\r
182 /// <param name="fontColor">描画色</param>
\r
183 /// <param name="edgeColor">縁取色</param>
\r
184 /// <param name="gradationTopColor">グラデーション 上側の色</param>
\r
185 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
\r
186 /// <returns>描画済テクスチャ</returns>
\r
187 public Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradataionBottomColor )
\r
189 return DrawPrivateFont( drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor );
\r
192 #if こちらは使わない // (Bitmapではなく、CTextureを返す版)
\r
194 /// 文字列を描画したテクスチャを返す
\r
196 /// <param name="drawstr">描画文字列</param>
\r
197 /// <param name="fontColor">描画色</param>
\r
198 /// <returns>描画済テクスチャ</returns>
\r
199 public CTexture DrawPrivateFont( string drawstr, Color fontColor )
\r
201 Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White );
\r
202 return CDTXMania.tテクスチャの生成( bmp, false );
\r
206 /// 文字列を描画したテクスチャを返す
\r
208 /// <param name="drawstr">描画文字列</param>
\r
209 /// <param name="fontColor">描画色</param>
\r
210 /// <param name="edgeColor">縁取色</param>
\r
211 /// <returns>描画済テクスチャ</returns>
\r
212 public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor )
\r
214 Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White );
\r
215 return CDTXMania.tテクスチャの生成( bmp, false );
\r
219 /// 文字列を描画したテクスチャを返す
\r
221 /// <param name="drawstr">描画文字列</param>
\r
222 /// <param name="fontColor">描画色</param>
\r
223 /// <param name="gradationTopColor">グラデーション 上側の色</param>
\r
224 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
\r
225 /// <returns>描画済テクスチャ</returns>
\r
226 //public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )
\r
228 // Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );
\r
229 // return CDTXMania.tテクスチャの生成( bmp, false );
\r
233 /// 文字列を描画したテクスチャを返す
\r
235 /// <param name="drawstr">描画文字列</param>
\r
236 /// <param name="fontColor">描画色</param>
\r
237 /// <param name="edgeColor">縁取色</param>
\r
238 /// <param name="gradationTopColor">グラデーション 上側の色</param>
\r
239 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
\r
240 /// <returns>描画済テクスチャ</returns>
\r
241 public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradataionBottomColor )
\r
243 Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor );
\r
244 return CDTXMania.tテクスチャの生成( bmp, false );
\r
251 /// 文字列を描画したテクスチャを返す(メイン処理)
\r
253 /// <param name="rectDrawn">描画された領域</param>
\r
254 /// <param name="ptOrigin">描画文字列</param>
\r
255 /// <param name="drawstr">描画文字列</param>
\r
256 /// <param name="drawmode">描画モード</param>
\r
257 /// <param name="fontColor">描画色</param>
\r
258 /// <param name="edgeColor">縁取色</param>
\r
259 /// <param name="gradationTopColor">グラデーション 上側の色</param>
\r
260 /// <param name="gradationBottomColor">グラデーション 下側の色</param>
\r
261 /// <returns>描画済テクスチャ</returns>
\r
262 protected Bitmap DrawPrivateFont( string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradationBottomColor )
\r
264 if ( this._fontfamily == null || drawstr == null || drawstr == "" )
\r
266 // nullを返すと、その後bmp→texture処理や、textureのサイズを見て・・の処理で全部例外が発生することになる。
\r
267 // それは非常に面倒なので、最小限のbitmapを返してしまう。
\r
268 // まずはこの仕様で進めますが、問題有れば(上位側からエラー検出が必要であれば)例外を出したりエラー状態であるプロパティを定義するなり検討します。
\r
269 if ( drawstr != "" )
\r
271 Trace.TraceWarning( "DrawPrivateFont()の入力不正。最小値のbitmapを返します。" );
\r
273 _rectStrings = new Rectangle( 0, 0, 0, 0 );
\r
274 _ptOrigin = new Point( 0, 0 );
\r
275 return new Bitmap(1, 1);
\r
277 bool bEdge = ( ( drawmode & DrawMode.Edge ) == DrawMode.Edge );
\r
278 bool bGradation = ( ( drawmode & DrawMode.Gradation ) == DrawMode.Gradation );
\r
280 // 縁取りの縁のサイズは、とりあえずフォントの大きさの1/4とする
\r
281 int nEdgePt = (bEdge)? _pt / 4 : 0;
\r
284 Size stringSize = System.Windows.Forms.TextRenderer.MeasureText( drawstr, this._font );
\r
286 //取得した描画サイズを基に、描画先のbitmapを作成する
\r
287 Bitmap bmp = new Bitmap( stringSize.Width + nEdgePt * 2, stringSize.Height + nEdgePt * 2 );
\r
288 bmp.MakeTransparent();
\r
289 Graphics g = Graphics.FromImage( bmp );
\r
290 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
\r
292 StringFormat sf = new StringFormat();
\r
293 sf.LineAlignment = StringAlignment.Far; // 画面下部(垂直方向位置)
\r
294 sf.Alignment = StringAlignment.Center; // 画面中央(水平方向位置)
\r
297 Rectangle r = new Rectangle( 0, 0, stringSize.Width + nEdgePt * 2, stringSize.Height + nEdgePt * 2 );
\r
299 if ( bEdge ) // 縁取り有りの描画
\r
301 // DrawPathで、ポイントサイズを使って描画するために、DPIを使って単位変換する
\r
302 // (これをしないと、単位が違うために、小さめに描画されてしまう)
\r
303 float sizeInPixels = _font.SizeInPoints * g.DpiY / 72; // 1 inch = 72 points
\r
305 System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
\r
306 gp.AddString( drawstr, this._fontfamily, (int) this._font.Style, sizeInPixels, r, sf );
\r
309 Pen p = new Pen( edgeColor, nEdgePt );
\r
310 p.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;
\r
311 g.DrawPath( p, gp );
\r
317 br = new LinearGradientBrush( r, gradationTopColor, gradationBottomColor, LinearGradientMode.Vertical );
\r
321 br = new SolidBrush( fontColor );
\r
323 g.FillPath( br, gp );
\r
325 if ( br != null ) br.Dispose(); br = null;
\r
326 if ( p != null ) p.Dispose(); p = null;
\r
327 if ( gp != null ) gp.Dispose(); gp = null;
\r
332 System.Windows.Forms.TextRenderer.DrawText( g, drawstr, _font, new Point( 0, 0 ), fontColor );
\r
335 g.DrawRectangle( new Pen( Color.White, 1 ), new Rectangle( 1, 1, stringSize.Width-1, stringSize.Height-1 ) );
\r
336 g.DrawRectangle( new Pen( Color.Green, 1 ), new Rectangle( 0, 0, bmp.Width - 1, bmp.Height - 1 ) );
\r
338 _rectStrings = new Rectangle( 0, 0, stringSize.Width, stringSize.Height );
\r
339 _ptOrigin = new Point( nEdgePt * 2, nEdgePt * 2 );
\r
342 #region [ リソースを解放する ]
\r
343 if ( sf != null ) sf.Dispose(); sf = null;
\r
344 if ( g != null ) g.Dispose(); g = null;
\r
351 /// 最後にDrawPrivateFont()した文字列の描画領域を取得します。
\r
353 public Rectangle RectStrings
\r
357 return _rectStrings;
\r
361 _rectStrings = value;
\r
364 public Point PtOrigin
\r
376 #region [ IDisposable 実装 ]
\r
377 //-----------------
\r
378 public void Dispose()
\r
380 if ( !this.bDispose完了済み )
\r
382 if ( this._font != null )
\r
384 this._font.Dispose();
\r
387 if ( this._pfc != null )
\r
389 this._pfc.Dispose();
\r
393 this.bDispose完了済み = true;
\r
396 //-----------------
\r
399 #region [ private ]
\r
400 //-----------------
\r
401 protected bool bDispose完了済み;
\r
402 protected Font _font;
\r
404 private System.Drawing.Text.PrivateFontCollection _pfc;
\r
405 private FontFamily _fontfamily;
\r
407 private Rectangle _rectStrings;
\r
408 private Point _ptOrigin;
\r
409 //-----------------
\r