计算字型 Baseline 是一个不常用的函数,但如果想要显示不同大小文字下方对齐,就得用它来计算字型的 Baseline 才行,如果计算不准,显示的文字就会高高低低不整齐。

  在 Firemonkey 的 Windows 平台下(其它平台没有问题),取得字型文字的 Baseline 总有些不对劲(因为并不是所有的字型都有问题,约 5% 的字型取得的 Baseline 位置会不对)。

  其实官方提供的计算函数 TFontGlyphManager.Current.GetBaseline 没什么问题,主要是与 Canvas.TextHeight 搭配运用所产的问题,简单的说就是:使用 Canvas.TextHeight 计算的高度与 GetBaseline 里计算的 Metrics.tmHeight 高度不同造成的,只要使这二个高度匹配,问题就解决了

测试工程下载:

[函数]TestFontBaseline_重新计算Baseline_Aone.zip

重新计算 Baseline 函数(无需修改官方代码,需要计算时请自行调用下列函数):

uses
Winapi.Windows,
FMX.Helpers.Win; // 计算正确的 Font Baseline for Windows by Aone (2016/11/09)
// 函数改自: FMX.Helpers.Win.pas 內的 TWinFontGlyphManager.LoadResource; 函数
// 参数 Font, Scale 与原来的 GetBaseline 相同,第3个参数 TextHeight1 请代入由 Canvas.TextHeight 取得的文字高度

function GetBaseline(const Font: TFont; const Scale: Single; const TextHeight1: Single): Single;
var Height: Integer;
Metrics: TTextMetric;
CurrentSettings: TFontSettings;
FFont: HFONT;
DC: HDC;
begin
Result := ; CurrentSettings.Family := Font.Family;
CurrentSettings.Size := Font.Size;
CurrentSettings.Style := Font.StyleExt;
CurrentSettings.Scale := Scale; Height := -Round(CurrentSettings.Size * CurrentSettings.Scale);
FFont := CreateFont(Height, , , , FontWeightToWinapi(CurrentSettings.Style.Weight),
Cardinal(not CurrentSettings.Style.Slant.IsRegular),
, , DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH or FF_DONTCARE, PChar(CurrentSettings.Family)); if FFont = then
Exit; DC := CreateCompatibleDC();
SelectObject(DC, FFont);
GetTextMetrics(DC, Metrics);
DeleteDC(DC); Result := TextHeight1 * (Metrics.tmAscent / Metrics.tmHeight);
end;

修正前:

修正后:

[函数] Firemonkey Windows 重新计算 Font Baseline的更多相关文章

  1. [修正] Berlin Firemonkey Windows 控件左方显示虚线问题

    说明:在 Wndows 显示时,有时控件左方会显示一条虚线 适用:Berlin Firemonkey 修正方法: 请将源码 FMX.Platform.Win.pas 复制到自己的工程目录里,再进行修改 ...

  2. Delphi调用API函数获取Windows目录信息、获取System目录信息、获取Temp临时文件目录信息

    var Str1, Str2: Array[..Max_Path]of Char;//开辟缓冲区 Str3: Array[..]of Char; begin GetWindowsDirectory(@ ...

  3. [修正] Firemonkey Windows & macOS 平台下 Edit & Memo 中文输入后会取消原选取文字的 BUG

    问题:Firemonkey Windows & macOS 平台下 Edit & Memo 中文输入后会取消原选取文字的 BUG 适用版本:Delphi 10.1.2 & 10 ...

  4. [修正] Firemonkey Windows 控件有虚线残影问题

    说明:在 Wndows 显示时,有时控件左方会显示一条虚线 适用:Firemonkey Windows (Berlin 或更高版) 修正方法: 请将源码 FMX.Canvas.D2D.pas 复制到自 ...

  5. printf函数对参数的计算顺序

    没想到啊,没想到: printf函数对参数的计算顺序是从右往左的! 我不禁想问一句,这么坑爹的事情,书里居然没有写过.还是我看书不仔细,没有找到?(回头,在自己翻翻那本c语言编程) 于是下面的程序结果 ...

  6. C 语言 clock() 函数,例:计算多项式值

    C 语言 clock() 函数,例:计算多项式值 /** * clock(): 捕捉从程序开始运行到 clock() 被调用时所耗费的时间. * 这个时间单位是 clock tick, 即" ...

  7. 在论坛中出现的比较难的sql问题:31(row_number函数+子查询 月环比计算)

    原文:在论坛中出现的比较难的sql问题:31(row_number函数+子查询 月环比计算) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  8. Windows下计算md5值

    目录 Windows下计算md5值 1.linux 下计算md5值 2.Windows下计算md5值 Windows下计算md5值 1.linux 下计算md5值 [root@master yl]# ...

  9. [函数] Firemonkey 取得 Windows 目前 User 的 Desktop 目录

    下列方法仅提供 Windows 平台使用,所以需要使用编译开关,代码如下: uses {$IFDEF MSWINDOWS} Winapi.Windows, Winapi.SHFolder, {$END ...

随机推荐

  1. Boost信号/槽signals2

    信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...

  2. BPM流程中心解决方案分享

    一.需求分析 在过去办公自动化的浪潮中,很多企业已经实施了OA流程,但随着客户的发展和对流程管理的越来越重视, 客户对流程应用需求越来越深 入,您可能面临以下需求: 1.流程功能不能满足需求,包括流程 ...

  3. Android开发学习—— shape标签的使用

    参考这片文章http://www.cnblogs.com/armyfai/p/5912414.html

  4. [AlwaysOn Availability Groups]健康模型 Part 1——概述

    健康模型概述 在成功部署AG之后,跟踪和维护健康状况是很重要的. 1.AG健康模型概述 AG的健康模型是基于策略管理(Policy Based Management PBM)的.如果不熟悉这个特性,可 ...

  5. JavaScript 写计算器改进版

    <html><head><style> .short{height:50px;width:55px;float:left;}</style></h ...

  6. 自定义可视化调试工具(Microsoft.VisualStudio.DebuggerVisualizers)

    前言: 最近飞机失联的太多,明天要飞北京处理服务器双机热备的问题,航空保险已买,单号是:TF10122913. 至于我的银行卡密码,在我枕头下面的字条里,要是我之后没再更新文章,请通知我家人,哈哈哈哈 ...

  7. JqueryQrcode生成二维码不支持中文的解决办法

    JqueryQrcode.js有一个小小的缺点,就是默认不支持中文. 这跟js的机制有关系,jquery-qrcode这个库是采用 charCodeAt() 这个方式进行编码转换的, 而这个方法默认会 ...

  8. ABP框架 - 模块系统

    文档目录 本节内容: 简介 模块定义 生命周期方法 PreInitialize(预初始化) Initialize(初始化) PostInitialize(提交初始化) Shutdown(关闭) 模块依 ...

  9. Entity Framework 6 Recipes 2nd Edition(13-9)译 -> 避免Include

    问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...

  10. [转载]:STM32为什么必须先配置时钟再配置GPIO

    转载来源 :http://blog.csdn.net/fushiqianxun/article/details/7926442 [原创]:我来添两句,就是很多同学(包括我)之前搞低端单片机,到了stm ...