第11章: テキスト

11.1. はじめに

SVG文書断片として描画されるテキストは、text要素を使って指定されます。 text要素内のテキストは、以下のように描画できます:

テキストレイアウトの章でテキストレイアウトの概要を説明します。 その後、コンテンツ領域アルゴリズム を使ったコンテンツ領域内テキストのレイアウト方法を解説します。 整形済み自動折返しパス上といった特殊なレイアウト規則については、それぞれの章で扱います。

SVG 1.1におけるテキストレイアウトの規則は主にSVG 1.1仕様で定義されています。 規則の多くはCSSに見られるものと類似しています。 SVG 2ではCSSへの依存がより明確となっています。実際のレイアウト結果は同じです。 CSS仕様に直接依存する変更により、SVG仕様が簡素化されるとともに、レンダリングエージェントがHTMLとSVGの両方のテキストを同じコードで描画できることが明示的になります。 特に、SVG 2の自動折返しテキストはCSSテキストレイアウトに基づいています。

SVGのtext要素は他のグラフィックス要素同様に描画されます。 したがって、座標系変換描画クリッピングマスキングの機能は text要素にも 図形パス長方形など)と同様に適用されます。

SVGテキストは高度な組版機能もサポートしています:

SVGテキストは、国際的なテキスト処理のニーズにも対応しています:

ユーザーの言語選好に応じて異なる文字列を切り替えることで、多言語SVGコンテンツが可能になります。

描画する文字は、text要素内に 文字データ([xml]第2.4節)として記述されます。結果として:

アクセシビリティの観点から、文書内のテキストには、機能を示す適切なセマンティックマークアップを付与することが推奨されます。 例えば、図の一部の可視ラベルとなるテキスト要素には、そのidが 対象のグループやパス要素のaria-labelledby属性で参照されるべきです。 詳細はSVGアクセシビリティガイドラインを参照してください。

11.1.1. 定義

文字
文字はXMLで定義されるテキストの最小単位です [XML]。

実質的にはUnicodeコードポイントです。 文字は制御命令(タブ、改行、復帰など)、描画可能な記号(文字、数字、句読点など)、修飾記号(合成アクセントなど)を含みます。

アドレス可能文字
文字のうち、テキスト位置属性やSVG DOMのテキストメソッドでアドレス指定可能なもの。 レイアウト時に破棄される文字(折り畳まれた空白文字など)や displayプロパティの値がnoneの要素内の文字はアドレス可能ではありません。 アドレス可能文字はUTF-16コード単位でインデックス指定されます(したがって、U+FFFFを超える単一Unicodeコードポイントは、UTF-16コード単位として2文字分になります)。 インデックスは、text-transform変換適用前に決定されます。 詳細はSVGTextContentElementインターフェースのメソッド参照。

将来CSS生成コンテンツテキストのサポートが導入された場合、アドレス可能文字配列にも含まれます。

組版文字
書記体系の単位(ラテン文字(ダイアクリティック含む)、ハングル音節、漢字、ミャンマー文字クラスタなど)であり、 特定の組版処理(改行、先頭文字効果、トラッキング、均等割付、縦組み等)に関して不可分なものです。正式な定義やUnicodeグラフムクラスタとの関係は CSS Text Module Level 3 ([css-text-3])参照。
フォント
フォントは、様々なグリフ表現が特定の外観やスタイルを共有するよう編成されたグリフ集です。
グリフ
グリフは、フォント内で描画される内容の単位を表します。 多くの場合、描画すべき文字と対応するグリフは1対1ですが(例:"A"は通常1つのグリフで描画)、 複数グリフで1文字を描画する場合(例:アクセント付き文字)や、1グリフで複数文字を描画する場合(例:合字)もあります。 通常グリフは、図形パスなど)で定義され、場合によっては小サイズでも判読性を保つレンダリングヒントなどの追加情報を持ちます。
テキストコンテンツ要素
テキストコンテンツ要素は、キャンバス上にテキスト文字列を描画するSVG要素です。 SVGのテキストコンテンツ要素は: texttextPathtspanです。
テキストコンテンツ子要素
テキストコンテンツ子要素は、他のテキストコンテンツ要素の子孫として許可される テキストコンテンツ要素です。 SVGにおけるテキストコンテンツ子要素は: textPathtspanです。
テキストコンテンツブロック要素
テキストコンテンツブロック要素は、テキストの単位として独立した要素であり、 必要に応じて特定の子テキストコンテンツ要素(例:‘tspan’)を含むこともあります。 SVG 2では、textのみがテキストコンテンツブロック要素です。
コンテンツ領域
テキストが通常レイアウトされる領域。これは CSSコンテンツ領域と同等です。 実際のテキストレイアウト領域はパディングや除外領域によって小さくなる場合があります。
折返しコンテキスト
テキストレイアウト時にコンテンツ領域から除外する領域(図形)の集合。 CSS折返しコンテキストと同等です。
折返し領域
テキストがレイアウトされる領域で、パディングや除外領域(折返しコンテキスト)を差し引いた後の領域。 CSS折返し領域と同等です。
行ボックス
単一行テキストのレイアウトに使われるすべての内容を含む矩形領域。 CSS行ボックスと同等です。

CSS 3系テキストレイアウト仕様で用語は使われていますが、現状正式な定義はありません。 そのためリンク先はCSS 2.1であり、CSS WGにissueが提出されています

インライン基本方向
行または行の一部の内容が並ぶ主要な方向。 行または行の一部の「開始側」「終了側」を定義します(例:text-anchorプロパティ適用時)。 directionプロパティで決定されます。 (注意:行内の文字の並び順は主にUnicode双方向アルゴリズムで制御され、インライン基本方向だけではありません。)
ブロックフロー方向
行ボックスが積み重なる方向。writing-modeプロパティで決定されます。
整列ポイント
次の組版文字を描画する際、現在のテキスト位置と整列すべき 組版文字上の点。グリフセルのメトリクスで決定され、スクリプトや インライン基本方向に依存する場合があります。
現在のテキスト位置
現在のユーザー空間において、次に描画する組版文字の整列ポイントが配置されるべき点。
テキストチャンク
すべての文字が一緒に配置される独立したテキストブロック。 新たな絶対位置調整(xy属性、強制改行など)ごとに新しいテキストチャンクが生成されます。 合字置換や双方向並び替えはテキストチャンク内のみで行われます。テキストチャンクは整形済みテキスト時のみ関連します。
空白文字
以下の文字が空白文字とみなされます: U+0009 タブ、 U+000C フォームフィード(FF)、 U+000D キャリッジリターン(CR)、 U+000A ラインフィード(LF)、 U+0020 スペース。

11.1.2. フォントとグリフ

フォントは、グリフの集合と、それらのグリフを視覚的メディア上で文字として表示するために必要なその他の情報(総称してフォントテーブル)で構成されます。 グリフの集合とフォントテーブルの組み合わせはフォントデータと呼ばれます。

フォントは、グリフの並びを再配置・合成・配置して複合グリフを生成するためにフォーマッタ(テキストシェイパー)が利用できる、置換・配置テーブルを提供することがあります。 合成は単純な合字の場合もあれば、複数の子音・母音グリフを順番入れ替えつつ合成するインド系音節のように複雑な場合もあります。 テーブルは言語依存で、言語ごとに適切な文字形を使うことができます。

グリフ(単純・複合を問わず)が組版上不可分単位を表す場合、それは組版文字と呼ばれます。

合字は高度なテキストレイアウトにおいて重要な機能です。一部の合字は任意ですが(discretionary)、他(例:アラビア語)は必須です。 合字生成に関する明示的な規則は以下の通りです:

SVG 2 要件: Web Open Font Format (WOFF)の明示的なサポートを含めること。
決議: SVG 2でWOFFサポートを義務化する。
目的: 国際化や高度な組版のため、OpenTypeの全機能へアクセス可能にする。
担当者: Chris(アクションなし)
ステータス: 完了

適切なテキスト描画には、制作時と同じフォントを使うことが重要です。 このため、SVGではFont Resources章で定義されるダウンロード可能フォントのサポートが必須です。 特に、Web Open Font Format(WOFF)のサポートが要求されます。

SVG 2の新機能として、WOFFにより著者が自身のコンテンツを適切に描画するためのフォントを提供できます。 これには、OpenTypeテーブルによる複雑なスクリプト、任意合字、スウォッシュ、オールドスタイル数字等のサポートや、 フォントの圧縮・サブセット化・ライセンス情報の付加が含まれます。

11.1.3. グリフのメトリクスとレイアウト

グリフの選択と配置は通常CSSの規則に従って処理されます。 ただし、SVGでは最終的なテキストレイアウトに個々のグリフの幾何プロパティを知る必要がある場合があります。

幾何学的なフォント特性はEMボックスを基準にした座標系で表現されます(EMはフォントのグリフの高さの相対単位です)。 1EM×1EMのボックスをデザイン空間と呼び、この空間はEMを細分してunits per emという単位で幾何座標が与えられます。

units per emはフォント特性で、典型的な値は1000や2048です。

EMボックスの座標空間はデザイン空間座標系と呼ばれます。スケーラブルフォントでは、グリフを描画する曲線や線はこの座標系で表現されます。

この座標系の(0,0)点は通常EMボックスの左端に位置しますが、左下隅ではありません。 ローマ字大文字の下端のY座標は通常0です。小文字ローマ字の下端(ディセンダー)は負の座標値を持ちます。

EMボックス内の'M'の座標系、ベースライン、アセント、ディセント

EMボックス(青い四角)内の'M'。'M'はベースライン(青い線)に載っています。座標系の原点は黒丸で示されています。

SVGは、フォントのフォントデータに少なくとも3つの特性(アセント・ディセント・ベースラインテーブル)が含まれることを前提とします。 アセントはフォントの(0,0)点からEMボックス上端までの距離、ディセントは同点から下端までの距離です。ベースラインテーブルについては後述します。

OpenTypeフォント([OPENTYPE])では、横書きモードの場合、アセント・ディセントはOS/2テーブルのsTypoAscender・sTypoDescenderで与えられます。 縦書きモードではディセント(この場合(0,0)点からグリフ左端までの距離)は通常0です((0,0)が左端なので)。縦書きのアセントは1emか、OpenType Baseテーブルのideographic top baseline値で指定されます。

グリフは各グリフの特定の点(整列ポイント)を基準に配置されます。 横書きではグリフの整列ポイントが縦に揃い、縦書きでは横に揃います。 整列ポイントの位置はスクリプトによって異なります。西洋グリフは大文字下端、北インド系グリフはほぼ上端の横線、 東アジアグリフは下端または中心で揃います。

同一フォントサイズ・同一スクリプト内のテキスト行では、整列ポイントの並びがインライン基本方向で幾何学的な線=ベースラインを定義します。 西洋や多くの音節文字は「アルファベット」ベースライン、北インド系は「ハンギング」、東アジアは「イデオグラフィック」ベースラインで揃います。

3種類のスクリプトのベースライン例

3種類のスクリプトのベースライン(赤線)例。左からアルファベット、ハンギング、イデオグラフィック。イデオグラフィックスクリプトのEMボックスは青色で表示。

グリフはベースラインに沿って順次配置され、各グリフの整列ポイントが通常現在のテキスト位置に配置されます(vertical-alignなどのプロパティで位置が変わる場合あり)。 配置後、現在のテキスト位置はグリフのadvance値(通常は横書きなら幅、縦書きなら高さ)だけ進み、 カーニングや他の間隔調整、新しい行(整形済み・自動折返しテキスト)にも対応します。 初期・最終の現在テキスト位置は整列(例:text-anchor値が'middle'や'end'の場合)に利用されます。 グリフのadvance値はパス上のテキスト配置にも必要です。

3種類のスクリプトのフォントメトリクス例

フォントメトリクスの例。青いボックスは3つのグリフの幾何ボックス。ラベル付きの小さい円はグリフ配置前の現在のテキスト位置を示す。小さい四角は最後のグリフ配置後の現在のテキスト位置。 'a'グリフの左端と'V'グリフの右端はカーニングにより揃っていない点に注意。

グリフが現在の向きに対応する明示的なadvance値を持たない場合は、適切な近似値を用いるべきです。縦書きテキストの場合、emサイズが推奨されます。

初期の現在のテキスト位置は、整形済みテキストの場合はxy属性(textまたは最初のtspan)、自動折返しテキストでコンテンツ領域inline-sizeプロパティで決定される場合も同様です。 その他の自動折返しテキストの場合、初期位置はCSSの行折返しアルゴリズム適用後の最初のグリフ位置で決まります。

ベースラインテーブルは、デザイン空間座標系で1つ以上のベースラインの位置を指定します。 ベースラインテーブルの役割は、同一行に複数スクリプトを混在させる際の相互整列を容易にすることです。 行(またはブロック)内で主となるスクリプトに応じて望ましい相対整列が変わるため、スクリプトごとに異なるベースラインテーブルを持つ場合があります。 また、横書き・縦書きで整列位置が異なるため、フォントは複数のベースラインテーブル(横書き用複数、縦書き用0個以上)を持つ場合があります。

一部のフォントはベースラインテーブル値を持たない場合があります。その場合、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プロパティの使用例。 左:'vertical-align:mathematical'('alignment-baseline:mathematical')がtspan要素([z])に適用。水色の線が数式ベースライン位置。 右:'vertical-align:super'('baseline-shift:super')がtspan要素(2)に適用。水色の線がベースラインのシフトを示す。

SVGは、フォントデータ内の各グリフに対して、2つの幅・2つの整列ベースライン・2つの整列ポイント(横書き用と縦書き用)を持つことを前提とします。 (幅といえども、縦書きでは縦方向に使われます。)整列ポイントのインライン基本方向位置はグリフの開始端にあります。

ベースラインについての詳細はCSS Inline Layout Module Level 3仕様 [css-inline-3]や、CSS Writing Modes Level 3仕様 [css-writing-modes-3]を参照してください。

SVG 2 要件: 異なるベースラインへのテキスト整列をサポートすること。
決議: SVG 2は既存または改善されたCSSプロパティでグリフの異なるベースライン整列をサポートする。
目的: 横書きテキストでスタイル効果のためグリフに異なる垂直整列を可能にする。
担当者: Chris(アクションなし)
ステータス: 完了

1行のテキストは行ボックス内にレイアウトされます。複数行テキストはこれらボックスを積み重ねて生成されます。 行ボックスの高さは、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要素の中に配置でき、 スタイルを切り替えたり、親要素に対して描画テキストの位置を調整したりできます。

textおよびtspan要素内の文字データは、関連属性やプロパティ、フォント内の文字―グリフ対応表とともに、描画されるグリフを定義します。 texttspan要素に指定する属性・プロパティは、書字方向、フォント指定、文字描画方法(塗り属性等)などを示します。 この章の後半でテキスト固有の属性やプロパティについて説明します。

texttspan要素は他のグラフィックス要素と同じ描画方式でレンダリングされるため、 塗り機能は図形パス矩形など)と同様に texttspan要素にも適用されます(マーカーを除く)。 さらに、座標系変換クリッピングマスキングtext要素全体に適用できます。

CSS的には、text要素はブロック要素として動作します。 tspantextPatha要素は、テキストコンテンツ要素の子孫の場合インライン要素として動作します。

テキストにもグラデーション、パターン、クリッピングパス、マスク、フィルタを適用できます。 これらをテキストに適用し、キーワード'objectBoundingBox'を使って「object bounding box」基準でグラフィカル効果を指定した場合は、 オブジェクトバウンディングボックス単位は常にtext要素全体に対して計算されます。 これは、同じtext要素内で異なるtspantextPath要素に異なる効果を適用した場合も同様です。

text要素は、双方向処理後の最初のグリフを 初期現在のテキスト位置text-anchorプロパティやtext-alignプロパティ値による調整あり)に描画します。 整形済みテキストやinline-sizeプロパティでコンテンツ領域が決まる自動折返しテキストの場合、 初期現在のテキスト位置は、最初に描画される文字を含む textまたはtspan要素の xy値で決まります。 図形内の自動折返しテキストやパス上のテキストの場合は、 自動折返しテキストパス上のテキストの章を参照して、 初期現在のテキスト位置を確認してください。 指定された文字に対応するグリフが描画された後、次の文字のために現在のテキスト位置が更新されます。 最も単純な場合、新しい現在のテキスト位置は、前の位置+グリフのadvance値(横書きなら横方向、縦書きなら縦方向)となります。 グリフ配置とadvance値についてはテキストレイアウト章を参照してください。

テキスト文字列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'のみ赤色

2つのtspan要素の位置を xy属性で 水平方向・垂直方向に調整しています。 すべてのテキストが1つの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
カテゴリ:
グラフィックス要素, 描画可能要素, テキストコンテンツ要素
内容モデル:
以下の要素や文字データを任意個・任意順で含むことができます:a, clipPath, marker, mask, script, style
属性:
DOMインターフェース:
SVG 2 要件: tspanでtransformを許可する。
決議: SVG 2では‘tspan’でtransformを許可する。
目的: 既にtransformが許可されているaなど他の要素と揃えるため。
担当者: Cameron(アクションなし)
ステータス: 完了

この決定は撤回されました。詳細は GitHub Issue 210を参照。 CSS/HTMLではインライン要素でtransformは許可されておらず、SVG・HTML両方でインライン状態のa要素にtransformをサポートするレンダラはありません。

tspan
カテゴリ:
グラフィックス要素, 描画可能要素, テキストコンテンツ要素, テキストコンテンツ子要素
内容モデル:
以下の要素または文字データを任意個・任意順で含むことができます:a, animate, script, set, style, tspan
属性:
DOMインターフェース:

11.2.1. 属性

名前 初期値 アニメーション可能
x, y [ [ <length-percentage> | <number> ]+ ]# textの場合は0;
tspanの場合は(なし)
はい

単一の<length>が指定された場合、その値はこの要素またはその子孫内の最初の文字に対応するグリフを描画するための現在のテキスト位置の新しい絶対X(Y)座標を表します。

カンマまたは空白区切りのn個の<length>が指定された場合、それぞれの値はこの要素またはその子孫内の最初のn個のアドレス可能文字に対応するグリフを描画するための現在のテキスト位置の新しい絶対X(Y)座標を表します。

文字数より多く<length>が指定された場合、余分な<length>はグリフ位置決めに影響しません。

文字数が<length>より多い場合、またはtspanに属性が指定されていない場合、追加の文字については以下の通りです:

  1. 祖先のtextまたはtspan要素が、その文字に対して‘x’‘y’)属性で絶対値を指定していれば(最も近い祖先が優先)、その絶対座標がその文字の開始座標として使われる。そうでなければ、
  2. グリフ描画用の開始座標は、現在のtext要素で直前に描画されたグリフの現在のテキスト位置座標となる。

SVG 2ではtexttspanxおよびy属性はプレゼンテーション属性ではなく、CSSで設定できません。将来のSVGバージョンで変更される可能性があります。

名前 初期値 アニメーション可能
dx, dy [ [ <length-percentage> | <number> ]+ ]# (なし) はい

単一の<length>が指定された場合、この値はこの要素またはその子孫内の最初の文字に対応するグリフを描画するための現在のテキスト位置の新しい相対X(Y)座標を表します。最初の文字グリフが描画される前に、現在のテキスト位置が現在のユーザー座標系のx軸(y軸)方向に<length>だけシフトされます。

カンマまたは空白区切りのn個の<length>が指定された場合、それぞれの値はこの要素またはその子孫内の最初のn個のアドレス可能文字に対応するグリフ描画前の現在のテキスト位置のx軸(y軸)方向への増分シフトを表します。つまり、各文字のグリフを描画する前に、直前の文字のグリフ描画による現在のテキスト位置<length>だけシフトします。

文字数より多く<length>が指定された場合、余分な値はグリフ位置決めに影響しません。

文字数が<length>より多い場合、または属性が指定されていない場合、追加の文字については以下の通りです:

  1. 祖先のtextまたはtspan要素がその文字に対して‘dx’‘dy’)属性で相対座標を指定していれば(最も近い祖先が優先)、現在のテキスト位置がその分だけx軸(y軸)方向にシフトします。そうでなければ、
  2. x軸(y軸)方向への追加シフトは行われません。
名前 初期値 アニメーション可能
rotate [ <number>+ ]# (なし) はい(加算不可)

この要素内の各文字に対応するすべてのグリフに適用される、現在のテキスト位置を中心とした補足回転(度単位)です。

カンマまたは空白区切りの<number>リストが指定された場合、最初の値は最初の文字に、2番目は2番目の文字に…と対応するグリフへの補足回転を表します。

文字数より多く<number>が指定された場合、余分な値は無視されます。

文字数が<number>より多い場合、追加の文字には最後の値で指定された回転を使わなければなりません。

属性が指定されておらず、tspan要素の祖先がrotate属性で補足回転を指定していれば(最も近い祖先が優先)、指定された補足回転がその文字に適用されます。祖先属性でも文字数が指定値を超えた場合、追加文字には最後の値を使う必要があります。

この補足回転は、グリフ描画時の現在のテキスト位置の変更規則には影響せず、パス上のテキストや、text-orientationglyph-orientation-horizontalglyph-orientation-verticalによる回転に追加されます。

名前 初期値 アニメーション可能
textLength <length-percentage> | <number> 下記参照 はい

