在包含多个实例的 TTF 文件中为 @font-face 使用特定实例

Posted

技术标签:

【中文标题】在包含多个实例的 TTF 文件中为 @font-face 使用特定实例【英文标题】:Using specific instance for @font-face in TTF file containing multiple instance 【发布时间】:2021-07-25 05:39:30 【问题描述】:

首先,我不知道 TTF 文件是如何组织的,所以我可能在这里的一些术语有误。

我有一个带有@font-face 的样式表,它引用了一个包含多个面的单个TTF 文件。在 Windows 字体查看器中,如果我循环浏览“下一个”,它看起来像这样(抱歉,GIF 变得乱七八糟,选择了错误的编码参数,不想重做它,但你明白了):

该文件具有 .ttf 扩展名,尽管我不确定与 OpenType 的关系(它在该窗口中显示“OpenType”)。

无论如何,我在样式表中这样引用它:

@font-face 
  font-family: TestFont;
  src: url(...) format('truetype');


:root 
  font-family: TestFont;

所以,文件中的字体名称是“Bahnschrift”,而我要使用的字体是“Bahnschrift Condensed”。除了使用基本的“Bahnschrift”字体之外,上面几乎可以工作。

我的问题是:如何指定我想使用“压缩”变体?

这是一个小提琴。我想为这篇文章嵌入字体作为数据 URI,但它太大而无法在此处发布(大约 500kB 编码)所以它就在这里:https://jsfiddle.net/qugoeam5/

【问题讨论】:

根据 OpenType 规范,没有“其中包含多个面的 ttf”之类的东西。有 ttf 字体,它们是带有 TrueType 轮廓图形的 OpenType 字体,它编码单个字体(但可能启用了字体变体),还有 OpenType 集合(使用ttc 作为文件扩展名而不是ttf),它们是本质上是在单个文件中包含多个字体的“字体包”。 @font-face 不支持集合。相反,您应该为特定的自定义 font-family 指定所需的单文件字体。 然后您可以为匹配的font-... 属性集指定多个文件,例如@font-face font-family: mycustomfont; src: url(...regular.ttf) format(...); font-weight: normal; 还有@font-face font-family: mycustomfont; src: url(...bold.ttf) format(...); font-weight: bold; ,现在浏览器知道当你写像h2 font-family: mycustomfont; font-weight: bold; 这样的页面CSS时该怎么做。 @Mike'Pomax'Kamermans 是的;谢谢,我也学到了。原来我指的是 OpenType 实例。使用 OpenType,单个文件可以存储参数化字形轮廓,然后该文件还可以存储命名参数集的列表。所以例如“bold”、“condensed”等都可以在一个文件中定义,但它们实际上是修改字形的不同值集(而不是显式的轮廓集)。查看docs.microsoft.com/en-us/typography/opentype/spec/otvaroverview。 是的,fvar 绝对是 OpenType 的未来。不过,术语很重要(至少在获得专家答案时=) 【参考方案1】:

好吧,我基本上想通了。我有一个基本的解决方案,只是没有确定浏览器的兼容性。

所以我所说的“变体”实际上被称为“instances”。本质上,它们只是命名为预设(存储在文件中),用于指定 OpenType 轴集合的值。

Windows 10 内置字体检查器可用于检查给定实例的轴/值集,假设该字体已安装在系统上并且是可变字体:

    打开字体设置

    在“可用字体”下搜索并选择字体

    在接下来打开的窗口中,一直向下滚动并点击“可变字体属性”。

    在这里您可以选择实例,然后遍历每个轴以查看其标签和值:

因此对于“压缩”实例,重量 (wght) 为 400,宽度 (wdth) 为 75。

至于 CSS,兼容性目前参差不齐。 CSS3 没有办法选择命名实例。它也没有正式支持设置轴值。不过,CSS4 正在标准化对两者(font-named-instance 和 font-variation-settings)的支持。

现在,我不知道这里的历史,但我认为font-variation-settings(设置单个轴值)可能在某个时候用于 CSS3,然后推迟到 CSS4?或者其他的东西。无论如何,似乎:

在 Edge、Firefox 和 Chrome 中支持它,但在 IE 和 Safari 中缺乏支持。 Among others。 当它在@ 规则之外使用时,似乎有更多的支持。我找不到任何关于原因的信息,我只是观察了一下。

