可靠的字体交付是 SVG 的一项要求。设计师需要使用任意字体创建 SVG 内容,并确保所有终端用户在查看该内容时都能获得相同的图形效果,即使终端用户在其计算机上未安装必要的字体。这与印刷界的情况类似,设计师在创作印刷绘图时使用特定的字体,图形内容在印刷版本中与在设计师的创作系统上显示的效果完全一致。
SVG 利用 WebFonts 设施(在 CSS2 中定义,参见 CSS2 第 15.1 节)作为将字体数据可靠地交付给最终用户的关键机制。 在常见场景中,SVG 创作应用程序为给定 SVG 文档片段使用的所有文本元素生成压缩、子集化的 WebFonts。 通常,WebFonts 被保存于相对于引用文档的位置。
到目前为止,WebFont 设施的一个缺点是 CSS2 等规范并未要求支持特定的字体格式。 其结果是不同实现支持不同的 Web 字体格式,从而使网站创建者很难只发布一个使用 WebFonts 的站点,而该站点能够在所有用户代理上工作。
为了为 SVG 提供一种所有 符合规范的 SVG 查看器 都保证支持的通用字体格式,SVG 提供了一种在 SVG 中定义字体的机制。 该机制称为 SVG 字体。
SVG 字体可以提升表示文本的图形的语义丰富度。 例如,许多公司的标志是以艺术化的方式绘制公司名称。 在某些情况下,可访问性 可以通过将标志表示为 SVG 字体中的一系列字形(glyph),随后使用引用该字体的 ‘text’ 元素来渲染标志而得到增强。
一个 SVG 字体 是使用 SVG 的 ‘font’ 元素定义的字体。
SVG 字体的目的在于在仅用于显示的环境中交付字形轮廓。 随网页一起提供的 SVG 字体仅须在浏览和查看情境中得到支持。 图形编辑应用或文件转换工具不得尝试将 SVG 字体转换为系统字体。 其意图是 SVG 文件可以在两个内容创建者之间互换,但不包括可能随这些 SVG 文件一起提供的 SVG 字体。 相反,每个内容创建者在能够成功编辑 SVG 文件之前都需要获得相应字体的授权。 ‘font-face-name’ 元素指示用于编辑的已授权字体名称。
SVG 字体包含未进行 hinting(微调)的字体轮廓。 因此,在许多实现中,小字号文本的质量和可读性可能受限。 为了在小字号下获得更高的质量和可读性,内容创建者可能需要使用其他字体技术,例如操作系统自带的字体或其他 WebFont 格式。
由于 SVG 字体是使用 SVG 元素和属性表达的,在某些情况下它们占用的空间会比专为紧凑表达字体数据而设计的 WebFont 格式更大。 为了实现网页的最快交付,内容创建者可能希望使用其他字体技术。
SVG 字体的一个关键价值是保证在 SVG 用户代理中可用。在某些情况下,SVG 字体作为某些文本渲染的首选可能是合适的。在其他情况下,SVG 字体可能是首选字体(可能是经过字形提示的系统字体)对于给定用户不可用时的替代备份字体。
SVG 字体的特性和属性与 Fonts 章节 中描述的 Cascading Style Sheets (CSS) level 2 规范(CSS2 第 15 章)中的字体特性和参数高度吻合。 在该模型中,各种字体度量(例如 advance 值和基线位置)以及字形轮廓本身,都用相对于一个抽象方形的单位来表示;该方形的高度等于同一字号排版时行间的预期距离。 这个方形被称为 em 方形,是定义字形轮廓的设计网格。 ‘units-per-em’ 属性的值指明了 em 方形被划分为多少单位。 其他字体类型常见的取值例如 250(Intellifont)、1000(Type 1)以及 2048(TrueType、TrueType GX 与 Open‑Type)。 与 SVG 中的标准图形不同,后者的初始坐标系 y 轴向下(参见 初始坐标系),SVG 字体的设计网格及字形的初始坐标系 y 轴向上,以与多数流行字体格式的行业惯例保持一致。
SVG 字体及其关联的字形不提供边界框信息。由于字形轮廓以 SVG 图形元素表达,实现可以选择使用标准图形调用渲染字形,或使用专用的字体渲染技术,此时可以通过分析字形轮廓中包含的图形元素来计算必要的最大边界框和溢出。
SVG 字体既可以嵌入到使用该字体的同一文档中,也可以作为外部资源的一部分保存。
以下是如何在 SVG 文档中嵌入 SVG 字体的示例。
<?xml version="1.0" standalone="yes"?>
<svg width="400px" height="300px" version="1.1"
xmlns = 'https://w3org.cn/2000/svg'>
<defs>
<font id="Font1" horiz-adv-x="1000">
<font-face font-family="Super Sans" font-weight="bold" font-style="normal"
units-per-em="1000" cap-height="600" x-height="400"
ascent="700" descent="300"
alphabetic="0" mathematical="350" ideographic="400" hanging="500">
<font-face-src>
<font-face-name name="Super Sans Bold"/>
</font-face-src>
</font-face>
<missing-glyph><path d="M0,0h200v200h-200z"/></missing-glyph>
<glyph unicode="!" horiz-adv-x="300"><!-- Outline of exclam. pt. glyph --></glyph>
<glyph unicode="@"><!-- Outline of @ glyph --></glyph>
<!-- more glyphs -->
</font>
</defs>
<text x="100" y="100"
style="font-family: 'Super Sans', Helvetica, sans-serif;
font-weight: bold; font-style: normal">Text
using embedded font</text>
</svg>
下面给出一个使用 CSS @font-face 设施(CSS2 第 15.3.1 节)引用保存在外部文件中的 SVG 字体的示例。 第一个引用的 SVG 字体文件
<?xml version="1.0" standalone="yes"?>
<svg width="100%" height="100%" version="1.1"
xmlns = 'https://w3org.cn/2000/svg'>
<defs>
<font id="Font2" horiz-adv-x="1000">
<font-face font-family="Super Sans" font-weight="normal" font-style="italic"
units-per-em="1000" cap-height="600" x-height="400"
ascent="700" descent="300"
alphabetic="0" mathematical="350" ideographic="400" hanging="500">
<font-face-src>
<font-face-name name="Super Sans Italic"/>
</font-face-src>
</font-face>
<missing-glyph><path d="M0,0h200v200h-200z"/></missing-glyph>
<glyph unicode="!" horiz-adv-x="300"><!-- Outline of exclam. pt. glyph --></glyph>
<glyph unicode="@"><!-- Outline of @ glyph --></glyph>
<!-- more glyphs -->
</font>
</defs>
</svg>
使用/引用上述 SVG 字体的 SVG 文件
<?xml version="1.0" standalone="yes"?>
<svg width="400px" height="300px" version="1.1"
xmlns = 'https://w3org.cn/2000/svg'>
<defs>
<style type="text/css">
<![CDATA[
@font-face {
font-family: 'Super Sans';
font-weight: normal;
font-style: italic;
src: url("myfont.svg#Font2") format("svg")
}
]]>
</style>
</defs>
<text x="100" y="100"
style="font-family: 'Super Sans'; font-weight:normal;
font-style: italic">Text using referenced font</text>
</svg>
‘font’ 元素定义一个 SVG 字体。
属性定义
每个 ‘font’ 元素必须包含一个 ‘font-face’ 子元素,用来描述该字体的各种特性。
‘glyph’ 元素定义给定字形的图形。该字形的坐标系由 ‘font’ 元素中的各种属性定义。
构成 ‘glyph’ 的图形可以是位于 ‘d’ 属性中的单个 路径数据 说明,也可以是 ‘glyph’ 内容中的任意 SVG,亦或两者兼有。这两种形式的处理方式不同(见下文)。
属性定义
字形的图形可以通过 ‘d’ 属性或作为 ‘glyph’ 内容的任意 SVG 来指定。
如果指定了 ‘d’,则该属性中的路径数据将按如下方式处理:
如果 ‘glyph’ 具有子元素,则这些子元素的渲染方式类似于 ‘use’ 元素渲染被引用符号的方式。渲染效果等同于将被引用的 ‘glyph’ 内容深度克隆到一个独立的、未暴露的 DOM 树中。由于该克隆的 DOM 树未暴露,SVG DOM 不会显示克隆实例。
对于支持 CSS 样式化 的用户代理,概念上的深度克隆同样会复制引用的 ‘glyph’ 以及其内容上由 CSS 层叠(CSS2 第 6 章)产生的属性值,还会应用于 ‘font’ 元素上的属性值。CSS2 选择器可以作用于原始(即被引用的)元素,因为它们是正式文档结构的一部分;但选择器不能作用于概念上的克隆 DOM 树,因为其内容不属于正式文档结构。
属性继承的行为则如同引用的 ‘glyph’ 已经作为深度克隆的子节点文本包含在文档树中一样。引用的 ‘glyph’ 会继承包含对应字符的元素的属性,而不会继承其原始父节点 ‘font’ 的属性。
在生成的内容中,对于每一次出现的特定 ‘glyph’,会创建一个 ‘g’,该 ‘g’ 承载所有由 CSS 层叠在 ‘font’ 上产生的属性值。该 ‘g’ 内部再包含一个 ‘g’,承载所有由 CSS 层叠在 ‘glyph’ 本身上产生的属性值。原始的 ‘glyph’ 内容会在内部 ‘g’ 中被深度克隆。
如果 ‘glyph’ 同时具有 ‘d’ 属性和子元素,则先渲染 ‘d’,随后渲染子元素。
总体而言,‘d’ 的渲染方式与系统字体相同。例如,若在系统字体或使用 ‘d’ 定义字形的 SVG 字体上应用虚线样式,通常会得到相同的视觉效果。许多实现能够快速渲染带有 ‘d’ 的字形,并且能够利用字体缓存来进一步提升性能。
通过在 ‘glyph’ 中包含子元素来定义字形能够提供更大的灵活性,却也带来更高的复杂度。不同的填充和描边技术可以分别应用于字形的不同部分。例如,字母 “i” 的主体可以是红色,而点可以是蓝色。此方式的一个固有复杂点是单位的处理。任何在表示长度的文本属性上指定的属性(例如 ‘stroke-width’)都可能产生意外结果,因为长度值会在字形的坐标系中进行处理。
‘missing-glyph’ 元素定义在尝试绘制某字体中未定义的字形时所使用的图形。该元素上的属性意义与 ‘glyph’ 元素上的相对应属性相同。
在决定要绘制哪一个或哪些字形以表示给定的字符序列时,会按逻辑顺序从 ‘font’ 元素的第一个 ‘glyph’ 到最后一个 ‘glyph’ 进行搜索,检查即将渲染的 Unicode 字符序列是否与该字形的 ‘unicode’ 属性中指定的序列匹配。首次成功匹配即被采用。因此,若要使用 “ffl” 连写字形,则必须先在字体中定义该连写字形,随后再定义单独的 “f” 字形;否则 “ffl” 将永远不会被选中。
请注意,任何 ‘altGlyph’ 的出现都优先于上述 SVG 字体内部的字形选择规则。
‘hkern’ 与 ‘vkern’ 元素分别定义水平和垂直方向上字形对的字距调整。
字距对标识同一字体内部的两字形,在它们相邻渲染时需要调整字形间距。除了要求两字形必须属于同一字体外,SVG 字体的字距调整仅在这两个字形对应的字符在属性 ‘font-family’、‘font-size’、‘font-style’、‘font-weight’、‘font-variant’、‘font-stretch’、‘font-size-adjust’ 与 ‘font’ 这几项属性值相同的情况下才会生效。
字距调整对的一个例子是字母 "Va",如果字母 "V" 和 "a" 靠得更近一些,印刷效果可能会更好。
Right-to-left and bidirectional text in SVG is laid out in a two-step process, which is described in Relationship with bidirectionality. If SVG fonts are used, before kerning is applied, characters are re-ordered into left-to-right (or top-to-bottom, for vertical text) visual rendering order. Kerning from SVG fonts is then applied on pairs of glyphs which are rendered contiguously. The first glyph in the kerning pair is the left (or top) glyph in visual rendering order. The second glyph in the kerning pair is the right (or bottom) glyph in the pair.
为了方便字体设计者并缩小文件体积,单个 ‘hkern’ 或 ‘vkern’ 元素可以对一组字形(例如一段 Unicode 字符)和另一组字形(例如另一段 Unicode 字符)之间的所有配对指定同一个字距调整值。
‘hkern’ 元素在水平排列(即并排放置)的连续字形对之间定义字距对和水平 advance 调整值。字距调整会减小字符之间的间距(负值会增大间距)。
‘vkern’ 元素在垂直堆叠的字形对之间定义字距对和垂直 advance 调整值,同样会减小字符之间的间距。
属性定义
必须同时提供 ‘u1’ 或 ‘g1’ 中的至少一个,以及 ‘u2’ 或 ‘g2’ 中的至少一个。
字体描述在作者的字体规范与实际字体数据(即用于排版文本并将抽象字形映射为实际可伸缩轮廓或位图的必要数据)之间架起桥梁。字体通过属性(例如 ‘font-family’)进行引用。
每个指定的字体描述都会被添加到字体数据库中,以便用于选择相应的字体数据。字体描述包含诸如字体数据在 Web 上的位置以及该字体数据的特性等描述符。字体描述同样用于将字体属性匹配到特定的字体数据。字体描述的细节程度可以从仅包含字体名称到列出字形宽度不等。
欲了解更多关于字体描述的内容,请参阅 CSS2 规范中的 Fonts 章节(CSS2 第 15 章)。
字体描述可以通过以下任一方式指定:
‘font-face’ 元素直接对应 CSS2 中的 @font-face 设施(CSS2 第 15.3.1 节),可用于描述任意字体(包括 SVG 字体)的特性。
当用于描述同一文档中包含的 SVG 字体的特性时,建议将 ‘font-face’ 元素作为其所描述的 ‘font’ 元素的子元素,以便 ‘font’ 元素能够自给自足并完整描述。在这种情况下,任何 ‘font-face-src’ 元素位于 ‘font-face’ 元素内部时均被忽略,因为假设该 ‘font-face’ 元素正在描述其父 ‘font’ 元素的特性。
属性定义
以下元素和属性对应 @font-face 规则中的 ‘src’ 描述符。(参见 CSS2 规范中 @font-face 规则 与 'src' 描述符 的章节[CSS2],第 15.3.1 与 15.3.5 节。)
‘font-face-src’ 元素与后续章节中描述的 ‘font-face-uri’ 与 ‘font-face-format’ 元素共同对应 @font-face 规则中的 ‘src’ 描述符。(参见 CSS2 规范中 @font-face 规则 与 'src' 描述符 的章节[CSS2],第 15.3.1 与 15.3.5 节。)
‘font-face-src’ 元素包含 ‘font-face-uri’ 与 ‘font-face-name’ 元素,前者用于引用外部字体,后者用于引用本地字体。
‘font-face-uri’ 元素在 ‘font-face-src’ 元素内部使用,用于引用定义在当前 SVG 文档内或外的字体。
当 ‘font-face-uri’ 引用的是 SVG 字体 时,引用必须指向一个 SVG ‘font’ 元素,因此需要使用片段标识符 [RFC3986]。被引用的 ‘font’ 元素可以是本地的(即与 ‘font-face-uri’ 同在一个文档中)或远程的(即位于不同文档中)。
属性定义
子元素 ‘font-face-format’(属于 ‘font-face-uri’)用于指明该 ‘font-face-uri’ 所引用字体所支持的格式。它们对应于 @font-face 规则中 ‘src’ 描述符的 format(…) 子句。
属性定义
‘font-face-name’ 元素在 ‘font-face-src’ 元素内部使用,以名称引用本地字体。它对应于 @font-face 规则中 ‘src’ 描述符的 local(…) 子句。
属性定义
The SVGFontElement interface corresponds to the ‘font’ element.
Object-oriented access to the attributes of the ‘font’ element via the SVG DOM is not available.
interface SVGFontElement : SVGElement,
SVGExternalResourcesRequired,
SVGStylable {
};
The SVGGlyphElement interface corresponds to the ‘glyph’ element.
Object-oriented access to the attributes of the ‘glyph’ element via the SVG DOM is not available.
interface SVGGlyphElement : SVGElement,
SVGStylable {
};
The SVGMissingGlyphElement interface corresponds to the ‘missing-glyph’ element.
Object-oriented access to the attributes of the ‘missing-glyph’ element via the SVG DOM is not available.
interface SVGMissingGlyphElement : SVGElement,
SVGStylable {
};
The SVGHKernElement interface corresponds to the ‘hkern’ element.
Object-oriented access to the attributes of the ‘hkern’ element via the SVG DOM is not available.
interface SVGHKernElement : SVGElement {
};
The SVGVKernElement interface corresponds to the ‘vkern’ element.
Object-oriented access to the attributes of the ‘vkern’ element via the SVG DOM is not available.
interface SVGVKernElement : SVGElement {
};
The SVGFontFaceElement interface corresponds to the ‘font-face’ element.
Object-oriented access to the attributes of the ‘font-face’ element via the SVG DOM is not available.
interface SVGFontFaceElement : SVGElement {
};
The SVGFontFaceSrcElement interface corresponds to the ‘font-face-src’ element.
Object-oriented access to the attributes of the ‘font-face-src’ element via the SVG DOM is not available.
interface SVGFontFaceSrcElement : SVGElement {
};
The SVGFontFaceUriElement interface corresponds to the ‘font-face-uri’ element.
Object-oriented access to the attributes of the ‘font-face-uri’ element via the SVG DOM is not available.
interface SVGFontFaceUriElement : SVGElement {
};
The SVGFontFaceFormatElement interface corresponds to the ‘font-face-format’ element.
Object-oriented access to the attributes of the ‘font-face-format’ element via the SVG DOM is not available.
interface SVGFontFaceFormatElement : SVGElement {
};
The SVGFontFaceNameElement interface corresponds to the ‘font-face-name’ element.
Object-oriented access to the attributes of the ‘font-face-name’ element via the SVG DOM is not available.
interface SVGFontFaceNameElement : SVGElement {
};