aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design
diff options
context:
space:
mode:
Diffstat (limited to 'docs/design')
-rw-r--r--docs/design/004-text.md61
1 files changed, 58 insertions, 3 deletions
diff --git a/docs/design/004-text.md b/docs/design/004-text.md
index f423221..4ee1cf2 100644
--- a/docs/design/004-text.md
+++ b/docs/design/004-text.md
@@ -7,7 +7,8 @@
착수 기준:
- 바꿀 결정: 셰이핑을 실행 중에 OpenType 표(GSUB, GPOS)를 해석해서 할지(HarfBuzz의 방식), 빌드할 때 글꼴의 행동을
- 단순한 표로 컴파일해 두고 실행 중에는 검증한 표를 제자리에서 읽기만 할지. 심볼과 같은 원칙이면 뒤쪽이다.
+ 단순한 표로 컴파일해 두고 실행 중에는 검증한 표를 제자리에서 읽기만 할지. 심볼과 같은 원칙이면 뒤쪽이다. (결과: 둘을
+ 나눴다. 계획은 빌드할 때 컴파일하고, 조회는 OpenType 그대로 읽는다. 아래 셰이핑 절.)
- 남은 질문: 컴파일한 표만으로 HarfBuzz와 같은 글리프와 자리가 나오는가? 어느 문자 체계까지인가? 양방향과 합성은 유니코드의
적합성 시험을 모두 통과하는가?
- 최소 확인: 유니코드 15.1의 `BidiTest.txt`(49만 줄)와 `BidiCharacterTest.txt`(9.6만 줄), `NormalizationTest.txt`를 모두
@@ -23,8 +24,8 @@
2. 양방향(UAX #9): 문단 수준, 명시적 수준과 격리(X1–X10), 약한 형(W1–W7), 괄호 쌍(N0), 중립(N1–N2), 암시적 수준(I1–I2),
줄(L1)과 보이는 순서(L2).
3. 정규화: 한글 음절과 정준 합성(NFC).
-4. 셰이핑: 빌드 도구가 글꼴마다 HarfBuzz로 커닝 쌍, 합자, 위치별 형태, 결합 부호의 자리를 뽑아 심볼 파일에 넣는다. 실행 중에는
- 그 표를 찾아 쓴다.
+4. 셰이핑: 빌드 도구가 글꼴의 셰이핑 계획을 컴파일해 배치 표와 함께 심볼 파일에 넣는다. 실행 중에는 HarfBuzz의 절차를
+ 그대로 옮긴 엔진이 그것을 읽는다. 빌드 도구는 HarfBuzz와 결과가 다른 파일을 만들지 않는다.
5. 비례폭 글줄: 셰이핑한 글리프를 제 advance로 늘어놓아 그린다.
6. 접근성.
@@ -49,3 +50,57 @@ U+3008·3009의 정준 동치, 바뀐 괄호 뒤의 결합 부호), 중립(N1–
`NormalizationTest.txt`의 19,074줄(줄마다 NFC와 NFD 16가지 대조)과, 그 1부에 없는 코드 포인트 1,095,035개가 제 자신의
NFC이자 NFD라는 것을 모두 지킨다. 적합성 시험 셋을 합쳐 Pi 5에서 0.9초다.
+
+## 셰이핑
+
+처음 계획은 HarfBuzz가 표본 문자열(글자 쌍, 부호 하나 붙은 글자, 위치별 형태)을 셰이핑한 결과를 표로 뽑는 것이었다. 글꼴을
+열어 보고 버렸다. DejaVu Sans 한 벌에만 표본으로 잡히지 않는 규칙이 여럿이다.
+
+- 라틴의 `ccmp`: i와 j는 위 부호가 뒤에 오면 점 없는 꼴이 된다. 사이에 아래 부호가 둘까지 있어도 그렇고, 셋이면 안 된다.
+ 대문자 뒤의 위 부호는 대문자용 꼴이 된다.
+- 히브리: ayin 뒤에 아래 부호가 오면 ayin이 다른 꼴이 된다. yod와 hiriq는 한 글리프가 된다.
+- 아랍: 부호끼리의 합자가 있다(shadda와 fatha). lam-alef는 사이의 부호를 건너뛰어 합쳐지고, 그 부호는 합자의 어느 성분에
+ 붙었는지를 따라간다(mark-to-ligature).
+
+이런 문맥은 규칙 자체를 옮기지 않고는 정확히 재현할 수 없다. 그래서 나눴다.
+
+- 빌드할 때: 계획을 컴파일한다. 문자 체계와 방향마다 HarfBuzz의 계획기가 하는 일을 그대로 한다. 기능을 모으고(기본, 아랍,
+ 히브리 셰이퍼의 목록과 단계), 중복을 합치고, 마스크 비트를 나누고, 글꼴의 문자 체계·언어 체계에서 기능을 찾고, 단계별로
+ 조회를 모아 정렬해 합친다. 결과는 조회 번호, 마스크, ZWJ/ZWNJ 규칙의 목록이다. 글꼴의 문자 지도와 advance, GDEF·GSUB·GPOS
+ 표는 그대로 싣는다([text/shape.h](../../text/shape.h), [text/shape-build.c](../../text/shape-build.c)).
+- 실행 중에: [text/shape.c](../../text/shape.c)가 HarfBuzz 10의 절차를 함수 단위로 옮긴다. 유니코드 성질과 자소 묶음,
+ 글꼴을 보는 정규화(없는 글자는 분해하고 있는 합성은 합치며, 부호는 HarfBuzz의 수정 결합 등급과 아랍 UTR #53, 히브리
+ 순서로 정렬한다), 거울 글자, 아랍 연결 상태 기계, GSUB(유형 1–8과 확장, 문맥과 연쇄 문맥의 형식 1–3, 역연쇄), 합자의
+ 성분 추적, GPOS(유형 1–8, 짝 형식 1·2, 필기체, 기저·합자·부호에 붙는 부호), 부착 오프셋의 전파, 보이지 않는 문자
+ 숨기기를 한다. 표는 제자리에서 읽고, 읽을 때마다 표의 끝을 넘는지 확인한다. 망가진 표는 틀리게 셰이핑할 뿐 밖을 읽지
+ 않는다.
+
+심볼 파일은 VEGASYM4가 됐다. 헤더의 깃발이 점들 뒤에 셰이핑 구역이 있다고 알린다. 셰이핑이 닿는 글리프(문자 지도,
+분해와 합성, 거울, GSUB의 닫힘)는 `0x110000 + 글리프 번호`로 심볼이 된다. 같은 글리프의 심볼들은 점을 나눠 쓴다.
+
+HarfBuzz와 다른 파일은 만들어지지 않는다. `vega-symbols build --shape`는 파일을 쓴 뒤 계획마다 무작위 실행을 HarfBuzz
+10.2와 함께 셰이핑한다. 실행은 두 종류다. 하나는 낱말들(글꼴의 치환이 시작되는 글자를 자주 섞고, 부호를 하나에서
+셋까지 붙이고, ZWJ·ZWNJ를 끼운다)이고, 다른 하나는 아무 순서의 문자(맨 앞의 부호, 쌓인 부호)다. 글리프, 클러스터,
+advance, 오프셋 가운데 하나라도 다른 실행이 있으면 파일을 지운다.
+
+결과(Pi 5):
+
+- DejaVu Sans, 라틴·그리스·키릴·히브리·아랍·Common, 양방향 12개 계획에 각 5만 실행(60만 실행, 1,270만 문자): 다른
+ 실행 0.
+- 설치된 글꼴 전부(Free, Liberation, Lato, Noto Sans Mono, URW, DejaVu 계열 등 60여 벌), 계획마다 1천 실행: 받아들인
+ 글꼴은 모두 다른 실행 0. 한 번 달랐다. 짝 위치 형식 2에서 두 번째 글리프의 등급이 0이면 다음 하위 표로 넘어가게 짰는데,
+ HarfBuzz 10.2는 그 하위 표를 적용하고 멈춘다(FreeSerif의 y와 마침표 커닝이 40 단위 달랐다). 고친 뒤 FreeSerif, FreeMono,
+ DejaVu Sans Bold, Liberation Mono, Lato에 계획마다 2만 실행으로 다시 확인했다.
+- 속도: 조회마다, 하위 표마다 시작 글리프의 요약(HarfBuzz의 set digest: 64비트 무늬 셋)을 열 때 만들어 두면, 버퍼에 없는
+ 글리프로 시작하는 조회와 하위 표를 건너뛴다. 문자 지도는 BMP를 쪽마다 바로 찾는다. 이것으로 HarfBuzz의 1.05–1.18배
+ 시간이다(문자당 라틴 422 대 404 ns, 아랍 428 대 371 ns, 히브리 313 대 274 ns). 요약 전에는 2.5배였다.
+
+받지 않는 것(빌드 도구가 이유를 말하고 거부한다):
+
+- GPOS가 없는 글꼴. HarfBuzz는 결합 등급과 글리프 외곽 상자로 부호를 놓는다(fallback positioning). CJK 글꼴, Nimbus Mono,
+ Noto Mono 등이 여기에 걸린다.
+- 옛 `kern` 표로 커닝하는 글꼴(Liberation Sans·Serif, FreeSans).
+- AAT 표(morx, kerx, trak), 늘이기(stch), 아랍 형태가 없어 HarfBuzz가 대체 셰이핑을 하는 글꼴.
+- 기본·아랍·히브리 셰이퍼가 아닌 문자 체계: 인도계, 태국·라오, 한글 자모, 크메르, 미얀마, USE 문자 체계들, 시리아.
+- 이체 선택자(cmap 형식 14)는 싣지 않는다. 선택자는 숨기고 앞 글자는 기본 글리프로 둔다.
+