windows - 获取由 DrawText[Ex] 解释的 GDI HFONT 行高
问题描述
我想知道哪些指标用于计算正确的行高(2 个相邻文本行的基线之间的垂直距离)。“正确”应任意定义为“无论做什么DrawTextW
”。
此处接受的答案似乎遵循此 MSDN 文章中提供的图表所说的内容:
TEXTMETRICW.tmHeight + TEXTMETRICW.tmExternalLeading;
但这似乎并不正确。使用 2 段文本进行一些测试,每段文本由 2 行组成:
// RECT rc is more than large enough to fit any text
int HeightChinese = DrawTextW(hdc, L"中\r\n文", -1, &rc, 0);
int HeightLatin = DrawTextW(hdc, L"Latin,\r\nlatin!", -1, &rc, 0);
预期的返回值应该是2 * <SomethingUnknown>
.
一个观察结果是,对于我机器上的所有字体,如果使用的话,返回值DrawTextW
将始终与RECT
输出匹配。DT_CALCRECT
所以我会假设 usingDT_CALCRECT
不会提供任何额外的价值,而不是使用DrawTextW
.
对于我机器上的所有字体,这些都是正确的:
HeightChinese == HeightLatin
LOGFONTW.lfHeight == TEXTMETRICW.tmHeight
(1)。
对于我机器上的大多数字体,这是真的:
HeightXxx == 2 * TEXTMETRICW.tmHeight
这已经与另一个问题中提供的公式相矛盾(TEXTMETRICW.tmExternalLeading
不起作用)。
例如,带有 , 和(不是 74)的“ LOGFONTW.lfHeight = 36
Arial TEXTMETRICW.tmExternalLeading = 1
” HeightXxx == 72
。截屏并测量像素时,线之间的距离也是 72(因此看起来返回值可以信任)。
同时,“Segoe UI”带有LOGFONTW.lHeight = 43
,TEXTMETRICW.tmExternalLeading = 0
和HeightXxx == 84
(不是 86)。
这是我系统上所有异常字体的列表:
"FontName" -- "DrawText return value" vs "2 * TEXTMETRICW.tmHeight"
Ebrima -- 84 vs 86
Leelawadee UI -- 84 vs 86
Leelawadee UI Semilight -- 84 vs 86
Lucida Sans Unicode -- 96 vs 98
Malgun Gothic -- 84 vs 86
Malgun Gothic Semilight -- 84 vs 86
Microsoft Tai Le -- 80 vs 82
Microsoft YaHei -- 82 vs 84
Microsoft YaHei UI Light -- 82 vs 84
MS Gothic -- 66 vs 64
MS UI Gothic -- 66 vs 64
MS PGothic -- 66 vs 64
Nirmala UI -- 84 vs 86
Nirmala UI Semilight -- 84 vs 86
Palatino Linotype -- 84 vs 86
Segoe UI -- 84 vs 86
Segoe UI Black -- 84 vs 86
Segoe UI Historic -- 84 vs 86
Segoe UI Light -- 84 vs 86
Segoe UI Semibold -- 84 vs 86
Segoe UI Semilight -- 84 vs 86
Segoe UI Symbol -- 84 vs 86
SimSun -- 66 vs 64
NSimSun -- 66 vs 64
SimSun-ExtB -- 66 vs 64
Verdana -- 76 vs 78
Webdings -- 62 vs 64
Yu Gothic UI -- 84 vs 86
Yu Gothic UI Semibold -- 84 vs 86
Yu Gothic UI Light -- 84 vs 86
Yu Gothic UI Semilight -- 84 vs 86
MS Mincho -- 66 vs 64
MS PMincho -- 66 vs 64
Ubuntu Mono -- 62 vs 64
有时返回值比计算值大 2,有时比计算值小 2。
我查看了 中的其他值TEXTMETRICW
,还查看了可用的额外数据 int OUTLINETEXTMETRICW
,但我找不到任何可以解释观察结果的模式。
那么,计算线高的正确指标是什么?我知道我可以调用DrawTextW
withDT_CALCRECT
来获取这个值,但我想了解这些信息的来源(以及字体设计师如何以可预测的方式控制它)。
这是一个带有完整 Windows 应用程序的要点,它演示了这一点。所有有趣的东西都在WM_PAINT
. 搜索@EDIT
一些有趣的代码切换和断点。在发布此问题时,我的 GitHub 帐户已被标记,并且 Gist 暂时不可用。我希望这可以很快得到解决。
(1)我EnumFontFamiliesEx
用来枚举所有字体,它恰好为LOGFONTW
结构提供了正值 lfHeight
。这意味着我使用的是单元格高度而不是字符高度。虽然字符高度是指定字体高度的更典型方式,但在这里有点无关紧要,碰巧单元格高度等于TEXTMETRICW.tmHeight
,但字符高度不是。计算的相关值是TEXTMETRICW.tmHeight
,而不是LOGFONTW.lfHeight
。
解决方案
DrawText()
仅在您调用它时设置TEXTMETRIC.tmExternalLeading
了DT_EXTERNALLEADING
标志时使用 - 您似乎没有考虑到这一点。
线高公式基本上是:
int iLineHeight = tm.tmHeight + ((format & DT_EXTERNALLEADING) ? tm.tmExternalLeading : 0);
推荐阅读
- ios - Swift UITableview 在文本框中编辑不同的值
- python - Stripe 订阅在 Django/Python 上创建重复付款
- elasticsearch - ElasticSearch 更新 API 脚本 - 创建结构数组
- javascript - 如何使用 Joi 最新版本验证枚举字符串?
- c++ - 如何将带有浮点数的字符串转换为十进制?
- python - 如何修复点子?pip 无法运行 main 函数
- c# - ASP.NET Core 3.0 中 UPN 的 Active Directory 身份验证
- python - Matplotlib 在 jupyter 和 python 中产生不同的结果
- javascript - React 状态上的映射函数 - 带有获取的 API 数据的状态
- swift - 在 iOS 13.x SDK viewWillDisappear/viewDidDisappear 在 popToRootViewController 操作期间不调用