아랍어 타이포그래피 렌더링의 놀라운 경험과 기술 부채에 대한 인터랙티브 입문
1 hour ago
1
- 아랍어 웹 타이포그래피는 글자 연결, 양방향 텍스트, 숫자·구두점 처리, 줄 맞춤이 함께 얽힌 렌더링 인프라 문제이며 단순 CSS 버그로 처리하기 어려움
- 고전 아랍어 조판은 단어 사이 공백이 아니라 글자 내부 획을 늘리는 카시다(kashida) 로 양쪽 정렬을 구현했지만, 현대 브라우저의 text-align: justify는 주로 단어 사이 공백을 늘림
- 아랍어 글자는 저장된 코드포인트 하나가 문맥에 따라 고립형·초성형·중성형·종성형으로 바뀌며, OpenType 기능과 셰이핑 엔진 없이는 글자가 분리된 형태로 렌더링됨
- Unicode의 Arabic Presentation Forms, 숫자 체계, UAX #9 양방향 알고리듬, 보이지 않는 제어문자는 검색 실패·전화번호 역전·커서 이동 혼란 같은 실제 제품 문제로 이어짐
- HarfBuzz, Amiri, W3C Arabic Layout Requirements 등 핵심 기반은 구축됐지만, 브라우저의 아랍어 정렬과 jstf 활용은 여전히 구현 공백으로 남아 있음
시작점: “CSS 버그”처럼 보인 아랍어 조판 문제
- 고객용 대시보드의 혼합 콘텐츠 아랍어 문단이 디자인 시안처럼 양쪽 정렬되지 않고 왼쪽 가장자리가 들쭉날쭉하게 렌더링됨
- 같은 블록의 라틴 문자 버전은 “fine”으로 보였지만, 아랍어에서는 줄이 오른쪽에서 시작하므로 들쭉날쭉한 가장자리가 왼쪽에 생김
- text-align: justify를 적용해도 디자인팀이 승인한 형태처럼 단어 내부 획을 늘려 줄을 채우지 못함
- 같은 제품에서 이전에도 PDF의 이름 글자 분리, 검색 인덱스 실패, 레거시 Unicode 코드포인트 문제 등 아랍어 처리 문제가 반복됨
- 문제의 본질은 특정 스타일시트의 결함이 아니라 웹의 아랍어 타이포그래피 상태에 있음
필사 전통이 해결했던 문제
- 고전 아랍어 필사 전통은 단어 사이 공백을 늘리지 않고 글자 형태 내부의 연결 획을 늘려 줄을 양쪽 정렬함
- 이 방식은 taṭwīl 또는 현대 기술 용어로 kashida라고 불리며, 특정 글자 쌍 사이 연결 획을 길게 늘리는 방식임
- 17세기 Naskh의 잘 짜인 페이지는 양쪽 여백이 맞고 단어 간격이 늘어나지 않아 조밀하고 규칙적인 질감을 만듦
- Ibn Muqla가 정리한 al-khaṭṭ al-mansūb는 갈대 펜촉의 마름모 점, alif 높이, 원호 비율 등으로 글자 형태를 체계화함
- 이 전통에서 줄 맞춤은 공백 배분 문제가 아니라 글자 형태와 대체 글리프를 고르는 셰이핑 문제였음
글자 하나, 네 가지 형태
- 아랍어는 항상 필기체처럼 이어지는 문자이며, 인쇄체와 손글씨를 나누는 블록 글자 구분이 없음
- 각 글자는 이웃 글자에 따라 고립형, 초성형, 중성형, 종성형으로 달라지고, 여섯 글자는 앞쪽으로 연결되지 않아 단어 내부 흐름을 끊음
- Unicode는 추상 글자를 저장하고, 글꼴은 위치별 글리프를 제공하며, 셰이핑 엔진은 isol, init, medi, fina, rlig, mark, mkmk 같은 OpenType 기능을 적용함
- محمد 같은 단어는 저장상 네 코드포인트지만, 렌더링 시 여러 글리프 선택과 OpenType 조회를 거쳐 하나의 이어진 획으로 보임
- HarfBuzz 같은 셰이핑 엔진이 없거나 PDF 생성기가 이를 거치지 않으면 같은 코드포인트가 서로 분리된 고립형 글자로 렌더링됨
Unicode의 화석: Arabic Presentation Forms
- DOS와 초기 Windows 시대의 8비트 코드페이지는 추상 글자가 아니라 초성형·중성형 같은 형태 자체를 별도 문자로 인코딩함
- Unicode는 왕복 호환성을 위해 이를 받아들였고, U+FB50부터 U+FEFF까지 Arabic Presentation Forms 블록으로 남아 있음
- 새 문서에는 이 코드포인트가 들어가면 안 되지만, PDF 텍스트 추출기는 오늘날에도 이를 내보낼 수 있음
- 같은 이름이 현대 Unicode와 Presentation Forms로 각각 저장되면 화면에서는 동일하게 보이지만 문자열 비교와 검색에서는 서로 다르게 처리됨
- NFKC 정규화를 적용하면 Presentation Forms를 추상 글자로 접어 검색 누락을 줄일 수 있음
셰이핑과 양방향 처리를 건너뛴 소프트웨어
- 셰이핑 엔진과 양방향 알고리듬을 건너뛰는 소프트웨어는 글자를 하나씩 고립형으로 그리고 줄을 왼쪽에서 오른쪽으로 배치함
- 이런 출력은 상점 간판, 탑승권, 워터마크, 오래된 영화 관련 아랍어 표기 등에서 아랍어 독자가 실제로 마주치는 형태임
- 오래된 Photoshop, 기본 설정의 matplotlib, npm의 여러 PDF 생성기, 영수증 프린터가 이런 문제를 낼 수 있음
- Python의 흔한 우회책인 arabic_reshaper와 python-bidi는 Presentation Forms 블록을 사용해 미리 셰이핑된 형태를 문자열에 구워 넣음
- 이 우회책은 렌더러가 해야 할 일을 문자열에 앞당겨 넣는 방식이며, 근본적으로 텍스트 스택의 결함을 드러냄
세 종류의 숫자와 구두점 문제
- 세계가 “Arabic numerals”라고 부르는 0–9는 대부분의 아랍어 독자가 일상적으로 쓰는 숫자 모양이 아님
- 이집트, 수단, 레반트, 이라크, 걸프 지역은 Unicode의 ARABIC-INDIC DIGITS ٠١٢٣٤٥٦٧٨٩를 사용함
- 마그레브 지역은 라틴 숫자 글리프를 사용하고, 이란·아프가니스탄·파키스탄은 EXTENDED ARABIC-INDIC DIGITS ۰۱۲۳۴۵۶۷۸۹를 사용함
- 숫자는 UAX #9에서 강한 문자가 아니라 약한 문자로 처리되며, 앞선 강한 문자의 방향성에 따라 유럽 숫자 또는 아랍 숫자로 재분류됨
- 아랍어 단어 뒤의 010-1234-5678 같은 전화번호는 하이픈이 중립 처리되면서 화면에서 5678-1234-010처럼 순서가 바뀔 수 있음
- 플랫폼이 제공하는 해결책은 번호를 ‎ 또는 <bdi>로 감싸 방향성을 분리하는 방식임
- 아랍어권의 소수점과 천 단위 구분자는 U+066B ٫와 U+066C ٬이며, ASCII .와 ,는 거의 비슷해 보이지만 코드포인트와 양방향 속성이 다름
인쇄부터 웹까지 이어진 우회와 단순화
- 1514년 Fano에서 인쇄된 _Kitāb Ṣalāt al-Sawāʿī_는 최초의 이동식 아랍어 활자본으로, 글자 연결 분리와 점 위치 오류가 보이는 사례임
- 1537년 Venice의 Paganini Qurʾān은 조판 오류와 텍스트 오류가 겹쳐 상업적으로 실패했고, 한 부가 1987년 Venice의 수도원 도서관에서 발견됨
- Ottoman 인쇄 금지 이야기는 Bayezid II와 Selim I의 칙령 원문이 남아 있지 않으며, 유럽 여행자 기록에 의존한다는 문제가 있음
- Cairo의 Bulaq Press는 1820년 Muhammad Ali가 세웠고, 수백 개 활자 조각과 많은 인내를 통해 아랍어 금속활자의 품질을 끌어올림
- 1924년 Cairo Qurʾān은 Amiria Press에서 금속활자로 제작됐고, 20세기 텍스트와 타이포그래피 표준화에 기여함
- 1950년대 후반 Kamel Mrowa와 Linotype은 90채널 매거진에 맞추기 위해 초성형을 중성형에, 종성형을 고립형에 합치고 합자를 줄인 Simplified Arabic을 만듦
- Simplified Arabic은 저렴하고 빠른 신문 제작을 가능하게 했고, 한 세대 안에 아랍어 뉴스룸을 장악함
웹이 아직 그리지 못하는 카시다
- CSS Text Module Level 3의 초기 초안에는 text-justify 값으로 kashida가 있었고, Internet Explorer 5.5는 2000년에 이를 구현함
- IE 5.5는 text-kashida-space 속성도 제공했지만, 다른 브라우저가 구현하지 않으면서 해당 값은 사양에서 빠짐
- 현대 Chrome, Firefox, Safari의 text-align: justify는 아랍어에서 단어 사이 공백을 늘리는 방식으로 동작함
- CSS Working Group의 아랍어 정렬 이슈는 적어도 2015년부터 열려 있고, W3C Arabic Layout Requirements 작업도 같은 해 시작됨
- 카시다 정렬은 늘어난 글리프가 폭을 바꾸고, 폭 변화가 줄바꿈과 필요한 늘림 폭을 다시 바꾸기 때문에 셰이핑과 레이아웃이 줄 단위로 반복 협상해야 함
- OpenType에는 1990년대부터 글꼴이 정렬 우선순위를 알릴 수 있는 jstf 테이블이 있었지만, 셰이핑 엔진은 거의 읽지 않고 글꼴 제작사는 거의 제공하지 않음
- Microsoft Word와 InDesign Middle East Edition은 카시다 정렬을 제공하지만, 사람들이 가장 많이 읽는 브라우저 렌더러 집합은 글자를 늘리지 못함
Tatweel 해킹과 합자·모음표 문제
- 웹에서 흔한 우회책은 텍스트 자체에 U+0640 TATWEEL 문자를 삽입해 늘어난 획처럼 보이게 만드는 방식임
- Tatweel은 콘텐츠를 바꾸므로 검색 매칭, 복사·붙여넣기, 화면낭독기, 컬럼 리플로우에서 문제가 생김
- Tatweel이 그리는 획은 글꼴과 문자의 규칙에 따라 배치되는 카시다가 아니라 작성자가 추측해 넣은 타자기식 막대임
- OpenType 합자는 rlig, liga, dlig로 나뉘며, lām-alif 같은 필수 합자가 깨지면 문자는 단순히 보기 나쁜 수준을 넘어 잘못됨
- U+200C ZERO WIDTH NON-JOINER를 글자 사이에 넣으면 저장 글자는 유지되지만 렌더링은 각 글자를 고립형으로 강제함
- Safari는 "rlig" 0, "liga" 0을 무시하므로 필수 합자 비활성화 데모가 영향을 주지 않음
- Amiri는 Khaled Hosny가 2011년 SIL Open Font License로 공개한 Naskh 글꼴이며, 2022년 1.0 재작성 뒤 곡선형 카시다와 정교한 모음표 쌓기를 제공함
- line-height: 1과 overflow: hidden이 결합된 카드 컴포넌트는 완전 모음 표기된 아랍어의 위쪽 모음표를 잘라낼 수 있음
양방향 알고리듬과 거짓말하는 커서
- 아랍어 문단 안의 버전 번호, 영어 식별자, URL, 프랑스어 단어 등은 Unicode Bidirectional Algorithm인 UAX #9를 호출함
- 아랍어 글자는 강한 오른쪽-왼쪽 문자, 라틴 글자는 강한 왼쪽-오른쪽 문자, 숫자는 문맥을 따르는 약한 문자, 공백과 구두점은 중립 문자로 처리됨
- 알고리듬은 문자별 방향 클래스를 부여하고, 약한 문자와 중립 문자를 단계적으로 해석한 뒤, 임베딩 레벨을 배정하고 같은 레벨의 런을 뒤집음
- 화면의 시각 순서와 메모리의 논리 순서가 달라지므로 커서 이동, 마우스 클릭, 선택 동작은 두 순서 사이를 계속 번역해야 함
- 런 경계에는 논리 위치와 시각 위치라는 두 가지 합법적인 커서 위치가 있으며, Chrome, Firefox, Qt, Outlook은 이를 서로 다르게 처리할 수 있음
- 혼합 아랍어-영어 텍스트 작성은 2026년에도 주요 편집기, 이메일 클라이언트, 채팅 애플리케이션에서 기본적으로 인지 비용이 큰 경험으로 남아 있음
- الصفحات 10-20 같은 범위는 규칙 W2와 중립 하이픈 처리 때문에 “20에서 10까지”처럼 보일 수 있으며, U+200E LEFT-TO-RIGHT MARK를 앞에 넣어 고칠 수 있음
작동하는 기반과 남은 공백
- Khaled Hosny는 Amiri를 만들었고, HarfBuzz 명령줄 도구 hb-shape를 작성했으며, HarfBuzz 공동 유지보수자 역할도 함
- Behdad Esfahbod는 Hosny 이전에 HarfBuzz의 많은 부분을 작성했으며, 현재 브라우저에서 아랍어 글자를 올바르게 그리는 셰이핑 엔진에 기여함
- Brill은 Semitics 카탈로그에 필요한 음역 문자를 모두 포함하기 위해 John Hudson에게 Brill 서체를 의뢰했고, 2011년 비상업용 무료로 공개함
- Sakhr AX-170은 1984년경 ROM에서 아랍어를 표시한 Saudi-Kuwaiti MSX 컴퓨터였고, 오른쪽에서 왼쪽으로 쓰는 Arabic BASIC 식별자를 지원함
- HarfBuzz, Amiri, Scheherazade, GNU Unifont의 Presentation Forms 지원, Noto Arabic, W3C Arabic Layout 문서는 소수의 개인·단체·자원봉사자 노력에 크게 의존함
- 브라우저 벤더는 HarfBuzz가 무료로 완성된 뒤 받아들였지만, 필사 전통의 정렬 방식을 화면에서 구현할 레이아웃 루프에는 거의 기여하지 않음
- 남은 격차는 몇몇 레이아웃 엔진에서 구현해야 하는 잘 이해된 알고리듬이며, 고객 대시보드의 들쭉날쭉한 왼쪽 여백은 이 투자 부재가 사용자에게 보이는 형태임
-
Homepage
-
개발자
- 아랍어 타이포그래피 렌더링의 놀라운 경험과 기술 부채에 대한 인터랙티브 입문