android - 将 .otf 字体系列部署到 FMX 应用程序
问题描述
我正在尝试为我的 Firemonkey 应用程序实现一个自定义字体系列(多个 .otf 文件,用于不同的权重,例如重、轻、常规、超轻……),它将同时部署在 Android 和 iOS 上。
在 iOS 上实现字体系列非常简单,我所要做的就是将它们包含在 info.plist 文件中。将字体应用于标签时,在“字体”>“系列”下,我只需输入“字体名称”即可应用。请记住,没有实际的“字体名称”文件,只有“字体名称重”和其他权重。
这里有一个额外的问题,我如何在 FMX 中使用字体粗细?我没有找到任何设置字体粗细的属性。
然而,在 Android 中做同样的事情时,结果却完全不同。我在部署中包含字体,输入“字体名称”根本不应用它,但是如果我输入“字体名称 Ultralight”,那么具有该重量的字体就会被应用(在 iOS 上,添加“Ultralight”没有效果)。更糟糕的是,为字体添加样式(例如斜体和粗体)根本不适用于 Android,而它们确实适用于 iOS。
为什么这两者的行为如此不同,如何克服这些差异,使它们都显示相同的东西?
解决方案
Delphi FMX 上的 Android 中对自定义字体的支持最近已在 Sydney 10.4 上实现,它在 Alexandria 11 中仍处于初级阶段。正如您所指出的,您必须输入“完整”字体名称才能使其在 Android 上工作,因为没有官方支持对于字体粗细。
但是,您仍然可以通过编辑和重新编译位于FMX.FontGlyphs.Android.pas
Delphi 安装文件中的一些源代码来获得所需的结果。你可以这样做:
LoadResource
从类中找到过程TAndroidFontGlyphManager
。您可以看到 FMX 如何查找仅采用系列名称和文件扩展名的字体。- 检查内部过程
CreateTypefaceFromFamilyName
以及它如何确定当前字体的粗细。 - Following the logic of
CreateTypefaceFromFamilyName
add something like this just before theFontFile
variable is initialized (don't forget to declareFontStyle
):
FontStyle:='';
if not CurrentSettings.Style.Slant.IsRegular and not CurrentSettings.Style.Weight.IsRegular then
FontStyle:=' Bold Italic'
else if not CurrentSettings.Style.Weight.IsRegular then
FontStyle:=' Bold'
else if not CurrentSettings.Style.Slant.IsRegular then
FontStyle:=' Italic';
- Change the assignment to
FontFile
from:
TPath.Combine(TPath.GetDocumentsPath, CurrentSettings.Family + '.otf');
to:
TPath.Combine(TPath.GetDocumentsPath, CurrentSettings.Family + FontStyle + '.otf');
(repeat for .ttf as well)
This should add support for Bold, Italic and Bold Italic for Android. This can be further extended to support more font weights as well, just check the TFontWeight
enum in unit FMX.Graphics.pas
.
推荐阅读
- emacs - 在 emacs 仪表板中过滤最近的条目
- android - Instant App 在上传到生产环境时显示问题
- reactjs - 如何删除 firebase.notifications().onNotificationOpened 监听器?
- c# - Parallel vs Await vs Result - 哪个更适合延迟执行
- sql - 将表达式转换为数据类型 int 的算术溢出错误,我该如何解决?
- python - python hex() 的问题
- javascript - 页面如何自动滚动到点击的列表项?
- c# - 为了在 ASP.NET Core 2.0 中执行模型单元测试,我应该将什么传递给控制器
- python - 在继续 while 循环之前运行定时函数
- android - AWS 服务中的 crashlytics 替代方案是什么?