この要素内の文字データに対応するすべてのadvance値(グリフのadvance値(横・縦)、letter-spacingword-spacingプロパティの効果、dxdy属性による調整など)の合計を著者が計算値として指定します。この値はユーザーエージェントの計算値と著者の計算値を調整するために使われます。

この属性の目的は、双方向並べ替え後の視覚的描画順で、最初と最後の描画グリフを厳密に揃えることです。最後の描画文字(双方向並べ替え後)は、通常グリフadvance以外の追加文字間スペースは無視され、textLengthの長さにフィットさせるためにテキスト文字列を拡張/圧縮する量をユーザーエージェントが決定します。

属性textLengthが要素とその祖先の両方に指定されている場合、この要素内の文字データの調整はこの要素でのみ制御され、他の同じ祖先内の内容とは調整比率が異なる場合があります。ユーザーエージェントは、他の祖先要素内の内容のadvance値合計を、祖先要素のadvance値とこの要素のadvance値の差分とみなします。

この属性はテキストの縮小や拡大などの効果を得るためのものではありません。

負の値はエラーです(エラー処理参照)。

textLength属性は、折返し領域shape-insideinline-sizeプロパティで定義されていない場合のみ適用されます。また、white-space値がpreまたはpre-lineによる強制改行があるtexttspan要素にも適用されません。

text要素内で属性がどこにも指定されていない場合、著者の計算値がユーザーエージェントの計算値と一致したものとみなされ、advance調整は行われません。DOMへの反映のための初期値は、現在のユーザーエージェントが計算した長さ(暗黙のユーザー単位で表現)です。

名前 初期値 アニメーション可能
lengthAdjust spacing | spacingAndGlyphs spacing はい
spacing
advance値のみ調整します。グリフ自体は伸縮されません。
spacingAndGlyphs
advance値を調整し、グリフ自体も1軸方向(インライン基本方向に平行)に伸縮します。

ユーザーエージェントはテキストの開始・終了位置を正しく合わせる必要がありますが、中間グリフの位置は予測できません。ユーザーエージェントは最適な組版のために高度なアルゴリズムを使い、テキスト文字列の伸縮と開始・終了位置のバランスをとる場合があります。

n文字のテキスト列の場合、advance値の調整は通常n−1文字にのみ行われ(textLength属性の説明参照)、グリフの伸縮は全n文字に適用されます。

11.2.2. 'x'、'y'、'dx'、'dy'、'rotate'に関する注意事項

text要素およびtspan要素のxydxdyrotateは、個々のグリフを精密に配置する必要がある高度な組版シナリオで有用です。これらの属性は、文字間の微細な位置調整や、テキストの一部を新しい行の視覚効果のために移動するなど(SVG 1.1互換)、大きな位置調整にも役立ちます。なお、xydxdyrotate属性は、自動折返しテキストの場合は無視されます(ただしinline-sizeプロパティでコンテンツ領域が指定された場合の初期現在のテキスト位置は除く)。

2015年シドニーF2Fで、自動折返しテキストでは'dx'、'dy'、'rotate'を無視することが決定されました。(技術的には適用は難しくありませんが、実用性が低いと判断されました。)

組版の高度な制御で微細な位置調整が必要な場合、SVGコンテンツ制作者は文書閲覧者全員に必要なフォントが利用可能となるよう配慮する必要があります(例:SVGフォントや同じWebサイトに保存された代替WebFont形式として必要なフォントデータを用意するなど)。また、閲覧ソフトウェアが期待通りにフォントを処理することも重要です(システムごとに機能やレイアウト機構が大きく異なります)。SVGコンテンツが特定のフォントやビューア向けにxydxdy属性値を指定していて、これらの条件を満たさない場合、テキストの表示品質が低下することがあります。

以下は、xydxdyrotate属性が数値リストを持つ場合の追加規則です:

例 tspan04では、tspan要素のrotate属性を使ってグリフを回転させています。この例では、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>
    例 tspan04 - rotate値の数が文字列の文字数より少ない場合。
  </desc>
  <text font-family="Verdana" font-size="55" fill="blue" >
    <tspan x="250" y="150" rotate="-30,0,30">
      Hello, out there
    </tspan>
  </text>
  <!-- 'rect'要素でビューポートのアウトラインを表示 -->
  <rect x="1" y="1" width="998" height="298"
  fill="none" stroke="blue" stroke-width="2" />
</svg>
例 tspan04 — tspan要素内の文字の単純な回転

例 tspan04

この例をSVGとして表示 (SVG対応ブラウザのみ)

例 tspan05では、text要素およびほとんどの子tspan要素にrotate属性を指定し、グリフ回転を行います。この例は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>
    例 tspan05 - ネストしたtspan要素への回転値伝播。
  </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>

  <!-- 'rect'要素でビューポートのアウトラインを表示 -->
  <rect x="1" y="1" width="498" height="118" fill="none"
        stroke="blue" stroke-width="2" />
</svg>
例 tspan05 — ネストしたtspan要素への回転値伝播

例 tspan05

この例をSVGとして表示 (SVG対応ブラウザのみ)

text要素内の赤色テキストの回転:

"child1"のtspan要素内のオレンジ色テキストの回転:

"child2"のtspan要素内の黄色テキストの回転:

青色テキスト("child5"のtspan要素)の回転:

下図は、text要素にネストされたtspan要素への回転値伝播を示しています:

回転値伝播の図

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プロパティを設定するか、SVG 図形を定義・参照するshape-insideプロパティを設定することで明示的に宣言できます。宣言されていない場合は、幅・高さとも無限大の矩形がデフォルトになります。

次に、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>
2行の整形済みテキスト画像。

整形済みテキスト。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>
2行に自動折返しされたテキスト画像。

自動折返しテキスト。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ではコンテンツ領域を明示的に指定する必要があり、CSS(ボックスモデル)で提供される自動有限(または半有限)領域はありません。 また、SVGには改行を生成する<p></p>や<br/>要素がなく、代わりにwhite-spaceプロパティのprepre-line値が改行を提供します。 SVG折返しテキストは、SVG 1.1レンダラが折返しテキストをサポートしない場合も自然なフォールバックが可能です(xy属性をtexttspan要素で使用し、SVG 2レンダラは自動折返しテキストの場合これら属性を無視)。

SVGのテキストレイアウト機能は、一般的な用途を広くカバーするよう設計されています。より複雑なレイアウト(箇条書きリスト、表など)が必要な場合は、foreignObject要素内でXHTML等の他のXML名前空間でテキストを描画できます。

11.4. テキストレイアウト ― コンテンツ領域

コンテンツ領域は、text要素でinline-sizeプロパティ、 またはSVG図形を定義・参照するshape-insideプロパティを指定することで定義されます。 コンテンツ領域が与えられない場合、コンテンツ領域は幅・高さとも無限大の矩形がデフォルトとなります(整形済みテキスト参照)。 inline-sizeプロパティと値が'none'以外のshape-insideプロパティが両方指定された場合は、shape-insideプロパティが優先されます。

折返しテキストは折返し領域内にレイアウトされます。折返し領域は通常コンテンツ領域と同じです。 shape-insideプロパティでコンテンツ領域が定義された場合、折返し領域shape-subtractプロパティやshape-paddingプロパティの影響で小さくなることがあります。 shape-subtractプロパティ(およびshape-marginプロパティ)は折返しコンテキストを定義します。 折返し領域は、コンテンツ領域shape-paddingの距離だけ内側に入れ、 さらに折返しコンテキストを差し引くことで求められます。

折返し領域が定義されると、テキストはCSSの規則(このセクションの特別な規則を含む)に従い、その折返し領域内にレイアウトされます。

SVGとHTMLで同等の折返し領域を構築すること。折返し領域内のテキストは両者で同じように描画されます。

円と2つの半円で砂時計形状を作成し、テキストが円内で折返される例。左右の半円が円の一部領域を除外する。

SVGで折返し領域を定義する例。 text要素はshape-insideプロパティとshape-subtractプロパティの両方を持ちます。 shape-insideプロパティは円を参照してコンテンツ領域(紫の点線)を定義します。 shape-subtractプロパティは2つの半円を参照し、折返しコンテキスト(緑の点線)を定義します。 これをコンテンツ領域から差し引くことで折返し領域(水色の線)が得られます。

円と2つの半円で砂時計形状を作成し、テキストが円内で折返される例。左右の半円が円の一部領域を除外する。

HTMLで折返し領域を定義する例。 wrapper<div>内に2つのfloat<div>が含まれます。wrapper <div>は矩形領域(紫実線)を定義し、そのshape-insideプロパティが<div>内のコンテンツ領域(紫点線)を定義します。 他2つの<div>は左(緑実線)と右(ピンク実線)にfloatし、矩形の形状です。各floatは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プロパティは折返し領域を矩形形状に設定できます。 プロパティの算出値は横書きテキストの場合矩形の幅、縦書きテキストの場合高さを設定します。 もう一方の寸法(横書きの場合高さ、縦書きの場合幅)は無限長です。値が0の場合は折返し領域の生成を無効化します。

初期の現在のテキスト位置は、xおよびy属性で決まります(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>
英語テキストが2行に折返された画像。

横書きテキストの折返し。水色の線がコンテンツ領域の限界を示します。コンテンツ領域の高さは無限です。赤い点は初期現在のテキスト位置です。

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>
アラビア語テキストが2行に折返された画像。

右から左の横書きテキストの折返し。水色の線がコンテンツ領域の限界を示します。コンテンツ領域の高さは無限です。赤い点は初期現在のテキスト位置です。

一部ブラウザはこのSVG 1.1画像を正しく描画しない場合があります。BatikとFirefoxは正しく描画されます。Chromeにはバグ報告済み。

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>
縦書き日本語テキストが2列に折返された画像。

縦書きテキストの折返し。水色の線がコンテンツ領域の限界を示します。コンテンツ領域の幅は無限です。赤い点は初期現在のテキスト位置です。

このSVG 1.1画像はFirefox(nightly含む)では動作しません。Firefoxは'writing-mode'プレゼンテーション属性をサポートしていません。バグ報告済み。

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>
英語テキストが中央アンカーで2行に折返された画像。

横書きテキストの折返し。水色の線がコンテンツ領域の限界を示します。テキストは中央にアンカーされています。赤い点は初期現在のテキスト位置です。

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の図形要素を参照していれば、その要素が図形を定義します。 画像を参照している場合は、指定画像のアルファチャンネルを使いshape-image-thresholdで形状を抽出します。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用図形を用意することが推奨されます。

特記以外はCSS Shapes Module Level 2の'shape-inside'定義を参照。[css-shapes-2]

'shape-inside'はCSS Exclusions and Shapes Module分割時に一度削除されましたが、東京SVG/CSS合同F2FでCSS Shapes Module Level 2で復活することに合意しました。

11.4.3. ‘shape-subtract’プロパティ

shape-subtractプロパティは、コンテンツ領域の一部を折返し領域から除外できます。 除外領域はCSS基本図形やSVG図形のリストで定義される全領域の和です。

2016年シドニーF2Fで、'shape-subtract'を使うことが決定されました('shape-outside'は除外領域面積を減らす動作のため挙動が異なる)。

絶対値やパーセンテージ値は現在のユーザー座標系viewBoxに基づいて定義されます。

名前: shape-subtract
値: none | [ <basic-shape>| <uri> ]+
初期値: none
適用対象: text要素
継承: いいえ
パーセンテージ: viewBoxを基準
メディア: 視覚
算出値: <basic-shape>は算出長さ、<uri>は絶対URI、それ以外は指定値
アニメーション可能: はい、基本図形の補間参照
<basic-shape>
形状は'circle()'、'ellipse()'、'polygon()'のいずれかの値で算出されます。
<uri>
<uri>がSVG図形要素を参照する場合、その要素が寄与形状となり、shape-margin距離だけ拡張されます。 画像参照の場合は、指定画像のアルファチャンネルを使いshape-image-thresholdで形状を抽出します。SVG図形要素や画像以外の参照は無視されます。

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>
2つの重なった矩形内で横書きテキストを折返した画像。

2つの重なった矩形内でshape-subtractshape-insideshape-paddingshape-marginを使って横書きテキスト折返し。黒い矩形がコンテンツ領域、内側の青い線が折返し領域を示します。

11.4.4. ‘shape-image-threshold’ プロパティ

shape-image-thresholdは画像を使って形状を抽出する際、アルファチャンネルの閾値を定義します。値0.5は、50%以上不透明なピクセルをすべて囲む形状となります。

SVGでは、このプロパティはtext要素に適用されます。

特記以外はCSS Shapes Module Level 1の'shape-image-threshold'定義を参照。[css-shapes-1]

11.4.5. ‘shape-margin’プロパティ

shape-marginプロパティは、shape-subtractで参照された図形にマージンを追加します。 このプロパティは元の図形から指定距離だけ離れた新しい図形を定義します。値は正のみ。

名前: shape-margin
値: <length-percentage>
初期値: 0
適用対象: text要素
継承: いいえ
パーセンテージ: 該当なし
メディア: 視覚
算出値: 絶対長さ
アニメーション可能: はい

特記以外はCSS Shapes Module Level 1の'shape-margin'定義を参照。[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は'textLength'を'tspan'でサポートしますがFirefoxは非対応です。

特記以外はCSS Shapes Module Level 2の'shape-padding'定義を参照。

11.5. テキストレイアウト ― アルゴリズム

テキストレイアウトは、text要素の内容(テキストデータ、スタイル情報、塗りつぶす図形の記述)をCSSベースのテキストレンダラーに渡すことから始まります。 text要素はブロック要素として扱われ、 その子孫のtspantextPatha要素はインライン要素として扱われます。 CSSレンダラーは、テキストを絶対位置でレイアウトしたかのような組版文字とその位置のセットを返します。

組版文字は複数のグリフを含む場合があります。 ここでは、グリフの相対位置は組版文字によりカプセル化され、ユーザーが制御できないものとします。

コンテンツ領域が定義されたら、次のアルゴリズムに従ってtext要素の組版文字とその位置を決定します:

以下のCSSプロパティはSVGテキストレイアウトにおいて効果がないか限定的です:

SVG属性やプロパティは、コンテンツ領域の定義方法に応じて組版文字の位置を調整する場合があります:

以下のSVGテキストレイアウトアルゴリズムは、DOM内の各文字についてtext要素サブツリー内での情報を返します。情報には以下が含まれます:

SVG属性xydxdyrotateの配列はアドレス可能文字でインデックスされますが、 実際の位置調整は組版文字に対して行われます。 例えば、組版文字が複数文字(例:合字)に対応する場合、最初の文字の配列値のみがその組版文字の位置決めに使われ、他の文字の配列値は(xとyの場合は)スキップ、(dxとdyの場合は)累積して次の組版文字に適用、(rotateの場合は)配列の最後の値なら次の組版文字に適用されます。 これにより、フォントに特定の合字があるかないかに関わらず、属性値が同じ文字に適用されることが保証されます。

SVG固有のテキストレイアウトアルゴリズムは以下の通りです:

  1. セットアップ
    1. rootを、text要素およびそのサブツリーに対して組版文字の位置を生成した結果とする。これは、絶対位置要素としてレイアウトされたものとする。

      white-spaceプロパティによる改行がない限り、これは1行のテキストとなる。

    2. countを、text要素サブツリー内のDOM 文字数とする。
    3. resultを、長さcountの配列とし、各エントリには上記の各文字情報を格納する。各エントリの初期値は以下の通り:
      • グローバルインデックス番号は配列内の位置
      • "x"座標は"未指定"
      • "y"座標は"未指定"
      • "rotate"座標は"未指定"
      • "hidden"フラグはfalse
      • "addressable"フラグはtrue
      • "middle"フラグはfalse
      • "anchored chunk"フラグはfalse
      resultが空の場合は、resultを返す。
    4. CSS_positionsを長さcountの配列として用意し、各エントリには対応する組版文字xy位置を格納する。初期値は(0, 0)。
    5. "horizontal"フラグを、textの書字モードが横書きならtrue、そうでなければfalseとする。
  2. フラグの設定と初期位置の割当

    resultのインデックスiごとに:

    1. インデックスiの文字が以下の場合、addressableをfalseに設定:

      下記のtext要素(標準フォント使用)にはグリフ位置属性でアドレス可能でない折り畳み可能な空白が含まれるため、"B"グリフはx=300に配置される:

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

      "A"の前の空白、および"A"と"B"の間の空白のうち1文字を除き、空白は折り畳みまたはトリムされるためである。

    2. インデックスiの文字が、同じ組版文字に対応する2文字目以降ならmiddleをtrueに設定。
    3. インデックスiの文字が行頭の組版文字に対応する場合、result[i]の"anchored chunk"フラグをtrueに設定。

      これによりtext-anchorによるチャンクシフトが複数行にまたがることを防ぐ。

    4. addressableがtrueかつmiddleがfalseなら、 CSS_positions[i]にCSSレンダラーで決定された対応組版文字の位置をセット。そうでなく、i > 0ならCSS_positions[i] = CSS_positions[i − 1]。
  3. 文字位置決定

    ノードによって指定された位置調整(例:x属性)は、そのノード内および子孫の全ての文字に適用される。ただし、子孫ノードで指定された調整は祖先ノードの調整を上書きする。ここで各文字への調整値を解決し、rotate座標も直接設定する。

    1. セットアップ:
      1. resolve_x, resolve_y, resolve_dx, resolve_dyを、長さcountで全て"未指定"で初期化。
      2. "in_text_path"フラグをfalseにセット。

        このフラグにより、textPath内の横書き(縦書き)テキストに対しyx)属性値を無視できる。

      3. 下記手順をtextノードに対して呼び出す。
    2. 手順:文字位置決定

      入力ノードnodeを取る再帰手順。処理内容は以下:

      1. nodetextまたはtspanノードの場合:
        1. indexをノード内最初の文字のグローバルインデックスとする。
        2. x, y, dx, dy, rotateを、対応するノード属性値リスト(未指定または無効なら空リスト)とする。
        3. "in_text_path"フラグがfalseの場合:
          • new_chunk_count = max(xリスト長, yリスト長)。
          そうでない場合:
          • "horizontal"フラグがtrueの場合:
            • new_chunk_count = xリスト長。
          • それ以外の場合:
            • new_chunk_count = yリスト長。
        4. lengthnodeサブツリー内のDOM文字数とする。
        5. i = 0, j = 0 とする。

          i:ノード内アドレス可能文字のインデックス、 j:ノード内全文字のインデックス。

        6. j < lengthの間ループ:

          このループでnode内部に対しxydxdyrotate 属性値を適用。

          1. result[index + j]の"addressable"フラグがtrueなら:
            1. i < new_check_countなら result[index + j]の"anchored chunk"フラグをtrue、それ以外はfalse。

              falseにすると、xy属性が、text要素で設定された際、textPath要素で不適切にanchored chunkを作らないようにする。

            2. i < x長ならresolve_x[index + j] = x[i]。
            3. "in_text_path"かつ"horizontal"がfalseならresolve_x[index]を未設定にする。

              xはパス上の縦書きテキストで無視される。

            4. i < y長ならresolve_y[index + j] = y[i]。
            5. "in_text_path"かつ"horizontal"がtrueならresolve_y[index]を未設定にする。

              yはパス上の横書きテキストで無視される。

            6. i < dx長ならresolve_dx[index + j] = dx[i]。
            7. i < dy長ならresolve_dy[index + j] = dy[i]。
            8. i < rotate長ならresult[index + j]のangle値をrotate[i]にセット。そうでなくrotateが空でなければ、result[index + j] = result[index + j − 1]。
            9. i = i + 1。
          2. j = j + 1。
      2. nodetextPathノードの場合:
        1. indexをノード内(子孫含む)最初の文字のグローバルインデックスとする。
        2. result[index]の"anchored chunk"フラグをtrueにする。

          textPath要素は必ずanchored chunkを作る。

        3. in_text_pathフラグをtrueにする。
      3. nodeの各子ノードchildに対し:
        1. グリフ位置決定childに適用。
      4. nodetextPathノードの場合:
        1. "in_text_path"フラグをfalseにする。
  4. 位置調整: dx, dy

    dxdyの調整は、textLength属性による調整の前に適用され、xyrotateの調整は後に適用される。

    1. xy属性による累積シフトshiftを(0,0)で初期化。
    2. resultのインデックスiごとに:
      1. resolve_x[i]が未指定なら0にする。resolve_y[i]も同様。
      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. 手順:textLength解決

      入力ノードnodeを取る再帰手順。処理内容は以下:

      1. 各子ノードchildに対し:
        1. textLength解決childに適用。

          子ノードの調整は親ノードより先に行う。

      2. nodetextまたはtspanノードで、かつ有効なtextLength属性値を持つ場合:
        1. a = +∞、b = −∞とする。
        2. ijnode内の最初と最後の文字のグローバルインデックスとする。
        3. [i, j]範囲の各kで、result[k]の"addressable"フラグがtrueの場合:

          このループでノード内の組版文字の左右(上下)端を探し、強制改行をチェックする。

          1. kの文字が改行(linefeedまたはcarriage return)の場合はreturn。強制改行があるノードにはtextLengthによる調整は行わない。
          2. pos = result[k]の位置のx座標("horizontal"がtrueの場合)、そうでなければy座標。
          3. advance = kに対応する組版文字のadvance。(RTL横書きテキストはadvanceが負になる)
          4. a = min(a, pos, pos + advance)。
          5. b = max(b, pos, pos + advance)。
        4. a ≠ +∞なら:
          1. delta = textLengthの算出値 − (b − a)。

            UAはノード内最後の組版文字deltaだけシフトする必要がある。横書きで"horizontal"かつdirectionlrtなら+x方向、rtlなら−x方向、それ以外は+y方向。UAは中間組版文字の調整も許可される。以下はlengthAdjust値がspacingの場合の調整例。

          2. n = このノード内の組版文字数(解決済み子孫ノードやその内部ノード除く)。
          3. n = n + 解決済み子孫ノード数 − 1。

            各解決済み子孫ノードはこの文脈では1つの組版文字として扱う。

          4. 文字ごとの調整量δ = delta/n
          5. shift = 0。
          6. [i,j]範囲の各kで:
            1. shiftresult[k]のx座標("horizontal"なら)、そうでなければy座標に加算。
            2. result[k]の"middle"フラグがfalse、かつkが解決済み子孫ノードの2文字目以降でなければshift = shift + δ
  6. 位置調整: x, y

    このループでxおよびy値を適用し、text-anchorチャンクが組版文字の途中で始まらないことを保証する。

    1. xy属性による現在の調整shiftを(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]の"middle"・"anchored chunk"フラグ両方がtrueなら:
        1. result[index]の"anchored chunk"フラグをfalse。
        2. index + 1 < countなら result[index + 1]の"anchored chunk"フラグをtrueに。
      5. index = index + 1。
  7. アンカリングの適用
    1. 各スライスresult[i..j](ij両端含む)で、以下を満たす場合:
      • result[i]の"anchored chunk"フラグがtrue
      • i < kjresult[k]の"anchored chunk"フラグはfalse
      • j = count − 1 またはresult[j + 1]の"anchored chunk"フラグがtrue
      実行:

      これは各anchored chunkに対するループ。

      1. a = +∞、b = −∞。
      2. [i, j]範囲の各kresult[k]の"addressable"フラグがtrueの場合:

        このループでチャンク内組版文字の左右(上下)端を探す。

        1. pos = result[k]の位置のx座標("horizontal"なら)、そうでなければy座標。
        2. advance = kに対応する組版文字のadvance。(RTL横書きテキストはadvanceが負になる)
        3. a = min(a, pos, pos + advance)。
        4. b = max(b, pos, pos + advance)。
      3. a ≠ +∞なら:

        ここでテキストアンカリングを行う。

        1. shiftを、result[i]のx座標("horizontal"なら)、そうでなければy座標とする。
        2. result[i]の要素の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. [i, j]範囲の各kで、 result[k]のx座標("horizontal"なら)、そうでなければy座標にshiftを加算。
  8. パス上の位置決定
    1. index = 0。
    2. "in path"フラグをfalseに。
    3. "after path"フラグをfalseに。
    4. path_endを、textPath要素の後に続く文字のオフセットとし、(0,0)で初期化。
    5. index < countの間ループ:
      1. インデックスiの文字がtextPath要素内で、かつ組版文字に対応する場合:
        1. "in path"フラグをtrueに。
        2. result[index]の"middle"フラグがfalseなら:

          ここでtextPath位置決めを適用。

          1. pathを、textPath要素が参照する基本図形要素の同等パスとする。参照が不正なら空パス。
          2. side属性が'right'ならpathを反転。
          3. length = pathの長さ。
          4. offset = textPath要素のstartOffset属性値、参照要素のpathLength属性値で調整。
          5. advance = kに対応する組版文字のadvance。(RTL横書きテキストではadvanceは負)
          6. result[index]の位置(x, y)と角度angleを取得。
          7. "horizontal"フラグの値に応じてmidを計算:
            true
            mid = x + advance / 2 + offset
            false
            mid = y + advance / 2 + offset

            UAは、spacing値が'auto'や、method値が'stretch'の場合、midの調整も許される。

          8. path閉じていないサブパスで、mid < 0またはmid > lengthなら、result[index]の"hidden"フラグをtrueに。
          9. path閉じたサブパスの場合、textPath要素のtext-anchordirection値に応じて:

            単一閉じたサブパス用の特別な折返し条件。

            (start, ltr)または(end, rtl)
            midoffset < 0 または midoffset > lengthなら"hidden"フラグtrue。
            (middle, ltr)または(middle, rtl)
            midoffset < −length/2 または midoffset > length/2なら"hidden"フラグtrue。
            (start, rtl)または(end, ltr)
            midoffset < −length または midoffset > 0なら"hidden"フラグtrue。

            mid = mid mod lengthとする。

          10. hiddenフラグがfalseの場合:
            1. point = mid距離だけpath上の位置、t = その点での単位接ベクトル。
            2. "horizontal"フラグに応じて
              true
              1. n = t + 90°方向の法線単位ベクトル。
              2. o = グリフの垂直中心線からアラインメントポイントまでの水平距離。
              3. result[index]の位置 = pointo×t + y×n
              4. r = 正のx軸から接ベクトルへの角度。
              5. result[index]のangle値 = angle + r
              false
              1. n = t − 90°方向の法線単位ベクトル。
              2. o = グリフの水平中心線からアラインメントポイントまでの垂直距離。
              3. result[index]の位置 = pointo×t + x×n
              4. r = 正のy軸から接ベクトルへの角度。
              5. result[index]のangle値 = angle + r
        3. そうでなく、result[index]の"middle"フラグがtrueなら:
          1. result[index]の位置とangle値をresult[index − 1]のそれと同じにする。
      2. インデックスiの文字がtextPath要素外で、かつ組版文字に対応する場合:

        textPath要素の後に続く文字の描画開始点をパス終端に設定。

        1. もし"in path"フラグがtrueなら:
          1. "in path"フラグをfalseに。
          2. "after path"フラグをtrueに。
          3. path_end = textPath要素が参照するパスの終端 − result[index]の位置。
        2. "after path"がtrueなら:
          1. result[index]の"anchored chunk"がtrueなら"after path"フラグをfalseに。
          2. それ以外なら result.x[index] = result.x[index] + path_end.xresult.y[index] = result.y[index] + path_end.y
      3. index = index + 1。
  9. resultを返す

SVG 2 要件: テキストレイアウト機能でCSSと整合。
決議: SVG 2はSVG固有でないテキストレイアウト(ホワイトスペース、双方向等)についてCSS3定義を使用する。
目的: HTMLとSVGでテキストレイアウトの仕様・実装を共有できるようにするため。
担当者: Cameron and Chris (ACTION-3004, ACTION-3005)

11.6. 整形済みテキスト

このオプションは基本的なSVG 1.1のテキストレイアウトに対応します。

これはデフォルトのテキストレイアウト手法であり、明示的なコンテンツ領域が定義されていない場合に使われます。また、パス上テキストのレイアウトの第一段階としても使用されます(ルールは若干変更されます)。このレイアウト方法では、自動的な改行やワードラップは行われません。名目上、テキストは無限の幅と高さを持つ矩形コンテンツ領域内で1行に描画されます。複数行のテキストを得るには、改行を事前計算して下記いずれかの方法を使います:

以下のプロパティは整形済みテキストには適用されません: text-align, text-align-last, line-break, word-break, hyphens, word-wrap, およびoverflow-wrap

11.6.1. 'white-space'による複数行テキスト

white-spacepre またはpre-lineを使うことで複数行の整形済みテキストを作成できます。これらの場合、改行(line-feedまたはcarriage return)は強制改行として保持され、新しいline boxを生成します。line boxはCSSの規則に従って積み重ねられます。

11.6.2. グリフの再配置

テキストが基本的なCSSテキストレイアウト規則でレイアウトされた後、組版文字はSVG独自のルールで再配置できます。絶対配置はxy属性、または強制改行で指定でき、text-anchorプロパティの影響を受ける場合があります。相対配置はdxdy属性で指定できます。組版文字rotate属性の値リストにより任意に回転できます。絶対配置(text-anchorプロパティによる調整も含む)は、相対配置や回転より先に行われます。

11.7. 自動折返しテキスト

text要素でコンテンツ領域を指定するとテキストは自動的に折り返されます。コンテンツ領域はテキスト折返しの外側コンテナを定義します。折返しコンテキスト(除外領域群)が指定される場合もあります。実際の折返し領域コンテンツ領域から折返しコンテキストを差し引いて定義されます。さらにshape-paddingプロパティ値で折返しコンテキストが縮小される場合もあります。除外領域の有効面積はshape-marginプロパティ値で拡大できます。

inline-sizeプロパティでコンテンツ領域が定義されている場合、最初に描画される組版文字に対応するxおよびy属性が初期現在のテキスト位置を定義します。コンテンツ領域が図形内の場合、初期現在のテキスト位置は図形内の最初の行ボックスレイアウト後の最初の描画組版文字の位置により決定されます。

初期現在のテキスト位置を決定する場合を除き、自動折返しテキスト内のtexttspan要素ではxy属性値は無視されます。

xy属性は、折返しテキストに対するSVG1.1レンダラ向けの自然なフォールバック機能を提供します。コンテンツ制作者は行ごとにtspan要素で区切り、各要素にxy属性を付与することで事前レイアウトできます。例えばフォールバックフォントでテキストを描画する場合、SVG2レンダラはこれら属性を無視し、フォールバックフォントのメトリクスでテキストを再フローします。SVG1.1レンダラは属性値を使用してテキストを描画し、形状と一致しなくても通常は可読となります。 本節の多くの折返しテキスト例は、このメカニズムを利用して折返し未実装のブラウザでもテキストを描画しています。

11.7.1. テキスト折返しについての注意

以下の例は図形内テキストレイアウトに関するいくつかの課題を示します。

11.7.1.1. 最初の行の位置決め

任意形状の折返し領域の場合、最初のline boxが必ずしも上端(縦書きの場合は側面)にぴったり収まるとは限りません。この場合、最初のline boxは収まるまでシフトされます。

CSSでは、形状の端は1ピクセル×1ピクセルのフロート集として扱われます。

将来のCSS仕様で、複数の折返し領域間でテキストの整列を可能にする行グリッドが定義される可能性があります。

最初の行が'The'、次の行が'first line'な2行テキスト画像。

上側のline box(薄青色の小さい矩形)は、最小限のテキストブロックで、折返し領域(薄青色のパス)内に収まるまで下方向に移動されます。line boxにはline-heightプロパティ(ここでは1.25)の効果が含まれます。赤い矩形は各line box内のグリフを厳密に囲んでいます。

これはSVG 1.2ドラフトとは異なり、折返し領域の上端が行グリッドの原点となっていました。最初の行はline-height分だけ下に移動し、形状内に収まっていました。

11.7.1.2. 行の分断

任意形状の折返し領域の場合、1行のテキストが複数部分に分断されることがあります。この場合、各部分にline boxが生成されます。同じ行内の全line boxの高さは同じでなければならず(すべて同じベースラインになるように)、この高さは行内すべてのグリフを見て計算されます。

このデフォルト動作は2016年シドニーCSS/SVG合同WG会議で合意されました。

将来のCSS仕様では、図形が複数部分に分かれた場合、どの部分を埋めるか(右端のみ、左端のみなど)を制御できるようになる可能性があります。

V字形内にレイアウトされたテキスト画像。

上段の行は2つのline box(薄青色の矩形)に分割され、各line box内のテキストは('text-align:center'により)中央揃えされています。

11.8. パス上のテキスト

SVGは、path要素や基本図形のパス同等体で定義されたパスに沿ってテキストを配置できます。これは、textPath要素内にテキストを含め、href属性でURL参照としてpath要素または基本図形を指すか、path属性で直接パスデータを指定することで実現します。

基本図形に沿ってテキストを配置する機能はSVG 2で新規追加されました。

基本図形へのテキスト配置は 2015年シドニー会議で決議されました。

'd'属性によるパス直接指定はSVG 2で追加されました。'd'属性は、2016年ロンドン編集会議で決定され、同時に'd'はプレゼンテーション属性へ昇格し、'path'へ改名されました。

パス上のテキストは概念的には、整形済みテキストの1行と同様ですが、それをパスに沿わせて変形したものです。特記以外、整形済みテキストに適用されるすべてのプロパティはパス上のテキストにも適用されます。

11.8.1. ‘textPath’要素

textPath
カテゴリ:
グラフィックス要素, 描画要素, テキストコンテンツ要素, テキストコンテンツ子要素
内容モデル:
以下の要素または文字データを任意個・任意順で含めることができます:a, animate, clipPath, marker, mask, script, set, style, tspan
属性:
DOMインターフェース:
SVG 2 要件: textPath stretch methodについてより正確な説明を持つこと。
決議: 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%に制限すると、テキストがパス上を移動するような効果を簡単に作成できなくなります。

パス上にミッドポイントがない組版文字は描画されません。

startOffsetの値によるクリッピング例

startOffset属性値ごとの描画例。上から下へ:デフォルト値、50%、-50%。

最下段のパスは左側のみ「path.」が表示されるべきです。ChromeとSafariは0%〜100%外のoffsetに非対応。Chromeバグ:https://bugs.chromium.org/p/chromium/issues/detail?id=476554

単一の閉じたサブパス基本図形の同等パス含む)からなる場合、組版文字はパス上を一周して描画されます。テキストはtext-anchorプロパティで決定される位置に、startOffset属性で配置されます。startend)値の場合、テキストはラインの開始(終了)から次に初期位置に戻るまで描画されます。middleの場合は、中央から両方向に、初期位置から等距離の点まで描画されます。

円形パス上でstartOffset値による描画例

circle参照のパス上テキストにおけるstartOffset値の描画例。左:0。右:75%または-25%。赤円はパスの開始点(円の正規分解後)を示す。

text-anchor値による円形パス上テキスト描画例

circle参照のパス上テキストにおけるtext-anchor属性値ごとの描画例。 左:'start'。中央:'middle'。右:'end'。 赤丸はパスの開始点(円の正規分解後)を、青四角は描画開始点(startOffset値75%でパス開始からシフト)を示す。灰色の矢印は組版文字配置の方向と停止点。directionrtlなら矢印は逆向き。

基本図形で全グリフを描画することは2015年シドニー会議で合意済(議事録には未記載)。単一閉じたサブパス・1周に限定し、'startOffset'属性で制御するのは2016年ロンドン編集会議で合意。

<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

グリフを描画するpath要素または基本図形要素へのURL参照path属性がない場合に使用されます。 この属性を使い、<url>が無効(例:該当する要素が存在しない、参照先がpath要素や基本図形でない等)の場合、textPath要素はエラーとなり、内容全体が描画されません。

URL参照属性非推奨XLink属性の共通処理を参照してください。

URL [URL]
初期値
上記参照
アニメーション可能
はい

参照されたpath要素や基本図形要素内のパスデータ座標は、現在のtext要素の座標系と同じであるとみなされます(path要素で定義された座標系でなく)。参照先path要素や基本図形要素のtransform属性は、現在のtext要素の現在のユーザー座標系に対する補助変換を表します(text要素のtransformプロパティによる調整も含む)。例:

