Skip to content

fix(text): KoPub 한자·전각 기호를 한글이 아닌 글꼴 자신의 전진폭으로 잰다 (#8099) - #8111

Open
planet6897 wants to merge 2 commits into
edwardkim:develfrom
planet6897:fix/8099-kopub-cjk-symbol-advance
Open

planet6897 wants to merge 2 commits into
edwardkim:develfrom
planet6897:fix/8099-kopub-cjk-symbol-advance

Conversation

@planet6897

@planet6897 planet6897 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Closes #8099

무엇을 고쳤나

KoPub돋움체·바탕체의 한자·전각 기호를 rhwp 가 한글 전진폭(돋움 0.872 · 바탕 0.94)으로 쟀고, 「」『』·× 등은 KoPub 표 밖이라 공통 폴백으로 갔다. 글꼴과 한/글 Print 는 이 글자들을 한글과 다른 900/1000em(낫표 450)으로 전진시킨다. 한자·기호가 많은 줄에서 바탕은 넓게, 돋움은 좁게 잡혀 줄 안 배치가 한컴과 갈렸다.

근거

① 글꼴 cmap+hmtx 직독 — KOPUS 배포 KoPub·KoPubWorld 바탕·돋움 × Light·Medium·Bold 12개 프로그램:

한글 가–힣                         바탕 936 · 돋움 872
한자 4E00–9FFF · F900–FAFF         900   (굵기 사이 차이는 한자 몇 자 ±2)
○□◆ ①② →⇒ ☆ ✓ ㉠ ㎜ Ⅰ ※ ×±       900
전각 !–~ · ¢–₩ · 옛 자모 ㅤ–ㆎ(ㆍ)  900
、。〈〉《》「」『』【】〔〕          450
◦ 600 · ₩ 894 · £ 533/555 · ¥ 520/706 (돋움/바탕)

② 한/글 Print — 정본 pdf/2025 행정업무운영 편람(최종)-2020-kopub.pdf(Hwp 2020 11.0.0.9136, KoPub 서브셋 내장, 383쪽)의 글자 전진(원점 차이)을 같은 줄 한글 전진으로 나눈 비가 글꼴 비와 맞는다.

돋움 (900/872 = 1.032) 바탕 (900/936 = 0.962)
한자 1.0345 (n=79) 0.9634 (n=82)
○①→ 등 1.0339 (n=419) 0.9625 (n=940)
「」『』 (450/872 = 0.516 · 450/936 = 0.481) 0.5172 (n=44) 0.4767 (n=134)

× 도 PDF 57쪽(문서 49쪽) (×) 에서 ○·→ 와 같은 0.804em(장평·자간 포함)으로 놓인다.

변경

  • text_measurement.rs kopub_cjk_symbol_units: KoPub·KoPubWorld 공통 갈래 — 한자 · 옛 자모 · 전각 FF01–FF5E·FFE0–FFE6 · CJK 기호(450 /  〃〓 900) · is_fullwidth_symbol 900 · ◦·₩·£·¥ 개별값. ※ 는 이 갈래로 옮겼다(값 0.9 그대로).
  • text_measurement/kopub_symbol_advances.rs(생성 표): KoPub돋움체·바탕체의 U+0080–U+2FFF 전진폭 668자(세 굵기 동일). × ± ¶·그리스·키릴·수학 기호 등이 글꼴 값으로 잡힌다. 다른 규칙이 소유하는 글자(좁은 구두점 ··‧, 곡선 따옴표, 공백류, U+00A0·U+00AD)는 넣지 않았다.
  • KoPubWorld 는 이 범위의 라틴·기호가 비례폭이고 일부는 굵기별로 달라(돋움 × 559 등) 공통 갈래만 쓴다.
  • 상자 그리기(U+2500–257F)는 표에서 뺐다. rhwp 에서 이 블록은 주로 한컴 PUA 글머리표·선 문자의 표시 대체(map_pua_bullet_char: U+F080F → ━ 등)로 생기고, 한/글은 그 PUA 글리프를 KoPub 이 아닌 기호 글꼴로 그린다(편람 PDF 140쪽 글머리표: Haansoft Batang 0.46em). 정본 383쪽 전체에서 KoPub 으로 그려진 상자 그리기 글자는 0건이다. 이 블록을 표에 넣었을 때 PDF 139·140·297쪽(글머리표 ━ 줄)이 1~3%p 떨어지는 것을 확인하고 뺐다.
  • 비범위: 현대 한글 호환 자모(ㄱ–ㅣ, 한글 전진폭과 같음)·가나(KoPubWorld 바탕만 1024 로 달라 출력 미확인)는 종전 경로. 글머리표 PUA 글리프의 전진폭을 문단 글꼴로 재는 것은 별도 결함이다(이 PR 범위 밖).

검증 (code head fd28c3bd2, 증적 head 84bdfc4bb, base devel 5e2b9bfbf)

회귀 검사 tests/cases/issue_8099_kopub_cjk_symbol_advance.rs

편람 HWP 의 쪽(아래 쪽 번호는 모두 PDF 쪽)마다 KoPub 글자 전진을 같은 쪽·같은 글꼴·같은 크기 한글 전진의 중앙값으로 나눈 비(한자는 언어 슬롯이 달라 한글과 다른 run 이 된다)를 정본에서 같은 방법으로 잰 값과 ±0.015 로 대조한다. 절대 px 이 아니라 비라서 줄 위치와 무관하다.

쪽 · 글꼴 · 글자 정본 수정 후
38 바탕 한자 0.9667 0.9718
38 돋움 한자 1.0345 1.0286
60 바탕 ○①→ 등 0.9651 0.9638 (n=367)
177 돋움 ○①→ 등 1.0307 1.0345
205 돋움 「」『』 0.5217 0.5182
288 바탕 「」『』 0.4778 0.4894
57 바탕 × 0.8889 0.8828

시험을 둔 채 src 만 되돌리면 첫 사례(38쪽 바탕 한자)부터 1.0070 으로 FAIL, 수정 후 PASS.

전쪽 Native / fresh WASM 2px 실루엣 — 편람 383쪽(정본 383쪽)

devel Native head Native devel fresh WASM head fresh WASM
90% 미만 2쪽 (p111 82.0 · p242 64.5) 2쪽 (같음) 2쪽 (p111 82.0 · p242 64.5) 2쪽 (같음)
평균 99.21 99.24 99.28 99.32
  • 변화(±0.05 초과): Native 상승 44쪽 · 하락 7쪽, fresh WASM 상승 41쪽 · 하락 6쪽. 하락은 모두 0.15%p 이하(PDF 36·38·74·98·106·140·170·272쪽).
  • 미달 2쪽(111·242)은 devel 과 같은 값이라 이 PR 과 무관하다.
  • 직접 판독: PDF 60쪽(문서 52쪽, 아래 그림) 서식 예시의 ○○○ 행이 devel 에서는 정본보다 넓게 밀려 겹쳤고 head 에서 정본과 겹친다(엄격 내용 픽셀 82.74 → 85.80). PDF 106쪽(−0.15)은 줄 끝 위치가 정본과 같고 남은 차이는 devel 과 같은 국소 차이다. PDF 57쪽 (×) 줄은 × 가 ○·→ 와 같은 폭으로 잡힌다.

편람 PDF 60쪽 review devel
편람 PDF 60쪽 review head
편람 PDF 60쪽 overlay head fresh WASM

측정: visual_sweep.py --silhouette-only --dpi 96 --compat 2022, Native(native-skia PNG 래스터)와 fresh WASM(scripts/wasm-pack-locked.sh 로 같은 소스에서 새로 빌드, rhwp_bg.wasm sha256 2fe597341ecb7c22…). RHWP_FONT_PATH 앞에 KOPUS 배포 KoPub돋움체·바탕체 TTF(Light·Medium·Bold) 폴더를 넣어 devel·head 를 모두 다시 돌렸다(이전 판은 그 폴더를 경로에 넣지 않았다). Native 는 검증 기계의 사용자 글꼴(fontconfig)로 이미 같은 KoPub 을 쓰고 있어 결과가 같았고, fresh WASM 은 평균이 0.01 낮아졌다. 위 그림은 이 재실행의 산출물이다(head 84bdfc4bb).

코퍼스·게이트

  • samples/** 1,252문서 layout-anomaly A/B(devel 대비): 바뀐 문서 0.
  • 정답지 쪽수 원장 547문서: 542 일치(devel 과 같음).
  • Rust lint 묶음(fmt diff 0 · Clippy native/wasm/workspace · manifest) 통과. nextest 11,017 중 11,016 통과 — 실패 1건 issue_6520_svg_layer_contract::subset_font_bytes_are_deterministic_for_multiple_codepoints 는 검증 기계에 한컴돋움(HDOTUM.TTF)이 사용자 글꼴로 설치돼 있어 시험이 그 TTF 를 임베드하면서 font/opentype 확인에 실패한 환경 문제다(그 글꼴이 없는 CI·devel 에서는 통과, 이 PR 무관).

🤖 Generated with Claude Code

KoPub돋움체·바탕체는 한자·전각 기호를 한글 전진폭(0.872 · 0.94)으로 쟀고, 「」『』·× 등은
KoPub 표 밖이라 공통 폴백으로 갔다. 글꼴(cmap+hmtx)은 한자·기호 900, 낫표 450 이고, 한/글
Print 내장 서브셋과 실제 전진이 같은 값을 증언한다.

- 공통 갈래(KoPub·KoPubWorld): 한자 · 옛 자모(ㆍ 포함) · 전각 FF01–FF5E·FFE0–FFE6 ·
  CJK 기호(、。〈〉《》「」『』【】〔〕 450,  〃〓 900) · is_fullwidth_symbol 900 · ◦ 600 ·
  ₩ 894 · £¥ 계열별.
- KoPub돋움체·바탕체는 U+0080–U+2FFF 를 글꼴 표(668자, 세 굵기 동일)로 잰다. 상자 그리기는
  rhwp 의 PUA 글머리표 표시 대체(━ 등)가 생기는 블록이고 한/글은 그 글리프를 KoPub 으로
  그리지 않아(정본 383쪽 중 0건) 표에서 뺐다.
@jangster77

jangster77 commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

@planet6897 korpub 폰트는 웹폰트로 이미 cdn 에서 다운받아서 사용하는데 이 pr 이 과연 유용한가요? 현재 샘플 png 파일들도 전부 폰트가 깨져서 보이는데요? 현재 메인터너 보정으로 기존에 korpub 폰트 없을때 pdf 로 산출해서 회귀테스트 하는것도 다 제거증입니다.
https://github.com/edwardkim/rhwp/actions/runs/39396877382/job/118545767665
PASS [ 0.077s] (3232/3671) rhwp::regression_suite_026 issue_6520_svg_layer_contract::subset_font_bytes_are_deterministic_for_multiple_codepoints
또한 위의 링크에서 보시다시피 subset_font_bytes_are_deterministic_for_multiple_codepoints 는 devel 에서는 정상입니다.

@planet6897

planet6897 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

@jangster77 확인 감사합니다. 세 가지로 답드립니다.

  1. 웹폰트와의 관계 — 웹폰트는 그리는 글리프만 바꿉니다. 글자 위치·줄 나눔은 rhwp 가 Rust 에서 계산하는 전진폭(text_measurement.rs kopub_char_advance_em → width_source: "kopubTable")으로 정해지고, WASM 도 같은 경로입니다(브라우저 measureText 는 supplemental_metrics 의 보충 글자에만 씁니다). 그래서 CDN 으로 실제 KoPub 글리프가 그려져도 devel 은 바탕체 한자를 0.94em 간격으로 놓고 그 자리에 0.9em 글리프를 그려 틈이 생깁니다(돋움은 반대로 0.872em 간격에 0.9em 글리프라 겹칩니다). 이 PR 은 그 간격을 글꼴 hmtx 와 한/글 Print 내장 서브셋의 900/450 으로 맞춥니다. 본문의 fresh WASM 결과가 Native 와 같은 방향으로 움직이는 것이 그 근거입니다.
  2. 증적 PNG 글꼴 — (정정) 확인해 보니 제 앞선 설명이 틀렸습니다. 검증 기계는 KoPub돋움·바탕을 사용자 글꼴로 갖고 있어 Native·WASM 모두 처음부터 KoPub 글리프로 그렸습니다. KoPub TTF 를 RHWP_FONT_PATH 에 직접 넣어 다시 찍어도 Native PNG 는 바이트까지 같았습니다(본문·그림 갱신, 증적 head 84bdfc4bb). 깨져 보이신 그림이 어느 것인지 알려 주시면 확인하겠습니다 — overlay 칸은 정본·rhwp 를 겹친 색 표시라 글자가 이중으로 보입니다. 정본의 굵은 번호(1.·가.)를 rhwp 가 보통 굵기로 그리는 차이는 따로 있습니다. 기준 PDF 는 KoPub 설치 환경에서 Print 한 pdf/2025 행정업무운영 편람(최종)-2020-kopub.pdf(KoPub 서브셋 내장)라, KoPub 없이 산출해 제거 중인 PDF 와는 다릅니다.
  3. subset_font_bytes_are_deterministic_for_multiple_codepoints — 말씀대로 devel 에서 정상입니다. 제 검증 기계에 한컴돋움(HDOTUM.TTF)이 사용자 글꼴로 설치돼 있어 시험이 그 TTF 를 임베드하면서 font/opentype 확인에 실패한 환경 문제였습니다. 본문의 «devel 에서도 실패» 표현을 정정하겠습니다(같은 표현을 쓴 fix(hwpx): 소프트 하이픈 요소를 한/글 표기 hp:hypen 으로 읽고 쓰며, 제어 표기는 줄 끝에서만 그린다 (#7993) #8026·수정(조판): 자리차지 표 뒤 host 글이 쪽 끝에 걸리면 줄 단위로 나눈다 (#7678) #8009·수정(renderer): 한양 face 의 가운뎃점은 문서가 적은 대체 TTF 글꼴로 재고 HWP5 대체 글꼴 유형을 보존한다 (#7092) #8006·fix(typeset): 쪽·종이 기준 자리차지 그림·도형의 세로 밴드를 문단 시작에 계상 (#7696) #8012 도 함께).

@edwardkim edwardkim added bug Something isn't working layout 문서 레이아웃/페이지네이션: 표·그림 배치, float/anchor, 줄·행 높이, 겹침·클리핑 rendering SVG/Canvas/PDF 등 렌더 출력과 시각 표시: 그리기, 표시 누락, bbox, paint 정합성 labels Oct 21, 2026 — with ChatGPT Codex Connector
@edwardkim edwardkim added this to the v1.0.0 milestone Oct 21, 2026 — with ChatGPT Codex Connector

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working layout 문서 레이아웃/페이지네이션: 표·그림 배치, float/anchor, 줄·행 높이, 겹침·클리핑 rendering SVG/Canvas/PDF 등 렌더 출력과 시각 표시: 그리기, 표시 누락, bbox, paint 정합성

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants