以前投稿した C# - フォントメトリクスを調査してみたらカオスだった件 - 未解決のイケてなかったとこを修正してみた。
イケてなかったとこ#1 - 単位が合っていなかった
フォントのインスタンスを生成するときに、new Font(フォント名,フォントサイズ)
で指定していたが、このコンストラクタではフォントサイズ
はピクセル単位ではなくポイント単位であり、解像度に依存する。
ピクセル単位で作りたいときは、new Font(フォント名,フォントサイズ,GraphicsUnit.Pixel)
のように指定する必要がある。
イケてなかったとこ#2 - フォントが代用されていた
代用されるのを避けるには、StringFormat
のプロパティFormatFlags
にStringFormatFlags.NoFontFallback;
を指定する必要がある。
(前記事でコメント頂いて知りました。感謝!)
画面キャプチャ
accent と accent+descent の位置に補助線(それぞれ青の点線と黒の実線)を入れています。
accent+descentで高さ方向が収まるっぽい。
公式には下記の記載があるので、多分あってるはず。
Note that the em height (also called size or em size) is not the sum of the ascent and the descent. The sum of the ascent and the descent is called the cell height. The cell height minus the internal leading is equal to the em height. The cell height plus the external leading is equal to the line spacing.
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
ソースコード
usingSystem;usingSystem.Collections.Generic;usingSystem.Drawing;usingSystem.Drawing.Drawing2D;usingSystem.Drawing.Imaging;usingSystem.Windows.Forms;classFontMetricsTest:Form{TrackBartrackbar;PictureBoxpct;ComboBoxcmbFonts;TextBoxtxtContent;FontMetricsTest(){Text="Font metrics test";ClientSize=newSize(600,400);cmbFonts=newComboBox();foreach(FontFamilyffinFontFamily.Families){cmbFonts.Items.Add(ff.Name);}cmbFonts.Text=SystemFonts.DefaultFont.Name;cmbFonts.Location=newPoint(0,0);cmbFonts.Width=300;cmbFonts.DropDownHeight=500;cmbFonts.DropDownStyle=ComboBoxStyle.DropDownList;cmbFonts.SelectedIndexChanged+=(sender,e)=>{MyRedraw();};Controls.Add(cmbFonts);trackbar=newTrackBar();trackbar.Location=newPoint(300,0);trackbar.Maximum=100;trackbar.Value=50;trackbar.Minimum=1;trackbar.TickFrequency=33;trackbar.ValueChanged+=(sender,e)=>{MyRedraw();};Controls.Add(trackbar);txtContent=newTextBox();txtContent.Location=newPoint(0,50);txtContent.Width=300;txtContent.Text="g あいう Qiita";txtContent.TextChanged+=(sender,e)=>{MyRedraw();};Controls.Add(txtContent);pct=newPictureBox();pct.Location=newPoint(0,80);pct.Size=newSize(600,300);pct.Image=newBitmap(600,300);Controls.Add(pct);MyRedraw();}voidMyRedraw(){intw=pct.Image.Width;inth=pct.Image.Height;stringfontName=cmbFonts.Text;Fontfont=newFont(fontName,(float)trackbar.Value,GraphicsUnit.Pixel);stringtext=txtContent.Text;if(font.Name!=fontName){text="Font unmatch: \""+font.Name+"\" is loaded.";}using(Graphicsg=Graphics.FromImage(pct.Image)){g.Clear(Color.White);FontFamilyff=font.FontFamily;intascent=ff.GetCellAscent(font.Style);intdescent=ff.GetCellDescent(font.Style);intemHeight=ff.GetEmHeight(font.Style);floatfontHeight=font.GetHeight(g);floatascentSize=font.Size*ascent/emHeight;floatdescentSize=font.Size*descent/emHeight;Console.Write("==== ");Console.Write(font.Name);Console.WriteLine(" ====");Console.Write("font.Size: ");Console.WriteLine(font.Size);Console.Write("fontHeight: ");Console.WriteLine(fontHeight);Console.Write("sum in pixel: ");Console.WriteLine(ascentSize+descentSize);Console.Write("ascent in pixel: ");Console.WriteLine(ascentSize);Console.Write("descent in pixel: ");Console.WriteLine(descentSize);Console.Write("sum: ");Console.WriteLine(ascent+descent);Console.Write("ascent: ");Console.WriteLine(ascent);Console.Write("descent: ");Console.WriteLine(descent);Console.Write("emHeight: ");Console.WriteLine(emHeight);Penpen=newPen(Color.Black,1.0f);PenpenDash=newPen(Color.Blue,1.0f);penDash.DashStyle=DashStyle.Dash;g.DrawLine(pen,0,ascentSize+descentSize,w,ascentSize+descentSize);g.DrawLine(penDash,0,ascentSize,w,ascentSize);StringFormatsf=newStringFormat();sf.FormatFlags=StringFormatFlags.NoFontFallback;g.DrawString(text,font,Brushes.Black,newPointF(0,0),sf);}pct.Refresh();}[STAThread]staticvoidMain(string[]args){Application.Run(newFontMetricsTest());}}