<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">Text on a path</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">Text on a path</textPath>
    </text>
  </g>
</svg>
  

さらに、次とも等価です:

<svg xmlns="http://www.w3.org/2000/svg">
  <text transform="rotate(45)">
    <textPath path="M0,20 L80,40 160,20"
            >Text on a path</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">
      We go up, then we go down, then up again
    </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属性はtextおよびtspan要素でのみ指定可能ですが、パス上テキストのグリフ描画にも影響する場合があります(パス上テキストのレイアウト規則参照)。

<?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 - textPath内のtspan</desc>

  <use href="#MyPath" fill="none" stroke="red"  />
  <text font-family="Verdana" font-size="42.5" fill="blue" >
    <textPath href="#MyPath">
      We go
      <tspan dy="-30" fill="red" >
        up
      </tspan>
      <tspan dy="30">
        ,
      </tspan>
      then we go down, then up again
    </textPath>
  </text>

  <!-- 'rect'要素でビューポートのアウトラインを表示 -->
  <rect x="1" y="1" width="998" height="298"
        fill="none" stroke="blue" stroke-width="2" />
</svg>
例 toap02 — textPath内のtspan

例 toap02

この例をSVGとして表示 (SVG対応ブラウザのみ)

例 toap03は、textPath要素でstartOffset属性を使い、テキスト文字列の開始位置をパス上の特定位置に指定する例です。パスの終端からはみ出したグリフは描画されません(パス上テキストのレイアウト規則参照)。

<?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%">
      We go up, then we go down, then up again
    </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">
      Choose shame or get war
    </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要素内の最初のグリフを拡大表示したものです。

パス上テキストの拡大図

上部の小さな点はグリフがパスに接続される点です。グリフを囲むボックスは、グリフがパスの接点での曲線の接線に平行になるよう回転されていることを示します。またボックスはグリフのcharwidth(横書きテキストレイアウトでグリフを描画するときに現在のテキスト位置が水平に進む量)も示します。

次の図はさらに拡大して詳細なレイアウト規則を示します。

パス上テキストの詳細レイアウト図

左から右の横書きテキストをパス上にレイアウトする場合(グリフ向きがインライン基本方向に垂直になる場合)、レイアウト規則は以下の通りです:

パス上縦書き(グリフ向きがインライン基本方向に平行)の場合、レイアウト規則は以下の通りです:

上記計算で、startpoint-on-the-pathまたはendpoint-on-the-pathがパス端より外の場合は、パス端での接線に平行な直線でパスを延長し、midpoint-on-the-pathを計算できるようにします。

インライン基本方向が水平の場合、texttspan要素の‘x’属性はパス上の新しい絶対オフセット(明示的なstartpoint-on-the-path値)を表し、‘y’属性は無視されます。 インライン基本方向が垂直の場合、texttspan要素の‘y’属性がパス上の新しい絶対オフセット(明示的なstartpoint-on-the-path値)を表し、‘x’属性は無視されます。

textPath内のすべての文字を配置した後、現在のテキスト位置はパスの終端に設定されます(パスが単一閉ループの場合はstartOffsetで補正)。つまり、textPath要素の後(かつtext要素内)の明示的な位置指定(xy属性)がないテキストは、パスの終端から配置されます。

<textPath>直後テキストの描画開始点(赤点)を示す図

明示的な位置指定のないtextPath要素の後のテキストの開始点はパス終端(赤点)。

パス終端を最後の文字位置ではなく選ぶのは、フォント等に依存せず著者にとって予測しやすいためです。2016年ロンドン編集会議で決定。GitHub Issue 84も参照。

11.9. テキストの描画順序

text要素は1つ以上のチャンクに分けて描画されます。 各チャンク(テキストレイアウトアルゴリズムで生成)を文書順で順に描画します。 描画される各チャンクは1つ以上のグリフからなり、1つのパスとして塗りつぶしとストロークが行われます。

これは、チャンク内のすべてのグリフを塗りつぶしてから一度にストロークするか、またはpaint-orderプロパティの値に従って逆の順で処理することを意味します。

塗りつぶし処理上、textは0個以上の同等パス(チャンクごとに1つ)を持ちます。各同等パスは、そのチャンク内のグリフごとに1つのサブパスを持ちます。

fill-ruleプロパティはSVGテキスト要素には適用されないため、 同等パス内のサブパスの順序は特に重要ではありません。

各サブパスの開始位置や、パスがグリフ形状の周囲を進む方向は定義されません。ただし、ユーザーエージェントは同じフォント・グリフについて一貫性を持つべきです。

これは、SVGテキストに対する破線ストロークが実装ごとに異なる位置にダッシュパターンを配置する場合があることを意味します。

11.10. プロパティおよび疑似要素

CSSにはテキストスタイル用の多数のプロパティがありますが、 SVGに適用されるのは主に2系統:どのグリフを描画するかを決定するもの (font-family, font-styleなど)と、 段落レベルで適用されるもの(direction, writing-mode, line-height, letter-spacingなど)。

SVGテキスト要素で必須サポートとなるCSSプロパティは スタイリング章に記載されています。

さらに、フォント選択に@font-face規則がサポートされ、text要素上で::first-lineおよび::first-letter疑似要素もサポートされます。 インタラクティブモードでは::selection疑似要素もサポートされるべきです。

SVGユーザーエージェントが他のCSSプロパティ(テキストレイアウトや描画に影響するもの)をサポートする場合もあります。その効果は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属性値、tspan要素の最初の描画文字へのxy属性値、textPath要素の初期位置決定などによります。各テキストチャンクには最終現在のテキスト位置(最後のグリフ配置後)があり、これらは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で中央揃えされた2行テキスト画像。

改行で2つのテキストチャンクが生成され、それぞれ独立してアンカーされる。

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'の3行テキスト画像。

テキストは3つのテキストチャンクxy属性値が3つあるため)に分割され、それぞれ独立してアンカーされる。

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 issue 80参照。

11.10.2. SVGへの適応

このセクションでは仕様中他で扱っていないCSSプロパティで、SVG固有の適応があるかSVG 1.1から大きく変更されたものを説明します。

SVG 2 要件: CSS3 Fontsを参照すること。
決議: SVG 2はCSS3 Fontsに依存する。
目的: Webフォント機能のためCSS 2.1やCSS3との整合、フォントの高度組版機能へのアクセス提供。
担当者: Chris (ACTION-3123)

11.10.2.1. ‘font-variant’プロパティ

CSS Font Module Level 3では、'font-variant'プロパティの意味がCSS 2.1時代から変更されました。これは再定義され(機能拡張も大きい)、単一フォント内のバリアント選択用のショートハンドとなりました。

