第11章:文本

11.1. 引言

要在 SVG 文档片段中渲染的文本使用 text 元素指定。text 元素中的文本可以被渲染为:

文本布局部分介绍了文本布局。接下来的部分涵盖了 内容区域 和 用于在 内容区域 内布局文本的 算法。 随后专门的布局规则对应于预格式化的文本 pre-formatted, 自动换行的文本 auto-wrapped 和沿路径的文本 on a path 将在单独的部分中讨论。

SVG 1.1 中的文本布局规则主要在 SVG 1.1 规范中定义。这些规则在很大程度上反映了 CSS 中的规则。在 SVG 2 中,对 CSS 的依赖更加明确。在实践中,结果布局是相同的。直接依赖 CSS 规范的变化简化了 SVG 规范,同时更明显地表明渲染代理可以使用相同的代码来渲染 HTML 和 SVG 中的文本。特别是,SVG 2 自动换行的文本基于 CSS 文本布局。

SVG 的 text 元素像其他图形元素一样被渲染。 因此,坐标系统变换绘制裁剪遮罩 特性适用于 text 元素, 与适用于 形状(如 路径矩形)的方式相同。

SVG 文本支持高级排版特性,包括:

SVG 文本支持国际文本处理需求,如:

通过 根据用户的首选语言替换不同的文本字符串,可以实现多语言 SVG 内容。

要绘制的字符以 字符数据 表达([xml], 第 2.4 节)在 text 元素内部。因此:

出于可访问性原因,建议包含在文档中的文本具有适当的语义标记以指示其功能。 例如, 为图表的某部分提供可见标签的文本元素应具有 id, 并由相关组或路径元素的 aria-labelledby 属性引用。 有关更多信息,请参见 SVG 可访问性指南

11.1.1. 定义

字符
字符是一个文本的原子单位,定义在XML中 [XML]。

本质上是一个Unicode代码点。 字符可以是控制指令(如制表符、回车或换行), 可呈现的标记(字母、数字、标点符号或其他符号), 或修饰符(如组合音调)。

可寻址字符
一个字符,可以通过文本定位 属性和SVG DOM文本方法进行寻址。 在布局过程中被丢弃的字符,如 折叠的 空格字符不可寻址,带有值为nonedisplay属性的元素内的字符也不可寻址。 可寻址字符通过其在UTF-16代码单元中的索引进行寻址 (因此,单个Unicode代码点大于U+FFFF将映射为两个可寻址字符,因为 一个UTF-16代码单元由16位组成)。 索引在应用任何text-transform转换之前确定, 如在SVGTextContentElement接口中所描述的那样。

如果将来引入对CSS生成内容文本的支持, 它将包括在可寻址字符数组中。

排版字符
一种书写系统的单位—例如拉丁字母(包括其变音符号)、韩文音节、汉字、 缅甸音节集—在特定排版操作(换行、首字母效果、字距调整、对齐、 垂直排列等)方面是不可分割的。有关规范性定义和此定义与Unicode字形集的关系,请参见 CSS 文本模块第3层, ([css-text-3] )。
字体
字体表示一个有组织的字形集合, 其中各种字形表示将共享特定的外观或样式。
字形
字形表示在字体中渲染内容的单位。 通常,要绘制的字符与相应的字形之间存在一对一的对应关系(例如,通常 字符"A"使用单个字形呈现),但有时多个字形用于渲染单个字符 (例如,带重音的字符)或单个字形可以用于渲染 多个字符(例如,连字)。通常,字形由一个或多个形状定义,例如 路径,可能还有其他 信息,例如帮助字体引擎在小尺寸下生成清晰文本的渲染提示。
文本内容元素
文本内容元素是一个SVG元素,导致文本 字符串被渲染到画布上。SVG文本内容 元素有: texttextPathtspan
文本内容子元素
文本内容子元素是一个文本内容元素 ,允许作为另一个文本内容元素的后代。在SVG中,文本内容子元素有: textPathtspan
文本内容块元素
文本内容块元素是一个文本内容元素 ,作为文本单位的独立元素,并且 可选地包含某些子文本内容元素(例如 ‘tspan’)。 SVG 2定义了一个文本内容块元素:text
内容区域
文本通常布局的区域。这等同于 CSS 内容区域。文本布局实际发生的区域可能因填充和/或排除而变小。
换行上下文
在文本布局过程中要排除的一个或多个区域(形状)。这与 CSS换行上下文相同。
换行区域
在减去任何填充或排除区域后,文本布局的区域(换行上下文)。这与 CSS换行区域相同。
行框
包含用于布局单行文本的所有内容的矩形区域。 这与 CSS行框相同。

尽管各种CSS 3文本布局规范使用此术语, 但目前没有建立正式定义。 因此,链接至CSS 2.1, 并且已向CSS工作组提交了一个问题

行内基本方向
内容在一行或一部分行文本中排列的主要方向。 它定义了一行或一部分行文本的开始结束两侧(例如与text-anchor属性的应用相关)。它由direction属性决定。 (注意:文本行中的字符排列主要由Unicode双向算法控制,而不是行内基本方向。)
块流方向
行框堆叠的方向。由writing-mode属性决定。
对齐点
字体字符上应与当前文本位置对齐的点。由字形单元指标决定,可能取决于脚本和行内基本方向
当前文本位置
在当前用户空间中,下一个要渲染的字体字符的对齐点应放置的位置。
文本块
一个独立的文本块,所有字符都一起定位。每次新的绝对定位调整 (由于xy属性,或 强制换行)都会创建一个新的文本块。连字替代和双向重排仅在文本块内发生。文本块仅与预格式化文本相关。
空格字符
以下字符被视为空格字符: U+0009 制表符, U+000C 换页符(FF), U+000D 回车符(CR), U+000A 换行符(LF)和 U+0020 空格。

11.1.2. 字体和字形

字体由一系列字形以及其他必要信息(统称为字体表)组成,用于在某种视觉媒介上呈现字符。这些字形集合和字体表的组合称为字体数据

字体可能提供替换和定位表,格式化程序(文本形状器)可以利用这些表重新排序、组合和定位一系列字形,以形成一个或多个复合字形。组合可能简单如连字,或复杂如一个印地文音节,通常通过重新排序结合多个辅音和元音字形。这些表可能依赖于语言,允许使用语言适当的字母形式。

当一个字形,无论简单或复合,代表一个不可分割的排版单位时,它被称为排版字符

连字是高级文本布局的重要特性。有些连字是任意的,而其他(例如阿拉伯语)是必需的。以下明确规则适用于连字形成:

SVG 2 要求: 包含对Web开放字体格式(WOFF)的明确支持。
决议: 我们将在SVG 2中强制要求支持WOFF。
目的: 允许访问完整的OpenType功能,以支持国际化和高级排版。
负责人: Chris(无行动)
状态: 完成

正确的文本渲染可能依赖于使用与创作时相同的字体。因此,SVG要求支持可下载字体,正如在 字体资源部分定义的那样, CSS字体模块。特别是,需要支持Web开放字体格式 [WOFF]。

SVG 2的新功能,WOFF允许作者提供渲染其内容所需的字体。这包括确保字体具有适当的OpenType表,以支持复杂脚本、 任意连字、装饰、旧式数字等。WOFF还允许字体被压缩、子集化,并包含许可信息。

11.1.3. 字形度量和布局

字形的选择和定位通常根据CSS规则进行。然而,在某些情况下,SVG中文本的最终布局需要了解单个字形的几何属性。

几何字体特性在基于EM框的坐标系统中表示。(EM是字形高度的相对度量。)一个1 EM高和1 EM宽的框称为设计空间。通过将EM细分为多个每em单位来赋予该空间几何坐标。

每em单位是字体特性。每em单位的典型值为1000或2048。

EM框的坐标空间称为设计空间坐标系统。对于可缩放字体,用于绘制字形的曲线和线条使用该坐标系统表示。

通常,该坐标系统中的(0,0)点位于EM框的左边缘,而不在左下角。罗马大写字母底部的Y坐标通常为零。小写罗马字母的下行部分具有负坐标值。

一个'M'在EM框内显示坐标系统、基线、上升和下降。

一个'M'在Em框(蓝色方块)内。'M'坐在基线(蓝线)上。坐标系统的原点由小黑圈表示。

SVG假设字体表将提供至少三个字体特性:上升、下降和一组基线表。上升是从字体的(0,0)点到EM框顶部的距离;下降是从字体的(0,0)点到EM框底部的距离。基线表将在下面解释。

在OpenType字体中([OPENTYPE]),对于水平书写模式,上升和下降由OS/2表中的sTypoAscender和sTypoDescender条目给出。对于垂直书写模式,下降(在这种情况下,从(0,0)点到字形左边缘的距离)通常为零,因为(0,0)点位于左边缘。垂直书写模式的上升为1 em或由OpenType基础表中的表意文字顶部基线值指定。

字形相对于每个字形上的特定点进行定位,该点称为对齐点。对于水平书写模式,字形的对齐点是垂直对齐的,而对于垂直书写模式,它们是水平对齐的。对齐点的位置取决于书写系统。例如,西方字形在大写字母的底部对齐,北印地文字形在字形顶部附近的水平笔画顶部对齐,远东字形则在字形的底部或中心对齐。

在一个书写系统内和在具有单一字体大小的文本行内,对齐点的序列定义了一个几何线,称为基线。西方及大多数其他字母和音节字形对齐到“字母”基线,北印地文字形对齐到“悬挂”基线,而远东字形对齐到“表意”基线。

三种不同书写系统中的基线示例。

三种不同书写系统中的基线示例(红线)。从左到右:字母、悬挂、表意。EM框在表意书写系统中以蓝色显示。

随着字形沿基线顺序放置,字形的对齐点通常位于当前文本位置(一些属性,例如vertical-align可能会改变定位)。每放置一个字形后,当前文本位置将通过字形的推进值(通常是水平文本的宽度或垂直文本的高度)进行推进,同时对字距或其他间距调整以及预格式化或自动换行文本中的新行进行任何修正。当text-anchor值为'middle'或'end'时,初始和最终的当前文本位置用于对齐。字形的推进在沿路径放置文本时是必需的。

三种不同书写系统中的字体度量示例。

字体度量的示例。蓝色框显示三个字形的几何框。标记的小圆圈显示在字形放置之前的当前文本位置。小方框显示放置最后一个字形后的最终当前文本位置。请注意,由于字距调整,字母'a'的框的左侧与字母'V'的框的右侧未对齐。

如果字形没有提供与当前字形方向对应的明确推进值,则应使用适当的近似值。对于垂直文本,建议的近似值是em大小。

初始当前文本位置xy属性在text元素或第一个渲染的tspan元素(用于预格式化文本)或当内容区域inline-size属性确定时的自动换行文本来建立。对于其他自动换行文本,初始当前文本位置由应用CSS换行算法后第一个渲染字形的位置决定。

基线表指定设计空间坐标系统中一个或多个基线的位置。基线表的功能是便于在同一文本行中混合不同书写系统时的对齐。由于所需的相对对齐可能取决于行(或块)中主导书写系统,因此每种书写系统可能有不同的基线表。此外,水平和垂直书写模式需要不同的对齐位置。因此,字体可能有一组基线表:通常,水平书写模式有一个或多个,垂直书写模式有零个或多个。

一些字体可能没有基线表的值。当给定字体不提供基线表时,建议在CSS Inline Layout Module Level 3 [css-inline-3]中使用启发式方法来近似基线表。

当在一段文本的中间指定不同的字体(或字体大小变化)时,主导基线决定用于将新字体(新大小)中的字形与先前字体对齐的基线。dominant-baseline属性用于设置主导基线。

对象相对于其父级的对齐由对齐基线确定。它通常与主导基线相同,但可以通过使用首选的简写vertical-align属性或长写形式alignment-baseline选择其他基线。

主导基线可以临时移动(根据需要用于上标或下标),通过使用首选的简写vertical-align属性或长写形式baseline-shift属性。请注意,移动可以嵌套,每次移动会增加到之前的移动中。

使用'vertical-align'属性的示例。左侧显示'[[z]]',其中内括号较小。右侧显示'x2',其中'2'为上标。

使用'vertical-align'属性的示例。 左侧:对包含'[z]'的tspan应用'vertical-align:mathematical'('alignment-baseline:mathematical')。浅蓝色线显示数学基线的位置。 右侧:对包含'2'的tspan应用'vertical-align:super'('baseline-shift:super')。浅蓝色线表示基线的移动。

SVG进一步假设,对于字体数据中的每个字形,有两个宽度值、两个对齐基线和两个对齐点,一个用于水平书写模式,另一个用于垂直书写模式。(尽管指定为宽度,但对于垂直书写模式,宽度在垂直方向上使用。)对齐点的内联基线方向位置位于字形的起始边缘。

关于基线的更多信息可以在CSS Inline Layout Module Level 3规范中找到。[css-inline-3](另见:CSS Writing Modes Level 3规范。[css-writing-modes-3])

SVG 2 需求: 支持文本对齐到不同的基线。
解决方案: SVG 2将支持字形对齐到不同的基线,可能通过使用现有或改进的CSS属性。
目的: 允许水平文本中的字形具有不同的垂直对齐,以实现风格效果。
负责人: Chris(无行动)
状态: 完成

一行文本在行框内布局。多行文本是通过堆叠这些框产生的。行框的高度通过找到应用line-height属性后所有字形的最大上升和最大下降来确定。行框的宽度通常是包含文本块的宽度。在SVG中,当包含文本块没有固定几何形状(如预格式化文本)时,行框紧密包裹框内的字形框。

句子'A big word.',其中'big'使用较大的字体。

确定行框高度的示例。 首先,每个字形框(小浅蓝框)根据line-height属性垂直延伸。在这种情况下,line-height属性为125%。较大的字形的font-size为96px,因此其额外高度为24px(96px的25%)。额外高度均匀分配在基线上下,形成红色框。(为清晰起见,所有在同一行内的字形已被组合在一起)。最终的行框(大型浅蓝框)是通过使用红框的最大扩展来找到的。

为了支持各种国际书写系统,行框可以水平或垂直定向。 在垂直行框中,文本从上到下流动。 在水平行框中,文本可以从左到右流动(例如,现代拉丁脚本),从右到左流动(例如,希伯来语或阿拉伯语),或混合左到右和右到左(双向文本)。

双向文本的处理模型如下:

虽然字距调整或连字处理可能是字体特定的,但首选模型是字距调整和连字处理在字符重新排序后发生。

行框的方向以及它们堆叠的方向(块流方向)由writing-mode属性决定。对于水平文本(writing-modehorizontal-tb),行框 从上到下堆叠。对于垂直文本,行框 从右到左堆叠(writing-modevertical-rl)或从左到右堆叠 (writing-modevertical-lr)。

11.2. ‘text’‘tspan’ 元素

text 元素定义了一个 包含文本的图形元素。tspan 元素 在 text 或另一个 tspan 元素内,允许 切换样式和/或调整渲染文本在 tspan 元素内相对于父元素的位置。

texttspan 元素中的字符数据,以及相关属性和特性,还有字体内部的字符到字形映射表,定义了 要渲染的字形。texttspan 元素上的属性和特性指示 诸如书写方向、字体规范和绘制属性等内容,这些属性描述了如何准确渲染字符。本章的后续部分描述了 相关的文本特定属性和特性。

由于 texttspan 元素使用 与其他图形元素相同的渲染方法,因此所有适用于 图形 特性也适用于 texttspan 元素, 除了 标记。 此外, 坐标系统变换裁剪遮罩 可以应用于 text 元素整体。

在 CSS 术语中,text 元素作为块级元素。tspantextPatha 元素从 文本内容元素 派生,作为内联元素。

可以对文本应用渐变、图案、裁剪路径、遮罩或滤镜。当这些功能应用于文本时,使用关键字 'objectBoundingBox' (见 对象边界框单位)来指定相对于“对象边界框”的图形效果,则对象边界框单位相对于整个 text 元素计算,即使在同一个 text 元素内,对不同的 tspantextPath 元素应用不同的效果时也是如此。

text 元素在初始 当前文本位置 渲染其第一个字形(在 双向重新排序后)(可能会因 text-anchor 属性或 text-align 属性的值而进行调整)。 对于预格式化文本和自动换行文本,其中 inline-size 属性决定了 内容区域,初始 当前文本位置xy 值确定,后者属于包含第一个渲染字符的 texttspan 元素。 对于形状中的自动换行文本或路径上的文本,请参见 自动换行文本路径上的文本 部分,分别确定初始 当前文本位置。 在渲染与给定字符对应的字形后,当前文本位置将更新为下一个字符。在最简单的情况下,新的当前文本位置为 先前的当前文本位置加上字形的推进值(水平或垂直)。有关字形放置和字形推进的描述,请参见 文本布局

文本字符串 Hello, out there! 使用 Verdana 字体家族渲染到画布上,字形填充为蓝色。

<?xml version="1.0" standalone="no"?>
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
     xmlns="http://www.w3.org/2000/svg" version="1.1">

  <text x="250" y="180"
        font-family="Verdana" font-size="64" fill="blue" >
    Hello, out there!
  </text>

</svg>
显示蓝色文本的图像。

使用 tspan 来 改变单词 not 的样式。

<?xml version="1.0" standalone="no"?>
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
     xmlns="http://www.w3.org/2000/svg" version="1.1">

  <g font-family="Verdana" font-size="64" >
    <text x="160" y="180" fill="blue" >
      You are
      <tspan font-weight="bold" fill="red" >not</tspan>
      a banana.
    </text>
  </g>

</svg>
蓝色文本,除了单词 'not' 是红色。

两个 tspan 元素通过 xy 属性在水平和垂直方向上重新定位。由于所有文本都在一个单一的 text 元素内,用户 将能够在支持 文本选择和 剪贴板操作 的用户代理中选择所有文本并将其复制到系统剪贴板。

<?xml version="1.0" standalone="no"?>
<svg width="10cm" height="3cm" viewBox="0 0 1000 300"
     xmlns="http://www.w3.org/2000/svg" version="1.1">

  <g font-family="Verdana" font-size="64" >
    <text x="100" y="180" fill="blue" >
      But you
      <tspan dx="2em" dy="-50" font-weight="bold" fill="red" >
        are
      </tspan>
      <tspan dy="100">
        a peach!
      </tspan>
    </text>
  </g>

</svg>
带有多个移动单词的句子。
text
类别:
图形元素可渲染元素文本内容元素
内容模型:
以下元素或字符数据的任意数量,顺序不限:aclipPathmarkermaskscriptstyle
属性:
DOM 接口:
SVG 2 要求: 允许在 tspan 上进行变换。
解决方案: SVG 2 将允许在 ‘tspan’ 上进行变换。
目的: 与已经允许变换的其他元素(如 a)保持一致。
负责人: Cameron(无行动)
状态: 完成

此决定已被推翻。请参阅 GitHub 问题 210。CSS/HTML 不允许在行内元素上进行变换, 并且没有渲染器支持在行内(在 SVG 和 HTML 中)对 a 元素进行变换。

tspan
类别:
图形元素可渲染元素文本内容元素文本内容子元素
内容模型:
可以是以下元素或字符数据的任意数量,顺序不限:aanimatescriptsetstyletspan
属性:
DOM 接口:

11.2.1. 属性

名称 初始值 可动画
x, y [ [ <length-percentage> | <number> ]+ ]# text 的默认值为 0;
tspan 没有默认值

如果提供了一个 <length> 值,那么该值表示第一个字符的绝对 X (Y) 坐标。

如果提供了多个 <length> 值,它们将作为第一个字符及其后续字符的 X (Y) 坐标。

如果提供的 <length> 多于字符数量,则多出的值将没有效果。

如果字符数量超过了提供的 <length>,或该属性未在 tspan 上定义,则每个附加字符将根据最近的祖先元素的坐标渲染。

  1. 祖先元素指定的绝对坐标将优先使用。
  2. 否则,字符将从当前文本位置的 X (Y) 坐标开始渲染。

在 SVG 2 中,texttspanxy 属性不是表现属性,无法通过 CSS 设置。

名称 初始值 可动画
dx, dy [ [ <length-percentage> | <number> ]+ ]# (无)

如果提供了一个 <length>,则该值表示 当前文本位置的新的相对 X(Y)坐标,用于渲染此元素或其任何后代中的第一个字符的字形。 在渲染第一个字符的字形之前,当前文本位置沿着当前用户坐标系的 x 轴(y 轴) 被 <length> 偏移。

如果提供了由逗号或空格分隔的 n<length> 列表, 则这些值表示在渲染字形之前,当前文本位置沿着 x 轴(y 轴)的增量偏移, 对应于该元素或其任何后代中的前 n可寻址字符。 因此,在渲染每个字符的字形之前,通过绘制上一个字符的字形, 当前文本位置会沿着当前用户坐标系的 x 轴(y 轴)发生偏移。

如果提供的 <length> 比字符多, 那么多余的 <length> 将不会对字形定位产生任何影响。

如果字符比 <length> 多,或者未指定该属性, 那么对于每个额外的字符:

  1. 如果祖先元素 texttspan 指定了通过 ‘dx’‘dy’)属性为给定字符的相对 X(Y)坐标 (最近的祖先优先),那么当前文本位置沿着当前用户坐标系的 x 轴(y 轴)偏移相应的量,否则
  2. 没有额外的 x 轴(y 轴)偏移。
名称 初始值 可动画
rotate [ <number>+ ]# (无) 是(不可叠加)。

补充旋转的角度(以度为单位),将应用于此元素中的每个字符对应的所有字形, 相对于当前文本位置进行旋转。

如果提供了由逗号或空格分隔的<number>列表, 则第一个<number>表示此元素或其任何后代中第一个字符的字形的补充旋转, 第二个<number>表示第二个字符的字形的补充旋转,依此类推。

如果提供的<number>比字符多, 那么多余的<number>将被忽略。

如果字符比<number>多, 则对于每个额外的字符,必须使用由最后一个数字指定的旋转值。

如果未指定该属性,并且某个tspan元素的祖先 为某个字符通过 rotate 属性 (最近的祖先优先)指定了补充旋转,那么将该补充旋转应用于该字符。 如果祖先的rotate属性中 指定的<number>少于字符, 则对于每个额外的字符,必须使用由最后一个数字指定的旋转值。

该补充旋转对渲染字形时当前文本位置的修改规则没有影响, 并且是对由于路径上的文本文本方向水平字形方向垂直字形方向的任何旋转的补充。

名称 初始值 可动画
textLength <length-percentage> | <number> 见下文

作者计算的对应于该元素中的字符数据的所有进度值的总和,包括字形上的进度值(水平或垂直)、 字母间距单词间距属性的影响, 以及由于该元素或其任何后代的 dxdy 属性的调整。 此值用于校准用户代理的计算结果与作者的计算结果。

此属性的目的是允许作者在视觉呈现顺序中,在双向重排后, 对应于此元素的第一个和最后一个渲染字形实现精确对齐; 因此,对于最后一个渲染字符(在双向重排后的视觉呈现顺序中), 当用户代理确定适当的扩展/压缩文本字符串以适应 textLength 的长度时, 超出正常字形进度的任何补充字符间距(在大多数情况下)都会被忽略。

如果某个元素上指定了 textLength 属性, 并且在其祖先上也指定了该属性,则该元素中的所有字符数据的调整 仅由该元素上的 textLength 属性值控制, 可能会导致该元素内容的调整比例与共享同一祖先的其他内容的调整比例不同。 用户代理必须假定该祖先内的其他内容的总进度值是该祖先的进度值与该元素的进度值之差。

此属性不适用于缩小或扩展文本的效果。

负值是错误 (参见错误处理)。

textLength 属性仅在 包裹区域 未由 shape-insideinline-size 属性定义时才应用。 它也不适用于任何有强制换行的 texttspan 元素 (由于 white-space 属性值为 prepre-line)。

如果在 text 元素中的任何地方都未指定该属性, 则效果与作者的计算结果与用户代理的计算结果完全匹配一样; 因此,不会进行任何进度调整。 为了在 DOM 中反映该属性, 初始值为用户代理当前计算的长度值,以隐含的用户单位表示。

名称 初始值 可动画
lengthAdjust spacing | spacingAndGlyphs spacing
spacing
表示仅调整进度值。字形本身不会被拉伸或压缩。
spacingAndGlyphs
表示进度值被调整,并且字形本身在一个轴上被拉伸或压缩 (即,平行于行内基准方向的方向)。

用户代理需要确保文本字符串的起始和结束位置正确, 但中间字形的位置不可预测,因为用户代理可能会采用高级算法来拉伸或压缩文本字符串, 以平衡正确的起始和结束定位与最佳排版效果。

请注意,对于包含 n 个字符的文本字符串,进度值的调整通常只发生在 n−1 个字符上 (请参阅属性 textLength 的描述), 而字形的拉伸或压缩将应用于所有 n 个字符。

11.2.2. 关于 'x'、'y'、'dx'、'dy' 和 'rotate' 的说明

xydxdyrotate 属性在 texttspan 元素中非常有用, 特别是在需要精确放置单个字形的高端排版场景中。这些属性可用于字符之间的小范围定位调整或大范围的定位调整, 例如移动文本部分到新位置,以实现新行的视觉效果(兼容 SVG 1.1)。注意,当 xydxdyrotate 属性在自动换行的文本中被忽略(除非初始当前文本位置inline-size 属性指定的 内容区域定义)。

在 2015 年悉尼 F2F 会议上决定,对于自动换行的文本,'dx'、'dy' 和 'rotate' 会被忽略。 (从技术上讲,应用它们并不困难,但被认为并不真正有用。)

在需要进行微观级别定位调整以实现高级排版控制的情况下,SVG 内容设计者需要确保所有文档查看者都能使用到所需的字体 (例如,将所需字体数据打包成 SVG 字体或存储在与 SVG 内容相同网站上的替代 WebFont 格式), 并确保查看软件会以预期的方式处理该字体(不同系统的字体处理能力、特性和字体布局机制差异很大)。 如果 SVG 内容包含 xydxdy 属性值, 这些值是为特定字体以及特定查看软件集处理时使用的,如果这些要求中的任何一个没有得到满足,那么文本可能会显示出较差的质量。

以下附加规则适用于属性 xydxdyrotate, 当它们包含数字列表时:

示例 tspan04tspan 元素上使用了 rotate 属性来旋转要渲染的字形。 此示例展示了在 tspan 元素中包含的一个文本字符串, 其字符数多于 rotate 属性中指定的值数。在这种情况下,rotate 属性的最后一个指定值必须应用于字符串中的剩余字符。

<?xml version="1.0" standalone="no"?>
    <svg width="10cm" height="3cm" viewBox="0 0 1000 300"
      xmlns="http://www.w3.org/2000/svg" version="1.1">
      <desc>
        Example tspan04 - The number of rotate values is less than the number of
        characters in the string.
      </desc>
      <text font-family="Verdana" font-size="55" fill="blue" >
        <tspan x="250" y="150" rotate="-30,0,30">
          Hello, out there
        </tspan>
      </text>
      <!-- Show outline of viewport using 'rect' element -->
      <rect x="1" y="1" width="998" height="298"
      fill="none" stroke="blue" stroke-width="2">
    </svg>
Example tspan04 — simple rotation of characters in a tspan element

Example tspan04

View this example as SVG (SVG-enabled browsers only)

示例 tspan05 指定了 rotate 属性在 text 元素上,并且在除了一个子 tspan 元素之外的所有子元素上旋转字形进行渲染。 该示例展示了 rotate 属性的传播。

<?xml version="1.0" standalone="no"?>
    <svg width="100%" height="100%" viewBox="0 0 500 120"
      xmlns="http://www.w3.org/2000/svg" version="1.1">
      <desc>
        Example tspan05 - propagation of rotation values to nested tspan elements.
      </desc>
      <text id="parent" font-family="Arial, sans-serif" font-size="32" fill="red" x="40" y="40"
        rotate="5,15,25,35,45,55">
        Not
    
        <tspan id="child1" rotate="-10,-20,-30,-40" fill="orange">
          all characters
    
          <tspan id="child2" rotate="70,60,50,40,30,20,10" fill="yellow">
            in
    
            <tspan id="child3">
              the
            </tspan>
          </tspan>
    
          <tspan id="child4" fill="orange" x="40" y="90">
            text
          </tspan>
    
          have a
        </tspan>
    
        <tspan id="child5" rotate="-10" fill="blue">
          specified
        </tspan>
    
        rotation
      </text>
    
      <!-- Show outline of viewport using 'rect' element -->
      <rect x="1" y="1" width="498" height="118" fill="none"
            stroke="blue" stroke-width="2">
    </svg>
Example tspan05 — propagation of rotation values to nested tspan elements

Example tspan05

View this example as SVG (SVG-enabled browsers only)

红色文本内 text 元素的旋转:

橙色文本在 "child1" tspan 元素中的旋转:

黄色文本在 "child2" tspan 元素中的旋转:

蓝色文本在 "child5" tspan 元素中的旋转:

下图说明了旋转值如何传播到嵌套在 text 元素中的 tspan 元素:

Image that shows propagation of rotation values

11.3. 文本布局 – 引言

SVG 2 需求: 包括来自 SVG Tiny 1.2 的文本布局改进。
决议: SVG 2 将包括来自 SVG Tiny 1.2 的改进文本, 涵盖字符和字形、文本布局、文本选择、文本搜索。
目的: 包括更清晰的文本布局描述;无功能性变化。
负责人: Chris (ACTION-3236)
SVG 2 需求: 支持形状中的文本。
决议: SVG 2 将要求自动文本换行与 CSS 兼容。
目的: 用于流程图等中的文本。
负责人: Tav(无行动)

本节简要概述了 SVG 文本布局。接下来的部分将更详细地介绍文本布局的不同方面。

SVG 中的文本布局是一个多阶段的过程,它接受 text 元素子树及其属性值作为输入,并生成一系列用于渲染的字形及其在每个 文本内容元素 坐标系中的位置。

首先,text 元素及其后代根据 CSS 布局在 内容区域换行区域 中布局,仿佛 text 是块元素, 而 tspantextPatha 后代是行内元素。 该布局考虑了本章描述的所有段落级别和字体相关的 CSS 属性。

内容区域 可以通过设置 inline-size 属性或 shape-inside 属性来明确声明, 后者定义或引用 SVG 形状。如果未声明 内容区域,则默认为无限宽度和高度的矩形。

其次,xydxdy 属性提供的任何定位 都应用于从 CSS 布局过程中生成的字形位置。 允许哪些变换的规则取决于是否明确声明了 内容区域。 如果未明确声明,这些规则定义了 预格式化 文本的布局; 如果声明了,则规则定义了 自动换行 文本的布局。

第三,如果需要,则应用 text-anchor 属性的效果。

最后,对任何 textPath 元素的字形布局进行处理,将 预格式化 文本转换为 路径上的文本

不同类型的文本布局示例:

预格式化:
适用于短字符串文本(例如标签)或需要精确放置字形的场景(例如手工调整字符间距的标题)。

多行预格式化文本的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

     <text x="20" y="45" style="font: 24px sans-serif;">
       Example of multi-line,
       <tspan x="20" y="75">pre-formatted text.</tspan>
     </text>

</svg>
显示两行预格式化文本的图像。

预格式化文本,其中使用了 tspan 元素创建多行文本。

自动换行文本:
适用于需要自动换行的长文本字符串。

自动换行文本的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

  <text x="20" y="45" style="font: 24px sans-serif; inline-size: 250px;">
    Example of text auto-wrapped.</text>

</svg>
显示自动换行文本在两行的图像。

自动换行文本。inline-size 属性定义了无限高度的矩形内容区域(以浅蓝色显示)。

路径上的文本:
用于沿指定路径的文本。

