delphi - FMX:为什么 TTextLayout.RegionForRange 在这种特殊情况下会失败?
问题描述
我创建了一个TTextLayout
对象,其文本包含连续的“t”字符和“Calibri”字体。然后我有以下代码使用该RegionForRange
函数返回每个字符的矩形区域。结果是第一个't'的宽度为0,第二个't'的位置与第一个相同。文本中的任何其他字符都是正确的——即使是错误之后的字符,尽管字母“f”也有同样的问题,以及“t”和“f”的任何连续组合。大多数其他字体似乎都不会导致问题,尽管 'Gabriola' 会。
procedure TForm1.FormCreate(Sender: TObject);
var
Layout : TTextLayout;
LRange : TTextRange;
LRegion : TRegion;
LRects : array of TRectF;
i : Integer;
begin
Layout := TTextLayoutManager.DefaultTextLayout.Create;
Layout.Font.Size := 20;
// Calibra and Gabriola fail but Arial and most other fonts don't
Layout.Font.Family := 'Calibri';// 'Gabriola';
Layout.Text := 'tt'; // ff, ft, tf also fail
LRange.Length := 1;
SetLength(LRects, Length(Layout.Text));
for i := 0 to Length(Layout.Text) - 1 do begin
LRange.Pos := i;
LRegion := Layout.RegionForRange(LRange);
LRects[i] := LRegion[0]; // Bounding rect of this character
end;
end;
在函数的末尾放置一个断点,可以查看存储在 中的 left 和 right 的值LRects
。
进入该RegionForRange
功能会导致TTextLayoutD2D.DoRegionForRange
但从那里我无法进一步查看可能出现的问题。为什么这些特定字符会发生这种情况并且只发生在这些字体上?为什么范围内的字符后面的字符会影响结果?它是一个错误吗?我也许可以编写一些代码来检测这些序列并纠正位置,但我觉得我不需要这样做。
请注意,我使用的是 Delphi 10.4。我没有尝试过最近的更新,所以如果有人能确认这个问题发生在哪个版本中,我将不胜感激。
解决方案
原因被称为连字。应用连字时,两个或多个字形的组合被另一个单个字形替换。
连字由 OpenType 字体定义。每种字体都定义了自己的一组连字。Calibri 定义了很多(你只找到了几个)。
推荐阅读
- vba - VBA动态添加的组合框不会触发更改事件
- typescript - 制作打字稿以允许解构未定义
- python - 为什么我的模型同时具有低 MAE 和低 R2 分数?
- c# - 在 ReactiveX 中为另一个主题创建计算主题
- android - 如何在 android 中装饰编辑文本?
- r - 如何在 rstudio 中读取多个文件并将其组合成一个数据帧?
- ios - 问题 - Xamarin.Forms 5.0 IOS黑屏
- azure-active-directory - 注销时如何禁用帐户选择?
- c# - C#中的IOC和DI有什么区别以及为什么IOC优于其他设计模式
- webpack - Webpack:在缩小的 JS 文件中插入标题