SVG 2ではすべてのfont-variantサブプロパティ(例:font-variant-ligatures)の実装が必須です。

11.10.2.2. ‘line-height’プロパティ

SVGではline-heightプロパティで複数行テキスト(横書き・縦書き両方)の行間リードスペース量を決定します。パス上テキストには適用されません。

ここで追加情報を除けば規範的定義はCSS 2.1仕様([CSS2])にあります。

CSS Inline Module Level 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の役割(text-anchorプロパティの基準点など)がやや明確になりましたが、解釈の余地が残りました。SVG 1.0・1.1で複数行テキストが許可されていなかったことも混乱要因でした。

ここで追加情報を除けば規範的定義はCSS Writing Modes Level 3([css-writing-modes-3])にあります。

11.10.2.4. ‘direction’プロパティ

このプロパティはtexttspan要素のインライン基本方向を指定します。これはtext-anchorinline-sizeプロパティで使われる行の開始終了点を定義します。また、unicode-bidiプロパティ値がembedbidi-overrideの場合、文字配置方向にも影響します。

directionプロパティはインライン基本方向に垂直な向きのグリフ(通常の横書きラテン・アラビア文字や、縦書きで90度回転したラテン・アラビア文字など)にのみ適用されます。

レビュワーは、これがCSS3 Writing modesと一致しているか特に注意して確認してください。

ここで追加情報を除けば規範的定義は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">
    文書の主要言語が右から左の場合の'direction'プロパティ利用簡易例。
  </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">
    主要言語が右から左の場合の'direction'および'unicode-bidi'プロパティ利用例。
  </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-orientationsidewaysの場合、dominant-baselineauto値はalphabeticですが、後方互換のためグリフはxy属性にcentralで整列されるべきです。

旧動作を好む実例があればぜひ情報提供ください。

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で削除されました。ユーザーエージェントは、レガシーSVGコンテンツ対応のため必要ならこの値を'0'として計算しても構いません

'baseline'値は、'vertical-align'が'alignment-baseline'と'baseline-shift'のショートハンドとなった際に削除されました('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ビューポート基準のパーセンテージ値は有用でないとされます。これによりCSSと'letter-spacing'定義が一致します。

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ビューポート基準のパーセンテージ値は有用でないとされます。これによりCSSと'word-spacing'定義が一致します。

11.10.2.10. ‘text-overflow’プロパティ

SVG 2要件: text-overflow機能の追加。
決議: SVG 2でtext-overflowを追加する。
目的: CSSと整合し、すべてのテキストが表示されない場合の表示を可能にするため。
担当者: Erik (ACTION-3003)

SVG 2で新規追加。 定義済み折返し領域をはみ出すテキスト文字列をUAがより便利に処理できるように追加。SVGとHTML/CSSテキスト処理を整合。

'text-overflow'の定義はCSS3 UI仕様参照。[css-ui-3]

SVGではtext-overflowプロパティで、line boxをはみ出した場合(例:white-spaceプロパティ値がnowrap)、テキストコンテンツブロック要素の描画方法を制御します。このプロパティは整形済みテキストやパス上テキストには適用されません。

SVGでtext-overflowは、有効な折返し領域が指定されていれば、overflowプロパティ値に関係なく効果があります。

text-overflowプロパティ値がellipsisの場合、描画されるテキストが折返し領域をはみ出すと、領域内に収まるよう省略記号(…)が描画されます。描画上、省略記号はその挿入位置の文字を置き換えたものとして扱われます。

text-overflowプロパティ値がclipの場合、折返し領域をはみ出したテキストは切り取られます。文字は部分的に描画される場合もあります。

text-overflowに他の値を指定した場合、未指定と同じ扱いになります。

text-overflowの効果は純粋に視覚的なもので、省略記号自体はDOMには現れません。DOMメソッド上は、text-overflow未適用・折返し領域で制約されていない場合と同じ扱いです。

下記はtext-overflowの使用例です。 上段は通常の描画(white-spacepreでテキストがはみ出し、overflowvisibleで表示)。 中段はtext-overflowclip、 下段はtext-overflowellipsisの例です。

<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プロパティで制御します。これは以下2点を指定します:

値と意味はCSS Text Module Level 3で定義。[css-text-3]

white-spacepre-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>
日本語詩(各行七文字後で改行)例。

複数行縦書きテキストの改行例。詩は日本語「いろは歌」。行は伝統的な位置で改行されています。

11.10.3.2. レガシーの空白処理 ‘xml:space’プロパティ

互換性のため、SVG 2ではXML属性xml:spaceもサポートされており、text要素の文字データ内で空白文字の扱いを指定できます。新しいコンテンツではxml:spaceは使用せず、代わりにwhite-spaceプロパティを使用してください。

このセクションはxml:spaceの説明を簡略化し、ユーザーエージェントのスタイルシートでwhite-spaceプロパティで定義すべきです。CSS Text 4仕様の'white-space-collapse'プロパティのpreserve-spaces値は、xml:space=preserveに対応することを意図しています。(fantasaiはSVG 1.1の特殊なxml:space="preserve"挙動に合う値追加に合意しています。)

text要素の子要素にもxml:space属性を指定でき、その子要素のテキストコンテンツに適用されます。SVGユーザーエージェントはこの属性に特別な処理規則を持ちます(下記参照)。これはXMLのパース後やDOM構築後に発生する挙動です。

xml:spaceは継承可能な属性で、値は2つあります:

'default'
xml:spaceの初期値/デフォルト値)xml:space="default"時、SVGユーザーエージェントは元の文字データのコピーを使って以下を行います。最初に改行文字を全て削除。次にタブ文字をスペースに変換。その後、先頭と末尾のスペース文字を取り除く。さらに連続するスペース文字を1つにまとめます。
'preserve'
xml:space="preserve"時、SVGユーザーエージェントは元の文字データのコピーを使って、改行とタブ文字を全てスペース文字に変換します。その後、先頭・末尾・連続した複数スペースも含めて全て描画されます。つまり、xml:space="preserve"で描画すると、文字列"a b"("a"と"b"の間にスペース3つ)は"a b"(スペース1つ)よりも広い間隔になります。

下記の例はxml:space="default"時の行インデントの重要性を示します。2組の似た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要素のペアは、インデントされた文字データの効果を示します。1つ目のtext要素のxml:space="default"属性はユーザーエージェントに以下を指示します:

2組目のtext要素は、非インデント文字データの効果を示します。3つ目のtext要素のxml:space="default"属性はユーザーエージェントに以下を指示します:

