OSDN Git Service

#xxxxx CPrivateFont (とCPrivateFastFont) に以下の修正を適用。
authoryyagi <yyagi.dtxmania@gmail.com>
Wed, 7 Mar 2018 17:50:49 +0000 (02:50 +0900)
committeryyagi <yyagi.dtxmania@gmail.com>
Wed, 7 Mar 2018 17:50:49 +0000 (02:50 +0900)
 * 外部フォントファイルだけでなく、内蔵フォント名を指定できるようにした。(Arial, MS PGothicなど)
 * フォントサイズ指定をintからfloatに変更。
 * PrivateFontCollectionへの追加により生成されるFontクラスへのアクセスパスの追加。(これにより、PrivateFontでDrawStringできるようになった)
なお、従来Font()で描画していた文字列は、DPI依存のサイズ指定となっていたため、(DPI非依存の)CPrivateFont経由でサイズ指定を変えずに描画すると大き目に表示される。そのため、Font()をCPrivateFont()に移行する際には、フォントサイズに72/96を掛けて帳尻を合わせる必要があるので注意。

DTXMania/コード/全体/CPrivateFastFont.cs
DTXMania/コード/全体/CPrivateFont.cs

index 237556e..0fdb859 100644 (file)
@@ -36,19 +36,19 @@ namespace DTXMania
 
 
                #region [ コンストラクタ ]
-               public CPrivateFastFont(FontFamily fontfamily, int pt, FontStyle style)
+               public CPrivateFastFont(FontFamily fontfamily, float pt, FontStyle style)
                {
                        Initialize(null, null, fontfamily, pt, style);
                }
-               public CPrivateFastFont(FontFamily fontfamily, int pt)
+               public CPrivateFastFont(FontFamily fontfamily, float pt)
                {
                        Initialize(null, null, fontfamily, pt, FontStyle.Regular);
                }
-               public CPrivateFastFont(string fontpath, int pt, FontStyle style)
+               public CPrivateFastFont(string fontpath, float pt, FontStyle style)
                {
                        Initialize(fontpath, null, null, pt, style);
                }
-               public CPrivateFastFont(string fontpath, int pt)
+               public CPrivateFastFont(string fontpath, float pt)
                {
                        Initialize(fontpath, null, null, pt, FontStyle.Regular);
                }
@@ -58,7 +58,7 @@ namespace DTXMania
                }
                #endregion
                #region [ コンストラクタから呼ばれる初期化処理 ]