路径上的文本示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

  <path id="MyPath" stroke="lightblue" fill="none"
	d="M 50,50 C 100,0 200,100 250,50">

  <text style="font: 24px sans-serif;">
    <textPath href="#MyPath">Text on a path.</textPath>
  </text>

</svg>
显示沿路径的文本的图像。

路径上的文本。textPath 元素引用了 path 元素(以浅蓝色显示)。

SVG 2 引入了通过指定 内容区域 自动换行文本的能力。 SVG 换行文本的设计旨在使其尽可能与 CSS 中的文本换行兼容,以便支持 CSS 文本换行的渲染器可以轻松实现 SVG 文本换行 (但不要求非 HTML 兼容的 SVG 渲染器实现 HTML)。SVG 与 CSS 文本换行之间有几个差异,最重要的是在 SVG 中,必须显式提供 内容区域,而 SVG 没有自动有限(或半有限) 内容区域(由 CSS 的盒模型提供)。 另一个区别是 SVG 没有 <p></p> 和 <br/> 元素来创建换行。相反,SVG 依赖 prepre-line 值的 white-space 属性来提供换行。SVG 换行文本还允许内容创建工具为不支持换行文本的 SVG 1.1 渲染器提供自然的回退选项 (通过在 texttspan 元素中使用 xy 属性, 这些属性在自动换行文本中会被 SVG 2 渲染器忽略)。

SVG 的文本布局选项旨在涵盖大多数常规使用场景。如果需要更复杂的布局(项目符号列表、表格等), 可以将文本以其他 XML 命名空间(如嵌入在 foreignObject 元素中的 XHTML [HTML])进行渲染。

11.4. 文本布局 – 内容区域

内容区域 通过在 text 元素中指定 inline-size 属性或 shape-inside 属性来定义,后者定义或引用一个 SVG 形状。如果未提供 内容区域,则 内容区域 默认为无限宽度和高度的矩形(请参阅 预格式化文本 部分)。如果同时指定了 inline-size 属性和 shape-inside 属性且其值不是 'none',则使用 shape-inside 属性。

换行文本在 换行区域 中布局。换行区域 通常与 内容区域 相同。当使用 shape-inside 属性定义 内容区域 时,由于存在 shape-subtract 属性和/或 shape-padding 属性,换行区域 可能会更小。shape-subtract 属性(以及 shape-margin 属性)定义了一个 换行上下文换行区域 是通过将 内容区域shape-padding 距离内嵌,然后减去 换行上下文 得到的。

一旦定义了 换行区域,文本就根据 CSS 的规则(遵守本节中的任何特殊规则)在 换行区域 内布局。

在 SVG 和 HTML 中构建等效的换行区域。换行区域内的文本在两种情况下呈现相同。

通过使用水平间隔开的两个半圆创建一个沙漏形状的图像。文本在圆形内换行,左右两个半圆排除圆形的一部分。

在 SVG 中定义 换行区域text 元素同时具有 shape-inside 属性和 shape-subtract 属性。 shape-inside 属性引用了一个定义 内容区域 的圆形(虚线紫色线)。 shape-subtract 属性引用了两个半圆,定义了 换行上下文(虚线绿色线),该上下文从 内容区域 中减去,得到了 换行区域(浅蓝色线)。

通过使用水平间隔开的两个半圆创建一个沙漏形状的图像。文本在圆形内换行,左右两个半圆排除圆形的一部分。

在 HTML 中定义 换行区域。 一个 wrapper <div> 包含两个 float <div>。wrapper <div> 定义了一个矩形区域(实线紫色线)。 它的 shape-inside 属性定义了 <div> 内的 内容区域(虚线紫色线)。两个其他的 <div> 定义了两个浮动块, 一个在左侧(实线绿色线),另一个在右侧(实线粉色线)。这些浮动块的形状是矩形的。 每个浮动块都有一个 shape-outside 属性,该属性定义了每个浮动块的 换行上下文(虚线绿色和粉色线)。 组合的 换行上下文内容区域 中减去,以定义 换行区域(浅蓝色线)。

11.4.1. ‘inline-size’ 属性

'extent' 于 2015年2月12日 决议中添加。 'extent' 替换了 'width' 和 'height' 属性,首次在 2013年6月27日决议中添加。 根据 2015年6月11日Linkoping F2F 决议, 被 'inline-size' 展示属性替换。

inline-size 属性允许将 换行区域 设置为矩形形状。 该属性的计算值设置矩形的宽度用于水平文本,设置矩形的高度用于垂直文本。 另一个维度(水平文本的高度,垂直文本的宽度)是无限长度。 值为零将禁用创建 换行区域

初始 当前文本位置 取自 xy 属性, 如果这些属性未在 text 元素上指定,则取自第一个子 tspan 元素。 对于从左到右的文本,初始 当前文本位置 位于矩形的左侧。 对于从右到左的文本,它位于矩形的右侧。 对于垂直文本,初始 当前文本位置 位于矩形的顶部。

矩形(换行区域)根据 text-anchor 属性进行锚定, 使用 换行区域 的边缘来确定起始、中间和结束位置。

使用 inline-size 属性进行文本换行是对预格式化 SVG 文本的扩展, 作者只需给出文本块的宽度或高度限制;因此, xy 属性以及 directiontext-anchor 属性用于定位第一行文本。 如果需要完全对齐,则应使用 shape-inside 属性创建 换行区域

