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 콘텐츠는 사용자의 선호 언어에 따라 서로 다른 텍스트 문자열을 대체함으로써 가능합니다.

그려질 문자는 문자 데이터 ([xml], 2.4절)로 text 요소 내에서 표현됩니다. 결과적으로:

접근성 측면에서, 문서에 포함된 텍스트에는 그 기능을 나타내는 적절한 시맨틱 마크업을 사용하는 것이 좋습니다. 예를 들어, 다이어그램의 일부에 대하여 눈에 보이는 라벨을 제공하는 텍스트 요소는 해당 그룹 또는 경로 요소의 id에 참조되어야 하며, aria-labelledby 속성으로 연결하는 것이 바람직합니다. 자세한 내용은 SVG 접근성 가이드라인을 참고하세요.

11.1.1. 정의

문자(character)
문자는 XML에서 정의된 텍스트의 원자적 단위입니다 [XML].

본질적으로 유니코드 코드 포인트입니다. 문자는 제어 명령(탭, 줄 바꿈, 캐리지 리턴 등), 렌더링 가능한 기호(글자, 숫자, 구두점 등), 또는 수정자(조합 악센트 등)일 수 있습니다.

주소 지정 가능한 문자(addressable character)
문자 중 텍스트 위치 속성 및 SVG DOM 텍스트 메소드를 통해 주소 지정할 수 있는 문자. 레이아웃 중 제거되는 문자(예: 접힌 공백 문자)나, display 속성이 none인 요소 내의 문자는 주소 지정 불가. 주소 지정 가능한 문자는 UTF-16 코드 유닛 기준 인덱스로 지정됨(즉, U+FFFF 이상의 단일 유니코드 코드 포인트는 두 개의 주소 지정 가능한 문자로 취급; UTF-16 코드 유닛은 16비트). 인덱스는 text-transform 변환 적용 이전에 결정되며, SVGTextContentElement 인터페이스 메소드 설명 참고.

향후 CSS에서 생성된 콘텐츠 텍스트 지원이 도입되면, 해당 텍스트도 주소 지정 가능한 문자 배열에 포함될 수 있습니다.

타이포그래픽 문자(typographic character)
라틴 알파벳 글자(음절·부호 포함), 한글 음절, 한자, 미얀마 음절군 등 문자 시스템의 불가분 단위로, 특정 타이포그래픽 작업(줄 바꿈, 첫 글자 효과, 자간, 정렬, 수직 배열 등)에 따라 나뉘지 않습니다. 공식 정의와 유니코드 grapheme cluster와의 관계는 CSS Text Module Level 3 ([css-text-3]) 참고.
글꼴(font)
글꼴은 글리프의 체계적인 모음으로, 여러 글리프들이 특정한 외형이나 스타일을 공유합니다.
글리프(glyph)
글리프는 글꼴 내에서 렌더링된 콘텐츠의 단위를 나타냅니다. 일반적으로 하나의 문자와 대응하지만(예: 문자 "A"는 하나의 글리프로 렌더링됨), 경우에 따라 하나의 문자를 여러 글리프로 렌더링하거나(악센트 포함 문자 등), 하나의 글리프로 여러 문자를 렌더링할 수도 있습니다(합자 등). 보통 글리프는 도형(예: 경로)으로 정의되며, 작은 크기의 텍스트를 명확하게 표시하기 위한 렌더링 힌트 등의 추가 정보가 포함될 수 있습니다.
텍스트 콘텐츠 요소(text content element)
텍스트 콘텐츠 요소는 SVG에서 텍스트 문자열을 캔버스에 렌더링하는 요소입니다. SVG 텍스트 콘텐츠 요소는 다음과 같습니다: text, textPath, tspan.
텍스트 콘텐츠 자식 요소(text content child element)
텍스트 콘텐츠 자식 요소는 다른 텍스트 콘텐츠 요소의 자손으로 허용되는 텍스트 콘텐츠 요소입니다. SVG에서 텍스트 콘텐츠 자식 요소는 다음과 같습니다: textPath, tspan.
텍스트 콘텐츠 블록 요소(text content block element)
텍스트 콘텐츠 블록 요소는 텍스트 단위에 대해 독립적으로 사용되는 텍스트 콘텐츠 요소로, 일부 자식 텍스트 콘텐츠 요소를 포함할 수 있습니다(예: ‘tspan’). SVG 2에서는 text만을 블록 요소로 정의합니다.
콘텐츠 영역(content area)
텍스트가 일반적으로 배치되는 영역입니다. 이는 CSS 콘텐츠 영역과 동일합니다. 실제 텍스트 레이아웃이 발생하는 영역은 패딩이나 제외 영역으로 인해 더 작아질 수 있습니다.
랩핑 컨텍스트(wrapping context)
텍스트 레이아웃 시 콘텐츠 영역에서 제외될 하나 이상의 영역(도형)입니다. 이는 CSS 래핑 컨텍스트와 동일합니다.
랩핑 영역(wrapping area)
텍스트가 배치되는 영역에서 패딩 또는 제외 영역(랩핑 컨텍스트)을 뺀 나머지 영역입니다. 이는 CSS 래핑 영역과 동일합니다.
라인 박스(line box)
한 줄의 텍스트를 레이아웃하기 위해 사용된 모든 콘텐츠를 포함하는 사각형 영역입니다. 이는 CSS 라인 박스와 동일합니다.

여러 CSS 3 텍스트 레이아웃 명세에서 이 용어를 사용하지만, 아직 공식 정의는 없습니다. 그래서 CSS 2.1로 링크하며, CSS WG에 이슈가 제기됨.

인라인 기본 방향(inline-base direction)
텍스트의 한 줄 또는 일부에서 콘텐츠가 정렬되는 주요 방향입니다. 이는 줄 또는 줄의 일부의 시작, 을 정의하며(예: text-anchor 프로퍼티 적용 방식에 영향), direction 프로퍼티로 결정됩니다. (참고: 줄 내 문자 순서는 주로 유니코드 bidi 알고리즘에 의해 결정되며, 인라인 기본 방향이 직접 제어하지 않습니다.)
블록 흐름 방향(block-flow direction)
라인 박스가 쌓이는 방향입니다. writing-mode 프로퍼티로 결정됩니다.
정렬 점(alignment point)
타이포그래픽 문자에서 현재 텍스트 위치에 맞춰야 하는 점입니다. 이는 글리프 셀 메트릭에 따라 결정되며, 스크립트 및 인라인 기본 방향에 따라 달라질 수 있습니다.
현재 텍스트 위치(current text position)
현재 사용자 공간에서 다음으로 렌더링할 타이포그래픽 문자의 정렬 점이 위치해야 하는 점입니다.
텍스트 청크(text chunk)
모든 문자가 함께 배치되는 독립적인 텍스트 블록입니다. x, y 속성 또는 강제 줄 바꿈에 따른 절대 위치 조정이 있을 때마다 새로운 텍스트 청크가 생성됩니다. 합자 대체 및 바이디 재정렬은 텍스트 청크 내에서만 발생합니다. 텍스트 청크는 서식 유지 텍스트에만 관련됩니다.
공백 문자(white space characters)
다음 문자가 공백 문자로 간주됩니다: U+0009 캐릭터 탭(Tab), U+000C 폼 피드(FF), U+000D 캐리지 리턴(CR), U+000A 줄 바꿈(LF), U+0020 스페이스(공백).

11.1.2. 폰트와 글리프

폰트는 글리프들의 모음과 그 글리프를 시각적 매체에 문자를 표시하기 위해 필요한 기타 정보(폰트 테이블 전체)를 포함합니다. 글리프 모음과 폰트 테이블의 조합을 폰트 데이터라고 합니다.

폰트는 서식자(텍스트 셰이퍼)가 글리프 시퀀스를 재정렬, 결합, 위치 지정하여 하나 이상의 복합 글리프를 생성할 수 있도록 대체 및 위치 지정 테이블을 제공할 수 있습니다. 결합은 단순한 합자일 수도 있고, 여러 자음과 모음 글리프를 재정렬해서 결합하는 인도 음절처럼 복잡할 수도 있습니다. 테이블은 언어에 따라 다를 수 있어, 언어에 맞는 문자 형태를 사용할 수 있게 합니다.

글리프가 단순 또는 복합이든 조판 목적에서 불가분의 단위를 나타내면 타이포그래픽 문자로 간주합니다.

합자는 고급 텍스트 레이아웃의 중요한 특징입니다. 일부 합자는 선택적이고, 다른 합자는(예: 아랍어) 필수입니다. 합자 형성에는 다음과 같은 명시적 규칙이 적용됩니다:

SVG 2 요구사항: Web Open Font Format(WOFF) 명시적 지원 포함.
결정: SVG 2에서 WOFF 지원을 필수로 함.
목적: 국제화 및 고급 타이포그래피를 위한 OpenType 기능 전체에 접근 가능하게 함.
담당자: Chris(조치 없음)
상태: 완료

적절한 텍스트 렌더링은 저작 시 사용한 폰트와 동일한 폰트를 사용하는 것에 의존할 수 있습니다. 이 때문에 SVG는 Font Resources(CSS Fonts Module)에 정의된 다운로드 가능한 폰트 지원을 요구합니다. 특히 Web Open Font Format[WOFF] 지원이 필수입니다.

SVG 2의 새로운 기능으로, WOFF를 통해 저자는 콘텐츠를 올바르게 렌더링하는 데 필요한 폰트를 직접 제공할 수 있습니다. 여기에는 복잡한 스크립트, 선택적 합자, 스와시, 올드 스타일 숫자 등 OpenType 테이블을 지원하는 폰트가 포함되며, WOFF로 폰트 압축, 서브셋 생성, 라이선스 정보 포함도 가능합니다.

11.1.3. 글리프 메트릭 및 레이아웃

글리프 선택 및 위치 지정은 일반적으로 CSS 규칙에 따라 처리됩니다. 하지만 경우에 따라 SVG 텍스트의 최종 레이아웃은 개별 글리프의 기하학적 속성에 대한 지식을 필요로 합니다.

기하학적 폰트 특성은 EM 박스를 기준으로 한 좌표계로 표현됩니다(EM은 폰트 글리프의 높이에 대한 상대적 단위). 1 EM 높이, 1 EM 너비의 박스를 디자인 공간이라 하며, 이 공간은 EM을 여러 units per em으로 분할하여 기하학적 좌표를 부여합니다.

units per em은 폰트의 특성입니다. 일반적으로 1000 또는 2048이 사용됩니다.

EM 박스의 좌표 공간은 디자인 공간 좌표계라 불립니다. 확장 가능한 폰트에서 글리프를 그릴 때 사용하는 곡선과 선은 이 좌표계로 표현됩니다.

일반적으로 이 좌표계의 (0,0) 점은 EM 박스의 왼쪽 가장자리에 위치하지만, 왼쪽 아래 모서리는 아닙니다. 로마자 대문자의 아래쪽 Y 좌표는 보통 0입니다. 소문자 로마자의 디센더는 음수 좌표값을 가집니다.

EM 박스 안의 'M' - 좌표계, 기준선, 상승, 하강 위치 표시.

EM 박스(파란색 사각형) 안의 'M'. 'M'은 기준선(파란색 선) 위에 있습니다. 좌표계의 원점은 작은 검은색 원으로 표시됨.

SVG는 폰트 테이블이 최소 3가지 폰트 특성을 제공한다고 가정합니다: 상승(ascent), 하강(descent), 기준선 테이블(baseline-tables). 상승은 폰트의 (0,0) 점에서 EM 박스의 위쪽까지의 거리, 하강은 (0,0) 점에서 EM 박스의 아래쪽까지의 거리입니다. 기준선 테이블은 아래에서 설명합니다.

OpenType 폰트([OPENTYPE])에서는 수평 글쓰기 모드에서 상승과 하강은 OS/2 테이블의 sTypoAscender, sTypoDescender 항목으로 제공됩니다. 수직 글쓰기 모드의 하강(이 경우 (0,0) 점에서 글리프 왼쪽 가장자리까지의 거리)은 보통 0입니다(원점이 왼쪽 가장자리에 있으므로). 수직 글쓰기 모드의 상승은 1 em이거나 OpenType Base 테이블의 ideographic top baseline 값에 의해 지정됩니다.

글리프는 각 글리프의 특정 위치, 즉 정렬 점을 기준으로 배치됩니다. 수평 글쓰기 모드에서는 글리프의 정렬 점이 수직으로 정렬되고, 수직 글쓰기 모드에서는 수평으로 정렬됩니다. 정렬 점의 위치는 스크립트에 따라 다릅니다. 예를 들어, 서양 글리프는 대문자 아래쪽에 정렬되고, 북인도 글리프는 글리프 상단 근처 수평선에 정렬되며, 극동 글리프는 글리프의 아래쪽 또는 가운데에 정렬됩니다.

같은 스크립트와 단일 폰트 크기 내에서 정렬 점의 시퀀스는 인라인 기본 방향에서 기준선(baseline)이라 불리는 기하학적 선을 정의합니다. 서양 및 대부분의 알파벳, 음절 글리프는 "알파벳" 기준선에 정렬되고, 북인도 글리프는 "행잉" 기준선, 극동 글리프는 "이데오그래픽" 기준선에 정렬됩니다.

세 가지 스크립트의 기준선 예시.

세 가지 스크립트의 기준선(빨간색 선) 예시. 왼쪽부터 알파벳, 행잉, 이데오그래픽. 이데오그래픽 스크립트의 EM 박스는 파란색으로 표시됨.

글리프는 기준선을 따라 순차적으로 배치되며, 글리프의 정렬 점은 일반적으로 현재 텍스트 위치에 위치합니다(vertical-align 등 프로퍼티가 위치를 바꿀 수 있음). 각 글리프가 배치된 후, 현재 텍스트 위치는 글리프의 advance 값(보통 수평 텍스트의 너비, 수직 텍스트의 높이)에 커닝이나 기타 간격 조정, 서식 유지 또는 자동 줄 바꿈 텍스트의 줄 바꿈 등을 반영해 이동됩니다. 초기 및 최종 현재 텍스트 위치text-anchor 값이 'middle'이나 'end'인 경우 정렬에 사용됩니다. 글리프의 advance는 경로 위에 텍스트를 배치할 때 필요합니다.

세 가지 스크립트의 기준선 예시.

폰트 메트릭 예시. 파란색 박스는 세 글리프의 기하학적 박스를 보여줍니다. 표시된 작은 원은 글리프 배치 전의 현재 텍스트 위치를 나타냅니다. 작은 사각형은 마지막 글리프 배치 후의 현재 텍스트 위치입니다. 'a' 글리프 박스의 왼쪽이 'V' 글리프 박스의 오른쪽과 커닝 때문에 정렬되지 않음에 주의하세요.

글리프가 현재 글리프 방향에 맞는 명시적인 advance 값을 제공하지 않으면, 적절한 근사값을 사용해야 합니다. 수직 텍스트의 경우 em 크기가 추천됩니다.

초기 현재 텍스트 위치는 서식 유지 텍스트의 경우 x, y 속성이 text 요소나 첫 렌더링된 tspan 요소에서 결정하고, 콘텐츠 영역inline-size 프로퍼티로 결정되는 자동 줄 바꿈 텍스트도 동일합니다. 그 외 자동 줄 바꿈 텍스트의 경우, CSS 줄 바꿈 알고리즘 적용 후 첫 렌더링 글리프의 위치가 초기 현재 텍스트 위치가 됩니다.

기준선 테이블(baseline-table)은 디자인 공간 좌표계에서 하나 이상의 기준선 위치를 지정합니다. 기준선 테이블의 역할은 한 줄의 텍스트에서 서로 다른 스크립트를 정렬할 수 있게 하는 것입니다. 원하는 상대적 정렬은 줄(또는 블록)에서 어느 스크립트가 우세한지에 따라 달라질 수 있으므로, 각 스크립트마다 다른 기준선 테이블이 있을 수 있습니다. 또한 수평/수직 글쓰기 모드마다 다른 정렬 위치가 필요합니다. 따라서 폰트에는 여러 기준선 테이블이 있을 수 있습니다: 일반적으로 수평 글쓰기 모드용 하나 이상, 수직 글쓰기 모드용 0개 이상.

일부 폰트에는 기준선 테이블 값이 없을 수 있습니다. 기준선 테이블이 없는 경우 CSS Inline Layout Module Level 3 [css-inline-3]에서 근사값을 구하기 위한 휴리스틱이 제안되어 있습니다.

텍스트 흐름 중간에 다른 폰트(또는 폰트 크기 변경)가 지정되면 지배적 기준선(dominant baseline)이 새 폰트(새 크기)의 글리프를 이전 폰트 글리프와 정렬할 때 쓰이는 기준선을 결정합니다. dominant-baseline 프로퍼티로 설정합니다.

객체와 부모 간의 정렬은 정렬 기준선(alignment baseline)으로 결정합니다. 보통 지배적 기준선과 같지만, 단축형 vertical-align 프로퍼티(권장)나 긴 형태 alignment-baseline을 사용해 다른 기준선을 선택할 수 있습니다.

지배적 기준선은 위 첨자/아래 첨자 등 필요에 따라 단축형 vertical-align 프로퍼티(권장) 또는 baseline-shift 프로퍼티로 임시로 이동할 수 있습니다. 이동은 중첩이 가능하며 각 이동은 이전 이동에 더해집니다.

'vertical-align' 프로퍼티 사용 예시. 왼쪽은 내부 괄호가 작은 '[[z]]', 오른쪽은 위 첨자 'x2'.

'vertical-align' 프로퍼티 사용 예시. 왼쪽: 'vertical-align:mathematical' ('alignment-baseline:mathematical')이 tspan에 적용됨. 연한 파란색 선이 수학적 기준선 위치를 표시. 오른쪽: 'vertical-align:super'('baseline-shift:super')가 '2'를 포함한 tspan에 적용됨. 연한 파란색 선들이 기준선 이동을 나타냄.

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 요소는 블록 요소로 동작합니다. tspan, textPath, a 요소는 텍스트 콘텐츠 요소의 자손인 경우 인라인 요소로 동작합니다.

텍스트에 그라디언트, 패턴, 클리핑 경로, 마스크 또는 필터를 적용할 수 있습니다. 텍스트에 이러한 효과를 적용할 때 'objectBoundingBox' 키워드를 사용하면 ("object bounding box"에 상대적으로 그래픽 효과를 지정, Object bounding box units 참조), 오브젝트 바운딩 박스 단위는 항상 전체 text 요소 기준으로 계산됩니다. 동일한 text 요소 내에서 서로 다른 tspan 또는 textPath에 각각 다른 효과를 적용하더라도 마찬가지입니다.

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'만 빨간색.

두 개의 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
카테고리:
그래픽 요소, 렌더링 가능 요소, 텍스트 콘텐츠 요소
콘텐츠 모델:
아래의 요소 또는 문자 데이터가 임의 개수로, 임의 순서로 포함될 수 있음:a, clipPath, marker, mask, script, style
속성:
DOM 인터페이스:
SVG 2 요구사항: tspan 요소에서 변환(transform) 허용.
결정: SVG 2는 ‘tspan’에서 변환(transform)을 허용함.
목적: 이미 변환을 허용하는 a 등 다른 요소와 일치시키기 위함.
담당자: Cameron (조치 없음)
상태: 완료

이 결정은 번복되었습니다. 자세한 내용은 GitHub 이슈 210 참조. CSS/HTML은 인라인 요소에서 변환(transform)을 허용하지 않으며, SVG와 HTML 모두에서 인라인 a 요소에 대해 렌더러가 변환을 지원하지 않습니다.

tspan
카테고리:
그래픽 요소, 렌더링 가능 요소, 텍스트 콘텐츠 요소, 텍스트 콘텐츠 자식 요소
콘텐츠 모델:
아래의 요소 또는 문자 데이터가 임의 개수로, 임의 순서로 포함될 수 있음:a, animate, script, set, style, tspan
속성:
DOM 인터페이스:

11.2.1. 속성

이름 초기값 애니메이션 가능
x, y [ [ <길이-퍼센트> | <숫자> ]+ ]# text의 경우 0;
tspan의 경우 (없음)

단일 <길이>가 제공되면, 해당 값은 이 요소 또는 자손 내 첫 번째 문자에 해당하는 글리프를 렌더링할 현재 텍스트 위치의 새로운 절대 X(Y) 좌표를 의미합니다.

쉼표 또는 공백으로 구분된 n개의 <길이>가 제공되면, 각 값은 이 요소 또는 자손 내 첫 n개의 주소 지정 가능한 문자에 해당하는 글리프를 렌더링할 현재 텍스트 위치의 새로운 절대 X(Y) 좌표를 의미합니다.

문자보다 많은 <길이>가 제공된 경우, 추가 <길이>는 글리프 위치에 영향을 주지 않습니다.

문자가 더 많거나 속성이 tspan에 지정되지 않은 경우, 추가 문자마다:

  1. 상위 text 또는 tspan 요소가 해당 문자에 대해 ‘x’ (‘y’) 속성으로 절대 좌표를 지정하면(가장 가까운 상위가 우선) 해당 좌표를 시작 위치로 사용, 아니면
  2. 해당 문자에 대한 글리프를 렌더링할 시작 X(Y) 좌표는 현재 text 요소에서 가장 최근에 렌더링된 글리프의 현재 텍스트 위치입니다.

SVG 2에서 texttspanxy 속성은 표현 속성이 아니며 CSS로 설정할 수 없습니다. 이는 향후 SVG 버전에서 변경될 수 있습니다.

이름 초기값 애니메이션 가능
dx, dy [ [ <길이-퍼센트> | <숫자> ]+ ]# (없음)

단일 <길이>가 제공되면, 해당 값은 이 요소 또는 자손의 첫 번째 문자에 해당하는 글리프를 렌더링할 현재 텍스트 위치의 새로운 상대 X(Y) 좌표를 의미합니다. 현재 텍스트 위치는 첫 번째 문자 글리프 렌더링 전에 현재 사용자 좌표계의 x축(y축)으로 <길이>만큼 이동됩니다.

쉼표 또는 공백으로 구분된 n개의 <길이>가 제공되면, 각 값은 현재 텍스트 위치를 첫 n개의 주소 지정 가능한 문자에 대해 글리프 렌더링 전 x축(y축)으로 점진적으로 이동합니다. 즉, 각 문자 글리프 렌더링 전, 이전 문자 글리프를 그린 후의 현재 텍스트 위치가 x축(y축)으로 <길이>만큼 이동됩니다.

문자보다 많은 <길이>가 제공된 경우, 추가 값은 글리프 위치에 영향 없음.

문자가 더 많거나 속성이 지정되지 않은 경우, 추가 문자마다:

  1. 상위 text 또는 tspan 요소가 해당 문자에 대해 ‘dx’ (‘dy’) 속성으로 상대 좌표를 지정하면(가장 가까운 상위가 우선), 현재 텍스트 위치는 해당 값만큼 x축(y축)으로 이동, 아니면
  2. x축(y축) 추가 이동 없음.
이름 초기값 애니메이션 가능
rotate [ <숫자>+ ]# (없음) 예(비가산).

이 요소 내 각 문자에 해당하는 모든 글리프에 적용될 현재 텍스트 위치 기준의 추가 회전(도 단위)입니다.

쉼표 또는 공백으로 구분된 <숫자> 리스트가 제공되면, 첫 번째 <숫자>는 첫 번째 문자 글리프의 추가 회전값, 두 번째 <숫자>는 두 번째 문자 글리프에 대한 추가 회전값, ... 식으로 적용됩니다.

문자보다 많은 <숫자>가 제공된 경우, 추가 값은 무시됨.

문자가 더 많으면 남은 문자마다 마지막 숫자 값을 사용해야 합니다.

속성이 지정되지 않았고, tspan 요소의 상위 요소가 rotate 속성으로 추가 회전값을 지정하면(가장 가까운 상위가 우선), 해당 값이 적용됩니다. 상위 속성에 지정된 숫자보다 문자가 많으면 남은 문자마다 마지막 숫자 값을 사용합니다.

이 추가 회전은 글리프 렌더링 시 현재 텍스트 위치가 변경되는 규칙에는 영향이 없으며, 경로 위 텍스트text-orientation, glyph-orientation-horizontal, glyph-orientation-vertical에 의한 회전과는 별도로 적용됩니다.

이름 초기값 애니메이션 가능
textLength <길이-퍼센트> | <숫자> 아래 참조

저자가 이 요소 내 문자 데이터 전체에 해당하는 advance 값의 합(글리프의 advance 값(수평 또는 수직), letter-spacing, word-spacing 프로퍼티 효과, 그리고 이 text 또는 tspan 요소 또는 자손에 지정된 dxdy 속성에 의한 조정 포함)을 계산한 값입니다. 이 값은 사용자 에이전트의 자체 계산을 저자와 맞추기 위해 사용됩니다.

이 속성의 목적은 바이디 재정렬 후 시각적 렌더링 순서에서 이 요소의 첫 번째 및 마지막 글리프를 정확하게 정렬하도록 하는 것입니다. 즉, 마지막 문자(바이디 재정렬 후 시각적 렌더링 순서에서)에 대해 정상 advance 외의 추가 문자 간 간격은(대부분의 경우) 무시되고, 사용자 에이전트가 텍스트 문자열을 textLength 길이에 맞게 확장/압축하는 양을 결정할 때 반영되지 않습니다.

textLength 속성이 이 요소와 상위 요소 모두에 지정되면, 이 요소 내 모든 문자 데이터에 대한 조정은 이 요소의 textLength 값만 따릅니다. 그 결과 이 요소 내용의 조정 비율이 같은 상위 요소의 다른 내용과 다를 수 있습니다. 사용자 에이전트는 해당 상위 요소의 다른 내용에 대한 advance 값의 총합을 상위 요소의 advance 값과 이 요소의 advance 값 차이로 간주해야 합니다.

이 속성은 텍스트를 축소/확장하는 효과를 얻기 위한 용도가 아닙니다.

음수 값은 오류입니다(오류 처리 참조).

textLength 속성은 래핑 영역shape-inside 또는 inline-size 프로퍼티로 정의되지 않은 경우에만 적용됩니다. 또한 white-space 값이 pre 또는 pre-line인 경우 강제 줄 바꿈이 있는 text 또는 tspan 요소에도 적용되지 않습니다.

text 요소 내 어디에도 이 속성이 지정되지 않으면, 저자 계산값이 사용자 에이전트 계산값과 정확히 일치하는 것처럼 동작하며 advance 조정은 없습니다. DOM에서 속성을 반영할 때 초기값은 현재 사용자 에이전트가 계산한 길이(암묵적 사용자 단위로 표현)입니다.

이름 초기값 애니메이션 가능
lengthAdjust spacing | spacingAndGlyphs spacing
spacing
advance 값만 조정함을 의미합니다. 글리프 자체는 늘어나거나 압축되지 않습니다.
spacingAndGlyphs
advance 값도 조정하고, 글리프 자체도 한 축(즉, 인라인 기본 방향과 평행한 방향)으로 늘이거나 압축합니다.

사용자 에이전트는 텍스트 문자열의 시작 및 끝 위치를 정확히 맞춰야 하지만, 중간 글리프 위치는 예측할 수 없습니다. 이는 사용자 에이전트가 최적의 타이포그래피와 시작/끝 위치를 균형 맞추기 위해 고급 알고리즘을 사용할 수 있기 때문입니다.

n개의 문자가 포함된 텍스트 문자열의 경우 advance 값 조정은 대개 n−1 문자에만 적용되고(textLength 설명 참조), 글리프의 늘이기/압축은 n문자 전체에 적용됨을 주의하세요.

11.2.2. 'x', 'y', 'dx', 'dy', 'rotate' 관련 참고사항

texttspan 요소의 x, y, dx, dy, rotate 속성은 개별 글리프의 정확한 위치 지정이 필요한 고급 타이포그래피 상황에서 유용합니다. 이들 속성은 문자 간 미세 위치 조정이나, 텍스트 일부를 새 위치로 이동시켜(새 줄 효과 등, SVG 1.1과 호환) 시각적 효과를 얻을 때 쓸 수 있습니다. x, y, dx, dy, rotate 속성은 자동 줄바꿈 텍스트에서는 무시됩니다(단, 콘텐츠 영역inline-size 프로퍼티로 지정된 경우 초기 현재 텍스트 위치에는 적용).

2015년 시드니 F2F에서 'dx', 'dy', 'rotate'는 자동 줄바꿈 텍스트에서 무시하기로 결정되었습니다. (기술적으로 적용은 어렵지 않지만 실제로는 별로 유용하지 않다는 판단.)

고급 타이포그래피 제어를 위해 미세 위치 조정이 필요한 경우, SVG 콘텐츠 디자이너는 모든 사용자에게 필요한 폰트가 제공될 수 있도록 해야 합니다(예: SVG 폰트 또는 같은 웹사이트에 저장된 대체 WebFont 포맷으로 폰트 데이터 포함) 그리고 뷰어 소프트웨어가 폰트를 예상대로 처리할 수 있어야 합니다(시스템마다 폰트 처리 기능/특성/레이아웃 메커니즘이 크게 다름). 만약 SVG 내용에 x, y, dx, dy 속성값이 특정 폰트와 특정 뷰어 소프트웨어에 맞춰 사용됐는데, 그 조건이 맞지 않으면 텍스트가 품질이 낮게 표시될 수 있습니다.

숫자 리스트를 포함하는 x, y, dx, dy, rotate 속성에는 다음 규칙이 적용됩니다:

예제 tspan04tspan 요소의 rotate 속성을 사용해 글리프를 회전시켜 렌더링합니다. 이 예제는 tspan 요소 내 지정된 rotate 값 개수보다 더 많은 문자를 포함하는 단일 텍스트 문자열을 보여줍니다. 이 경우 tspanrotate 마지막 값이 남은 문자에 적용됩니다.

<?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

예제 tspan04

SVG로 보기(SVG 지원 브라우저 한정)

예제 tspan05text 요소와 자식 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>
    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

예제 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는 블록 요소, tspan, textPath, a 자손은 인라인 요소로 취급합니다. 이 레이아웃은 이 장에서 설명된 모든 문단 수준 및 폰트 관련 CSS 프로퍼티를 고려합니다.

콘텐츠 영역inline-size 프로퍼티를 설정하거나, SVG 도형을 정의/참조하는 shape-inside 프로퍼티를 설정해서 명시적으로 선언할 수 있습니다. 콘텐츠 영역이 선언되지 않으면 기본값은 무한 너비와 높이의 사각형입니다.

두 번째 단계에서는 x, y, dx, dy 속성에 의해 CSS 레이아웃 과정에서 산출된 글리프 위치가 조정됩니다. 어떤 변환이 허용되는지의 규칙은 콘텐츠 영역을 명시적으로 선언했는지 여부에 따라 달라집니다. 명시적으로 선언하지 않은 경우 서식 유지 텍스트의 레이아웃을 정의하고, 선언한 경우 자동 줄바꿈 텍스트 레이아웃을 정의합니다.

세 번째 단계에서는 필요하다면 text-anchor 프로퍼티 효과가 적용됩니다.

마지막으로 textPath 요소에 대한 글리프 레이아웃이 수행되어 서식 유지 텍스트가 경로 위 텍스트로 변환됩니다.

텍스트 레이아웃 유형별 예시:

서식 유지(Pre-formatted):
짧은 텍스트(예: 라벨)나 글리프의 정확한 위치 지정이 필요한 경우(예: 수작업 커닝된 제목 등).

여러 줄의 서식 유지 텍스트 예시입니다.

<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 요소를 사용해 여러 줄 텍스트를 만듦.

자동 줄바꿈(Wrapped text):
긴 텍스트 문자열에서 자동 줄바꿈이 필요한 경우.

자동 줄바꿈 텍스트 예시입니다.

<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 프로퍼티가 무한 높이의 사각 콘텐츠 영역을 정의(연파란색으로 표시).

경로 위 텍스트(Text on path):
지정한 경로를 따라가는 텍스트.

경로 위 텍스트 예시입니다.

<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/> 요소가 없고, 대신 prepre-line white-space 값을 이용해 줄 바꿈을 합니다. SVG 줄바꿈 텍스트는 SVG 1.1 렌더러가 wrapped text를 지원하지 않을 때도 자연스러운 폴백을 제공할 수 있는데(x, y 속성을 texttspan 요소에 지정하면, SVG 2 렌더러에서는 자동 줄바꿈 텍스트에서 무시됨).

SVG의 텍스트 레이아웃 옵션은 대부분의 일반적인 사용 사례를 커버하도록 설계되었습니다. 더 복잡한 레이아웃(글머리 리스트, 테이블 등)이 필요한 경우에는 XHTML 등 다른 XML 네임스페이스의 텍스트를 foreignObject 요소에 인라인으로 포함해 렌더링할 수 있습니다.

11.4. 텍스트 레이아웃 – 콘텐츠 영역

콘텐츠 영역text 요소에서 inline-size 프로퍼티를 지정하거나, SVG 도형을 정의하거나 참조하는 shape-inside 프로퍼티를 지정함으로써 정의됩니다. 콘텐츠 영역이 제공되지 않으면, 콘텐츠 영역은 기본적으로 무한 너비와 높이의 사각형이 됩니다(서식 유지 텍스트 절 참조). inline-size 프로퍼티와 shape-inside 프로퍼티 값이 모두 주어지고, 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>는 각각 float을 정의(왼쪽은 실선 녹색, 오른쪽은 실선 분홍색). float들은 사각형 형태입니다. 각 float에는 shape-outside 프로퍼티가 있어서 각 float의 래핑 컨텍스트(점선 녹색/분홍색 선)를 정의합니다. 합쳐진 래핑 컨텍스트콘텐츠 영역에서 빼면 래핑 영역(연파란색 선)이 정의됩니다.

11.4.1. ‘inline-size’ 프로퍼티

'extent'는 2015년 2월 12일 결의로 추가됨. 'extent'는 2013년 6월 27일 결의로 추가된 'width', 'height' 속성을 대체함. 2015년 6월 11일 Linkoping F2F 결의로 'inline-size' 표현 속성으로 대체됨.

inline-size 프로퍼티는 래핑 영역을 사각형 형태로 설정할 수 있게 합니다. 이 프로퍼티의 계산값은 수평 텍스트의 경우 사각형 너비, 수직 텍스트의 경우 사각형 높이를 설정합니다. 나머지 치수(수평 텍스트의 높이, 수직 텍스트의 너비)는 무한 길이입니다. 값이 0이면 래핑 영역 생성을 비활성화합니다.

초기 현재 텍스트 위치x, y 속성이 text 요소(또는 속성이 없으면 첫 번째 자식 tspan 요소)에 지정된 값에서 가져옵니다. 좌→우 텍스트의 경우 초기 현재 텍스트 위치는 사각형의 왼쪽입니다. 우→좌 텍스트는 사각형의 오른쪽입니다. 수직 텍스트의 경우 초기 현재 텍스트 위치는 사각형의 위쪽입니다.

사각형(래핑 영역)은 text-anchor 프로퍼티에 따라 래핑 영역의 가장자리로 시작, 중간, 끝 위치가 결정되도록 앵커링 됩니다.

inline-size 프로퍼티를 활용한 텍스트 줄바꿈 방식은 저자가 텍스트 블록의 너비나 높이만 제한하는 서식 유지 SVG 텍스트의 확장입니다. 따라서 x, y 속성, direction, text-anchor 프로퍼티로 첫 줄 위치를 지정합니다. 완전한 양쪽 정렬이 필요하면 shape-inside 프로퍼티로 래핑 영역을 생성해야 합니다.

이름: inline-size
값: <길이-퍼센트>
초기값: 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는 제대로 동작하는 듯하며, 크롬에 버그 보고됨.

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에서 동작하지 않습니다(nightly에서도). Firefox는 표현 속성 'writing-mode'를 지원하지 않습니다. Firefox에 버그 보고됨.

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>가 이미지를 참조하면, 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 도형을 제공하는 것이 권장됩니다. 예를 들어 사용자가 글꼴 크기를 키운 경우 모든 텍스트 접근성 보장을 위해서입니다.

별도 언급 외에는 CSS Shapes Module Level 2에서 'shape-inside' 정의를 참고하세요. [css-shapes-2]

'shape-inside'는 CSS Exclusions and Shapes Module이 Exclusions과 Shapes로 분리될 때 삭제되었다가, 도쿄 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>
<uri>가 SVG 도형 요소를 참조하면 해당 요소가 기여 도형을 정의하며, shape-margin 거리만큼 확장됩니다. <uri>가 이미지를 참조하면 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-inside, shape-padding, shape-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
값: <길이-퍼센트>
초기값: 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은 'tspan'의 'textLength'를 지원하지만 Firefox는 지원하지 않습니다.

별도 언급 외에는 CSS Shapes Module Level 2에서 'shape-padding' 정의를 참고하세요.

11.5. 텍스트 레이아웃 – 알고리즘

텍스트 레이아웃은 text 요소의 내용(텍스트 데이터, 스타일 정보, 하나 이상의 채워질 도형 설명 포함)을 CSS 기반 텍스트 렌더러에 전달하는 것으로 시작합니다. text 요소는 블록 요소로 취급되고, 그 자손 tspan, textPath, a 요소는 인라인 요소로 취급됩니다. CSS 렌더러는 텍스트를 절대 위치로 배치한 것처럼 레이아웃하여 타이포그래픽 문자와 그 위치를 반환합니다.

하나의 타이포그래픽 문자는 하나 이상의 글리프를 포함할 수 있습니다. 여기서는 타이포그래픽 문자 내부의 글리프 상대 위치는 타이포그래픽 문자에 캡슐화되어 있으며 사용자가 제어할 수 없는 것으로 간주합니다.

콘텐츠 영역이 정의된 후, 아래 알고리즘을 사용해 특정 text 요소에 대한 타이포그래픽 문자와 그 위치를 결정합니다:

일부 CSS 프로퍼티는 SVG 텍스트 레이아웃에 영향을 주지 않거나 제한적으로만 영향을 줍니다:

다양한 SVG 속성과 프로퍼티는 콘텐츠 영역이 어떻게 정의되는지에 따라 타이포그래픽 문자의 위치를 다시 지정할 수 있습니다:

아래 SVG 텍스트 레이아웃 알고리즘은 text 요소 서브트리의 DOM 내 각 문자에 대한 출력 정보를 반환합니다. 이 정보에는 다음이 포함됩니다:

SVG 속성 x, y, dx, dy, rotate 배열은 주소 지정 가능한 문자 기준으로 인덱싱됩니다. 하지만 위치 지정은 타이포그래픽 문자에 대해 적용됩니다. 타이포그래픽 문자가 여러 문자를 포함하는 경우(예: 합자) 위치 지정에는 첫 번째 문자 해당 배열 값만 사용됩니다. 해당 타이포그래픽 문자의 나머지 문자 배열 값은(‘x’, ‘y’) 무시되거나(‘dx’, ‘dy’) 누적되어 다음 타이포그래픽 문자에 적용되거나(‘rotate’) 배열의 마지막 값이면 이후 타이포그래픽 문자에 적용됩니다. 이 처리로 폰트에 특정 합자가 있든 없든 속성값이 동일 문자에 적용됨을 보장합니다.

SVG 전용 텍스트 레이아웃 알고리즘은 다음과 같습니다:

  1. 설정
    1. roottext 요소와 그 서브트리의 타이포그래픽 문자 위치를 생성한 결과로, 해당 요소가 절대 위치 요소로 배치된 것처럼 레이아웃합니다.

      white-space 프로퍼티가 줄 바꿈을 유발하지 않으면, 단일 줄 텍스트가 됩니다.

    2. counttext 요소의 서브트리 내 DOM 문자의 개수입니다.
    3. result는 길이 count의 배열로, 각 항목에는 위에서 설명한 문자별 정보를 포함합니다. 각 항목의 초기값:
      • 글로벌 인덱스 번호: 배열 내 위치,
      • "x" 좌표: "지정되지 않음",
      • "y" 좌표: "지정되지 않음",
      • "rotate" 좌표: "지정되지 않음",
      • "hidden" 플래그: false,
      • "addressable" 플래그: true,
      • "middle" 플래그: false,
      • "anchored chunk" 플래그: false.
      result가 비어 있으면 result를 반환합니다.
    4. CSS_positionscount 길이의 배열로, 각 항목에는 root 내 해당 타이포그래픽 문자x, y 위치가 채워집니다. 초기값은 (0, 0)입니다.
    5. "horizontal" 플래그는 text의 글쓰기 모드가 수평이면 true, 아니면 false입니다.
  2. 플래그 설정 및 초기 위치 지정

    result 배열의 각 인덱스 i에 대해:

    1. addressable은 다음 경우 false로 설정:

      아래 text 요소(표준 폰트 사용)에서 글리프 위치 지정 속성으로 주소 지정할 수 없는 축소 공백이 있으므로 "B" 글리프는 x=300에 위치함.

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

      "A" 앞의 공백, "A"와 "B" 사이의 공백 중 하나를 제외한 모든 공백은 축소 또는 잘림되어 사라집니다.

    2. i번째 문자가 타이포그래픽 문자의 두 번째 이상 문자라면 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 속성값)은 해당 노드와 자손의 모든 문자에 적용됨. 하지만 자손 노드에서 지정한 조정은 상위 노드의 조정을 덮어씀. 이 단계에서는 어떤 조정을 어떤 문자에 적용할지 결정하며, resultrotate 좌표도 직접 설정함.

    1. 준비:
      1. resolve_x, resolve_y, resolve_dx, resolve_dycount 길이의 배열로 모두 "지정되지 않음"으로 초기화.
      2. "in_text_path" 플래그를 false로 설정.

        이 플래그는 y(x) 속성값이 textPath 요소 내 수평(수직) 텍스트에서는 무시되도록 합니다.

      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 동안 반복:

          이 반복은 x, y, dx, dy, rotate 속성을 node의 콘텐츠에 적용.

          1. result[index + j]의 "addressable" 플래그가 true면:
            1. i < new_check_count이면 result[index + j]의 "anchored chunk" 플래그를 true, 아니면 false로 설정.

              false로 설정하면 text 요소에 설정된 x, y 속성이 textPath 요소에서는 불필요하게 anchored chunk를 만들지 않도록 함.

            2. i < x 길이면 resolve_x[index + j] = x[i].
            3. "in_text_path" 플래그가 true이고 "horizontal"이 false면 resolve_x[index] 해제.

              x 속성은 경로 위 수직 텍스트에서 무시됨.

            4. i < y 길이면 resolve_y[index + j] = y[i].
            5. "in_text_path" 플래그가 true이고 "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]의 각도값을 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

    dx, dy 조정은 textLength 속성 조정보다 먼저 적용되고, x, y, rotate 조정은 그 후에 적용됨.

    1. shiftx, y 속성에 의한 누적 x, y 이동값, 초기값은 (0,0).
    2. result 배열의 각 인덱스 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. resolved descendant node: 유효한 textLength 속성을 가지며, 자손 중 유효한 textLength 속성을 가진 자손 노드의 자손이 아닌 노드.
      2. 아래 절차를 text 요소 노드에 적용.
    2. 절차: 텍스트 길이 결정:

      입력으로 node를 받아 다음 단계 수행하는 재귀 절차:

      1. node의 각 자식 노드 child에 대해:
        1. 텍스트 길이 결정을 child에 적용.

          자식 노드를 부모 노드보다 먼저 조정.

      2. nodetext 또는 tspan 노드이고, 유효한 textLength 속성값이 있으면:
        1. a = +∞, b = −∞.
        2. i, jnode의 첫/마지막 문자의 글로벌 인덱스.
        3. [i, j] 구간의 각 인덱스 kresult[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는 노드 내 마지막 타이포그래픽 문자를 "horizontal" 플래그 true이면서 direction이 ltr이면 x방향(+), rtl이면 x방향(−), 아니면 y방향(+)으로 delta만큼 이동시켜야 함. UA는 최적 타이포그래피를 위해 중간 타이포그래픽 문자도 자유롭게 조정할 수 있음. 아래 단계는 lengthAdjust 값이 spacing일 때 조정 예시.

          2. n = 이 노드(자손 중 resolved descendant node 또는 그 내부가 아닌) 내 타이포그래픽 문자 총 개수.
          3. n = n + resolved descendant node 개수 − 1.

            각 resolved descendant node는 단일 타이포그래픽 문자로 간주.

          4. 문자별 조정값 δ = delta/n
          5. shift = 0
          6. [i,j] 구간의 각 인덱스 k에 대해:
            1. "horizontal" 플래그가 true면 result[k]의 x좌표에, 아니면 y좌표에 shift를 더함.
            2. result[k]의 "middle" 플래그가 true가 아니고, k가 resolved descendant node 내 첫 문자 이외가 아니면 shift = shift + δ
  6. 위치 조정: x, y

    이 반복은 x, y 값을 적용하고, text-anchor 청크가 타이포그래픽 문자 중간에서 시작하지 않도록 보장함.

    1. shift는 현재 x, y 속성에 의한 조정값, 초기값 (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. 각 slice result[i..j] (i, j 모두 포함)에서:
      • result[i]의 "anchored chunk" 플래그가 true
      • result[k]의 "anchored chunk" 플래그(i < k ≤ j)는 모두 false
      • j = count − 1이거나 result[j + 1]의 "anchored chunk" 플래그가 true
      수행:

      각 anchored chunk를 반복.

      1. a = +∞, b = −∞
      2. [i, j] 구간의 각 k 중 result[k]의 "addressable" 플래그가 true인 경우:

        이 반복은 anchored chunk 내 타이포그래픽 문자의 좌/우(상/하) 끝을 찾음

        1. pos = "horizontal" 플래그 true면 result[k]의 x좌표, 아니면 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 = "horizontal" 플래그 true면 result[i]의 x좌표, 아니면 y좌표
        2. shift를 적용:
          (start, ltr) 또는 (end, rtl)
          shift = shift − a
          (start, rtl) 또는 (end, ltr)
          shift = shift − b
          (middle, ltr) 또는 (middle, rtl)
          shift = shift − (a + b) / 2
        3. [i, j] 구간의 각 k에 대해:
          1. "horizontal" 플래그 true면 result[k]의 x좌표에, 아니면 y좌표에 shift를 더함
  8. 경로 위 위치 지정
    1. index = 0
    2. "in path" 플래그 false로 설정
    3. "after path" 플래그 false로 설정
    4. path_endtextPath 요소 뒤의 문자에 대한 오프셋. 초기값 (0,0)
    5. index < count 동안 반복:
      1. index i 문자가 textPath 요소 내에 있고, 타이포그래픽 문자에 대응하면:
        1. "in path" 플래그 true로 설정
        2. result[index]의 "middle" 플래그가 false면:

          여기서 textPath 위치 지정 적용

          1. pathtextPath 요소가 참조하는 기본 도형 요소의 등가 경로, 참조가 올바르지 않으면 빈 경로
          2. side 속성이 'right'면 path를 반전
          3. length = path의 길이
          4. offset = textPathstartOffset 속성값, 참조 요소의 pathLength에 따라 조정
          5. advance = k에 대응하는 타이포그래픽 문자의 advance. [참고: RTL 수평 텍스트는 advance가 음수임.]
          6. (x, y), angle = result[index]의 위치와 각도
          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가 닫힌 하위 경로면 다음에 따라:

            단일 닫힌 하위 경로의 특수 래핑 기준 구현

            (start, ltr) 또는 (end, rtl)
            mid − offset < 0 또는 mid − offset > length이면 result[index]의 "hidden" 플래그를 true로 설정
            (middle, ltr) 또는 (middle, rtl)
            mid − offset < −length/2 또는 mid − offset > length/2이면 result[index]의 "hidden" 플래그를 true로 설정
            (start, rtl) 또는 (end, ltr)
            mid − offset < −length 또는 mid − offset > 0이면 result[index]의 "hidden" 플래그를 true로 설정

            mid = mid mod length

          10. If hidden 플래그가 false면:
            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" 플래그가 true면:
          1. result[index]의 위치와 각도값을 result[index − 1]과 동일하게 설정
      2. index 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.x, result.y[index] = result.y[index] + path_end.y
      3. index = index + 1
  9. result 반환

SVG 2 요구사항: 텍스트 레이아웃 기능을 위해 CSS와 일치시킵니다.
결정: SVG 2는 SVG에만 특화되지 않은 텍스트 레이아웃(공백, 바이디 등)에 대해 CSS3 정의를 사용합니다.
목적: HTML과 SVG에서 텍스트 레이아웃의 공동 명세 및 구현을 용이하게 하기 위함입니다.
담당자: Cameron, Chris (ACTION-3004, ACTION-3005)

11.6. 서식 유지 텍스트

이 옵션은 기본 SVG 1.1 텍스트 레이아웃에 해당합니다.

이것이 기본 텍스트 레이아웃 방식이며, 콘텐츠 영역이 명시적으로 정의되지 않은 경우 사용됩니다. 또한 경로 위 텍스트를 레이아웃할 때 첫 단계로 사용되며(규칙이 약간 수정됨), 이 방식에서는 자동 줄 바꿈이나 단어 줄 바꿈이 이루어지지 않습니다. 명목상 텍스트는 무한 너비와 높이를 가진 사각형 콘텐츠 영역 내에 한 줄로 렌더링됩니다. 여러 줄 텍스트를 얻으려면 줄 바꿈을 미리 계산하고 다음 방법 중 하나를 사용할 수 있습니다:

다음 속성들은 서식 유지 텍스트에는 적용되지 않습니다: text-align, text-align-last, line-break, word-break, hyphens, word-wrap, overflow-wrap.

11.6.1. 'white-space'로 여러 줄 텍스트

여러 줄 서식 유지 텍스트는 white-space 값을 pre 또는 pre-line을 사용해 만들 수 있습니다. 이 경우 줄 바꿈(line-feed)이나 캐리지 리턴(carriage return)이 강제 줄 바꿈으로 보존되어 새로운 라인 박스를 생성합니다. 라인 박스들은 CSS 규칙에 따라 쌓입니다.

11.6.2. 글리프 위치 조정

텍스트가 기본 CSS 텍스트 레이아웃 규칙에 따라 배치된 후, SVG 전용 규칙으로 타이포그래픽 문자의 위치를 조정할 수 있습니다. 절대 위치 조정은 x, y 속성에 절대 좌표를 지정하거나, 강제 줄 바꿈으로 할 수 있습니다. 절대 위치 조정은 text-anchor 속성에 의해 영향을 받을 수 있습니다. 상대 위치 조정은 dx, dy 속성에 상대 좌표를 지정하여 할 수 있습니다. 타이포그래픽 문자rotate 속성에 값 리스트를 지정해 임의로 회전시킬 수 있습니다. 절대 위치 조정(및 text-anchor 속성에 의한 조정 포함)은 상대 위치 조정과 회전보다 먼저 적용됩니다.

11.7. 자동 줄바꿈 텍스트

text 요소에 콘텐츠 영역이 지정되면, 텍스트는 자동으로 줄바꿈됩니다. 콘텐츠 영역은 줄바꿈 텍스트의 가장 바깥쪽 컨테이너를 정의합니다. 래핑 컨텍스트(제외 영역 집합)가 추가로 지정될 수 있습니다. 실제 래핑 영역콘텐츠 영역에서 래핑 컨텍스트를 뺀 영역입니다. 래핑 컨텍스트shape-padding 속성 값에 따라 더 줄어들 수 있습니다. 제외 영역의 실질 영역은 shape-margin 속성 값에 따라 더 커질 수 있습니다.

inline-size 속성으로 콘텐츠 영역이 정의된 경우, 첫 렌더링 타이포그래픽 문자에 해당하는 x, y 속성값이 초기 현재 텍스트 위치를 정의합니다. 도형 내부에 콘텐츠 영역이 있으면, 도형 내 첫 줄 박스가 레이아웃된 후 첫 렌더링 타이포그래픽 문자 위치에서 초기 현재 텍스트 위치가 결정됩니다.

초기 현재 텍스트 위치를 결정할 때를 제외하고, text, tspan 요소의 모든 x, y 값은 자동 줄바꿈 텍스트에서 무시됩니다.

x, y 속성은 SVG1.1 렌더러에서 줄바꿈 텍스트에 자연스러운 폴백 메커니즘을 제공합니다. 콘텐츠 제작자는 줄을 tspan 요소로 나누고 x, y 속성을 지정해 사전 레이아웃할 수 있습니다. 예를 들어 폴백 폰트로 텍스트를 렌더링할 때, SVG2 렌더러는 x, y 속성을 무시하고, 폴백 폰트의 폰트 메트릭을 사용해 텍스트를 다시 흐르게 합니다. SVG1.1 렌더러는 x, y 속성을 사용해 텍스트를 렌더링하며, 보통 모양에 맞지 않아도 읽을 수 있게 렌더링됩니다. 본 절의 많은 텍스트 줄바꿈 예시는 아직 줄바꿈 기능을 구현하지 않은 브라우저에서 텍스트를 렌더링하는 데 이 메커니즘을 활용합니다.

11.7.1. 텍스트 줄바꿈 참고사항

다음 예제들은 도형 안에 텍스트를 배치할 때 발생하는 몇 가지 문제를 보여줍니다.

11.7.1.1. 첫 줄 위치 지정

임의의 형태의 래핑 영역이 주어졌을 때, 첫 라인 박스가 꼭대기에 맞게 들어가지 않을 수 있습니다(수직 텍스트의 경우 옆면). 이 경우, 첫 라인 박스가 들어맞을 때까지 아래로 이동합니다.

CSS에서는 도형의 가장자리를 1픽셀 × 1픽셀 float들의 연속으로 취급합니다.

향후 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 요소 또는 기본 도형의 등가 경로로 정의된 경로를 따라 텍스트를 배치할 수 있습니다. 이는 textPath 요소 내에 텍스트를 포함하고, href 속성에 path 요소 또는 기본 도형을 가리키는 URL 참조를 지정하거나, path 속성에 경로 데이터를 직접 지정해서 사용할 수 있습니다.

기본 도형을 따라 텍스트를 배치하는 기능은 SVG 2에서 새롭게 추가되었습니다.

기본 도형을 따라 텍스트를 배치하는 기능은 2015년 시드니 회의에서 결정되었습니다.

경로를 직접 지정하는 'd' 속성 사용은 SVG 2에 추가되었습니다. 'd' 속성은 2016년 런던 에디터 회의에서 'path'로 이름이 바뀌었으며, 동시에 'd'는 표현 속성으로 승격되었습니다.

경로 위 텍스트는 개념적으로 서식 유지 텍스트 한 줄을 변형하여 경로를 따라 배치하는 것과 같습니다. 별도 명시된 경우를 제외하고, 서식 유지 텍스트에 적용되는 모든 속성은 경로 위 텍스트에도 적용됩니다.

11.8.1. ‘textPath’ 요소

textPath
카테고리:
그래픽 요소, 렌더링 가능 요소, 텍스트 콘텐츠 요소, 텍스트 콘텐츠 자식 요소
콘텐츠 모델:
아래의 요소 또는 문자 데이터가 임의 개수로, 임의 순서로 포함될 수 있음:a, animate, clipPath, marker, mask, script, set, style, tspan
속성:
DOM 인터페이스:
SVG 2 요구사항: 텍스트 경로 stretch 방식에 대해 더 정확한 설명 제공.
결정: ‘textPath’ 요소의 method="stretch"를 명확히 함.
목적: 기능 상호운용성 개선.
담당자: Cameron (조치 없음)

path 속성과 href 속성 모두 타이포그래픽 문자가 렌더링될 경로를 지정합니다.

textPath 요소에 두 속성이 모두 지정된 경우, 사용되는 경로의 우선순위는 다음과 같습니다:

  1. path 속성
  2. href 속성
  3. xlink:href 속성

path 속성에 오류가 있는 경우, href 속성을 사용해야 합니다.

11.8.2. 속성

startOffset

초기 현재 텍스트 위치를 위한 경로 시작점으로부터의 오프셋으로, 사용자 에이전트의 경로를 따라 거리 알고리즘을 사용하여 계산되며, 경로를 textPath 요소의 좌표계로 변환한 후 계산됩니다.

백분율이 아닌 <길이>가 주어진 경우, startOffsettextPath 요소의 현재 사용자 좌표계에서 경로를 따라 측정되는 거리입니다.

백분율이 주어진 경우, startOffset은 전체 경로를 따라 비율로 해석됩니다. 예를 들어, startOffset="0%"은 경로의 시작점, startOffset="100%"은 경로의 끝점을 의미합니다.

음수 값 및 경로 길이보다 큰 값(예: 150%)도 허용됩니다.

값을 0%-100%로 제한하면 경로를 따라 텍스트를 움직이는 효과를 쉽게 만들 수 없습니다.

경로 위에 중간점이 없는 타이포그래픽 문자는 렌더링되지 않습니다.

startOffset 값에 따라 경로를 벗어난 글리프가 잘림되는 예시

startOffset 속성에 따른 렌더링. 위에서 아래로: 기본값, 50%, -50%.

아래 경로에서는 "path."만 왼쪽에 표시되어야 함. 크롬과 사파리는 0%~100% 범위 밖의 오프셋을 지원하지 않음. 크롬 버그 https://bugs.chromium.org/p/chromium/issues/detail?id=476554

단일 닫힌 하위 경로로 이루어진 경로(기본 도형의 등가 경로 포함)에서는 타이포그래픽 문자가 경로를 한 바퀴 따라 렌더링됩니다. 텍스트는 text-anchor 속성에 의해 정렬되고, startOffset 속성으로 경로 위 위치가 결정됩니다. start 또는 end 값의 경우, 텍스트는 경로의 시작(끝)부터 다시 시작 지점에 도달할 때까지 렌더링됩니다. middle의 경우, 텍스트는 중간점에서 양쪽으로 동일한 거리에 도달할 때까지 렌더링됩니다.

startOffset 값에 따라 원형 경로에서 모든 글리프가 렌더링되는 예시

circle을 참조하는 경로 위 텍스트의 startOffset 값에 따른 렌더링. 왼쪽: 0. 오른쪽: 75% 또는 -25%. 빨간 원은 경로의 시작점을 표시.

text-anchor 값에 따라 원형 경로에서 글리프가 어떻게 렌더링되는지 보여주는 예시

circle을 참조하는 경로 위 텍스트의 text-anchor 값에 따른 렌더링. 왼쪽: 'start'. 가운데: 'middle'. 오른쪽: 'end'. 빨간 원은 경로 시작점(원 분해 후), 파란 네모는 렌더링 시작점(75% 오프셋), 회색 화살표는 타이포그래픽 문자 배치 방향과 끝 지점을 표시. directionrtl이면 화살표 방향이 반대.

모든 글리프 렌더링은 2015년 시드니 회의에서 기본 도형에 대해 합의됨(의사록에 누락됨). 'startOffset' 속성으로 래핑을 단일 닫힌 하위 경로와 한 바퀴로 제한하기로 2016년 런던 에디터 회의에서 합의됨.

<길이-퍼센트> | <숫자>
초기값
0
애니메이션 가능
method

경로를 따라 텍스트를 렌더링하는 방식 지정.

align 값은 타이포그래픽 문자를 단순 2×3 행렬 변환을 사용해(즉, 타이포그래픽 문자의 늘이기/왜곡 없이) 렌더링함을 의미합니다. 일반적으로 각 타이포그래픽 문자마다 회전, 스케일, 이동 변환이 추가로 적용됩니다. 이 방식에서는 커서체처럼 연결된 폰트의 경우 경로를 따라 텍스트 렌더링 시 연결이 올바르게 정렬되지 않을 수 있습니다.

stretch 값은 타이포그래픽 문자 윤곽을 경로로 변환한 후, 모든 끝점 및 제어점을 경로의 수직 벡터에 맞게 조정하여 글리프를 늘이거나 왜곡하는 방식입니다. 이 방식에서는 커서체 등 연결 글리프도 연결이 유지됩니다. (비수직 직선 경로는 수평 직선 경로가 타이포그래픽 문자가 렌더링되는 경로에서 일정 오프셋을 갖도록 베지에 곡선으로 변환해야 함.)

영어와 아랍어 텍스트가 호 위에 렌더링된 모습

method 값에 따른 경로 위 텍스트 렌더링: 왼쪽 'align', 오른쪽 'stretch'.

align | stretch
초기값
align
애니메이션 가능
spacing

경로를 따라 렌더링할 타이포그래픽 문자 간격 결정 방식 지정.

exact 값은 textPath 레이아웃 규칙에 명시된 간격대로 정확히 렌더링함을 의미합니다.

auto 값은 사용자 에이전트가 경로 위 텍스트 레이아웃 알고리즘을 사용해 타이포그래픽 문자 간격을 시각적으로 보기 좋게 조정함을 의미합니다.

auto | exact
초기값
exact
애니메이션 가능
side

경로의 어느 쪽에 텍스트를 배치할지 결정(경로 방향 기준). right 값을 지정하면 경로가 반전됩니다.

side 값에 따라 원형 경로 안팎에 텍스트가 렌더링되는 예시

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 요소나 기본 도형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">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와 경로 참조에 모두 적용됩니다. 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 x="1" y="1" width="998" height="298"
        fill="none" stroke="blue" stroke-width="2" />
</svg>
예제 toap01 — 경로 위 간단한 텍스트

예제 toap01

SVG로 보기(SVG 지원 브라우저 한정)

예제 toap02tspan 요소를 textPath 요소 내에 포함시켜 스타일 속성 및 특정 글리프 렌더링 전 현재 텍스트 위치를 조정하는 방법을 보여줍니다. "up" 단어의 첫 번째는 빨간색으로 채워져 있습니다. dy 속성은 "up" 단어를 기준선에서 들어올리는 데 사용됩니다.

x, y, dx, dy, rotate 속성은 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 - 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 x="1" y="1" width="998" height="298"
        fill="none" stroke="blue" stroke-width="2" />
</svg>
예제 toap02 — textPath 내 tspan

예제 toap02

SVG로 보기(SVG 지원 브라우저 한정)

예제 toap03textPath 요소의 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 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 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 계산이 가능하게 합니다.

인라인 기본 방향이 수평이면 text, tspan 요소의 ‘x’ 속성은 경로를 따라 새로운 절대 오프셋을 나타내므로 startpoint-on-the-path의 명시적 새 값을 제공합니다. text, tspan 요소의 ‘y’ 속성은 무시됩니다. 인라인 기본 방향이 수직이면 text, tspan 요소의 ‘y’ 속성은 경로를 따라 새로운 절대 오프셋을 나타내므로 startpoint-on-the-path의 명시적 새 값을 제공합니다. text, tspan 요소의 ‘x’ 속성은 무시됩니다.

textPath 내 모든 문자를 배치한 후, 현재 텍스트 위치는 경로의 끝점(단일 닫힌 루프 경로의 경우 startOffset 반영 후)으로 설정됩니다. 즉, textPath 요소 뒤에(여전히 text 요소 내부) 명시적 위치 지정 정보가 없는 텍스트(x, y 속성 없음)는 경로 끝점에서 배치됩니다.

textPath 뒤 텍스트의 렌더링 시작점을 보여주는 이미지

명시적 위치 지정 정보가 없는 textPath 요소 뒤 텍스트의 시작점은 경로 끝점(빨간 점)입니다.

경로 마지막 문자 위치 대신 경로 끝점을 선택한 것은 폰트 등과 무관하게 저자가 예측하기 쉽기 때문입니다. 2016년 런던 에디터 회의에서 결정됨. GitHub Issue 84 참조.

11.9. 텍스트 렌더링 순서

text 요소는 하나 이상의 청크로 렌더링됩니다. 각 청크(텍스트 레이아웃 알고리즘에 의해 생성됨)는 문서 순서대로 연이어 렌더링됩니다. 각 렌더링된 청크(하나 이상의 글리프로 구성됨)는 하나의 경로처럼 채우기 및 스트로크 처리가 이루어집니다.

즉, 청크 내 모든 글리프를 채운 후, 모든 글리프를 한 번에 스트로크하거나, paint-order 속성 값에 따라 반대로 처리할 수 있습니다.

페인팅 관점에서 text는 0개 이상의 등가 경로를 가지며, 각각의 청크마다 하나씩 존재합니다. 각 등가 경로는 해당 청크 내 글리프마다 하나의 하위 경로로 구성됩니다.

fill-rule 속성은 SVG 텍스트 요소에 적용되지 않으므로, 등가 경로 내 하위 경로의 구체적 순서는 중요하지 않습니다.

각 하위 경로의 시작 위치와 경로가 글리프 형태를 따라 진행하는 방향은 정의되어 있지 않습니다. 단, 사용자 에이전트는 특정 폰트와 글리프에 대해 일관성을 유지해야 합니다.

텍스트에 대시 스트로크를 적용할 경우, 서로 다른 구현체에서 대시 패턴의 위치가 동일하게 나오지 않을 수 있습니다.

11.10. 속성 및 의사 요소

CSS는 텍스트 스타일링을 위한 다양한 속성을 제공합니다. 일반적으로 SVG에는 두 종류의 속성만 적용됩니다: 어떤 글리프를 렌더링할지 결정하는 속성(font-family, font-style 등)과, 문단 단위에 적용되는 속성(direction, writing-mode, line-height, letter-spacing 등)입니다.

SVG 텍스트 요소에서 반드시 지원해야 하는 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 요소 내 개별 텍스트 청크마다 적용됩니다. 각 텍스트 청크는 초기 현재 텍스트 위치를 가지며, 이는(상황에 따라) text 요소의 x, y 속성 적용, tspan 요소의 첫 렌더링 문자에 명시적으로 할당된 x 또는 y 값, 또는 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로 가운데 정렬된 두 줄 텍스트 이미지

보존된 줄 바꿈으로 두 개의 텍스트 청크가 생성되며, 각각 독립적으로 앵커링됩니다.

또 다른 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줄로 나눈 이미지

x, y 속성의 좌표 3개로 텍스트가 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의 약어(shorthand)로 매핑하여 지원해야 합니다:

그 외 값은 모두 잘못된 값으로 처리해야 합니다.

11.10.1.4. ‘kerning’ 속성

kerning’ 속성은 SVG 2에서 삭제되었습니다.

SVG 1.1에서는 'kerning' 속성을 사용해 폰트 커닝 테이블을 활용하여 글리프 사이 간격을 조정할지 결정합니다. 또한 <길이> 값을 사용할 수 있는데, 이 값이 주어지면 글리프 사이 간격에 추가됩니다(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에 의존합니다.
목적: 웹 폰트 기능을 위한 CSS 2.1 및 CSS3와의 정렬, 그리고 폰트의 고급 타이포그래픽 기능 접근성 제공.
담당자: Chris (ACTION-3123)

11.10.2.1. ‘font-variant’ 속성

CSS Font Module Level 3에서는 'font-variant' 속성의 의미를 CSS 2.1과 다르게 변경했습니다. 이 속성은 단일 폰트 내에서 폰트 변형을 선택하는 약어(shorthand)로 재설계되었으며, 기능이 크게 확장되었습니다.

SVG 2에서는 모든 font-variant 하위 속성(예: font-variant-ligatures) 구현이 필수입니다.

11.10.2.2. ‘line-height’ 속성

SVG에서는 line-height 속성을 사용해 여러 줄 텍스트(수평/수직 모두)에서 줄 간 간격(leading)을 결정합니다. 경로 위 텍스트에는 적용되지 않습니다.

여기서 제공된 추가 정보 외에, 정식 정의는 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 역할(예: directiontext-anchor의 기준점을 설정한다는 것)에 대해 좀 더 명확했으나, 해석의 여지는 남았습니다. SVG 1.0과 1.1 모두 여러 줄 텍스트를 허용하지 않아 혼란이 가중되었습니다.

여기서 제공된 추가 정보 외에, 정식 정의는 CSS Writing Modes Level 3에 있습니다 ([css-writing-modes-3]).

11.10.2.4. ‘direction’ 속성

이 속성은 text 또는 tspan 요소의 인라인 기본 방향을 지정합니다. 텍스트 줄의 startend 지점을 정의하며, 이는 text-anchorinline-size 속성에서 사용됩니다. 또한 unicode-bidi 속성 값이 embed 또는 bidi-override인 경우 문자 배치 방향에도 영향을 줄 수 있습니다.

direction 속성은 인라인 기본 방향에 수직으로 배치된 글리프(일반적으로 수평 라틴/아랍 텍스트, 또는 좁은 셀 라틴/아랍 문자가 위→아래 인라인 방향에서 90도 시계 방향으로 회전된 경우)에만 적용됩니다.

리뷰어는 반드시 이것이 CSS3 Writing modes와 일치하는지 특별히 확인해 주세요.

여기서 제공된 추가 정보 외에, 정식 정의는 CSS Writing Modes Level 3에 있습니다 ([css-writing-modes-3]).

많은 경우 유니코드의 양방향 알고리즘([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>
Example

예제

이 예제를 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>
Example

예제

이 예제를 SVG로 보기(SVG 지원 브라우저 한정)

11.10.2.5. ‘dominant-baseline’ 속성

이 속성은 CSS Line Layout Module 3 명세에서 정의되어 있습니다. 'dominant-baseline' 참고. [css-inline-3]

SVG 2에서는 이 속성 정의에 몇 가지 변경점이 있습니다. 특히:

SVG에서는 dominant-baseline 속성 값을 사용해 글리프를 x, y 속성 기준으로 정렬합니다. text-orientation 값이 sideways일 때 dominant-baselineauto 값은 alphabetic이지만, 하위 호환을 위해 글리프는 x, y 속성 기준으로 central 값으로 정렬해야 합니다.

이전 동작을 선호하는 실제 사용 사례가 있다면 알려주세요.

11.10.2.6. ‘alignment-baseline’ 속성

이 속성은 CSS Line Layout Module 3 명세에서 정의되어 있습니다. 'alignment-baseline' 참고. [css-inline-3]

새로운 콘텐츠에서는 vertical-align 속성 약어(shorthand) 사용이 권장됩니다.

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 속성 약어(shorthand) 사용이 권장됩니다.

SVG 1.1의 초기값 'baseline'은 SVG 2에서 삭제되었습니다. 사용자 에이전트는 레거시 SVG 콘텐츠 지원이 필요하다면 이 값을 '0'으로 계산하도록 허용됩니다.

'baseline' 값은 'vertical-align'을 'alignment-baseline'과 'baseline-shift'의 약어(shorthand)로 변환하면서 삭제되었습니다. 이 값은 'alignment-baseline'에도 존재하고, 길이값 '0'과 중복되기 때문입니다.

SVG 2 요구사항: CSS와 기준선 정렬(baseline alignment) 기능을 일치시킴.
결정: SVG 2는 ‘baseline-shift’를 폐기하고 ‘vertical-align’ 사용.
목적: CSS와 일치시킴.
담당자: Cameron (ACTION-3281)

'baseline-shift'는 아래첨자, 윗첨자 정렬에 중요합니다(이 목적에 인크스케이프가 의존함). CSS Inline Layout Module Level 3에도 남아 있습니다. 'vertical-align'은 여러 속성을 한 번에 바꾸는 약어(shorthand)이며, 그 안에 '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 텍스트 처리 방식과 일치합니다.

'text-overflow' 정의는 CSS3 UI 명세 참고([css-ui-3]).

SVG는 text-overflow 속성을 사용해 텍스트 콘텐츠 블록 요소라인 박스를 넘길 때(예: white-space 속성 값이 nowrap일 때) 렌더링 방식을 제어합니다. 이 속성은 서식 유지 텍스트나 경로 위 텍스트에는 적용되지 않습니다.

SVG에서 text-overflowoverflow 속성의 계산값과 관계없이, 유효하게 지정된 래핑 영역이 있으면 효과를 가집니다.

text-overflow 값이 ellipsis이면, 렌더링할 텍스트가 래핑 영역을 넘칠 때, 주어진 영역 내에 맞게 생략 기호(ellipsis)가 렌더링됩니다. 렌더링 시에는 ellipsis가 삽입되는 위치의 문자를 대신하는 것처럼 처리합니다.

text-overflow 값이 clip이면, 래핑 영역을 넘는 텍스트는 잘려서 일부 문자만 부분적으로 렌더링될 수 있습니다.

text-overflow의 다른 값은 지정되지 않은 것처럼 처리합니다.

text-overflow 효과는 순수하게 시각적 효과만 가지며, ellipsis 자체는 DOM에 포함되지 않습니다. 모든 DOM 메서드에서는 text-overflow가 적용되지 않은 것과 같으며, 래핑 영역이 텍스트를 제약하지 않은 것과 같습니다.

아래 예제는 text-overflow 활용을 보여줍니다. 맨 위 줄은 일반적으로 렌더링되는 텍스트(white-space 값 pre로 인해 텍스트가 넘치고, overflowvisible로 표시됨)입니다. 중간 줄은 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 속성이 텍스트 요소에 적용된 모습. 맨 아래 줄은 생략 기호가 적용된 텍스트를 보여줍니다.

이 속성이 쓸모없다는 주장도 있습니다. 만약 생략된 텍스트를 노출하는 메커니즘(ellipsis 위에 마우스 오버 시 툴팁 등)이 있었다면 더 유용할 수 있습니다. 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-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>
일본 시에서 7글자마다 전통적으로 줄 바꿈된 세로 텍스트 예시.

줄 바꿈이 적용된 세로 다중 줄 텍스트 예시. 텍스트는 일본 시 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 값은 'white-space-collapse' 속성에서 xml:space=preserve 동작과 일치하도록 설계됨. (fantasai가 동의함. 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 요소 두 쌍을 보여주며, 모두 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 쌍은 들여쓰기 문자 데이터의 효과를 보여줍니다. xml:space="default" 속성이 첫 번째 text 요소에 적용되면 사용자 에이전트는 다음을 수행합니다:

두 번째 text 쌍은 들여쓰기 없는 문자 데이터의 효과를 보여줍니다. xml:space="default" 속성이 세 번째 text 요소에 적용되면 사용자 에이전트는 다음을 수행합니다:

XML 파서는 줄 바꿈 표준 표현("U+000D U+000A" 문자 시퀀스, 캐리지 리턴+줄 바꿈 또는 단독 U+000D 혹은 U+000A)을 문자 데이터 전달 전 단일 문자 U+000A로 변환해야 합니다. 따라서 SVG 내 모든 줄 바꿈은 원본 리소스에서 어떤 줄 바꿈 표현을 사용했든 간에 단일 문자 U+000A로 처리됩니다. (XML 줄 끝 처리 참고.)

문자 위치 번호에 기반한 SVG 언어나 SVG DOM의 기능(예: x, y, dx, dy, rotate 등)은 본 절에서 설명한 공백 처리 규칙이 적용된 후의 문자 위치를 기준으로 합니다. 특히 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 약어(shorthand) 속성으로도 지정할 수 있습니다. 이 정의는 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 속성으로 지정된 것처럼 해석합니다.

텍스트 장식의 채우기(fill)나 스트로크(stroke)가 명시적으로 지정되지 않은 경우(text-decoration, text-decoration-color, text-decoration-fill, text-decoration-stroke 미지정), 텍스트가 선언된 위치의 fill/stroke 속성 값이 장식에 적용됩니다(아래 예시 참고).

text-decoration-linetext-decoration-style 속성은 SVG 2에서 새롭게 추가되었습니다. SVG 1.1/CSS 2.1 text-decoration 속성은 이들 속성의 약어(shorthand)로 하위 호환성 있게 변환됩니다. text-decoration-fill, text-decoration-stroke는 SVG 고유 속성으로, 향후 CSS Text Decoration 명세에 추가될 수 있습니다.

텍스트와 장식이 그려지는 순서는 CSS Text Decoration Module Level 3의 Painting Order of Text Decorations 절에서 정의됩니다. 장식 자체의 페인트 순서(fill/stroke)는 장식이 선언된 위치의 paint-order 속성 값에 의해 결정됩니다.

예제 textdecoration01text-decoration 속성 예시를 보여줍니다. 첫 번째 줄은 text-decoration 값이 없어 text-decoration:none이 적용됩니다. 두 번째 줄은 text-decoration:line-through을 보여주고, 세 번째 줄은 text-decoration:underline을 보여줍니다. 네 번째 줄은 장식이 text 요소에 선언될 때 요소의 fill/stroke 속성이 그대로 장식에 적용된다는 규칙을 보여줍니다(즉, blue fill, red stroke). 단, 단어 "different"는 text-decoration 값을 명시적으로 지정하므로, 해당 단어의 언더라인은 tspan 요소의 fill/stroke 값(yellow fill, darkgreen 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 텍스트 장식에 이 속성을 추가하고, 동시에 텍스트에 '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 생성기는 텍스트 문자열의 DOM 순서가 자연스러운 읽기 순서와 일치하도록 배치하여, 웹 브라우저 등 SVG 뷰어에서 올바른 순서로 텍스트 선택이 이루어지도록 해야 합니다.

11.12.1. 텍스트 선택 구현 참고사항

다음 구현 참고사항은 텍스트 선택 작업 중 어떤 문자가 선택되는지 결정하는 알고리즘을 설명합니다.

텍스트 선택 작업이 발생하는 동안(예: 사용자가 마우스를 클릭하고 드래그하여 선택 범위를 지정할 때), 사용자 에이전트는 선택 시작 위치선택 종료 위치를 결정하며, 각각은 문자 사이의 텍스트 문자열 내 위치를 나타냅니다. 선택 시작 위치와 종료 위치가 결정되면, 사용자 에이전트는 적절한 문자를 선택하며, 결과 텍스트 선택은 다음 중 하나가 됩니다:

포인터 장치가 있는 시스템에서는, 선택 시작 위치를 결정하기 위해 SVG 사용자 에이전트는 렌더링된 글리프에 대응하는 문자 사이의 경계 중 현재 포인터 위치와 가장 가까운(최적의) 경계를 선택합니다(예: 선택 작업을 시작하는 이벤트 시점의 마우스 위치). 이후 사용자 에이전트는 선택 작업 완료까지(예: 마우스 드래그 후 mouse up) 진행을 추적합니다. 선택 작업이 끝나면, 선택 종료 위치에 대해 가장 가까운(최적의) 문자 경계를 결정합니다.

양방향성으로 인한 문자 재정렬이 없는 경우, 선택 범위는 선택 시작 위치선택 종료 위치 사이의 모든 문자입니다. 예를 들어, text 요소에 "abcdef"가 있고, 선택 시작/종료 위치가 각각 0과 3(즉, "a"의 왼쪽이 0)이라면, 선택된 문자열은 "abc"가 됩니다.

사용자 에이전트가 양방향 텍스트 선택을 구현할 때, 선택이 논리적 순서상 인접하지 않은 문자 사이에서 시작/끝나면, 선택 범위로 간주할 수 있는 여러 조합이 있을 수 있습니다. 가능한 선택 옵션들 중, 알고리즘은 텍스트 문자열의 시각적 렌더링 순서와 가장 가까운 선택 옵션을 선택해야 합니다.

여러 문자가 하나의 글리프 집합에 불가분하게 매핑되는 경우, 사용자 에이전트는 선택이 글리프 집합 중간에서 시작되는 것을 허용하지 않거나, 글리프 집합이 차지하는 영역을 해당 문자별로 할당하려 시도할 수 있습니다.

마우스 등 포인터 장치가 지원되는 시스템에서는, 텍스트에 이벤트 핸들러나 링크가 할당되어 있어 이벤트 처리 우선순위로 인해 텍스트 선택이 막힐 수 있는 경우에도, 사용자 에이전트는 텍스트 선택 메커니즘을 반드시 제공해야 합니다(포인터 이벤트 참고). 한 가지 구현 옵션: 마우스 등 포인터 장치가 있는 플랫폼에서는 사용자 에이전트가 글자 셀 주변에 작은 추가 영역을 제공해, 해당 영역에서는 텍스트 선택 작업이 시작되지만 이벤트 핸들러나 링크는 실행되지 않도록 할 수 있습니다.

11.13. DOM 인터페이스

SVG 2 요구사항: text 요소를 윤곽선(path 데이터)로 변환하는 DOM 메서드가 필요함.
결정: ‘text’ 요소를 윤곽선 path 데이터로 변환하는 DOM 메서드를 추가할 예정이며, 해당 기능을 FXTF로 옮길 수도 있음.
목적: 텍스트를 path로 조작할 수 있도록 함.
담당자: Cameron (ACTION-3076)
상태: 향후 wishlist

11.13.1. SVGTextContentElement 인터페이스

SVGTextContentElement 인터페이스는 자식 텍스트 콘텐츠 렌더링을 지원하는 요소에서 구현됩니다.

이 인터페이스의 메서드 중 문자 인덱스나 문자 개수와 관련된 참조는 각각 UTF-16 코드 유닛 인덱스 및 UTF-16 코드 유닛 개수로 해석되어야 합니다. 이는 DOM Level 2 Core와의 일관성을 위한 것으로, CharacterData 인터페이스의 메서드가 문자 데이터 내 인덱스 및 개수로 UTF-16 코드 유닛을 사용하기 때문입니다. 예를 들어, text 요소의 텍스트 콘텐츠가 U+10000과 같은 하나의 non-BMP 문자라면, 해당 요소에 getNumberOfChars를 호출하면, 해당 문자를 표현하는 두 개의 UTF-16 코드 유닛(서로게이트 페어)이 있으므로 2를 반환합니다.

[Exposed=Window]
interface SVGTextContentElement : SVGGraphicsElement {

  // lengthAdjust 타입 상수
  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 텍스트 노드인 경우, 부모 요소의 white-space 속성값에 따라 공백을 정규화한 후 node의 텍스트 콘텐츠 길이를 반환
  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가 음수이면 throw IndexSizeError
  3. length를 사용자 단위의 길이로 0으로 초기화
  4. 이 요소 내 DOM의 각 주소 지정 가능한 문자 중 인덱스가 charnum ≤ index < (charnum + nchars)인 경우:
    1. 해당 문자가 타이포그래픽 문자에 대응하고, 해당 타이포그래픽 문자에 처음 대응되는 문자라면:
      1. 해당 타이포그래픽 문자의 advance(kerning 포함)를 length에 더함
      2. letter-spacing 또는 word-spacing 속성에서 글자 뒤에 공간이 추가됐다면 그 공간도 length에 더함

      예: 리가처가 부분적으로만 부분 문자열에 포함될 경우, 타이포그래픽 문자의 advance 및 뒤따르는 letter-spacing, word-spacing 공간은 첫 번째 문자에만 포함됩니다.

  5. length 반환

이전 버전 SVG에서는 이 메서드와 getComputedTextLength가 자식 요소의 dx, dy에 의한 인라인 방향 위치 조정도 포함해야 했으나, 명세가 불명확하고 구현도 미흡하며 실질적 이점이 없어서, 구현과 일치시키도록 단순화되었습니다.

텍스트 길이 메서드 변경은 2015년 8월 파리 F2F에서 합의.

요소 element 내 인덱스 index의 문자에 대해 해당 문자의 타이포그래픽 문자를 찾으려면, 다음 절차를 따릅니다:

  1. 이 요소 내 DOM의 각 주소 지정 가능한 문자에 인덱스를 할당(첫 번째 문자가 인덱스 0)
  2. last를 문자에 할당된 최대 인덱스로 설정
  3. charnum < last이고 해당 인덱스의 문자가 타이포그래픽 문자에 대응하지 않으면:
    1. charnum = charnum + 1
  4. charnum이 최대 인덱스보다 크면 null 반환
  5. 그 외에는 charnum에 대응하는 타이포그래픽 문자를 반환

getStartPositionOfChar 메서드는 텍스트 레이아웃 후 타이포그래픽 문자의 위치를 구하는 데 사용됩니다. getStartPositionOfChar(charnum) 호출 시 다음 절차를 따릅니다:

  1. 현재 요소 내 인덱스 charnum에서 해당 문자의 타이포그래픽 문자 찾기 결과를 cluster로 설정
  2. cluster가 null이면 throw IndexSizeError
  3. 해당 타이포그래픽 문자정렬점p로 설정(현재 요소 좌표계)
  4. p를 나타내는 detached DOMPoint 객체를 새로 생성하여 반환

getEndPositionOfChar 메서드는 텍스트 레이아웃 후 타이포그래픽 문자의 끝 위치를 구하는 데 사용됩니다. getEndPositionOfChar(charnum) 호출 시 다음 절차를 따릅니다:

  1. 현재 요소 내 인덱스 charnum에서 해당 문자의 타이포그래픽 문자 찾기 결과를 cluster로 설정
  2. cluster가 null이면 throw IndexSizeError
  3. 해당 cluster정렬점p로 설정(현재 요소 좌표계)
  4. directioncluster의 advance 방향 단위 벡터로 설정(글쓰기 모드, 문자 방향, text-orientation, glyph-orientation-horizontal, glyph-orientation-vertical 속성, 해당 rotate 값, textPath 회전 등 반영)
  5. advancecluster의 advance로 설정
  6. p = p + advance · direction
  7. p를 나타내는 detached DOMPoint 객체를 새로 생성하여 반환

getExtentOfChar 메서드는 주어진 타이포그래픽 문자에 대응하는 글리프 셀의 타이트 바운딩 박스를 계산하는 데 사용됩니다. getExtentOfChar(charnum) 호출 시 다음 절차를 따릅니다:

  1. 현재 요소 내 인덱스 charnum에서 해당 문자의 타이포그래픽 문자 찾기 결과를 cluster로 설정
  2. cluster가 null이면 throw IndexSizeError
  3. 현재 요소 좌표계에서 cluster의 글리프 셀에 해당하는 회전 사각형을 quad로 설정
  4. 현재 요소 좌표계에서 quad를 가장 꽉 차게 감싸는 사각형을 rect로 설정
  5. rect를 나타내는 새 DOMRect 객체 반환

getRotationOfChar 메서드는 타이포그래픽 문자의 회전 각도를 구하는 데 사용됩니다. getRotationOfChar(charnum) 호출 시 다음 절차를 따릅니다:

  1. 현재 요소 내 인덱스 charnum에서 해당 문자의 타이포그래픽 문자 찾기 결과를 cluster로 설정
  2. cluster가 null이면 throw IndexSizeError
  3. directioncluster의 advance 방향 각도(도 단위)로 설정(글쓰기 모드, 문자 방향, text-orientation, glyph-orientation-horizontal, glyph-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. 해당 인덱스의 문자가 타이포그래픽 문자에 대응하고, 해당 타이포그래픽 문자에 처음 대응되는 문자이며, 요소 좌표계에서 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. 문서의 range를 모두 selection에서 제거 [DOM][EDITING]
  6. selectiondirection을 forwards로 설정
  7. selection에 새 range를 추가(시작점은 (node, charnum), 끝점은 (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. 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;
};

x, y, dx, dy, rotate IDL 속성은 각각 x, y, dx, dy, rotate 콘텐츠 속성과 반영됩니다.

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 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 콘텐츠 속성과 연결됩니다. method숫자형 타입 값은 위의 타입 상수 테이블에 설명된 대로입니다.

spacing IDL 속성은 반영되어 spacing 콘텐츠 속성과 연결됩니다. spacing숫자형 타입 값은 위의 타입 상수 테이블에 설명된 대로입니다.