-               protected new void Initialize(string fontpath, string baseFontPath, FontFamily fontfamily, int pt, FontStyle style)
+               protected new void Initialize(string fontpath, string baseFontPath, FontFamily fontfamily, float pt, FontStyle style)
                {
                        this.bDispose完了済み_CPrivateFastFont = false;
                        this.listFontCache = new List<FontCache>();
index 92b6788..960d1ec 100644 (file)
@@ -24,7 +24,10 @@ namespace DTXMania
        /// 簡単な使い方
        /// CPrivateFont prvFont = new CPrivateFont( CSkin.Path( @"Graphics\fonts\mplus-1p-bold.ttf" ), 36 );   // プライベートフォント
        /// とか
-       /// CPrivateFont prvFont = new CPrivateFont( new FontFamily("MS UI Gothic"), 36, FontStyle.Bold );              // システムフォント
+       /// CPrivateFont prvFont = new CPrivateFont( "MS UI Gothic", 36, FontStyle.Bold );                                              // システムフォント
+       /// CPrivateFont prvFont = new CPrivateFont( CSkin.Path( @"Graphics\fonts\Arial" ), 36 );                               // システムフォント(拡張子の有無で判断。拡張子なしの場合はパス名を指定しても無視する)
+       /// とか
+       /// CPrivateFont prvFont = new CPrivateFont( new FontFamily("MS UI Gothic"), 36, FontStyle.Bold );              // システムフォント指定方法その2
        /// とかした上で、
        /// Bitmap bmp = prvFont.DrawPrivateFont( "ABCDE", Color.White, Color.Black );                                                  // フォント色=白、縁の色=黒の例。縁の色は省略可能
        /// とか
@@ -43,24 +46,30 @@ namespace DTXMania
        /// </remarks>
        public class CPrivateFont : IDisposable
        {
+               public Font font
+               {
+                       get => _font;
+               }
+
+
                #region [ コンストラクタ ]
-               public CPrivateFont(FontFamily fontfamily, int pt, FontStyle style)
+               public CPrivateFont(FontFamily fontfamily, float pt, FontStyle style)
                {
                        Initialize(null, null, fontfamily, pt, style);
                }
-               public CPrivateFont(FontFamily fontfamily, int pt)
+               public CPrivateFont(FontFamily fontfamily, float pt)
                {
                        Initialize(null, null, fontfamily, pt, FontStyle.Regular);
                }
-               public CPrivateFont(string fontpath, FontFamily fontfamily, int pt, FontStyle style)
+               public CPrivateFont(string fontpath, FontFamily fontfamily, float pt, FontStyle style)
                {
                        Initialize(fontpath, null, fontfamily, pt, style);
                }
-               public CPrivateFont(string fontpath, int pt, FontStyle style)
+               public CPrivateFont(string fontpath, float pt, FontStyle style)
                {
                        Initialize(fontpath, null, null, pt, style);
                }
-               public CPrivateFont(string fontpath, int pt)
+               public CPrivateFont(string fontpath, float pt)
                {
                        Initialize(fontpath, null, null, pt, FontStyle.Regular);
                }
@@ -70,7 +79,7 @@ namespace DTXMania
                }
                #endregion
 
-               protected void Initialize(string fontpath, string baseFontPath, FontFamily fontfamily, int pt, FontStyle style)
+               protected void Initialize(string fontpath, string baseFontPath, FontFamily fontfamily, float pt, FontStyle style)
                {
                        this._pfc = null;
                        this._fontfamily = null;
@@ -80,6 +89,16 @@ namespace DTXMania
                        this._ptOrigin = new Point(0, 0);
                        this.bDispose完了済み = false;
                        this._baseFontname = baseFontPath;
+                       this.bIsSystemFont = false;
+
+                       float emSize = 0f;
+                       using (Bitmap b = new Bitmap(1, 1))
+                       {
+                               using (Graphics g = Graphics.FromImage(b))
+                               {
+                                       emSize = pt * 96.0f / 72.0f * g.DpiX / 96.0f;   // DPIを考慮したpxサイズ。GraphicsUnit.Pixelと併用のこと
+                               }
+                       }
 
                        if (fontfamily != null)
                        {
@@ -89,9 +108,21 @@ namespace DTXMania
                        {
                                try
                                {
-                                       this._pfc = new System.Drawing.Text.PrivateFontCollection();    //PrivateFontCollectionオブジェクトを作成する
-                                       this._pfc.AddFontFile(fontpath);                                                                //PrivateFontCollectionにフォントを追加する
-                                       _fontfamily = _pfc.Families[0];
+                                       //拡張子あり == 通常のPrivateFontパス指定
+                                       if (Path.GetExtension(fontpath) != string.Empty)
+                                       {
+                                               this._pfc = new System.Drawing.Text.PrivateFontCollection();    //PrivateFontCollectionオブジェクトを作成する
+                                               this._pfc.AddFontFile(fontpath);                                //PrivateFontCollectionにフォントを追加する
+                                               _fontfamily = _pfc.Families[0];
+                                               bIsSystemFont = false;
+                                       }
+                                       //拡張子なし == Ariel, MS Gothicなど、システムフォントの指定
+                                       else
+                                       {
+                                               //指定されたフォント名のFontオブジェクトを作成する
+                                               this._font = PublicFont(Path.GetFileName(fontpath), emSize, style, GraphicsUnit.Pixel); 
+                                               bIsSystemFont = true;
+                                       }
                                }
                                catch (Exception e) when (e is System.IO.FileNotFoundException || e is System.Runtime.InteropServices.ExternalException)
                                {
@@ -119,9 +150,14 @@ namespace DTXMania
                                //}
                        }
 
-                       // 指定されたフォントスタイルが適用できない場合は、フォント内で定義されているスタイルから候補を選んで使用する
+                       // 通常フォントの登録に成功した場合
+                       if (bIsSystemFont && _font != null)
+                       {
+                               // 追加処理なし。何もしない
+                       }
+                       // PrivateFontの登録に成功したが、指定されたフォントスタイルが適用できない場合は、フォント内で定義されているスタイルから候補を選んで使用する
                        // 何もスタイルが使えないようなフォントなら、例外を出す。
-                       if (_fontfamily != null)
+                       else if (_fontfamily != null)
                        {
                                if (!_fontfamily.IsStyleAvailable(style))
                                {
@@ -141,32 +177,48 @@ namespace DTXMania
                                                Trace.TraceWarning("フォント{0}は適切なスタイル{1}を選択できませんでした。", Path.GetFileName(fontpath), style.ToString());
                                        }
                                }
-                               //this._font = new Font(this._fontfamily, pt, style);                   //PrivateFontCollectionの先頭のフォントのFontオブジェクトを作成する
-                               float emSize = pt * 96.0f / 72.0f;
                                this._font = new Font(this._fontfamily, emSize, style, GraphicsUnit.Pixel); //PrivateFontCollectionの先頭のフォントのFontオブジェクトを作成する
-                                                                                                                                                                                                                                                                                                                                               //HighDPI対応のため、pxサイズで指定
                        }
+                       // PrivateFontと通常フォント、どちらの登録もできていない場合は、MS PGothicを代わりに設定しようと試みる
                        else
-                       // フォントファイルが見つからなかった場合 (MS PGothicを代わりに指定する)
                        {
-                               float emSize = pt * 96.0f / 72.0f;
-                               this._font = new Font("MS PGothic", emSize, style, GraphicsUnit.Pixel); //MS PGothicのFontオブジェクトを作成する
-                               FontFamily[] ffs = new System.Drawing.Text.InstalledFontCollection().Families;
-                               int lcid = System.Globalization.CultureInfo.GetCultureInfo("en-us").LCID;
-                               foreach (FontFamily ff in ffs)
-                               {
-                                       // Trace.WriteLine( lcid ) );
-                                       if (ff.GetName(lcid) == "MS PGothic")
-                                       {
-                                               this._fontfamily = ff;
-                                               Trace.TraceInformation("MS PGothicを代わりに指定しました。");
-                                               return;
-                                       }
+                               this._font = PublicFont("MS PGothic", emSize, style, GraphicsUnit.Pixel);               //MS PGothicのFontオブジェクトを作成する
+                               if (this._font != null )
+                               { 
+                                       Trace.TraceInformation("{0}の代わりにMS PGothicを指定しました。", Path.GetFileName(fontpath));
+                                       bIsSystemFont = true;
+                                       return;
                                }
                                throw new FileNotFoundException("プライベートフォントの追加に失敗し、MS PGothicでの代替処理にも失敗しました。({0})", Path.GetFileName(fontpath));
                        }
                }
 
+
+               /// <summary>
+               /// プライベートフォントではない、通常のフォント指定
+               /// </summary>
+               /// <param name="fontname">フォント名</param>
+               /// <param name="emSize">フォントサイズ</param>
+               /// <param name="style">フォントスタイル</param>
+               /// <param name="unit">GraphicsUnit</param>
+               /// <returns></returns>
+               private Font PublicFont(string fontname, float emSize, FontStyle style, GraphicsUnit unit)
+               {
+                       Font f = new Font(fontname, emSize, style, unit);
+                       FontFamily[] ffs = new System.Drawing.Text.InstalledFontCollection().Families;
+                       int lcid = System.Globalization.CultureInfo.GetCultureInfo("en-us").LCID;
+                       foreach (FontFamily ff in ffs)
+                       {
+                               // Trace.WriteLine( lcid ) );
+                               if (ff.GetName(lcid) == fontname)
+                               {
+                                       this._fontfamily = ff;
+                                       return f;
+                               }
+                       }
+                       return null;
+               }
+
                [Flags]
                protected enum DrawMode
                {
@@ -284,7 +336,7 @@ namespace DTXMania
                #endregion
 
                /// <summary>
-               /// 文字列を描画したテクスチャを返す(メイン処理)
+               /// 文字列を描画したbitmapを返す(メイン処理)
                /// </summary>
                /// <param name="rectDrawn">描画された領域</param>
                /// <param name="ptOrigin">描画文字列</param>
@@ -314,7 +366,7 @@ namespace DTXMania
                        bool bGradation = ((drawmode & DrawMode.Gradation) == DrawMode.Gradation);
 
                        // 縁取りの縁のサイズは、とりあえずフォントの大きさの1/4とする
-                       int nEdgePt = (bEdge) ? _pt / 4 : 0;
+                       float nEdgePt = (bEdge) ? _pt / 4 : 0;
 
                        // 描画サイズを測定する
                        Size stringSize = System.Windows.Forms.TextRenderer.MeasureText(drawstr, this._font, new Size(int.MaxValue, int.MaxValue),
@@ -323,7 +375,7 @@ namespace DTXMania
                        );
 
                        //取得した描画サイズを基に、描画先のbitmapを作成する
-                       Bitmap bmp = new Bitmap(stringSize.Width + nEdgePt * 2, stringSize.Height + nEdgePt * 2);
+                       Bitmap bmp = new Bitmap((int)(stringSize.Width + nEdgePt * 2), (int)(stringSize.Height + nEdgePt * 2));
                        bmp.MakeTransparent();
 
                        using (Graphics g = Graphics.FromImage(bmp))
@@ -339,7 +391,7 @@ namespace DTXMania
                                        sf.FormatFlags = StringFormatFlags.NoWrap;
 
                                        // レイアウト枠
-                                       Rectangle r = new Rectangle(0, 0, stringSize.Width + nEdgePt * 2, stringSize.Height + nEdgePt * 2);
+                                       Rectangle r = new Rectangle(0, 0, (int)(stringSize.Width + nEdgePt * 2), (int)(stringSize.Height + nEdgePt * 2));
 
                                        // 縁取り有りの描画
                                        if (bEdge)
@@ -382,7 +434,7 @@ namespace DTXMania
                        g.DrawRectangle( new Pen( Color.Green, 1 ), new Rectangle( 0, 0, bmp.Width - 1, bmp.Height - 1 ) );
 #endif
                                        _rectStrings = new Rectangle(0, 0, stringSize.Width, stringSize.Height);
-                                       _ptOrigin = new Point(nEdgePt * 2, nEdgePt * 2);
+                                       _ptOrigin = new Point((int)(nEdgePt * 2), (int)(nEdgePt * 2));
                                }
                        }
 
@@ -450,10 +502,11 @@ namespace DTXMania
 
                private System.Drawing.Text.PrivateFontCollection _pfc;
                private FontFamily _fontfamily;
-               private int _pt;
+               private float _pt;
                private Rectangle _rectStrings;
                private Point _ptOrigin;
                private string _baseFontname = null;
+               private bool bIsSystemFont;
                //-----------------
                #endregion
        }