名称: inline-size
值: <length-percentage>
初始值: 0
适用于: text 元素
继承:
百分比: 相对于当前 SVG 视口的宽度(用于水平文本)或高度(用于垂直文本)(请参阅 单位
媒体: 视觉
计算值: 绝对长度或百分比
可动画化

使用 inline-size 进行水平文本换行的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

  <text x="50" y="30" style="font: 20px sans-serif; inline-size: 200px">
    This text wraps at 200 pixels.
  </text>

</svg>
显示英文文本换行成两行的图像。

水平文本换行。浅蓝色线表示 内容区域 的边界。 请注意,内容区域的高度是无限的。红点表示初始 当前文本位置

使用 inline-size 进行从右到左水平文本换行的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

  <text x="250" y="30"
	style="font: 20px PakType Naqsh; inline-size: 200px; direction: rtl;">
    هذا النص يلتف في 200 بكسل.</text>

</svg>
显示阿拉伯文文本换行成两行的图像。

从右到左文本的水平换行。浅蓝色线表示 内容区域 的边界。 请注意,内容区域的高度是无限的。红点表示初始 当前文本位置

某些浏览器可能无法正确呈现此 SVG 1.1 图形。Batik 和 Firefox 似乎呈现正确。已针对 Chrome 提交 Bug。

使用 inline-size 进行垂直文本换行的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="100" height="300" viewBox="0 0 100 300">

  <text x="62.5" y="25" inline-size="200"
	style="font: 25px IPAMincho; inline-size: 200px; writing-mode: vertical-rl;">
    テキストは10文字後に折り返されます。</text>

</svg>
显示日文垂直文本换行成两列的图像。

垂直文本换行。浅蓝色线表示 内容区域 的边界。 请注意,内容区域的宽度是无限的。红点表示初始 当前文本位置

此 SVG 1.1 图像在 Firefox 中无法正常工作,即使在夜间版本中也是如此。Firefox 不支持 'writing-mode' 展示属性。已针对 Firefox 提交 Bug。

使用 inline-size 进行水平文本换行,并居中对齐的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

  <text x="50" y="30" style="font: 20px sans-serif; inline-size: 200px; text-anchor: middle">
    This text wraps at 200 pixels.
  </text>

</svg>
显示居中对齐的英文文本换行成两行的图像。

水平文本换行。浅蓝色线表示 内容区域 的边界。 文本居中对齐。红点表示初始 当前文本位置

11.4.2. ‘shape-inside’ 属性

shape-inside 属性允许将 内容区域 设置为 CSS 基本形状 或 SVG 形状

在 CSS/HTML 中,shape-inside 应用于块级元素, 绝对值和百分比值是相对于块级元素定义的。 在 SVG 中,绝对值和百分比值是相对于当前 用户坐标系统viewBox 定义的。

名称: shape-inside
值: auto | [ <basic-shape> | <uri> ]+
初始值: auto
适用于: text 元素
继承:
百分比: 相对于 viewBox 定义
媒体: 视觉
计算值: 计算后的长度用于 <shape>,绝对 URI 用于 <uri>,否则按指定处理
可动画化 是,详见 基本形状插值
auto
对于 SVG 来说,'auto' 值表示内容区域应通过 inline-size 属性或按预格式化文本定义。
<basic-shape>
形状基于 'circle()'、'ellipse()' 或 'polygon()' 的值计算得出。CSS 值 'inset()' 对于 SVG 是无效的。

使用 CSS 基本形状进行水平文本换行的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="300" viewBox="0 0 300 300">

  <text style="font: 20px/25px sans-serif;
               text-align: center;
               shape-inside: circle(120px at 150px 150px);">
    Lorem ipsum dolor sit amet, consec-tetuer adipiscing elit...</text>

</svg>
显示文本包裹在圆形内的图像。

文本包裹在 CSS 圆形形状内。浅蓝色圆形表示 内容区域 的边界。

<uri>
如果 <uri> 引用了 SVG 形状 元素,则该元素定义形状。 否则,如果 <uri> 引用的是图像,形状基于指定图像的 alpha 通道并使用 shape-image-threshold 计算得出。 如果 <uri> 未引用 SVG 形状元素或图像,则效果与指定 'auto' 值时相同。

使用引用 SVG 形状 进行水平文本换行的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

  <defs>
    <rect id="wrap" x="50" y="10" width="200" height="80">
  </defs>

  <text style="font: 20px sans-serif; shape-inside: url(#wrap);">
    This text wraps in a rectangle.</text>

</svg>
显示文本包裹在矩形内的图像。

文本包裹在 SVG 矩形形状内。浅蓝色线表示 内容区域 的边界。

CSS 的 'outside-shape'、'shape-box' 和 'display' 值对于 SVG 是无效的。

SVG 允许 shape-inside 属性包含形状列表。每个形状定义一个独立的 内容区域。文本首先布局在第一个形状的内容区域内。 如果文本溢出了第一个形状,则溢出文本会布局在下一个形状内,直到所有文本布局完成或没有更多形状可用为止。

该效果类似于 CSS 列布局,但列可以具有任意形状。

建议提供一个 "overflow" 形状,以确保在某些情况下(例如用户增加字体大小时)所有文本的可访问性。

除非另有说明,'shape-inside' 的定义请参见 CSS Shapes Module Level 2。 [css-shapes-2]

'shape-inside' 在 CSS 排除和形状模块拆分为单独的排除和形状模块时被移除。 在东京联合 SVG/CSS F2F 会议上,达成共识,将其重新出现在 CSS Shapes Module Level 2 中。

11.4.3. ‘shape-subtract’ 属性

shape-subtract 属性允许从 内容区域 中排除部分区域, 从而影响 换行区域。 被排除的区域是通过一个 CSS 基本形状 和/或 SVG 形状 列表定义的所有区域的组合。

在 2016 年悉尼 F2F 会议上决定,由于需要不同的行为,应使用 'shape-subtract' 而不是 'shape-outside'。 ('shape-outside' 减少了排除区域的面积。)

绝对值和百分比值是相对于当前 用户坐标系统viewBox 定义的。

名称: shape-subtract
值: none | [ <basic-shape>| <uri> ]+
初始值: none
适用于: text 元素
继承:
百分比: 相对于 viewBox 定义
媒体: 视觉
计算值: 计算后的长度用于任何 <basic-shape>,绝对 URI 用于 <uri>,否则按指定处理
可动画化 是,详见 基本形状插值
<basic-shape>
形状基于 'circle()'、'ellipse()' 或 'polygon()' 的值计算得出。
<uri>
对于引用 SVG 形状 元素的 <uri>, 该元素定义了贡献的形状,并由其 shape-margin 距离扩展。 对于引用图像的 <uri>,贡献的形状基于指定图像的 alpha 通道并使用 shape-image-threshold 计算得出。 如果 <uri> 未引用 SVG 形状元素或图像,则忽略该 <uri>。

使用 shape-subtract 的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="450" height="300" viewBox="0 0 450 300">

  <rect id="rect1" x="25"  y="25"  width="225" height="175" fill="white" stroke="black">
  <rect id="rect2" x="200" y="125" width="225" height="150" fill="white" stroke="black"
        style="shape-margin:25px;">

  <text style="shape-inside:url(#rect1);
	       shape-subtract:url(#rect2);
	       shape-padding:25px;
           font-family:DejaVu Sans;
	       font-size:12px;
	       text-align:justified;
	       line-height:110%">Lorem ipsum ...</text>
  <text style="shape-inside:url(#rect2);
	       shape-padding:25px;
               font-family:DejaVu Sans;
	       font-size:12px;
	       text-align:justified;
	       line-height:110%">Lorem ipsum ...</text>
</svg>
显示水平文本包裹在两个重叠矩形中的图像。

使用 shape-subtract 以及 shape-insideshape-paddingshape-margin 在两个重叠矩形中进行水平文本换行。 黑色矩形显示 内容区域。 内部的蓝色线条显示 换行区域

11.4.4. ‘shape-image-threshold’ 属性

shape-image-threshold 定义了用于从图像中提取形状的 alpha 通道阈值。值为 0.5 意味着形状将包含所有不透明度超过 50% 的像素。

对于 SVG,这个属性适用于 text 元素。

除非另有说明,'shape-image-threshold' 的定义请参见 CSS Shapes Module Level 1。 [css-shapes-1]

11.4.5. ‘shape-margin’ 属性

shape-margin 属性为使用 shape-subtract 引用的形状添加边距。 它定义了一个新的形状,其中每个点都距离原始形状指定的距离。此属性仅接受正值。

名称: shape-margin
值: <length-percentage>
初始值: 0
适用于: text 元素
继承:
百分比: N/A
媒体: 视觉
计算值: 绝对长度
可动画化

除非另有说明,'shape-margin' 的定义请参见 CSS Shapes Module Level 1。 [css-shapes-1]

11.4.6. ‘shape-padding’ 属性

shape-padding 属性用于在元素内部的包裹内容流中创建偏移。 由 'wrap-padding' 属性产生的偏移是相对于元素的内容区域进行的。此属性仅接受正值。

使用 shape-padding 的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="300" viewBox="0 0 300 300">

  <circle id="circle" cx="150" cy="150" r="125" fill="none" stroke="black">
  <text style="shape-inside: url(#circle);
	       shape-padding: 25px;
	       font: 18px DejaVu Sans;
	       text-align: justified;
	       line-height: 110%;">This is an
  example of wrapped text in SVG 2! There should
  be 25 pixel padding around the text. The text is
  justified on both sides. It looks good!</text>

</svg>
显示带有填充的圆形内部水平文本包裹的图像。

带有 shape-padding 的圆形内部水平文本包裹。 外部黑色圆形表示 内容区域。内部蓝色圆形表示 包裹区域

此图像为 PNG。找出如何制作优质的 SVG。注意:Chrome 支持 'tspan' 上的 'textLength',但 Firefox 不支持。

除非另有说明,'shape-padding' 的定义请参见 CSS Shapes Module Level 2。

11.5. 文本布局 – 算法

文本布局从将 text 元素的内容(包括文本数据、 样式信息以及一个或多个要填充的形状描述)传递给基于 CSS 的文本渲染器开始。 text 元素被视为块元素, 其后代 tspantextPatha 元素被视为内联元素。 CSS 渲染器返回一组 印刷字符单元 及其布局文本的结果位置, 如同文本是绝对定位一样。

一个 印刷字符 可能包含多个 字形。 这里假设 字形印刷字符单元 内的相对位置是封装的,用户无法控制。

一旦定义了 内容区域,以下算法用于确定给定 text 元素的 印刷字符及其位置:

某些 CSS 属性对 SVG 文本布局没有或只有有限影响:

根据如何定义 内容区域,各种 SVG 属性和属性可能会重新定位 印刷字符

以下 SVG 文本布局算法返回关于 DOM 中的每个字符的信息,该信息包含:

SVG 属性 xydxdyrotate 中给出的数组由 可寻址字符索引。 但是,重新定位应用于 印刷字符。如果 印刷字符 对应多个字符(例如连字),则仅使用与第一个字符对应的数组值来定位 印刷字符。 与其他字符对应的数组值将被跳过(对于 xy), 累积并应用于下一个 印刷字符(对于 dxdy), 或者如果它是数组中的最后一个值,则应用于后续的 印刷字符(对于 rotate)。这确保了,无论字体是否包含特定的连字, 属性值都应用于相同的字符。

SVG 特定文本布局算法如下:

  1. 设置
    1. root 为生成 排版字符 位置的结果, 对于 text 元素及其子树进行布局,仿佛它是一个绝对定位的元素。

      除非 white-space 属性 导致换行,否则这将是单行文本。

    2. count 为 DOM 字符text 元素的子树中的数量。
    3. result 为一个长度为 count 的数组, 其条目包含上述每个字符的信息。每个条目初始化如下:
      • 其全局索引号等于其在数组中的位置,
      • 其 "x" 坐标设置为 "未指定",
      • 其 "y" 坐标设置为 "未指定",
      • 其 "rotate" 坐标设置为 "未指定",
      • 其 "hidden" 标志为假,
      • 其 "addressable" 标志为真,
      • 其 "middle" 标志为假,
      • 其 "anchored chunk" 标志为假。
      如果 result 为空,则返回 result
    4. CSS_positions 为一个长度为 count 的数组,其条目将填充对应的 xy 位置 在 root 中的 排版字符。 数组条目初始化为 (0, 0)。
    5. 让 "horizontal" 为一个标志,如果 text 的书写模式是水平,则为真,否则为假。
  2. 设置标志并分配初始位置

    对于 result 中索引为 i 的每个数组元素:

    1. 如果索引 i 处的字符为:

      由于以下 text 元素中有可折叠的空白 (使用标准字体),因此 "B" 字形将被放置在 x=300。

      <text x="100 200 300">
      	      A
      	      B
      	      </text>

      这是因为 "A" 前的空白,以及 "A" 和 "B" 之间的所有空白字符,已被折叠或修剪。

    2. 如果索引 i 处的字符是第二个或后续的对应于 排版字符,则将 middle 设置为真。
    3. 如果索引 i 处的字符对应于一行开头的 排版字符,则将 result[i] 的 "anchored chunk" 标志设置为真。

      这确保由于 text-anchor 移动的块不会跨越多行。

    4. 如果 addressable 为真且 middle 为假,则将 CSS_positions[i] 设置为对应的 排版字符 的位置, 由 CSS 渲染器确定。否则,如果 i > 0,则设置 CSS_positions[i] = CSS_positions[i − 1]
  3. 解析字符定位

    位置调整(例如在 x 属性中的值) 由节点指定,适用于该节点中的所有字符,包括 节点子孙中的字符。然而,在子孙节点中指定的调整会覆盖祖先节点的调整。此部分解析将应用于 哪些字符的调整。它还直接设置 resultrotate 坐标。

    1. 设置:
      1. resolve_xresolve_yresolve_dxresolve_dy 为长度为 count 的数组,所有条目初始化为 "未指定"。
      2. 设置 "in_text_path" 标志为假。

        此标志将允许 yx) 属性值在 textPath 元素中的 水平(垂直)文本被忽略。

      3. 使用 text 元素节点调用以下过程。
    2. 程序: 解析字符定位

      一个递归程序,输入为 node,步骤如下:

      1. 如果 nodetexttspan 节点:
        1. index 等于节点中第一个字符的 "全局索引编号"。
        2. xydxdyrotate 为对应于 node 的属性值列表,或者如果对应的属性未指定或无效则为空列表。
        3. 如果 "in_text_path" 标志为假:
          • new_chunk_count = max(x 的长度, y 的长度)。
          否则:
          • 如果 "horizontal" 标志为真:
            • new_chunk_count = x 的长度。
          • 否则:
            • new_chunk_count = y 的长度。
        4. length 为以 node 为根的子树中的 DOM 字符数。
        5. i = 0 和 j = 0。

          i 是节点中的 可寻址字符索引; j 是节点中的所有 字符索引。

        6. j < length 时,执行:

          此循环将 xydxdyrotate 属性应用于 node 内的内容。

          1. 如果 result[index + j] 的 "addressable" 标志为真,则:
            1. 如果 i < new_check_count,则 将 result[index + j] 的 "anchored chunk" 标志设为真。否则将标志设为假。

              将标志设为假确保 xy 属性在 text 元素中设置时不会在 textPath 元素中创建不应存在的锚定块。

            2. 如果 i < x 的长度, 则将 resolve_x[index + j] 设为 x[i]。
            3. 如果 "in_text_path" 标志为真且 "horizontal" 标志为假,则取消设置 resolve_x[index]。

              x 属性在路径上的垂直文本中被忽略。

            4. 如果 i < y 的长度, 则将 resolve_y[index + j] 设为 y[i]。
            5. 如果 "in_text_path" 标志为真且 "horizontal" 标志为真,则取消设置 resolve_y[index]。

              y 属性在路径上的水平文本中被忽略。

            6. 如果 i < dx 的长度, 则将 resolve_dx[index + j] 设为 dy[i]。
            7. 如果 i < dy 的长度, 则将 resolve_dy[index + j] 设为 dy[i]。
            8. 如果 i < rotate 的长度, 则将 result[index + j] 的角度值设为 rotate[i]。 否则,如果 rotate 不为空,则 将 result[index + j] 设为 result[index + j − 1]。
            9. i = i + 1。
          2. j = j + 1。
      2. 如果 node 是一个 textPath 节点:
        1. index 等于节点中第一个字符的全局索引号(包括子节点)。
        2. result[index] 的“锚定块”标志设置为 true。

          textPath 元素始终创建一个锚定块。

        3. in_text_path 标志设置为 true。
      3. 对于每个子节点 childnode
        1. 解析字形定位 child
      4. 如果 node 是一个 textPath 节点:
        1. 将 “in_text_path” 标志设置为 false。
  4. 调整位置:dx, dy

    dxdy 调整在因 textLength 属性的调整之前应用,而 xyrotate 调整在之后应用。

    1. shift 为因 xy 属性的累计 xy 偏移,初始化为 (0,0)。
    2. 对于结果中索引为 i 的每个数组元素:
      1. 如果 resolve_x[i] 未指定,则将其设置为 0。 如果 resolve_y[i] 未指定,则将其设置为 0。
      2. shift.x = shift.x + resolve_x[i] 和 shift.y = shift.y + resolve_y[i]。
      3. result[i].x = CSS_positions[i].x + shift.x 和 result[i].y = CSS_positions[i].y + shift.y。
  5. 应用 textLength 属性
    1. 设置:
      1. 定义 已解析的 后代节点 为具有有效的 textLength 属性的节点,其本身不是具有有效 textLength 属性的后代节点的后代节点。
      2. 调用以下过程,使用 text 元素节点。
    2. 过程: 解析文本长度

      一个递归过程,输入为 node,其步骤如下:

      1. 对于节点的每个子节点 child
        1. 解析文本长度 子节点。

          子节点在父节点之前调整。

      2. 如果 node 是一个 texttspan 节点,并且该节点具有有效的 textLength 属性值:
        1. a = +∞ 和 b = −∞。
        2. ijnode 中第一个字符和最后一个字符的全局索引。
        3. 对于范围 [i, j] 中的每个索引 k,其中 result[k] 的“可寻址”标志为 true:

          此循环找到节点中 排版字符 的最左(上)和 最右(下)范围,并检查强制换行。

          1. 如果字符在 k 处为换行符或回车符,则返回。没有因 textLength 对具有强制换行的节点进行调整。
          2. pos = result[k] 中位置的 x 坐标,如果“水平” 标志为 true,则为 y 坐标,否则。
          3. advance = 与字符 k 对应的 排版 字符 的进位。[注意:此进位对于 RTL 水平文本将为负。]
          4. 设置 a = min(a, pos, pos + advance)。
          5. 设置 b = max(b, pos, pos + advance)。
        4. 如果 a ≠ +∞ 则:
          1. 找到距离 delta = textLength 计算值 − (b − a)。

            用户代理需要将节点中最后一个 排版字符delta 的正 x 方向移动,如果“水平”标志为 true,并且 方向lrt;如果“水平”标志为 true 且 方向rtl,则向负 x 方向移动;否则向 正 y 方向移动。用户代理可以自由调整中间的 排版字符 以获得最佳 排版。下一步说明了一种在 lengthAdjust 属性值为 spacing 时调整 排版字符 的方法。

          2. 找到 n,节点中 排版字符 的总数 包括任何未解析的后代节点或在解析的后代节点内的节点。
          3. n = n + 已解析后代节点的数量 − 1。

            每个已解析的后代节点在此上下文中视为一个单独的 排版字符

          4. 找到每个字符的调整 δ = delta/n
          5. shift = 0。
          6. 对于范围 [i,j] 中的每个索引 k
            1. 如果“水平”标志为 true,则将 shift 加到 result[k] 中位置的 x 坐标,否则加到 y 坐标。
            2. 如果 result[k] 的“中间”标志不为 true 且 k 不是解析的后代节点中的字符(除了第一个字符), 则 shift = shift + δ
  6. 调整位置:x, y

    此循环应用 xy 值, 并确保 text-anchor 块不在 排版字符 的中间开始。

    1. shift 为当前因 xy 属性的调整,初始化为 (0,0)。
    2. 设置 index = 1。
    3. index < count 时:
      1. 如果 resolved_x[index] 被设置,则让 shift.x = resolved_x[index] − result.x[index]。
      2. 如果 resolved_y[index] 被设置,则让 shift.y = resolved_y[index] − result.y[index]。
      3. result.x[index] = result.x[index] + shift.x 和 result.y[index] = result.y[index] + shift.y。
      4. 如果 result[index] 的“中间”和“锚定块”标志 都为 true,则:
        1. result[index] 的“锚定块”标志 设置为 false。
        2. 如果 index + 1 < count,则设置 result[index + 1] 的“锚定块”标志为 true。
      5. index 设置为 index + 1。
  7. 应用锚定
    1. 对于每个切片 result[i..j] (包括 ij),其中:
      • result[i] 的“锚定块”标志为 true,
      • result[k] 的“锚定块”标志,其中 i < kj 为 false,
      • j = count − 1 或 result[j + 1] 的“锚定 块”标志为 true;
      执行:

      此循环遍历每个锚定块。

      1. a = +∞ 和 b = −∞。
      2. 对于范围内的每个索引 k [i, j],其中 result[k] 的“可寻址”标志 为 true:

        此循环找到锚定块内的 排版字符 的左(上)和 右(下)最边缘。

        1. pos = result[k] 中的位置的 x 坐标, 如果“水平”标志为 true,则为 y 坐标。
        2. advance = 与字符 k 对应的 排版字符 的进展。 [注意:此进展对于 RTL 水平文本将为负。]
        3. 设置 a = min(a, pos, pos + advance)。
        4. 设置 b = max(b, pos, pos + advance)。
      3. 如果 a ≠ +∞,则:

        在这里我们执行文本锚定。

        1. shiftresult[i] 的 x 坐标, 如果“水平”标志为 true,则为 y 坐标。
        2. 根据 text-anchordirection 的值 调整 shift:
          (start, ltr) 或 (end, rtl)
          设置 shift = shifta
          (start, rtl) 或 (end, ltr)
          设置 shift = shiftb
          (middle, ltr) 或 (middle, rtl)
          设置 shift = shift − (a + b) / 2。
        3. 对于范围内的每个索引 k [i, j]:
          1. shift 添加到 result[k] 中位置的 x 坐标, 如果“水平”标志为 true,则添加到 y 坐标。
  8. 路径上的位置
    1. 设置 index = 0。
    2. 将“在路径内”标志设置为 false。
    3. 将“路径后”标志设置为 false。
    4. path_end 为跟随 textPath 元素的字符的偏移量。设置 path_end 为 (0,0)。
    5. index < count 时:
      1. 如果索引 i 处的字符在 textPath 元素内并 对应于 排版字符,则:
        1. 将“在路径内”标志设置为 true。
        2. 如果 result[index] 的“中间”标志为 false,则:

          在这里我们应用 textPath 定位。

          1. path 为与 textPath 元素引用的 基本形状 元素的 等效路径,如果引用无效,则为 空路径。
          2. 如果 side 属性的值为 'right',则反转 path
          3. lengthpath 的长度。
          4. offsettextPath 元素的 startOffset 属性的值,根据引用元素上的任何 pathLength 属性进行调整。
          5. advance = 与字符 k 对应的 排版字符 的前进值。 [注意:对于 RTL 水平文本,这个前进值将为负。]
          6. 让 (x, y) 和 angleresult[index] 中的位置和角度。
          7. mid 为根据“水平”标志的值而定的坐标值:
            true
            midx + advance / 2 + offset
            false
            midy + advance / 2 + offset

            用户代理可以根据 spacing 值为 'auto'method 值为 'stretch' 进行任何必要的附加调整。

          8. 如果 path 不是 封闭子路径 并且 mid < 0 或 mid > length,则将 result[index] 的“隐藏”标志设置为 true。
          9. 如果 path封闭子路径,则根据 text-anchordirection 的值判断该字符的状态:

            这实现了单个 封闭子路径 的特殊换行标准。

            (start, ltr) 或 (end, rtl)
            如果 midoffset < 0 或 midoffset > length, 则将 result[index] 的“隐藏”标志设置为 true。
            (middle, ltr) 或 (middle, rtl)
            如果 midoffset < −length/2 或 midoffset > length/2, 则将 result[index] 的“隐藏”标志设置为 true。
            (start, rtl) 或 (end, ltr)
            如果 midoffset < −lengthmidoffset > 0, 则将 result[index] 的“隐藏”标志设置为 true。

            设置 mid = mid mod length

          10. 如果hidden标志为假:
            1. point为位置,t为沿path前进mid距离的切向单位向量。
            2. 如果“horizontal”标志为
              true
              1. n为指向t + 90°方向的法向单位向量。
              2. o为从字形垂直中心线到对齐点的水平距离。
              3. 然后将result[index]中的位置设置为point - o×t + y×n
              4. r为从正x轴到切线的角度。
              5. result[index]中的角度值设置为angle + r
              false
              1. n为指向t - 90°方向的法向单位向量。
              2. o为从字形水平中心线到对齐点的垂直距离。
              3. 然后将result[index]中的位置设置为point - o×t + x×n
              4. r为从正y轴到切线的角度。
              5. result[index]中的角度值设置为angle + r
        3. 否则,result[index]的“middle”标志为真:
          1. result[index]的位置信息和角度值设置为result[index − 1]中的值。
      2. 如果索引i处的字符不在 textPath元素内并且 对应于排版字符,则:

        这为渲染任何在textPath元素之后出现的字符 设置起始点,直到路径的结束。

        1. 如果“in path”标志为真:
          1. 将“in path”标志设置为假。
          2. 将“after path”标志设置为真。
          3. path_end设置为 textPath 所引用路径的终点 - result[index]的位置。
        2. 如果“after path”为真。
          1. 如果result[index]的anchored chunk为真,将“after path”标志设置为假。
          2. 否则, 设result.x[index] = result.x[index] + path_end.x 并且result.y[index] = result.y[index] + path_end.y
      3. 设置index = index + 1。
  9. 返回result

SVG 2 需求: 与CSS对齐以实现文本布局功能。
解决方案: SVG 2将使用CSS3定义的文本布局(空白、双向等),不特定于SVG。
目的: 促进HTML和SVG中文本布局的共享规范和实现。
负责人: Cameron和Chris(ACTION-3004ACTION-3005

11.6. 预格式化文本

此选项对应于基本的 SVG 1.1 文本布局。

这是默认的文本布局方法,并在没有明确定义的内容区域时使用。它也作为布置路径文本的第一步(稍微修改了一些规则)。在此布局方法中,不进行自动换行或单词换行。通常,文本被呈现为在一个无限宽度和高度的矩形内容区域内的单行文本。可以通过预先计算换行并使用以下方法之一获得多行文本:

以下属性不适用于预格式化文本:text-aligntext-align-lastline-breakword-breakhyphensword-wrap,以及overflow-wrap

11.6.1. 通过 'white-space' 实现多行文本

可以通过使用 white-spaceprepre-line 来创建多行预格式化文本。在这些情况下,换行符或回车符会被保留为强制换行,从而创建一个新的行框。这些 行框 按照 CSS 的规则堆叠。

11.6.2. 重新定位字形

文本按照基本的 CSS 文本布局规则排布之后,可以使用 SVG 特定规则重新定位 排版字符。通过在 xy 属性中提供绝对坐标,或通过强制换行来实现绝对重新定位。绝对重新定位可能会受到 text-anchor 属性的影响。相对重新定位可以通过在 dxdy 属性中提供相对坐标来实现。通过在 rotate 属性中提供值列表,可以对排版字符进行任意旋转。绝对重新定位(包括任何由于 text-anchor 属性的调整)在相对重新定位和旋转之前进行。

11.7. 自动换行文本

当在 text 元素中指定 内容区域 时,文本会自动换行。内容区域 定义了换行文本的最外层容器。可以还定义一个 换行上下文(排除区域的集合)。实际的 换行区域 是通过从 内容区域 中减去 换行上下文 来定义的。换行上下文 还可以通过 shape-padding 属性的值进行缩小。排除区域的有效面积可以通过 shape-margin 属性的值来放大。

内容区域inline-size 属性定义时,第一渲染的 排版字符 对应的 xy 属性定义了初始的 当前文本位置。当 内容区域 位于 形状 内时,初始的 当前文本位置 是在布局形状内的第一行框后确定的。

除了用于确定初始的 当前文本位置 之外,所有的 xy 值在自动换行文本中的 texttspan 元素上都将被忽略。

xy 属性可以为 SVG1.1 渲染器提供一种自然的回退机制用于换行文本。内容制作者可能希望通过将文本分解为带有 xy 属性的 tspan 元素预先布局文本。然后,例如,如果使用了替代字体来渲染文本,SVG2 渲染器将忽略 xy 属性,并使用替代字体的字体度量重新布局文本。而 SVG1.1 渲染器将使用 xy 属性渲染文本,这通常会生成可读文本,即使渲染效果与形状不匹配。 本节中的许多文本换行示例依赖于此机制在未实现文本换行的浏览器中呈现文本。

11.7.1. 关于文本换行的说明

以下示例展示了一些在形状内布置文本时遇到的问题。

11.7.1.1. 第一行定位

给定一个任意形状的换行区域,第一行框可能无法紧贴顶部(或对于垂直文本,紧贴侧面)。在这种情况下,第一行框会被移动直到它适合。

在 CSS 中,形状的边缘被视为一系列 1 像素 × 1 像素的浮动点。

未来的 CSS 规范可能会定义一个行网格,可以用于控制第一行文本的位置,以允许不同换行区域之间的文本对齐。

图像显示了两行文本,第一行为'The',下一行为'first line'。

顶部的行框(小的浅蓝色矩形),由最小的可能文本块组成,被向下移动直到行框适合换行区域(浅蓝色路径)内。注意,行框包括line-height属性的效果,此处设置为 1.25。红色矩形紧紧包裹每个行框中的字形。

这似乎与 SVG 1.2 草案不同,在草案中,换行区域的顶部作为行网格的起点。第一行通过行高向下移动直到适合形状内。

11.7.1.2. 断行

给定一个任意形状的换行区域,单行文本可能会被拆分为多个部分。在这种情况下,为每个部分创建一个行框。同一行文本中的所有行框的高度必须相同(确保所有部分具有相同的基线)。这个高度是通过查看该行文本中的所有字形来计算的。

这一默认行为是在 2016 年悉尼 CSS/SVG 联合工作组会议上达成的共识。

未来的 CSS 规范可能允许控制被拆分为不同部分的形状的哪些部分被填充(例如,仅填充最右侧的部分,仅填充最左侧的部分等)。

显示文本布局在一个'V'形中的图像。

顶部的行被拆分为两个行框(浅蓝色矩形),每个行框中的文本在框内居中(由于 'text-align:center')。

11.8. 路径上的文本

SVG 可以将文本放置在由path元素或基本形状的路径等效项定义的路径上。这是通过将文本包含在具有 href 属性的 textPath 元素中实现的,该属性包含指向 path 元素或基本形状的 URL 参考,或者通过为 path 属性直接指定路径数据的值来实现。

在基本形状上放置文本是 SVG 2 中的新功能。

在基本形状上放置文本是在2015 年悉尼会议上解决的。

直接使用 'd' 属性指定路径是在 SVG 2 中添加的。'd' 属性在2016 年伦敦编辑会议上被重命名为 'path',同时 'd' 被提升为表现属性。

路径上的文本概念上类似于一行经过转换以跟随路径的预格式化文本。除非有指示,否则所有适用于预格式化文本的属性也适用于路径上的文本。

11.8.1. ‘textPath’ 元素

textPath
类别:
图形元素可渲染元素文本内容元素文本内容子元素
内容模型:
任意数量的以下元素或字符数据,顺序不限:aanimateclipPathmarkermaskscriptsetstyletspan
属性:
DOM 接口:
SVG 2 要求: 提供文本路径拉伸方法的更精确解释。
解决方案: 我们将澄清 method="stretch">'textPath' 元素上。
目的: 改善该功能的互操作性。
负责人: Cameron(无行动)

path 属性和 href 属性 指定了 排版字符 渲染的路径。

如果在 textPath 元素上同时指定了这两个属性, 则使用的路径必须遵循以下优先顺序:

  1. path 属性
  2. href 属性
  3. xlink:href 属性

如果 path 属性包含错误, 则必须使用 href 属性。

11.8.2. 属性

startOffset

从路径起点的偏移量,用于初始文本位置,使用用户代理的 沿路径的距离 算法计算, 在将路径转换为 textPath 元素的坐标系统后。

如果给定的是除百分比以外的 <length>, 则 startOffset 表示在当前用户坐标系统中沿路径测量的距离 适用于 textPath 元素。

如果给定的是百分比,则 startOffset 表示沿整个路径的百分比距离。因此, startOffset="0%" 表示路径的起点, startOffset="100%" 表示路径的终点。

允许负值和超过路径长度的值(例如 150%)。

将值限制在 0%-100% 范围内可防止轻松创建文本沿路径移动的效果。

任何 排版字符 的中点不在路径上时将不会被渲染。

Three paths with various values of 'startOffset' showing clipping
		  when glyphs are outside path region.

不同值的 startOffset 属性的渲染。从上到下:默认值,50%,-50%。

底部路径应只在路径的左侧显示“path。” Chrome 和 Safari 都不处理 0% 到 100% 范围外的偏移量。 Chrome bug https://bugs.chromium.org/p/chromium/issues/detail?id=476554

对于由单个 封闭子路径 组成的路径 (包括基本形状的等效路径),排版字符 将沿路径的一次完整环路渲染。文本根据 text-anchor 属性确定的方式对齐到路径上 由 startOffset 属性设置的位置。对于 startend)值,文本将从行的起始(结束)渲染,直到再次到达路径上的初始位置。对于 middle,文本从中点在两个方向渲染,直到路径上到达距离初始位置等距离的点。

Two circular path with different values of
		  'startOffset' showing that all glyphs are rendered.

引用 circle 的路径上文本的渲染, 具有不同的 startOffset 属性的值。左:0。右:75% 或 -25%。 红色圆圈标记路径的起始位置(经过圆的标准分解为路径后)。

Three circular path with different values of
		  'text-anchor' showing how glyphs are rendered.

引用 circle 的路径上文本的渲染, 具有不同值的 text-anchor 属性。 左:'start'。 中间:'middle'。 右:'end'。 红色圆圈标记路径的起始位置(经过圆的标准分解为路径后)。 蓝色方块标记渲染起始位置的参考点(从路径起始位置偏移 startOffset 值为 75%)。灰色箭头显示 排版字符 放置的方向,以及 排版字符 放置停止的点。如果 direction 属性的值为 rtl,箭头将反转。

为基本形状渲染所有字形是在悉尼 (2015) 会议上达成一致(但在会议记录中缺失)。将包装限制为具有单个封闭子路径的路径和一次循环,由 伦敦 (2016) 编辑会议上达成的 'startOffset' 属性影响。

<length-percentage> | <number>
初始值
0
可动画
method

指示文本沿路径渲染的方法。

值为 align 表示 排版字符 应该通过简单的 2×3 矩阵变换进行渲染,以确保 排版字符 不会被拉伸或扭曲。 通常,会对每个要渲染的 排版字符 进行额外的旋转、缩放和平移变换。因此,使用 align 时,如果字体的 排版字符 设计为连接的(例如,草书字体),文本在沿路径渲染时,连接可能不会正确对齐。

值为 stretch 表示 排版字符 的轮廓将被转换为路径,然后所有端点和控制点将被调整到沿路径的垂直向量上,从而拉伸并可能扭曲字形。通过这种方法,连接的 排版字符(例如,草书脚本中的字符)将保持其连接状态。(非垂直直路径段应以这样的方式转换为贝塞尔曲线,使得水平直路径与 排版字符 渲染的路径之间具有(大约)恒定的偏移。)

英文和阿拉伯文文本在弧上的渲染。

不同 method 值的路径上文本渲染: 左:'align'。 右:'stretch'。

align | stretch
初始值
align
可动画
spacing

指示用户代理如何确定要沿路径渲染的 排版字符 之间的间距。

值为 exact 表示 排版字符 应该完全按照 路径上的文本布局规则 渲染。

值为 auto 表示用户代理应使用路径上的文本布局算法来调整 排版字符 之间的间距,以实现视觉上美观的效果。

auto | exact
初始值
exact
可动画
side

确定文本放置在路径的哪一侧(相对于路径方向)。指定值为 right 将有效地反转路径。

两个圆形路径,具有不同的'side'值,显示'left'的字形在圆外渲染,而'right'的字形在圆内渲染。

在一个 circle 上路径渲染文本,具有不同的 side 属性值。左:left。右:right

在 SVG 2 中添加,以允许文本放置在 封闭子路径基本形状(例如矩形、圆形和椭圆形)内或外。

添加'side'是在悉尼(2015)会议上决定的。

left | right
初始值
left
可动画
path

一个路径数据字符串,描述将要渲染的 排版字符 的路径。 空字符串表示该元素没有路径数据。这意味着 textPath 中的文本不会渲染或 对text 元素的 边界框 产生影响。 如果未指定该属性,则使用 href 指定的路径。

路径数据
初始值
(无)
可动画
href

一个URL引用,指向 path 元素 或 基本形状 元素,字形将在其上渲染,如果未提供 path 属性。 如果使用该属性,且<url>是无效引用(例如,没有这样的元素存在,或者引用的元素不是 path 元素或基本形状),则 textPath 元素出错,其全部内容不应由用户代理渲染。

请参阅 URL引用属性已弃用的 XLink 属性 定义的常见处理。

URL [URL]
初始值
见上。
可动画

引用的 path 元素或 基本形状 元素中的路径数据坐标被假定在与当前 text 元素相同的坐标系统中,而不是在 定义 path 元素的坐标系统中。引用的 path 元素或 基本形状 元素上的 transform 属性表示相对于当前用户坐标系统的补充变换,包括对当前用户坐标系统的任何调整,这些调整可能由于当前 text 元素上的 transform 属性而产生。例如,以下 SVG 内容片段:

<svg xmlns="http://www.w3.org/2000/svg">
  <g transform="translate(25,25)">
    <defs>
      <path id="path1" transform="scale(2)" path="M0,10 L40,20 80,10" fill="none" stroke="red">
    </defs>
  </g>
  <text transform="rotate(45)">
    <textPath href="#path1">沿路径的文本</textPath>
  </text>
</svg>
    

应该与以下效果相同:

<svg xmlns="http://www.w3.org/2000/svg">
  <g transform="rotate(45)">
    <defs>
      <path id="path1" transform="scale(2)" path="M0,10 L40,20 80,10" fill="none" stroke="red">
    </defs>
    <text>
      <textPath href="#path1">沿路径的文本</textPath>
    </text>
  </g>
</svg>
    

并等效于:

<svg xmlns="http://www.w3.org/2000/svg">
  <text transform="rotate(45)">
    <textPath path="M0,20 L80,40 160,20"
            >沿路径的文本</textPath>
  </text>
</svg>
    

注意,transform="translate(25,25)"textPath 元素没有影响, 而 transform="rotate(45)" 应用于 text 和将 path 元素作为文本路径引用的形状。进一步注意,transform="scale(2)" 对路径进行缩放(等同于将每个坐标乘以 2 以进行简单的线性路径),但不缩放沿路径放置的文本。

示例 toap01 提供了一个简单的沿路径的文本示例:

<?xml version="1.0" standalone="no"?>
<svg width="12cm" height="3.6cm" viewBox="0 0 1000 300" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <defs>
    <path id="MyPath"
          d="M 100 200
             C 200 100 300   0 400 100
             C 500 200 600 300 700 200
             C 800 100 900 100 900 100">
  </defs>
  <desc>示例 toap01 - 沿路径的简单文本</desc>

  <use href="#MyPath" fill="none" stroke="red" >
  <text font-family="Verdana" font-size="42.5" fill="blue" >
    <textPath href="#MyPath">
      我们上升,然后下降,然后再次上升
    </textPath>
  </text>

  <!-- 使用 'rect' 元素显示视口的轮廓 -->
  <rect x="1" y="1" width="998" height="298"
        fill="none" stroke="blue" stroke-width="2">
</svg>
示例 toap01 — 沿路径的简单文本

示例 toap01

在 SVG 中查看此示例(仅限支持 SVG 的浏览器)

示例 toap02 显示了如何在 tspan 元素中 包含 textPath 元素,以调整样式属性并在渲染特定字形之前调整当前文本位置。单词“up”的第一次出现填充为红色。属性 dy 用于将单词 “up”从基线提升。

xydxdyrotate 属性 只能在 texttspan 元素上指定(但可能影响沿路径的文本中字形的渲染—— 请参阅 沿路径的文本布局规则)。

<?xml version="1.0" standalone="no"?>
<svg width="12cm" height="3.6cm" viewBox="0 0 1000 300" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <defs>
    <path id="MyPath"
          d="M 100 200
             C 200 100 300   0 400 100
             C 500 200 600 300 700 200
             C 800 100 900 100 900 100">
  </defs>
  <desc>示例 toap02 - tspan 在 textPath 中</desc>

  <use href="#MyPath" fill="none" stroke="red" >
  <text font-family="Verdana" font-size="42.5" fill="blue" >
    <textPath href="#MyPath">
      我们向上走,
      <tspan dy="-30" fill="red" >
        上
      </tspan>
      <tspan dy="30">
        ,
      </tspan>
      然后我们向下走,再次向上
    </textPath>
  </text>

  <!-- 使用 'rect' 元素显示视口轮廓 -->
  <rect x="1" y="1" width="998" height="298"
        fill="none" stroke="blue" stroke-width="2">
</svg>
示例 toap02 — tspan 在 textPath 中

示例 toap02

查看此示例为 SVG(仅限支持 SVG 的浏览器)

示例 toap03 演示了 startOffset 属性的使用 在 textPath 元素中以指定文本字符串的起始位置为路径上的特定位置。注意,掉落在路径末端之外的字形不会被渲染 (参见 路径上的文本布局规则)。

<?xml version="1.0" standalone="no"?>
<svg width="12cm" height="3.6cm" viewBox="0 0 1000 300" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <defs>
    <path id="MyPath"
          d="M 100 200
             C 200 100 300   0 400 100
             C 500 200 600 300 700 200
             C 800 100 900 100 900 100">
  </defs>
  <desc>示例 toap03 - 带有 startOffset 属性的路径文本</desc>

  <use href="#MyPath" fill="none" stroke="red" >
  <text font-family="Verdana" font-size="42.5" fill="blue" >
    <textPath href="#MyPath" startOffset="80%">
      我们向上走,然后向下走,再次向上
    </textPath>
  </text>

  <!-- 使用 'rect' 元素显示视口轮廓 -->
  <rect x="1" y="1" width="998" height="298"
        fill="none" stroke="blue" stroke-width="2">
</svg>
示例 toap03 — 带有 startOffset 属性的路径文本

示例 toap03

查看此示例为 SVG(仅限支持 SVG 的浏览器)

11.8.3. 路径上的文本布局规则

从概念上讲,路径上的文本将目标路径拉伸成水平或垂直的直线段。对于水平文本布局流,路径被拉伸成一个假设的水平线段, 使路径的起点映射到线段的左侧。对于垂直文本布局流,路径被拉伸成一个假设的垂直线段, 使路径的起点映射到线段的顶部。标准的 文本布局规则应用于假设的直线段, 然后结果映射回目标路径。垂直和双向 文本布局规则同样适用于路径上的文本。

每个字形在路径上的方向是单独确定的。 对于水平文本布局流,给定字形的默认方向(“向上”方向)沿着从字形附着到路径的交点开始的向量, 该向量指向相对于曲线在交点处角度逆时针90度的方向。 对于垂直文本布局流,给定字形的默认方向沿着从字形附着到路径的交点开始的向量, 该向量指向相对于曲线在交点处角度顺时针180度的方向。

左边,水平文本 'A' 在路径上。右边,垂直文本 '字' 在路径上。

沿路径的默认字形方向。 左边,水平文本。右边:垂直文本。

示例 toap04 将用于 说明路径上文本的特定布局规则, 这些规则补充了针对直线水平或垂直文本的基本 文本布局规则。

<?xml version="1.0" standalone="no"?>
<svg width="12cm" height="3.6cm" viewBox="0 0 1000 300" version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <defs>
    <path id="MyPath"
          d="M 100 125
             C 150 125 250 175 300 175
             C 350 175 450 125 500 125
             C 550 125 650 175 700 175
             C 750 175 850 125 900 125">
  </defs>
  <desc>示例 toap04 - 路径上的文本布局规则</desc>

  <use href="#MyPath" fill="none" stroke="red" >
  <text font-family="Verdana" font-size="60" fill="blue" letter-spacing="2" >
    <textPath href="#MyPath">
      选择羞耻或获得战争
    </textPath>
  </text>

  <!-- 使用 'rect' 元素显示视口轮廓 -->
  <rect x="1" y="1" width="998" height="298"
        fill="none" stroke="blue" stroke-width="2">
</svg>
示例 toap04 — 路径上的文本布局规则

示例 toap04

查看此示例为 SVG(仅限支持 SVG 的浏览器)

下图初步放大了 text 元素中的第一个字形。

显示路径上的文本的图像

上方的小点显示了字形附着到路径的点。字形周围的框显示字形旋转, 使其水平轴与曲线在字形附着到路径的点的切线平行。 框还显示了字形的 字符宽度 (即在使用水平文本布局绘制字形时,当前文本位置水平前进的量)。

下一幅图片进一步放大以展示详细的布局规则。

显示路径上文本的图像

对于路径上的从左到右的水平文本布局(即字形方向垂直于 内联基准方向时),布局规则如下:

可比较的规则适用于路径上的自上而下的垂直文本布局(即,当字形方向与 内联基准方向平行时, 布局规则如下:

在上述计算中,如果路径上的起点或终点超出路径的末端, 则将路径延伸到其末端以外,并以一条与路径末端切线平行的直线延伸, 以便仍然可以计算路径上的中点。

内联基准方向 为水平时, ‘x’ 属性代表路径上的新绝对偏移量, 因此为路径上的起点提供明确的新值。 ‘y’ 属性则被忽略。

内联基准方向 为垂直时, ‘y’ 属性代表路径上的新绝对偏移量, 为路径上的起点提供明确的新值。‘x’ 属性则被忽略。

将所有字符定位在 textPath 中后, 当前文本位置 设置为路径的终点, 并在单一封闭路径的情况下调整 startOffset

路径上的文本显示了 <textPath> 元素后文本的起始点。

没有显式定位信息的 textPath 元素后文本的起始点位于路径的终点(红点)。

选择路径的末端作为起始点是因为它对作者来说更具可预测性(不依赖于字体等)。在 伦敦(2016)编辑会议上决定。 另见 GitHub Issue 84

11.9. 文本渲染顺序

一个 text 元素被渲染为一个或多个块。 每个块(由 文本布局算法 生成) 按文档顺序逐一渲染。每个渲染块由一个或多个字形组成, 它们像单一路径一样被填充和描边。

这意味着块中的所有字形都应该先被填充, 然后一次性描边,或者根据 paint-order 属性的值反过来。

就绘制而言,一个 text 有零个、一个或多个 等效路径,每个块一个。每个等效路径由该块内每个字形的一个子路径组成。

由于 fill-rule 属性不适用于 SVG 文本元素, 因此 等效路径 内子路径的具体顺序无关紧要。

每个子路径的起始位置和路径绕字形形状的方向没有定义。 然而,对于给定的字体和字形,用户代理应该保持一致。

这意味着在文本上应用虚线描边时,不同实现中的虚线模式可能不会位于相同的位置。

11.10. 属性和伪元素

CSS 提供了许多用于文本样式的属性。通常,只有两组属性适用于 SVG: 确定要渲染的字形的属性 (font-family, font-style 等) 和 应用于段落级别的属性 (direction, writing-mode, line-height, letter-spacing 等)。

必须支持的 CSS 属性列表可以在 样式章节中找到。

此外,必须支持 @font-face 规则用于字体选择,并且必须在 text 元素上支持 ::first-line 和 ::first-letter 伪元素。在交互模式下,还必须支持 ::selection 伪元素。

其他影响文本布局和渲染的 CSS 属性也可以被 SVG 用户代理支持; 它们的效果应在整个 SVG 文本布局过程的 CSS 文本布局步骤中考虑。

例如,虽然 SVG 2 不要求支持 text-combine-upright 属性, 但其在 SVG 上下文中的行为应该是显而易见的。

一些 CSS 属性在 SVG 文本元素上不得有任何效果:

此外,::before 和 ::after 生成内容的伪元素不得应用于 SVG 文本元素。

将来的规范可能会引入对 ::before 和 ::after 生成内容伪元素的支持; 作者不应依赖于它们被忽略。

11.10.1. SVG属性

本节介绍了在本规范的其他部分未涉及且特定于SVG的属性。

11.10.1.1. 文本对齐,‘text-anchor’ 属性

text-anchor 属性用于对齐(开始对齐、居中对齐或结束对齐) 预格式化文本或自动换行文本,其 换行区域 是相对于给定点由 inline-size 属性确定的。 它不适用于其他类型的自动换行文本,可参考 text-align。 对于多行文本, 每行的对齐方式独立进行。

text-anchor 属性应用于给定 text 元素中的每个独立的 文本块。每个文本块都有一个初始的当前文本位置, 该位置表示用户坐标系统中的点(根据上下文)由 xy 属性或其他因素决定。每个文本块的最后一个 当前文本位置 是在放置文本块的最后一个字形之后的 当前文本位置。这些位置是在应用text-anchor 属性之前确定的。

名称: text-anchor
值: start | middle | end
初始值: start
适用于: 文本内容元素
是否继承:
百分比: 不适用
媒体: 视觉
计算值: 按指定
是否可动画化:

各个值具有以下含义:

start
渲染的字符对齐,使得渲染文本的起始位置位于初始当前文本位置。 对于属性 direction 值为 "ltr" 的元素(适用于大多数欧洲语言), 文本的左侧在初始文本位置渲染。对于属性 direction 值为 "rtl" 的元素(适用于阿拉伯语和希伯来语), 文本的右侧在初始文本位置渲染。对于垂直主文本方向的元素(常见于亚洲文本), 文本的顶部在初始文本位置渲染。
middle
渲染的字符被移动,使得渲染文本的几何中点(在应用 text-anchor 属性之前从初始和最终 当前文本位置 确定)位于初始当前文本位置。
end
渲染的字符被移动,使得渲染文本的末端(在应用 text-anchor 属性之前的最终 当前文本位置)位于初始当前文本位置。 对于属性 direction 值为 "ltr" 的元素(适用于大多数欧洲语言), 文本的右侧在初始文本位置渲染。对于属性 direction 值为 "rtl" 的元素(适用于阿拉伯语和希伯来语), 文本的左侧在初始文本位置渲染。对于垂直主文本方向的元素(常见于亚洲文本), 文本的底部在初始文本位置渲染。

在多行文本上使用text-anchor 的示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="100" viewBox="0 0 300 100">

  <text x="150" y="30" style="font: 20px sans-serif; white-space: pre-line;
                              text-anchor: middle;">
    This multi-line text is
    anchored to the middle.</text>

</svg>
图片显示了通过 text-anchor 居中对齐的两行文本。

保留的换行符创建了两个文本块,每个文本块独立对齐。

在多行文本上使用text-anchor 的另一个示例。

<svg xmlns="http://www.w3.org/2000/svg"
     width="200" height="150" viewBox="0 0 200 150">
  <path d="m 100,0 0,150" style="fill:none;stroke:#add8e6">
  <text x="100 100 100" y="50 95 140"
	style="font-size: 42px; text-anchor: middle">I❤SVG</text>
</svg>
图片显示了分为'I', '❤', 'SVG'的三行文本。

文本被分为三个文本块(由于 xy 属性中的三个坐标)。每个文本块独立对齐。

11.10.1.2. ‘glyph-orientation-horizontal’ 属性

此属性在SVG 2中已被移除。

11.10.1.3. ‘glyph-orientation-vertical’ 属性

此属性仅适用于垂直文本。在SVG 2中已被废弃,并部分由CSS Writing Modes Level 3中的 text-orientation 属性替代。 以下SVG 1.1值仍必须通过将该属性作为 text-orientation 的简写来支持:

任何其他值都必须视为无效。

11.10.1.4. ‘kerning’ 属性

kerning’ 属性在SVG 2中已被移除。

SVG 1.1 使用 'kerning' 属性来确定是否应使用字体字距调整表来调整字形之间的间距。它还允许一个 <length> 值,该值(如果给定)将添加到字形之间的间距中(作为 letter-spacing 属性的补充)。此属性在SVG 2中被 CSS 的 font-kerning 属性替代,后者仅控制是否启用/禁用字体字距调整表。

Chrome的UseCounter数据显示在2014年使用率为0.01%。参见GitHub问题80。

11.10.2. SVG适配

本节涵盖了其他规范中未涉及的CSS属性,并且这些属性要么针对SVG进行了特定的适配,要么与SVG 1.1有显著的改变。

SVG 2要求: 参考CSS3 Fonts。
决议: SVG 2将依赖于CSS3 Fonts。
目的: 与CSS 2.1和CSS3对Web字体功能保持一致,并提供对字体高级排版功能的访问。
负责人: Chris (ACTION-3123)

11.10.2.1. ‘font-variant’ 属性

CSS字体模块3级改变了 'font-variant' 属性的含义,该属性的功能已被重新定义(并大大扩展)为用于从单个字体中选择字体变体的简写。

SVG 2要求实现所有的font-variant子属性(例如font-variant-ligatures)。

11.10.2.2. ‘line-height’ 属性

SVG使用line-height属性来确定多行文本中添加的行间距(无论是水平还是垂直文本)。此属性不适用于路径文本。

除了此处提供的附加信息外,规范定义line-height属性在CSS 2.1 规范中给出 ([CSS2])。

CSS Inline Module 3级可能会更新'line-height'的定义。

11.10.2.3. ‘writing-mode’ 属性

此属性设置块流方向,即文本行的堆叠方向。因此,它还决定了文本是水平还是垂直的方向。

SVG 2参考CSS Writing Modes Level 3中对 'writing-mode'属性的定义。该规范引入了新的属性值。 SVG 1.1的属性值已废弃,但必须通过将指定值转换为计算值来支持,具体如下:

在SVG 1.0中,此属性还可以被解释为设置内联基方向,这导致了关于它与direction属性之间角色的混淆。SVG 1.1更具体地定义了direction的作用 (例如,direction设置了text-anchor属性的参考点),但仍存在解释空间。由于SVG 1.0和SVG 1.1都不允许多行文本,这增加了混乱。

除了这里提供的附加信息外,规范定义writing-mode属性在CSS Writing Modes 3中给出 ([css-writing-modes-3])。

11.10.2.4. ‘direction’ 属性

此属性指定texttspan元素的内联基方向。 它定义了文本行的开始结束点,供text-anchorinline-size属性使用。 它还可能影响字符的定位方向,特别是当unicode-bidi属性的值为 embedbidi-override时。

direction属性仅适用于相对于内联基方向垂直定向的字形, 这包括通常的水平排列的拉丁或阿拉伯文本,以及相对于从上到下的内联基方向顺时针旋转90度的拉丁或阿拉伯窄格字符。

审阅者,请特别注意确保这与CSS3书写模式一致。

除了这里提供的附加信息外,规范定义direction属性在CSS Writing Modes Level 3 ([css-writing-modes-3])中给出。

在许多情况下,Unicode双向算法 ([UNICODE])会自动产生期望的结果,作者在这种情况下不需要使用这些属性。 对于其他情况,例如使用从右到左的语言时,可以将direction属性添加到最外层的svg元素, 并允许该方向继承到所有文本元素,如下例所示(可用作模板):

<svg xmlns="http://www.w3.org/2000/svg"
     width="100%" height="100%" viewBox="0 0 600 72"
     direction="rtl" xml:lang="fa">

  <title direction="ltr" xml:lang="en">Right-to-left Text</title>
  <desc direction="ltr" xml:lang="en">
    A simple example for using the 'direction' property in documents
    that predominantly use right-to-left languages.
  </desc>

  <text x="300" y="50" text-anchor="middle" font-size="36">داستان SVG 1.1 SE طولا ني است.</text>

</svg>
示例

示例

以SVG查看此示例(仅限支持SVG的浏览器)

下面是另一个示例,其中隐式的双向重排不足以满足需求:

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
     width="100%" height="100%" viewBox="0 0 600 72"
     direction="rtl" xml:lang="he">

  <title direction="ltr" xml:lang="en">Right-to-left Text</title>
  <desc direction="ltr" xml:lang="en">
    An example for using the 'direction' and 'unicode-bidi' properties
    in documents that predominantly use right-to-left languages.
  </desc>

  <text x="300" y="50" text-anchor="middle" font-size="36"> כתובת MAC:&#x200F;
    <tspan direction="ltr" unicode-bidi="embed">00-24-AF-2A-55-FC</tspan>
  </text>

</svg>
示例

示例

以SVG查看此示例(仅限支持SVG的浏览器)

11.10.2.5. ‘dominant-baseline’ 属性

此属性在CSS Line Layout Module 3规范中定义。参见 ‘dominant-baseline’。 [css-inline-3]

SVG 2对该属性的定义进行了修改,具体如下:

SVG 使用dominant-baseline属性的值来对齐字形, 相对于xy属性。 对于text-orientation 值为sidewaysauto值的dominant-baseline值为alphabetic; 但为了向后兼容,字形应使用central值与xy属性对齐。

我们对此旧行为的实际使用场景感兴趣,是否有人仍希望保留旧行为。

11.10.2.6. ‘alignment-baseline’ 属性

此属性在CSS Line Layout Module 3规范中定义。参见 ‘alignment-baseline’。 [css-inline-3]

在新内容中应优先使用vertical-align属性的简写形式。

SVG 2对该属性的定义也做了一些修改,特别是:移除了'auto'、'before-edge'和'after-edge'值。 为了向后兼容,'text-before-edge' 应映射为 'text-top',而 'text-after-edge' 应映射为 'text-bottom'。 'text-before-edge' 和 'text-after-edge' 不应与vertical-align属性一起使用。

11.10.2.7. ‘baseline-shift’ 属性

此属性在CSS Line Layout Module 3规范中定义。参见 'baseline-shift'。 [css-inline-3]

在新内容中应优先使用vertical-align属性的简写形式。

SVG 1.1 中的初始值 'baseline' 已被 SVG 2 移除。用户代理可以将此值视为 '0' 来支持旧版 SVG 内容。

'baseline' 值被移除是因为'vertical-align'已被转换为 'alignment-baseline' 和 'baseline-shift' 的简写形式, 且'baseline'也是'alignment-baseline'的一个值,与 '0' 的长度值重复。

SVG 2 要求: 与CSS对基线对齐功能的保持一致。
解决方案: SVG 2将弃用‘baseline-shift’并使用‘vertical-align’代替。
目的: 与CSS保持一致。
负责人: Cameron (ACTION-3281)

'baseline-shift' 对齐下标和上标很重要(Inkscape依赖此功能)。 它仍在CSS Inline Layout Module Level 3中保留。 'vertical-align' 是一个用于同时更改多个属性的简写,包括'baseline-shift'。

11.10.2.8. ‘letter-spacing’ 属性

SVG 2 删除了letter-spacing属性中的百分比值。

除了特别说明,参见CSS Text Level 3中对letter-spacing的定义。([css-text-3])。

基于SVG视口的百分比值被认为不太实用。这使'letter-spacing'的定义与CSS保持一致。

11.10.2.9. ‘word-spacing’ 属性

SVG 2 改变了word-spacing属性中百分比值的含义。 在 SVG 1.1 中,百分比定义了相对于SVG视口大小的额外间距。 在 SVG 2 中,遵循 CSS Text Level 3,百分比定义了相对于受影响字符宽度的额外间距。

除了特别说明,参见CSS Text Level 3中对word-spacing的定义。([css-text-3])。

基于SVG视口的百分比值被认为不太实用。这使'word-spacing'的定义与CSS保持一致。

11.10.2.10. ‘text-overflow’ 属性

SVG 2 要求: 添加 text-overflow 功能。
解决方案: 我们将在 SVG 2 中添加 text-overflow。
目的: 与 CSS 保持一致,允许指示文本未全部显示。
负责人: Erik (ACTION-3003)

SVG 2 新增功能。 添加此功能是为了让用户代理能够以更有用的方式处理超出预定义换行区域的文本字符串。此功能使得SVG文本处理与HTML/CSS对齐。

参见 CSS3 UI 规范中关于'text-overflow'的定义。 [css-ui-3]

SVG 使用text-overflow属性来控制当文本内容块元素中的文本溢出行框时的渲染方式, 例如,当white-space属性的值为nowrap时。此属性不适用于预格式化文本或路径文本。

在SVG中,text-overflow在有有效的换行区域时生效, 无论overflow属性的计算值在文本内容块元素上如何。

如果text-overflow属性的值为ellipsis, 那么如果要呈现的文本溢出了换行区域,则呈现省略号,使其适合给定区域。为了渲染的目的,省略号将被视为替换了插入点的字符。

如果text-overflow属性的值为clip, 则任何超出换行区域的文本都将被剪裁。字符可能会部分呈现。

对于text-overflow属性的任何其他值,都将被视为未指定。

注意,text-overflow的效果是纯视觉的,省略号本身不会成为DOM的一部分。 对于所有DOM方法,text-overflow的应用效果不会反映在DOM中, 换行区域对文本的约束也不会在DOM中体现。

以下示例展示了如何使用text-overflow。 第一行显示了正常渲染的文本(由于white-space的值为 pre,并且overflow值为 visible,因此文本溢出并显示出来)。 中间行显示使用text-overflow值为 clip的文本, 底部行显示使用text-overflow值为 ellipsis的文本。

<svg xmlns="http://www.w3.org/2000/svg"
     width="300" height="150" viewBox="0 0 300 150">
  <style>
    text { font: 25px sans-serif; white-space: pre; }
    path { fill: none; stroke: #add8e6; }
  </style>

  <path d="m  50,0 0,150">
  <path d="m 200,0 0,150">

  <text x="50" y="35"  inline-size="100" style="overflow:visible">SVG is awesome</text>
  <text x="50" y="85"  inline-size="100" style="text-overflow:clip">SVG is awesome</text>
  <text x="50" y="135" inline-size="100" style="text-overflow:ellipsis">SVG is awesome</text>

</svg>
显示 text-overflow 属性使用效果的图像。

text-overflow 属性用于文本元素,底部行应用了省略号。

有人认为此属性用处不大。如果它能与揭示隐藏文本的机制(例如在悬停省略号时显示工具提示)结合使用,可能会更有用。 text-overflow 属性仅处理超出行尾的文本,而不处理超出换行区域末端的文本。

11.10.3. 空白处理

SVG 2 新增。添加了 white-space 属性, 提供了一种更有用的方式来控制空白处理。使得SVG与HTML/CSS文本处理保持一致。 xml:space 在新内容中已被弃用,但为了向后兼容而保留。

11.10.3.1. SVG 2 首选的空白处理,‘white-space’ 属性

在SVG 2中,空白的渲染由white-space属性控制。该属性指定了以下两点:

各个值及其含义在CSS Text Module Level 3中定义。 [css-text-3]

使用 white-space 属性值 pre-line 的示例。

<svg xmlns="http://www.w3.org/2000/svg">
     width="200" height="200" viewBox="0 0 200 200">

     <text x="150" y="30" style="font: 20px IPAMincho; writing-mode: vertical-rl;
	                         white-space: pre-line;">
       千利奴流乎和加
       餘多連曽津祢那
       良牟有為能於久
       耶万計不己衣天
       阿佐伎喩女美之
       恵比毛勢須</text>
</svg>
展示每七个汉字后的传统换行的日文诗歌。

多行垂直文本的换行示例。文本摘自日文诗歌Iroha,每行按照传统的换行方式分段。

11.10.3.2. 传统空白处理,‘xml:space’ 属性

为了兼容性,SVG 2 还支持 XML 属性 xml:space,用于指定 在给定的 text 元素的字符数据内如何处理空白字符。 新内容不应使用 xml:space,而应使用 white-space 属性。

本节应简化,以限制对 xml:space 的讨论,并使用 white-space 属性在用户代理样式表中定义它。 CSS Text 4 规范中的 preserve-spaces 值意在匹配 xml:space=preserve 的行为。 (fantasai 同意white-space 添加一个合适的值,以匹配 SVG 1.1 中的 xml:space="preserve" 的奇怪行为。)

请注意,任何 text 元素的子元素也可能 有一个 xml:space 属性,该属性将应用于该 子元素的文本内容。SVG 用户代理有与该属性相关的特殊处理规则,如下所述。这些行为是在 XML 解析 [XML] 和 DOM 构建之后发生的。

xml:space 是可继承的属性,可以有以下两种值:

'default'
xml:space 的初始/默认值。)当 xml:space="default" 时,SVG 用户代理将使用原始字符数据内容的副本执行以下操作。首先,它将删除所有换行符。 然后,它将所有制表符转换为空格符。接着,它会删除所有前导和尾随空格。最后,所有连续的空格字符将被合并为一个空格。
'preserve'
xml:space="preserve" 时,SVG 用户代理将使用原始字符数据内容的副本执行以下操作。 它将所有换行符和制表符转换为空格符。然后,它会绘制所有空格字符,包括前导、尾随和多个连续的空格字符。因此, 当使用 xml:space="preserve" 绘制时,字符串 "a   b"(“a”和“b”之间有三个空格) 将产生比 "a b"(“a”和“b”之间有一个空格)更大的间隔。

以下示例说明了使用 xml:space="default" 时行缩进的重要性。以下片段展示了两对相似的 text 元素,两个 text 元素都使用了 xml:space="default"。 对于这些示例,任何行末都没有额外的空格(即,换行发生在最后一个可见字符之后)。

[01]  <text xml:space='default'>
[02]    WS example
[03]    indented lines
[04]  </text>
[05]  <text xml:space='preserve'>WS example indented lines</text>
[06]
[07]  <text xml:space='default'>
[08]WS example
[09]non-indented lines
[10]  </text>
[11]  <text xml:space='preserve'>WS examplenon-indented lines</text>
  

上面第一对 text 元素展示了 缩进字符数据的效果。第一个 text 元素中的 xml:space="default" 属性指示用户代理:

上面第二对 text 元素展示了 非缩进字符数据的效果。第三个 text 元素中的 xml:space="default" 属性指示用户代理:

请注意,XML 解析器需要将换行指示符的标准表示形式(例如,字面上的两个字符序列 "U+000D U+000A" 或独立的字面 U+000D 或 U+000A)转换为单个字符 U+000A, 然后再将字符数据传递给应用程序。因此,SVG 中的每个换行符都将由单个字符 U+000A 表示,无论在原始资源中使用了何种换行符表示形式。 (请参阅 XML 换行处理。)

SVG 语言或 SVG DOM 中基于字符位置号的任何特性,如 xydxdyrotate 属性,都是基于应用此处描述的空白处理规则后的位置。特别地, 如果 xml:space="default",通常情况下,空白字符会在处理过程中被删除。字符位置号在应用白空处理规则后索引到文本字符串中。

请注意,空白字符对应的字形应仅显示为可见但空白的空间,即使字形本身是非空白的。 请参阅 不支持字符的显示 [UNICODE]。

xml:space 属性为:

    可动画:否。

11.10.3.3. 重复空白指令

较旧的 SVG 1.1 内容会使用 xml:space。新的内容以及正在重新处理的较旧内容会使用 white-space 并移除任何现有的 xml:space。然而, 用户代理可能会遇到在同一元素上同时使用这两种方法的内容。如果在任何元素上设置了 white-space 属性,那么 xml:space 的值将被忽略。

11.11. 文本装饰

SVG 中的文本可以通过下划线、上划线和/或删除线进行 装饰。装饰的位置和样式分别由 text-decoration-linetext-decoration-style 属性决定, 或通过 text-decoration 速记属性来指定,如 线装饰部分在 CSS 文本装饰模块 3 级 [(css-text-decor-3)] 规范中定义的那样。装饰的填充和描边由 text-decoration-filltext-decoration-stroke 属性指定。 如果通过 text-decoration-color 属性或 text-decoration 速记属性指定了颜色值, 并且没有指定 text-decoration-fill 属性, 则它将被解释为仿佛已通过该颜色值指定了 text-decoration-fill 属性。

如果没有明确指定文本装饰的填充或描边(通过 text-decorationtext-decoration-colortext-decoration-filltext-decoration-stroke), 那么它们将由声明文本装饰的地方的填充和描边属性决定(见下方示例)。

text-decoration-linetext-decoration-style 属性是 SVG 2 中的新属性。 SVG 1.1/CSS 2.1 的 text-decoration 属性以向后兼容的方式 转化为这些属性的速记。text-decoration-filltext-decoration-stroke 是 SVG 特有的属性, 可能会添加到未来的 CSS 文本装饰规范中。

文本和装饰的绘制顺序由 文本装饰的绘制顺序部分在 CSS 文本装饰模块 3 级中定义。 文本装饰本身的绘制顺序(填充/描边)由声明文本装饰的地方的 paint-order 属性的值决定。

示例 textdecoration01 提供了 text-decoration 的示例。 第一行文本没有指定 text-decoration 的值,因此使用了初始值 text-decoration:none。 第二行显示了 text-decoration:line-through。 第三行显示了 text-decoration:underline。 第四行说明了装饰使用与声明 text-decoration 的元素相同的填充和描边属性的规则。 由于 text-decoration 是在 text 元素上声明的, 所以 text 元素内的所有文本 都将使用该元素的填充和描边属性(即蓝色填充,红色描边)绘制下划线, 即使各个词语具有不同的填充和描边属性。 然而,单词 "different" 明确指定了 text-decoration 的值; 因此,它的下划线使用了包围单词 "different" 的 tspan 元素的填充和描边属性 (即黄色填充,深绿色描边):

<?xml version="1.0" standalone="no"?>
<svg width="12cm" height="4cm" viewBox="0 0 1200 400"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <desc>Example textdecoration01 - behavior of 'text-decoration' property</desc>
  <rect x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2">
  <g font-size="60" fill="blue" stroke="red" stroke-width="1" >
    <text x="100" y="75">Normal text</text>
    <text x="100" y="165" text-decoration="line-through" >Text with line-through</text>
    <text x="100" y="255" text-decoration="underline" >Underlined text</text>
    <text x="100" y="345" text-decoration="underline" >
      <tspan>One </tspan>
      <tspan fill="yellow" stroke="purple" >word </tspan>
      <tspan fill="yellow" stroke="black" >has </tspan>
      <tspan fill="yellow" stroke="darkgreen" text-decoration="underline" >different </tspan>
      <tspan fill="yellow" stroke="blue" >underlining</tspan>
    </text>
  </g>
</svg>
Example textdecoration01 — behavior of 'text-decoration' property

示例 textdecoration01

查看此示例为 SVG(仅限支持 SVG 的浏览器)

11.11.1. ‘text-decoration-fill’ 与 ‘text-decoration-stroke’ 属性

CSS 工作组在 2014 年 TPAC CSS/SVG 联合会议上同意了 SVG 规范中的 'text-decoration-fill' 和 'text-decoration-stroke' 属性。 他们在 2015 年悉尼的联合会议上再次支持使用这些属性。他们表示有意在扩展 CSS 文本装饰功能时,将这些属性与 'fill' 和 'stroke' 一同应用于文本。

名称: text-decoration-fill
值: <paint>
初始值: 详见文本。
适用对象: 文本内容元素
是否继承: 详见文本。
百分比: N/A
媒体: 视觉
计算值: 按指定计算,但将 <color> 值计算出来,并将 <url> 值转换为绝对路径。
是否可动画化:
名称: text-decoration-stroke
值: <paint>
初始值: 详见文本。
适用对象: 文本内容元素
是否继承: 详见文本。
百分比: N/A
媒体: 视觉
计算值: 按指定计算,但将 <color> 值计算出来,并将 <url> 值转换为绝对路径。
是否可动画化:

11.12. 文本选择和剪贴板操作

在具备文本选择功能(例如,配备了鼠标等指针设备的系统)并支持系统剪贴板复制/粘贴操作的系统上,合规的 SVG 浏览器需要支持:

文本选择操作在满足以下条件时开始:

当文本选择操作进行时(例如,用户继续按住给定的鼠标按钮),与其他图形元素相关的所有事件将被忽略(即,文本选择操作是模态的),SVG 用户代理应动态指示哪些字符被选中,方法是应用 ::selection 伪类的样式。随着文本选择过程中指针的移动,文本选择操作的结束字形是在同一 text 元素中,字形单元最接近指针的字形。所有在 text 元素中位置位于选择开始和选择结束之间的字符都应被高亮显示,不论其在画布上的位置或是否有其他图形元素覆盖了选择结束点。

一旦文本选择操作结束(例如,用户释放给定的鼠标按钮),所选文本将保持高亮,直到发生取消文本选择的事件,例如指针设备激活事件(例如,按下鼠标按钮)。

文本选择实现说明中提供了确定文本选择操作期间应高亮显示哪些字符的详细规则。

对于具有系统剪贴板的系统,SVG 用户代理需要提供用户界面以启动将当前选定文本复制到系统剪贴板的操作。将选定的文本字符串以纯文本格式发布到系统的适当剪贴板格式是足够的,但如果 SVG 用户代理还发布包含给定文本字符串的各种字体属性的富文本替代内容,则更为理想。

对于双向文本,用户代理必须支持按逻辑顺序进行文本选择,这将导致由于字符的双向重排序而产生不连续的字形高亮显示。用户代理可以提供另一种选择双向文本的能力,即按视觉渲染顺序(即,在应用双向文本布局算法之后),这将导致所选字符数据在逻辑上不连续。在这种情况下,如果用户请求将双向文本复制到剪贴板,则用户代理必须进行适当的调整,以仅复制视觉上选定的字符到剪贴板。

SVG 作者和SVG 生成器应该按顺序排列其文本字符串,以便在 SVG 查看应用程序(如 Web 浏览器)中实现正确的文本选择;换句话说,文本的 DOM 顺序应与文本的自然阅读顺序相匹配。

11.12.1. 文本选择实现说明

以下实现说明描述了在文本选择操作过程中决定选中哪些字符的算法。

在文本选择操作进行时(例如,当用户点击并拖动鼠标以标识选择区域),用户代理会确定一个开始选择位置和一个结束选择位置,每个位置表示文本字符串中两个字符之间的位置。在确定了开始选择位置和结束选择位置后,用户代理选择适当的字符,最终的文本选择结果由以下两种情况之一组成:

在配有指针设备的系统上,为了确定开始选择位置,SVG 用户代理基于事件触发时指针当前的位置(例如,鼠标按下事件),确定哪个字符之间的边界是最合适的目标(例如,距离最近的)。然后用户代理跟踪选择操作的完成过程(例如,鼠标拖动,最终伴随鼠标松开)。在选择操作结束时,用户代理确定哪个字符之间的边界是最合适的目标(例如,距离最近的),作为结束选择位置

如果由于双向性没有发生字符重排序,则选择包括从开始选择位置结束选择位置之间的所有字符。例如,如果一个 text 元素包含字符串“abcdef”,且开始选择位置和结束选择位置分别为 0 和 3(假设“a”的左侧为位置 0),那么选择将包括“abc”。

当用户代理实现双向文本的选择时,如果选择从(或结束于)在逻辑顺序上不连续的字符之间发生,则可能有多种潜在的字符组合可被视为选择的一部分。选择算法应选择最接近文本字符串的视觉呈现顺序的选项。

当多个字符不可分割地映射到一个或多个字形集时,用户代理可以禁止在字形集的中间开始选择,或者尝试将字形集所占的区域分配给与该字形对应的字符。

对于支持指针设备(例如鼠标)的系统,用户代理需要提供一种机制,即使当给定的文本有相关的事件处理程序或链接时,用户也可以选择文本,这可能由于事件处理优先级规则而阻止文本选择(参见 指针事件)。一种实现选项是:对于支持指针设备(例如鼠标)的平台,用户代理可以为字符单元周围提供一个小的额外区域,该区域用于启动文本选择操作,但不会触发事件处理程序或链接。

11.13. DOM 接口

SVG 2 要求: 拥有将 text 元素转换为轮廓路径数据的 DOM 方法。
决议: 我们将添加一个 DOM 方法,用于将 ‘text’ 元素转换为轮廓路径数据,可能将该功能移至 FXTF。
目的: 允许将文本作为路径进行操作。
负责人: Cameron (ACTION-3076)
状态: 未来愿望清单

11.13.1. 接口 SVGTextContentElement

SVGTextContentElement 接口由支持渲染子文本内容的元素实现。

对于此接口上指代字符索引或字符数量的方法,这些引用应解释为 UTF-16 代码单元的索引或 UTF-16 代码单元的数量。这是为了与 DOM Level 2 Core 保持一致,其中 CharacterData 接口上的方法使用 UTF-16 代码单元作为字符数据中的索引和计数。因此,例如,如果 text 元素的文本内容是单个非 BMP 字符,如 U+10000,那么在该元素上调用 getNumberOfChars 将返回 2,因为使用了两个 UTF-16 代码单元(代理对)来表示该字符。

[Exposed=Window]
interface SVGTextContentElement : SVGGraphicsElement {

  // lengthAdjust Types
  const unsigned short LENGTHADJUST_UNKNOWN = 0;
  const unsigned short LENGTHADJUST_SPACING = 1;
  const unsigned short LENGTHADJUST_SPACINGANDGLYPHS = 2;

  [SameObject] readonly attribute SVGAnimatedLength textLength;
  [SameObject] readonly attribute SVGAnimatedEnumeration lengthAdjust;

  long getNumberOfChars();
  float getComputedTextLength();
  float getSubStringLength(unsigned long charnum, unsigned long nchars);
  DOMPoint getStartPositionOfChar(unsigned long charnum);
  DOMPoint getEndPositionOfChar(unsigned long charnum);
  DOMRect getExtentOfChar(unsigned long charnum);
  float getRotationOfChar(unsigned long charnum);
  long getCharNumAtPosition(optional DOMPointInit point);
  void selectSubString(unsigned long charnum, unsigned long nchars);
};

SVGTextContentElement 上定义的数字长度调整类型常量用于表示 lengthAdjust 属性可以取的关键字值。其含义如下:

常量 含义
LENGTHADJUST_SPACING spacing 关键字。
LENGTHADJUST_SPACINGANDGLYPHS spacingAndGlyphs 关键字。
LENGTHADJUST_UNKNOWN 其他值。

textLength IDL 属性 反映textLength 内容属性。

textLength 内容属性的初始值被定义为等于用户代理计算的元素长度。换句话说,当没有设置该内容属性时,IDL 属性会初始化为等于在同一元素上调用 getComputedTextLength 的返回值,结果以用户单位表示。

lengthAdjust IDL 属性 反映lengthAdjust 内容属性。lengthAdjust 的数字类型值如上表所述。

getNumberOfChars 方法返回当前元素内可渲染的所有 可寻址字符 总数,无论这些字符是否会被实际渲染。当调用 getNumberOfChars() 时,执行以下步骤:

  1. node 设置为调用此方法的元素或节点。
  2. 如果 node 是 DOM 文本节点,返回 node 文本内容的长度,并根据其父元素的 white-space 属性值进行空白字符规范化。
  3. 如果 nodeElement
    • 如果该元素 未被渲染(例如,display 属性的使用值为 none),则返回 0;
    • 否则,将 count 设置为 0,并对 node 的每个子元素:
      • 递归调用此算法,并将返回值加到 count 中。
      返回 count
  4. 对于所有其他节点类型(例如 DOM 注释),返回 0。

getComputedTextLength 方法用于计算元素中文本的“长度”。当调用 getComputedTextLength() 时,执行以下步骤:

  1. count 设置为调用 getNumberOfChars 方法时返回的值。
  2. length 设置为调用 getSubStringLength 方法,并传递 0 和 count 作为参数时返回的值。
  3. 返回 length

getSubStringLength 方法用于计算元素中子字符串的格式化文本前进距离。当调用 getSubStringLength(charnum, nchars) 时,执行以下步骤:

  1. 为此元素 DOM 中的每个 可寻址字符 分配一个索引,第一个字符的索引为 0。
  2. 如果 charnum 大于分配给字符的最高索引或 nchars 为负数,则 抛出 IndexSizeError
  3. length 设置为以用户单位表示的长度,初始值为 0。
  4. 对于此元素 DOM 中索引满足 charnum ≤ index < (charnum + nchars) 的每个 可寻址字符
    1. 如果字符对应于 排版字符单元,并且它是文档顺序中第一个对应于该 排版字符单元 的字符,则:
      1. 将该 排版字符单元 的前进量添加到 length 中,并根据生效的任何字体字距调整。
      2. 如果 letter-spacingword-spacing 属性在该 排版字符单元 之后贡献了空格,则将该空格添加到 length 中。

      这意味着,例如,如果有一个部分包含在子字符串中的连字,则 排版字符单元 的前进量及其后的 letter-spacingword-spacing 空格将分配给第一个字符的文本长度。

  5. 返回 length

以前的 SVG 版本要求该方法和 getComputedTextLength 还包括子元素上的 dxdy 引起的行内方向上的位置调整, 以使返回值等于用户代理计算的 textLength 值。 然而,这一要求规格不清晰,实施不佳,且效益存疑,因此已简化以匹配实现。

对文本长度方法的更改在 2015年8月巴黎面对面会议 中得到解决。

查找字符的排版字符,在元素 element 的索引 index 处,执行以下步骤:

  1. 为此元素 DOM 中的每个 可寻址字符 分配一个索引,第一个字符的索引为 0。
  2. last 设为分配给字符的最高索引。
  3. charnum < last 且索引 charnum 处的字符不对应于 排版字符 时:
    1. charnum 增加 1。
  4. 如果 charnum 大于分配给字符的最高索引,则返回 null。
  5. 否则,返回与 charnum 对应的 排版字符

getStartPositionOfChar 方法用于在文本布局完成后获取 排版字符 的起始位置。当调用 getStartPositionOfChar(charnum) 时,执行以下步骤:

  1. cluster 成为在当前元素中 查找字符的排版字符 的结果。
  2. 如果 cluster 为 null,则 抛出 IndexSizeError
  3. p 为与索引 charnum 处字符对应的 排版字符对齐点,以当前元素的坐标系表示。
  4. 返回一个新创建的、独立的 DOMPoint 对象,表示点 p

getEndPositionOfChar 方法用于在文本布局完成后获取 排版字符 的结束位置。当调用 getEndPositionOfChar(charnum) 时,执行以下步骤:

  1. cluster 成为在当前元素中 查找字符的排版字符 的结果。
  2. 如果 cluster 为 null,则 抛出 IndexSizeError
  3. pcluster对齐点,以当前元素的坐标系表示。
  4. direction 为一个单位向量,表示 cluster 的前进方向。该方向考虑了使用的书写模式、字符的方向、text-orientationglyph-orientation-horizontalglyph-orientation-vertical 属性、应用于 cluster 的任何 rotate 值,以及由于 textPath 应用的任何旋转。
  5. advancecluster 的前进量。
  6. p 更新为 p + advance · direction
  7. 返回一个新创建的、独立的 DOMPoint 对象,表示点 p

getExtentOfChar 方法用于计算与给定 排版字符 对应的字形单元的紧密边界框。当调用 getExtentOfChar(charnum) 时,执行以下步骤:

  1. cluster 成为在当前元素中 查找字符的排版字符 的结果。
  2. 如果 cluster 为 null,则 抛出 IndexSizeError
  3. quad 为当前元素坐标系中可能旋转的矩形,即 cluster 的字形单元。
  4. rect 为在当前元素的坐标系中围绕 quad 的最紧密的边界框。
  5. 返回一个新创建的 DOMRect 对象,表示矩形 rect

getRotationOfChar 方法用于获取 排版字符 的旋转角度。当调用 getRotationOfChar(charnum) 时,执行以下步骤:

  1. cluster 成为在当前元素中 查找字符的排版字符 的结果。
  2. 如果 cluster 为 null,则 抛出 IndexSizeError
  3. direction 为表示 cluster 前进方向的角度(单位为度)。此方向考虑了使用的书写模式、字符方向、text-orientationglyph-orientation-horizontalglyph-orientation-vertical 属性、应用于 clusterrotate 值,以及由于 textPath 旋转的效果。
  4. direction 为表示 cluster 前进方向的角度(以度为单位)。此方向考虑了所使用的书写模式、字符的方向、text-orientationglyph-orientation-horizontalglyph-orientation-vertical 属性,应用于 cluster 的任何 rotate 值,以及由于 textPath 引发的任何旋转。
  5. 返回 direction

getCharNumAtPosition 方法用于查找在坐标系中导致呈现文本字形的字符。由于字符与字形之间的关系不是一对一的,因此只返回相关的第一个 排版字符 的字符。当调用 getCharNumAtPosition(point) 时,执行以下步骤:

  1. 为此元素内的每个字符分配一个索引,文档中的第一个字符的索引为 0。
  2. last 为分配给字符的最高索引。
  3. charnum 为 0。
  4. result 为 -1。
  5. charnum 小于 last 时:
    1. 如果索引为 charnum 的字符对应于 排版字符,且它是文档顺序中第一个对应于该 排版字符 的字符,并且 point 位于此元素的坐标系中该 排版字符 的字形单元内,则将 result 设置为 charnum
  6. 返回 result

selectSubString 方法用于在元素内选择文本。当调用 selectSubString(charnum, nchars) 时,执行以下步骤:

选择该元素中的一个子字符串,从字符索引 charnum 开始,并向前扩展 nchars 个字符。调用此方法时必须执行以下步骤:

  1. 设定 node 为此文本内容元素。
  2. 设定 count 为此文本内容元素中的字符数量。
  3. 设定 end = charnum + nchars
  4. 如果 charnumcountendcount,则 抛出 IndexSizeError 异常。
  5. 从文档的 选择中移除所有 range。[DOM][EDITING]
  6. 选择方向设置为向前。
  7. 将新的 range 添加到 选择中,其 起点nodecharnum 组成的边界点元组,终点nodeend 组成的边界点元组。

忽略参数检查和异常抛出,这等同于执行以下操作:

var selection = document.getSelection();
selection.removeAllRanges();
var range = new Range();
range.setStart(textContentElement, charnum);
range.setEnd(textContentElement, charnum + nchars);
selection.addRange(range);

此方法已被弃用,因为它重复了 Selection API 的功能。

11.13.2. 接口 SVGTextPositioningElement

SVGTextPositioningElement 接口由支持定位单个文本字形属性的元素实现。它由 SVGTextElementSVGTSpanElement 继承。

[Exposed=Window]
    interface SVGTextPositioningElement : SVGTextContentElement {
      [SameObject] readonly attribute SVGAnimatedLengthList x;
      [SameObject] readonly attribute SVGAnimatedLengthList y;
      [SameObject] readonly attribute SVGAnimatedLengthList dx;
      [SameObject] readonly attribute SVGAnimatedLengthList dy;
      [SameObject] readonly attribute SVGAnimatedNumberList rotate;
    };

xydxdyrotate IDL 属性 反映相应的内容属性。

11.13.3. 接口 SVGTextElement

SVGTextElement 对象表示 DOM 中的 text 元素。

[Exposed=Window]
    interface SVGTextElement : SVGTextPositioningElement {
    };

11.13.4. 接口 SVGTSpanElement

SVGTSpanElement 对象表示 DOM 中的 tspan 元素。

[Exposed=Window]
    interface SVGTSpanElement : SVGTextPositioningElement {
    };

11.13.5. 接口 SVGTextPathElement

SVGTextPathElement 对象表示 DOM 中的 textPath 元素。

[Exposed=Window]
    interface SVGTextPathElement : SVGTextContentElement {
    
      // textPath 方法类型
      const unsigned short TEXTPATH_METHODTYPE_UNKNOWN = 0;
      const unsigned short TEXTPATH_METHODTYPE_ALIGN = 1;
      const unsigned short TEXTPATH_METHODTYPE_STRETCH = 2;
    
      // textPath 间距类型
      const unsigned short TEXTPATH_SPACINGTYPE_UNKNOWN = 0;
      const unsigned short TEXTPATH_SPACINGTYPE_AUTO = 1;
      const unsigned short TEXTPATH_SPACINGTYPE_EXACT = 2;
    
      [SameObject] readonly attribute SVGAnimatedLength startOffset;
      [SameObject] readonly attribute SVGAnimatedEnumeration method;
      [SameObject] readonly attribute SVGAnimatedEnumeration spacing;
    };
    
    SVGTextPathElement 包含 SVGURIReference;

SVGTextPathElement 定义的数值方法类型常量用于表示 method 属性可以采用的关键字值。它们的含义如下:

常量 含义
TEXTPATH_METHODTYPE_ALIGN align 关键字。
TEXTPATH_METHODTYPE_STRETCH stretch 关键字。
TEXTPATH_METHODTYPE_UNKNOWN 其他值。

SVGTextPathElement 定义的数值间距类型常量用于表示 spacing 属性可以采用的关键字值。它们的含义如下:

常量 含义
TEXTPATH_SPACINGTYPE_AUTO auto 关键字。
TEXTPATH_SPACINGTYPE_EXACT exact 关键字。
TEXTPATH_SPACINGTYPE_UNKNOWN 其他值。

startOffset IDL 属性 反映 startOffset 内容属性。

method IDL 属性 反映 method 内容属性。数值类型值 如上文所述。

spacing IDL 属性 反映 spacing 内容属性。数值类型值 如上文所述。