所以这里的一般解决方案是单独设置与您想要的命名实例相对应的轴值(至少在font-named-instance 滚动之前)。

好消息是,某些轴有更广泛支持的高级等效项;在这种情况下我很幸运:对于这个字体,只设置了粗细和宽度,可以通过font-weightfont-stretch 设置。尽管如此,font-stretch 支持现在也有点 inconsistent (取决于您是否使用命名形式与 % 形式)。

无论如何,我不能说兼容性,但这里有很多选择。

撇开兼容性不谈,这些都相当于重量: [W1]font-weight: 400 [W2]font-weight: normal [W3]font-variation-settings: "wght" 400; 并且这些都等价于宽度: [S1]font-stretch: 75% [S2]font-stretch: condensed [S3]font-variation-settings: "wdth" 75; 注意:对于font-variation-settings,如果您设置了多个,则必须同时设置它们: [WS3]font-variation-settings: "wght" 400, "wdth" 75; 再次忽略兼容性,它们可以放在 @ 规则中(定义默认值)或其他位置(覆盖默认值),因此它们也是等效的:

人脸定义中的设置:

@font-face 
   font-family: "TestFont";
   src: ...;
   [ one of the width settings ];
   [ one of the stretch settings ];

:root 
   font-family: "TestFont";

或者,在@规则之外:

@font-face 
   font-family: "TestFont";
   src: ...;

:root 
   font-family: "TestFont";
   [ one of the width settings ];
   [ one of the stretch settings ];

因此,将所有这些放在一起,一个选项的示例(尽管兼容性)是:

@font-face 
    font-family: 'TestFont';
    src: ...;
    font-weight: normal;
    font-stretch: condensed;

:root  
    font-family: 'TestFont', sans-serif;

现在,我还没有在很多浏览器上进行过真正的测试,但以上这些组合至少似乎可以在 Chrome 90.0.4430.93(Windows 10、64 位)上运行。 YMMV:

@font-face :root div
[W1] font-weight:400 YES YES YES
[W2] font-weight:normal YES YES YES
[W3] font-variation-settings:"wght" 400 no YES YES
[S1] font-stretch:75% YES no no
[S2] font-stretch:condensed YES no no
[S3] font-variation-settings:"wdth" 75 no YES YES
[WS3] font-variation-settings:"wght" 400,"wdth" 75 no YES YES

这意味着,至少对于 Chrome:

如果要将两者都放入@font-face,则必须使用[W1/2] + [S1/2],例如:

@font-face 
  font-family: "TestFont";
  src: ...;
  font-weight: normal; 
  font-stretch: condensed;

:root 
  font-family: "TestFont", sans-serif;

但是如果你想同时放入:root或其他元素,你可以使用任何形式的重量,但你必须使用font-variation-settings作为宽度(有效的组合是[W1+S3],[W2 +S3] 或 [WS3]),例如:

@font-face 
  font-family: "TestFont";
  src: ...;

:root 
  font-family: "TestFont", sans-serif;
  font-weight: normal; 
  font-variation-settings: 'wdth' 75;

我不知道其他浏览器的行为是什么;我没有做更多的测试,主要是因为这篇文章有点累人,而且打字的时间比我真正弄清楚这一切的时间要长 100 倍,哈哈。

希望有人指出正确的方向。一旦 CSS4 上街,理论上这一切都会简单得多。

【讨论】:

font-variation-settings 已经在 Safari 中支持了几年。它只是将 font-variation-settings 合并到 font-face 中,它仍处于 Safari 的技术预览中。早在 2017 年,Safari、Chrome 和(pre-chromium)Edge 中就添加了 font-face 之外的支持。

以上是关于在包含多个实例的 TTF 文件中为 @font-face 使用特定实例的主要内容,如果未能解决你的问题,请参考以下文章

HTML/CSS 通过 unicode + CSS 中的类使用 ttf 字体

如何从具有多个 TTF 文件的字体系列导入自定义 java.awt.Font? (包括一个例子)

在 Pail Tap Hadoop 作业中为输入指定多个文件夹

如何在 Core Data 中为多个对象(相同实体类型)生成数组实例?

css的力量坑技巧

css的力量坑技巧