XMLパーサは標準的な改行表現(例:"U+000D U+000A"、CR LFや単独のU+000DまたはU+000A)をU+000Aに変換してからアプリケーションに文字データを渡す必要があります。よってSVG内の改行は元リソースでどんな表記でもU+000A1文字で表されます。(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ショートハンドプロパティ(Line Decorationセクション、CSS Text Decoration Module Level 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等で)明示的に指定されていない場合、装飾宣言時点のテキストのfill/stroke値が使われます(下記例参照)。

text-decoration-linetext-decoration-styleプロパティはSVG 2で新規追加です。SVG 1.1/CSS 2.1のtext-decorationプロパティは、これらのプロパティのショートハンドとして後方互換変換されます。text-decoration-filltext-decoration-strokeはSVG固有プロパティで、将来的にCSS Text Decoration仕様に追加される可能性があります。

テキストおよび装飾の描画順序はCSS Text Decoration Module Level 3の「Painting Order of Text Decorations」で定義されます。装飾自体の塗り・線の描画順は、装飾宣言時点のpaint-orderプロパティ値で決まります。

例 textdecoration01text-decorationの例です。1行目はtext-decoration値未指定なので初期値text-decoration:noneで描画されます。2行目はtext-decoration:line-throughの例。3行目はtext-decoration:underlineの例。4行目は、装飾宣言要素のfill/stroke値で装飾される規則を示します(この場合、text要素上で指定されているので、全テキストが青fill・赤strokeの下線になりますが、単語ごとに異なるfill/stroke指定があっても適用されます)。ただし"different"だけはtspan要素上でtext-decorationを明示指定しているため、その単語だけ黄色fill・濃緑strokeの下線になります:

<?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>例 textdecoration01 - 'text-decoration'プロパティの挙動</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>
例 textdecoration01 — 'text-decoration'プロパティの挙動

例 textdecoration01

この例をSVGとして表示(SVG対応ブラウザのみ)

11.11.1. ‘text-decoration-fill’ および‘text-decoration-stroke’プロパティ

CSSワーキンググループは2014年CSS/SVG合同TPAC会議でSVG仕様の'text-decoration-fill'/'text-decoration-stroke'プロパティを承認しました。2015年シドニー合同会議でもこれらプロパティの使用を再度支持しました。今後CSSテキスト装飾仕様で'text-decoration-fill'/'text-decoration-stroke'プロパティが追加される際、テキストへの'fill'/'stroke'プロパティ適用も同時に許可される予定です。

名前: text-decoration-fill
値: <paint>
初期値: 本文参照。
適用対象: テキストコンテンツ要素
継承: 本文参照。
パーセンテージ: 該当なし
メディア: 視覚
算出値: 指定値。ただし<color>値は算出済み、<url>値は絶対化される。
アニメーション可能: はい
名前: text-decoration-stroke
値: <paint>
初期値: 本文参照。
適用対象: テキストコンテンツ要素
継承: 本文参照。
パーセンテージ: 該当なし
メディア: 視覚
算出値: 指定値。ただし<color>値は算出済み、<url>値は絶対化される。
アニメーション可能: はい

11.12. テキスト選択とクリップボード操作

適合SVGビューアは、テキスト選択機能(例:マウス等のポインタデバイス搭載)と、コピー&ペースト用のシステムクリップボードを持つシステム上で、以下をサポートする必要があります。

テキスト選択操作は以下すべてが成立した場合に開始されます:

テキスト選択操作が進行中(例:ユーザーがマウスボタンを押し続けている間)、他のグラフィックス要素への全ての関連イベントは無視されます(選択操作はモーダル)。SVGユーザーエージェントは::selection疑似クラス用スタイルを適用して、選択された文字を動的に表示します。 選択処理中にポインタが移動すると、選択操作の終了グリフは、同じtext要素内でポインタに最も近いグリフセルとなります。選択開始から終了までのtext要素内の全ての文字は、キャンバス上の位置や終了点の上にグラフィックス要素があっても、強調表示されます。

テキスト選択操作が終了したら(例:マウスボタンを離す)、選択されたテキストは、選択解除イベント(例:マウスボタン押下等)が発生するまで強調表示されたままになります。

テキスト選択操作中にどの文字を強調表示するかの詳細ルールは テキスト選択実装ノートに記載されています。

システムクリップボードを持つシステムでは、SVGユーザーエージェントは、現在選択中のテキストをシステムクリップボードへコピーするためのUIを提供する必要があります。SVGユーザーエージェントは、選択されたテキスト文字列をシステムのプレーンテキスト用クリップボード形式で投稿すれば十分ですが、可能ならテキストのフォントプロパティ等を含むリッチテキスト形式でも投稿するのが望ましいです。

双方向テキストの場合、ユーザーエージェントは論理順でのテキスト選択をサポートしなければならず、双方向並び替えによってグリフの強調表示が非連続になる場合があります。ユーザーエージェントは、視覚的レンダリング順(双方向テキストレイアウトアルゴリズム適用後)で選択できる代替機能も提供できます。この場合、クリップボードへのコピー要求時、ユーザーエージェントは視覚的に選択された文字のみをクリップボードへコピーするよう調整する必要があります。

SVG著者およびSVG生成ツールは、テキスト選択がWebブラウザ等のSVG閲覧アプリで正しい順序になるよう、テキスト文字列の順序を工夫すべきです。つまり、DOM上の順番が自然な読書順になるよう配置してください。

11.12.1. テキスト選択実装ノート

以下はテキスト選択操作でどの文字が選択されるかを決定するアルゴリズムの実装ノートです。

選択操作中(例:ユーザーがマウスでクリック&ドラッグして選択範囲を指定)、ユーザーエージェントは開始選択位置終了選択位置を決定します。どちらも文字間の位置を表します。開始・終了選択位置を決定した後、ユーザーエージェントは適切な文字を選択します。選択結果は次のいずれかです:

ポインタデバイス搭載システムでは、開始選択位置の決定は、現在のポインタ位置から見て描画済みグリフに対応する文字間境界のうち最適(例:最も近い)ものを選びます(選択操作開始時のイベント例:マウスダウン)。その後、選択操作完了まで(例:マウスドラッグ後にマウスアップ)を追跡します。選択操作の終了時、終了選択位置として、最適な文字間境界(例:最も近い)を決定します。

双方向性による文字並び替えがなければ、選択範囲は開始選択位置終了選択位置の間の全ての文字となります。例えば、text要素の文字列が"abcdef"で、開始・終了選択位置が0と3("a"の左端が0)なら、選択範囲は"abc"になります。

双方向テキストの選択を実装する場合、選択開始(または終了)が論理順で隣接しない文字間の場合、選択範囲として複数の組合せがあり得ます。選択アルゴリズムは、視覚的レンダリング順に最も近い選択範囲を選ぶべきです。

複数文字が1つ以上のグリフに不可分にマッピングされる場合、ユーザーエージェントはグリフセット中間で選択開始を禁じるか、グリフセットの領域を対応文字ごとに割り当てる工夫をしてもよいです。

マウス等のポインタデバイス対応システムでは、イベントハンドラやリンクが割り当てられ、イベント処理優先度のため選択が阻害される場合でも、ユーザーエージェントはテキスト選択機構を提供する必要があります(Pointer events参照)。 一実装例:ポインタデバイス対応プラットフォームでは、文字セル周囲に小さな追加領域を設け、テキスト選択のみを開始しイベントハンドラやリンクは発火しないようにできます。

11.13. DOMインターフェース

SVG 2 要件: text要素をアウトラインパスデータへ変換するDOMメソッドを持つこと。
決議: ‘text’要素をアウトラインパスデータへ変換するDOMメソッドを追加(機能はFXTFへ移す可能性あり)。
目的: テキストをパスとして操作可能にするため。
担当者: Cameron (ACTION-3076)
ステータス: 将来の要望リスト

11.13.1. Interface SVGTextContentElement

SVGTextContentElement インターフェイスは、子テキストコンテンツの描画をサポートする要素によって実装されます。

このインターフェイスのメソッドで文字のインデックスや文字数を参照する場合、その参照はUTF-16コード単位のインデックスまたはUTF-16コード単位の数として解釈されます。これは、DOM Level 2 Coreで CharacterData インターフェイスのメソッドが文字データ内のインデックスやカウントにUTF-16コード単位を使用することと一貫性を保つためです。例えば、text 要素のテキストコンテンツがU+10000のようなBMP外文字1文字の場合、その要素で getNumberOfChars を呼び出すと、1文字を表すために2つのUTF-16コード単位(サロゲートペア)が使われているので2を返します。

[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 コンテンツ属性に対応します。数値型値は、上記表の数値型長調整定数に従います。

getNumberOfChars メソッドは、現在の要素内で描画可能な アドレス可能文字 の総数を返します(実際に描画されるかどうかに関係なく)。 getNumberOfChars() が呼ばれると、以下の手順が実行されます:

  1. node をこのメソッドが呼ばれた要素またはノードとする
  2. node がDOMテキストノードなら、親要素の white-space プロパティ値に従い空白を正規化した後のテキスト内容の長さを返す。
  3. nodeElement なら:
    • 要素が 非描画(例:display プロパティused値が 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 が負なら throw IndexSizeError
  3. length をユーザー単位の長さとして0で初期化。
  4. この要素内DOMの各 アドレス可能文字 の中でインデックスが charnum ≤ index < (charnum + nchars) のものについて:
    1. 文字が 組版文字に対応し、かつその 組版文字に対応する最初の文字なら:
      1. その 組版文字 のadvance(フォントカーニングも調整)を length に加算。
      2. letter-spacingword-spacing プロパティで直後に追加スペースがあれば、それも length に加算。

      たとえばリガチャの一部だけ部分文字列に含まれている場合、その 組版文字 のadvanceや letter/word-spacing は最初の文字のtext lengthに割り当てられます。

  5. length を返す。

SVGの過去バージョンでは、このメソッドや getComputedTextLength で、子要素の dxdy によるインライン方向位置調整も含める必要があり、返り値はユーザーエージェントの textLength 計算値と等しくなるはずでした。ですが仕様も実装も不完全かつ有用性が低いため、実装に合わせて単純化されました。

テキスト長メソッドの変更は 2015年8月パリF2Fで決議

要素 element 内インデックス index の文字に対して 組版文字を対応させるには、以下の手順を実行します:

  1. この要素内DOMの各 アドレス可能文字 にインデックスを割り当て、最初の文字が 0。
  2. last を割り当てられた最大インデックスとする。
  3. charnum < last かつ、そのインデックスの文字が 組版文字に対応しない間:
    1. charnum = charnum + 1。
  4. charnum が最大インデックスより大きいなら null を返す。
  5. それ以外なら、その 組版文字を返す。

getStartPositionOfChar メソッドはテキストレイアウト後の 組版文字 の位置を取得します。getStartPositionOfChar(charnum) が呼ばれると、以下の手順を実行します:

  1. 現在の要素内インデックス charnum の文字に対して 組版文字を対応させる結果を cluster とする。
  2. cluster が null なら throw IndexSizeError
  3. p を、そのインデックスの文字に対応する 組版文字アラインメントポイント(要素座標系)とする。
  4. p を表す新規作成・detachedDOMPoint オブジェクトを返す。

getEndPositionOfChar メソッドはテキストレイアウト後の 組版文字 の終了位置を取得します。getEndPositionOfChar(charnum) が呼ばれると、以下の手順を実行します:

  1. 現在の要素内インデックス charnum の文字に対して 組版文字を対応させる結果を cluster とする。
  2. cluster が null なら throw IndexSizeError
  3. pcluster のアラインメントポイント(インデックスの文字に対応、要素座標系)とする。
  4. directioncluster のadvance方向の単位ベクトルとする。この方向は書字モード、文字のdirection、text-orientationglyph-orientation-horizontalglyph-orientation-vertical、適用される rotate 値、textPathによる回転などを考慮します。
  5. advancecluster のadvanceとする。
  6. p = p + advance · direction とする。
  7. p を表す新規作成・detachedDOMPoint オブジェクトを返す。

getExtentOfChar メソッドは、指定した 組版文字 に対応するグリフセルの厳密なバウンディングボックスを計算します。getExtentOfChar(charnum) が呼ばれると、以下の手順を実行します:

  1. 現在の要素内インデックス charnum の文字に対して 組版文字を対応させる結果を cluster とする。
  2. cluster が null なら throw IndexSizeError
  3. quad を現在の要素座標系で回転されている可能性がある cluster のグリフセル矩形とする。
  4. rectquad の周囲で最も厳密なバウンディングボックス矩形(要素座標系)とする。
  5. rect を表す新規作成 DOMRect オブジェクトを返す。

getRotationOfChar メソッドは 組版文字 の回転角度を取得します。getRotationOfChar(charnum) が呼ばれると、以下の手順を実行します:

  1. 現在の要素内インデックス charnum の文字に対して 組版文字を対応させる結果を cluster とする。
  2. cluster が null なら throw IndexSizeError
  3. directioncluster のadvance方向角度(度)とする。この方向は書字モード、文字のdirection、text-orientationglyph-orientation-horizontalglyph-orientation-vertical、適用される rotate 値、textPathによる回転などを考慮します。
  4. direction を返す。

getCharNumAtPosition メソッドは、指定した座標系上の位置にどの文字が原因でグリフが描画されたかを調べるために使われます。文字とグリフの関係が1対1ではないため、該当 組版文字 の最初の文字だけが返されます。 getCharNumAtPosition(point) が呼ばれると、以下の手順を実行します:

  1. この要素内DOMの各文字にインデックスを割り当て、最初の文字が 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. charnumcount または endcount なら throw IndexSizeError
  5. 文書の selection から全 range を削除する。[DOM][EDITING]
  6. selectiondirection を forwards に設定。
  7. selection に新しい range を追加。その start は (node, charnum)、end は (node, end)。

引数チェックと例外スローを除けば、これは以下と同等:

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. Interface SVGTextPositioningElement

SVGTextPositioningElement インターフェイスは、個別テキストグリフの位置指定属性をサポートする要素によって実装されます。これは SVGTextElement および SVGTSpanElement に継承されます。

[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;
};

x, y, dx, dy, rotate の各IDL属性は、 それぞれ 反映される xydxdyrotate コンテンツ属性に対応します。

11.13.3. Interface SVGTextElement

SVGTextElement オブジェクトは、DOM内の text 要素を表します。

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

11.13.4. Interface SVGTSpanElement

SVGTSpanElement オブジェクトは、DOM内の tspan 要素を表します。

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

11.13.5. Interface SVGTextPathElement

SVGTextPathElement オブジェクトは、DOM内の textPath 要素を表します。

[Exposed=Window]
interface SVGTextPathElement : SVGTextContentElement {

  // textPath Method Types
  const unsigned short TEXTPATH_METHODTYPE_UNKNOWN = 0;
  const unsigned short TEXTPATH_METHODTYPE_ALIGN = 1;
  const unsigned short TEXTPATH_METHODTYPE_STRETCH = 2;

  // textPath Spacing Types
  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 includes 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 コンテンツ属性に対応します。数値型値は、上記表の数値型スペーシングタイプ定数に従います。