Task #977: 목차 개요번호 WASM 정렬 어긋남 정정 — 문자 폭 폴백 공용화#980
Closed
planet6897 wants to merge 3 commits into
Closed
Conversation
목차 개요번호가 rhwp-studio(WASM)에서만 ~9px 어긋나는 원인을 진단. - 분기점: compute_char_positions 가 플랫폼별 이중 구현 - 네이티브: EmbeddedTextMeasurer (font_size*0.5 상수 폴백) - WASM: WasmTextMeasurer (브라우저 measureText 실측 폴백) - 미등록 폰트 공백 폭이 폰트별로 달라져 선두 공백 폰트가 다른 인접 목차 문단의 개요번호가 WASM 경로에서만 어긋남 - bbox.x / PageLayerTree / LayerBuilder 는 무결 (layer-svg 검증) - 소스 정정 없음 (진단 전용 단계) 수행·구현 계획서 및 단계 1 완료 보고서 포함. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
미등록 폰트 문자 폭 산출이 네이티브(휴리스틱)와 WASM(브라우저 measureText 실측)에서 달라, 선두 공백 폰트가 다른 인접 목차 문단의 개요번호가 WASM 경로에서만 어긋나던 문제 정정. - base_char_width 공용 함수 신설 (내장 메트릭 → 휴리스틱 폴백) - EmbeddedTextMeasurer 3개소: 인라인 if-else → base_char_width (순수 리팩터, 네이티브 동작 불변) - WasmTextMeasurer 2개소: measure_char_width_hwp(JS 실측) → base_char_width (휴리스틱) — 네이티브와 동일 규칙으로 통일 - 사용처 없어진 wasm_internals::measure_char_width_hwp 제거 - 옛한글 합성 클러스터 경로는 회귀 방지로 종전 유지 검증: cargo build/test(1297 passed) 통과, wasm32 check 통과, export-svg 2쪽 무회귀. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Docker WASM 빌드 후 rhwp-studio 검증: 개요번호 캔버스 x좌표가 SVG(네이티브)와 동일 — 종전 ~9px 어긋남 해소 - 회귀 점검: 표 샘플, 수능 모의고사형 샘플 정상 렌더 - 단계 3 완료 보고서 + 최종 결과 보고서 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 19, 2026
edwardkim
pushed a commit
that referenced
this pull request
May 20, 2026
Task #874 (cross-run RIGHT+leader 의 text_start_offset 미포함 정렬 보정) 의 후속 영역으로, 단일-run 케이스 — \t 가 한 run 안에 있고 그 뒤에 content 가 같은 run 으로 이어지는 케이스 (예: 목차 한 줄 "Ⅰ. 사업개요\t...3") — 의 cell right inner 미달 정렬을 보정한다. 본질: - 인라인 (2, _) RIGHT + leader 분기의 단일-run path 는 body_right_legacy (= available_width - line_x_offset) 사용 → text_start_offset 미포함 으로 cell right inner (= text_start_offset + available_width) 까지 미달. - 또한 seg_w 가 leading space 를 skip → digit right edge 가 cell right inner 보다 좌측으로 정렬 미달. - Task #874 가 도입한 cross-run path (override_to_right + body_right_text_rel + right_tab_block_width_override) 는 단일-run 케이스를 cover 하지 않음 (그 경로는 다음 run 으로 carry-over 된 후만 활성). Fix (text_measurement.rs): - 두 measurer (EmbeddedTextMeasurer + WasmTextMeasurer) 의 (2, _) RIGHT + leader 분기를 분리: * if fill_low != 0 안에서 has_content_after 검사 * \t 뒤 content 가 있는 단일-run → cell_right_run_rel (= text_start_offset + available_width - line_x_offset) 정렬 + seg_w_full (i+1 부터, leading space 포함) 측정 * \t 뒤 trailing space / 끝만 있으면 (cross-run 직전) → 원본 path 유지 (body_right_legacy - seg_w). 다음 run 의 pending_right_tab 분기가 처리. ★ native + WASM 두 path 정책: rhwp 의 텍스트 측정/배치는 native CLI 의 EmbeddedTextMeasurer 와 rhwp-studio Canvas 의 WasmTextMeasurer 두 구현으로 병존하므로 (rhwp-studio Canvas 시각 정합을 위해) 양쪽 동시 fix 가 필수. 회귀 영향: - cross-run RIGHT+leader path (Task #874) 영향 0 — 경로 분기 보존 - RIGHT (no leader) 분기 영향 0 — (2, _) 별도 분기 보존 - LEFT/CENTER/DECIMAL 분기 영향 0 검증 환경: - Linux + cargo + wasm-pack (Docker 미사용, 로컬 네이티브) - 한컴오피스 2024 한글 + Windows + 한컴 폰트 설치 (시각 정합 비교) 회귀 검증: - cargo check --lib: OK (10.20s) - cargo check --target wasm32-unknown-unknown --lib: OK (23.33s) - cargo test --lib: 1307 passed, 0 failed, 2 ignored (57.39s) - cargo clippy --lib -- -D warnings: 0건 - cargo test --test svg_snapshot: 8 passed (UPDATE_GOLDEN=1 갱신) - wasm-pack build --target web --dev: OK (15s) Golden 갱신 (한 가지 패턴): - tests/golden_svg/issue-267/ktx-toc-page.svg - 14 lines 변경, 모두 text element 의 x 속성 (좌표) 만 — y/글자/폰트/색상 변경 0 - 페이지번호 4개 (8 / 16 / 20 / 24) 의 x 좌표가 10px 좌측 이동 - Leader 점선 끝 (x2) 영역 보존 → 점선-페이지번호 gap 15px → 5px 정합 - 다른 6개 golden (form-002, issue-147, issue-157, issue-617, issue-677, table-text) 영향 0 본가 PDF baseline 정합: - pdf/KTX-2022.pdf 페이지 2 (한글 2022 편집기 출력) 시각 비교 결과: * 페이지번호 우측 끝이 모두 cell right inner 에 정렬 (RIGHT 정합) * Leader 점선이 페이지번호 직전까지 도달 (점선-숫자 gap ~1-3px) * 단일/두자리 페이지번호 우측 끝이 동일 x — RIGHT 정합 - 새 SVG (fix 후) 영역 영역 정합 방향 일치, 기존 SVG (fix 전) 는 overshoot. 시각 검증: - 사용자 시각 검증 OK (KTX.hwp + 본가 두 대상 파일 영역 4장 캡쳐) - 본가 PDF baseline 정합 확인 (Claude 영역 PDF 페이지 2 시각 비교) 관련: - Task #874 (cross-run RIGHT+leader text_start_offset) - Issue #977 (Skia replay 경로 outline number x 영역) — 본 PR 영역 밖, 좌측 정합 영역. 본 PR 은 우측 정합 (cell right inner) 영역. - PR #980 (closed) — text_measurement.rs::compute_char_positions 의 native vs WASM 휴리스틱 통일 시도, 영역 별도. Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced May 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
문제
목차(개요번호 포함) 페이지를 rhwp-studio(WASM)로 열면, 선두 공백 글자의 CharShape가 인접 문단과 다를 때 일부 개요번호가 ~9px 어긋났다.
export-svg(네이티브) 출력은 정상이라 WASM 전용 문제.원인
src/renderer/layout/text_measurement.rs의compute_char_positions가 플랫폼별 이중 구현:EmbeddedTextMeasurer— 미등록 폰트 문자 폭을 휴리스틱(font_size*0.5등)으로 산출WasmTextMeasurer— 미등록 폰트를 브라우저measureText실측미등록 폰트의 공백 폭이 WASM에서만 폰트별로 달라져, 선두 공백 폰트가 다른 인접 목차 문단의 개요번호가 어긋났다. 네이티브 휴리스틱은 한컴 PDF 정합 기준값이므로 WASM 실측이 정답지에서 이탈한 것.
변경
src/renderer/layout/text_measurement.rs단일 파일:base_char_width신설 — 내장 메트릭 → 휴리스틱 폴백EmbeddedTextMeasurer3개소 인라인 if-else →base_char_width(순수 리팩터, 네이티브 동작 불변)WasmTextMeasurer2개소 —measure_char_width_hwp(JS 실측) →base_char_width(휴리스틱)로 통일wasm_internals::measure_char_width_hwp제거→ 미등록 폰트 문자 폭이 네이티브·WASM 동일 규칙으로 산출.
검증
cargo build --release✅cargo check --target wasm32-unknown-unknown✅cargo test --release --lib✅ 1297 passed, 0 failedexport-svg회귀 ✅ 무회귀 (네이티브 동작 불변)closes #977
🤖 Generated with Claude Code