计算字型 Baseline 是一个不常用的函数,但如果想要显示不同大小文字下方对齐,就得用它来计算字型的 Baseline 才行,如果计算不准,显示的文字就会高高低低不整齐。
在 Firemonkey 的 Windows 平台下(其它平台没有问题),取得字型文字的 Baseline 总有些不对劲(因为并不是所有的字型都有问题,约 5% 的字型取得的 Baseline 位置会不对)。
其实官方提供的计算函数TFontGlyphManager.Current.GetBaseline 没什么问题,主要是与 Canvas.TextHeight 搭配运用所产的问题,简单的说就是:。
测试工程下载:
重新计算 Baseline 函数(无需修改官方代码,需要计算时请自行调用下列函数):
<span style="color: #008000">//<span style="color: #008000"> 计算正确的 Font Baseline for Windows by Aone (2016/11/09)<span style="color: #008000">
//<span style="color: #008000"> 函数改自: FMX.Helpers.Win.pas 內的 TWinFontGlyphManager.LoadResource; 函数<span style="color: #008000">
//<span style="color: #008000"> 参数 Font,Scale 与原来的 GetBaseline 相同,第3个参数 TextHeight1 请代入由 Canvas.TextHeight 取得的文字高度
<span style="color: #0000ff">function GetBaseline(<span style="color: #0000ff">const Font: TFont; <span style="color: #0000ff">const Scale: Single; <span style="color: #0000ff">const<span style="color: #000000"> TextHeight1: Single): Single;
<span style="color: #0000ff">var<span style="color: #000000"> Height: Integer;
Metrics: TTextMetric;
CurrentSettings: TFontSettings;
FFont: HFONT;
DC: HDC;
<span style="color: #0000ff">begin<span style="color: #000000">
Result := <span style="color: #800080">0<span style="color: #000000">;
//<span style="color: #008000"> 函数改自: FMX.Helpers.Win.pas 內的 TWinFontGlyphManager.LoadResource; 函数<span style="color: #008000">
//<span style="color: #008000"> 参数 Font,Scale 与原来的 GetBaseline 相同,第3个参数 TextHeight1 请代入由 Canvas.TextHeight 取得的文字高度
<span style="color: #0000ff">function GetBaseline(<span style="color: #0000ff">const Font: TFont; <span style="color: #0000ff">const Scale: Single; <span style="color: #0000ff">const<span style="color: #000000"> TextHeight1: Single): Single;
<span style="color: #0000ff">var<span style="color: #000000"> Height: Integer;
Metrics: TTextMetric;
CurrentSettings: TFontSettings;
FFont: HFONT;
DC: HDC;
<span style="color: #0000ff">begin<span style="color: #000000">
Result := <span style="color: #800080">0<span style="color: #000000">;
CurrentSettings.Family :</span>=<span style="color: #000000"> Font.Family;
CurrentSettings.Size :</span>=<span style="color: #000000"> Font.Size;
CurrentSettings.Style :</span>=<span style="color: #000000"> Font.StyleExt;
CurrentSettings.Scale :</span>=<span style="color: #000000"> Scale;
Height :</span>= -Round(CurrentSettings.Size *<span style="color: #000000"> CurrentSettings.Scale);
FFont :</span>= CreateFont(Height,<span style="color: #800080">0</span>,<span style="color: #800080">0</span><span style="color: #000000">,FontWeightToWinapi(CurrentSettings.Style.Weight),Cardinal(</span><span style="color: #0000ff">not</span><span style="color: #000000"> CurrentSettings.Style.Slant.IsRegular),</span><span style="color: #800080">0</span>,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH </span><span style="color: #0000ff">or</span><span style="color: #000000"> FF_DONTCARE,PChar(CurrentSettings.Family));
</span><span style="color: #0000ff">if</span> FFont = <span style="color: #800080">0</span> <span style="color: #0000ff">then</span><span style="color: #000000">
Exit;
DC :</span>= CreateCompatibleDC(<span style="color: #800080">0</span><span style="color: #000000">);
SelectObject(DC,FFont);
GetTextMetrics(DC,Metrics);
DeleteDC(DC);
Result :</span>= TextHeight1 * (Metrics.tmAscent /<span style="color: #000000"> Metrics.tmHeight);
<span style="color: #0000ff">end;
修正前:
修正后: