aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design
diff options
context:
space:
mode:
Diffstat (limited to 'docs/design')
-rw-r--r--docs/design/004-text.md42
1 files changed, 42 insertions, 0 deletions
diff --git a/docs/design/004-text.md b/docs/design/004-text.md
new file mode 100644
index 0000000..703967b
--- /dev/null
+++ b/docs/design/004-text.md
@@ -0,0 +1,42 @@
+# 004 — 글자: 양방향, 합성, 셰이핑을 빌드할 때 컴파일한 표로
+
+2026-09-28. Pure 외부 피드백 002의 셋째 항목. [002](002-symbol-format.md)는 FreeType을 실행 중에서 빼고 글꼴을
+빌드할 때 곡선 레코드로 바꿨다. 그 대가로 Vega는 코드 포인트 하나를 글리프 하나로 그렸다. 합자, 커닝, 아랍 문자의 위치별
+형태, 결합 부호의 자리, 오른쪽에서 왼쪽으로 쓰는 글(양방향)이 없었다.
+
+착수 기준:
+
+- 바꿀 결정: 셰이핑을 실행 중에 OpenType 표(GSUB, GPOS)를 해석해서 할지(HarfBuzz의 방식), 빌드할 때 글꼴의 행동을
+ 단순한 표로 컴파일해 두고 실행 중에는 검증한 표를 제자리에서 읽기만 할지. 심볼과 같은 원칙이면 뒤쪽이다.
+- 남은 질문: 컴파일한 표만으로 HarfBuzz와 같은 글리프와 자리가 나오는가? 어느 문자 체계까지인가? 양방향과 합성은 유니코드의
+ 적합성 시험을 모두 통과하는가?
+- 최소 확인: 유니코드 15.1의 `BidiTest.txt`(49만 줄)와 `BidiCharacterTest.txt`(9.6만 줄), `NormalizationTest.txt`를 모두
+ 통과한다. 셰이핑은 라틴(커닝, 합자), 아랍(위치별 형태, lam-alef, 결합 부호), 히브리(결합 부호) 문장에서 HarfBuzz 10.2와
+ 글리프와 자리가 같다.
+- 중단 기준: 적합성 시험에 틀린 줄이 하나라도 있으면 그 단계를 쓰지 않는다. 셰이핑이 HarfBuzz와 다른 문장은 원인을 찾을
+ 때까지 그 문자 체계를 받지 않는다(빌드 도구가 거부한다).
+
+## 단계
+
+1. 유니코드 성질 표: UCD에서 생성한 두 단계 표(코드 포인트 → 값). [text/unicode.py](../../text/unicode.py)가
+ [text/unicode-data.c](../../text/unicode-data.c)를 만든다.
+2. 양방향(UAX #9): 문단 수준, 명시적 수준과 격리(X1–X10), 약한 형(W1–W7), 괄호 쌍(N0), 중립(N1–N2), 암시적 수준(I1–I2),
+ 줄(L1)과 보이는 순서(L2).
+3. 정규화: 한글 음절과 정준 합성(NFC).
+4. 셰이핑: 빌드 도구가 글꼴마다 HarfBuzz로 커닝 쌍, 합자, 위치별 형태, 결합 부호의 자리를 뽑아 심볼 파일에 넣는다. 실행 중에는
+ 그 표를 찾아 쓴다.
+5. 비례폭 글줄: 셰이핑한 글리프를 제 advance로 늘어놓아 그린다.
+6. 접근성.
+
+## 양방향
+
+[text/bidi.c](../../text/bidi.c)는 UAX #9를 규칙 이름 그대로 짠다. 문단 수준(P2–P3), 명시적 수준과 방향 상태 스택(깊이
+125, 넘친 격리·내장·유효 격리의 계수, X1–X8), 제거(X9)와 격리 실행 열(X10: 격리 시작자로 끝나는 실행은 짝 PDI로 시작하는
+실행으로 이어지고, sos와 eos는 명시적 수준으로 정한다), 약한 형(W1–W7), 괄호 쌍(N0: 깊이 63의 스택, U+2329·232A와
+U+3008·3009의 정준 동치, 바뀐 괄호 뒤의 결합 부호), 중립(N1–N2), 암시적 수준(I1–I2), 그리고 한 줄로서의 L1과 보이는
+순서(L2)다. 성질은 UCD에서 만든 표다(양방향 클래스는 두 단계 표 37 KiB, 괄호 128개, 거울 글자 428개).
+
+유니코드 15.1의 적합성 시험을 모두 통과한다. `BidiTest.txt`의 770,241 경우(클래스 열마다 비트 집합이 가리키는 문단 방향)와
+`BidiCharacterTest.txt`의 91,707 경우(코드 포인트, 괄호 포함)에서 수준과 보이는 순서가 하나도 틀리지 않는다. Pi 5에서 전체가
+0.74초다. 처음 짠 것은 148 경우가 틀렸다. 앞선 격리 실행 열의 암시적 수준(I1–I2)이 바꾼 수준으로 다음 열의 sos를 정했기
+때문이다(sos와 eos는 명시적 수준으로 정해야 한다).