Task #1037: HWP5 변환본 ParaShape unit normalize + Dialog 한컴 정합 fix (closes #1037)#1040
Task #1037: HWP5 변환본 ParaShape unit normalize + Dialog 한컴 정합 fix (closes #1037)#1040jangster77 wants to merge 9 commits into
Conversation
devel baseline 측정: - HWP3 sample16: 64 페이지 - HWP5 변환본 sample16: 64 페이지 - alignment 정합률: 24/64 (37.5%) — 40 페이지 미정합 PR edwardkim#1009 hunks 임시 적용 결과: - sample16-hwp5: 64 → 65 (+1 over-split 회귀 재현) - alignment: 24 → 23 (오히려 악화) - main_trigger 자체는 정확 (pi=472 prev_end=68312 > 0.85×72848=61920 + pi=473 vpos=284 < 1500) - HWP3 native 동일 paragraph 도 vpos=0 reset 패턴 — 휴리스틱 의도는 정확 Over-split 메커니즘: - p18~p23: PR edwardkim#1009 휴리스틱 정확히 작동 - p24 부근 PartialParagraph 처리 (pi=460 paragraph 내부 vpos-reset@line3) - PR edwardkim#1009 force-break + PartialParagraph split 효과 누적 → +1 추가 페이지 Narrow 가드 후보 4 식별: - A: PartialParagraph 가능성 paragraph 에서 trigger skip - B: high_threshold 0.85 → 0.90/0.95 - C: 다음 paragraph height 검증 - D (권고): naturally-breaks 단언 — paginator 가 자연 break 할 위치인지 미리 계산, 자연 break 시 force-break skip CHARS_PER_LINE 45 (PR edwardkim#1009 commit message claim 45→50 부정확, actual diff 없음). 본 task 에서 composer.rs 무수정. Stage 2 진행: PR edwardkim#1009 base + narrow 가드 D 우선 시도. Refs edwardkim#1035 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…% → 93.75%) PR edwardkim#1009 (Task edwardkim#1007, closed) 의 cross-paragraph vpos reset 감지 휴리스틱 base 적용 + Task edwardkim#1035 narrow 가드 2 항목: 1. high_threshold 0.85 → 0.95 (자연 paginator break 영역 외 제외) 2. aux_trigger 제거 (empty bridge 휴리스틱은 false positive 다수) Stage 1 진단 + Stage 2 narrow 가드 실험 결과: | 시도 | sample16-hwp5 | alignment | |------|---------------|-----------| | devel baseline | 64 | 24/64 (37.5%) | | PR edwardkim#1009 그대로 (0.85+aux) | 65 (+1) | 23/64 (악화) | | 0.95 + aux 유지 | 65 | 23/64 | | all triggers disabled | 64 | 24/64 | | 0.95 + aux 제거 (채택) | 64 ✓ | 60/64 (93.75%) ✓ | → aux_trigger 자체가 over-split 의 직접 원인 (empty bridge 휴리스틱 false positive). main_trigger 만 + threshold 0.95 narrow 로 정합률 대폭 향상. 변경 파일 (PR edwardkim#1009 base): - src/renderer/pagination/engine.rs (+84, variant_vpos_reset_break) - src/renderer/typeset.rs (+136, 동일 로직 두 경로 정합) - src/renderer/pagination.rs (PaginationOpts::is_hwp3_variant 필드) - src/document_core/queries/rendering.rs (is_hwp3_variant 전달) variant 식별 인프라 (cfb_reader/parser/model) 는 이미 edwardkim#1005 머지 — 재활용. 회귀 sweep: - 변환본 9종 페이지 수: 모두 무변동 (over-split 회귀 0) - HWP3 native + 일반 HWP5 (exam_*, aift, biz_plan): 무변동 - cargo test --lib: 1308 passed (1 추가 — variant 인프라 테스트) - cargo test --tests: FAILED 0 (전체 integration) - clippy / fmt --all: clean (feedback_cargo_fmt_all_required 정합) 회귀 가드 추가: tests/issue_1035_alignment.rs hwp3_sample16_hwp5_page_count_64 — sample16-hwp5 64 유지 단언 (PR edwardkim#1009 over-split 65 회귀 재발 방지). 성공 기준 C1~C6 자동 단언 완료. C7 (시각 검증) Stage 4 시점. Refs edwardkim#1035 / PR edwardkim#1009 follow-up Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ension 진단 p21 미정합 (HWP5 변환본 p21 시작 pi=442 vs HWP3 pi=440) case-specific fix 시도: - aux_trigger narrow (empty_between≥3 + prev_end > body × 0.75): 65p +1 over-split 회귀 - aux_trigger 그대로 + main만 narrow: 동일 회귀 - 모든 narrow 가드 실패 — aux_trigger 발동 자체가 over-split 직접 원인 Root cause — paginator cumulative height vs encoder vpos signal: - HWP5 변환본 encoder: pi=440 vpos=852 (page-reset signal, hwp_used=32.7px 작음) - rhwp paginator: cumulative paragraph height 측정 971.0px (body 거의 full) - HWP5 변환본 paragraph height 가 HWP3 보다 약 2배 (font/spacing metric 차이) - aux_trigger force-break 후 paginator cumulative 누적이 자연 break 보다 큼 → +1 페이지 한컴 정답지 비교 단언: - 한컴 한글 viewer p21 (footer "-21-") = rhwp HWP3 p23 (idx=22) 내용 정합 (11 items pi=450~460 + "나." Table subheader) - HWP5 변환본 p23 (rhwp): 같은 11 items 이나 paragraph height 2배 → pi=460 PartialParagraph split + 시각적 overflow - 38 페이지 추정 = 한컴 viewer 로딩 시 근사값 (별도 issue 등록 대상 아님) 잔존 미정합의 본질: - p21 alignment + p23 overflow 모두 HWP5 변환본 paragraph height 과대 측정 원인 - Task edwardkim#1008 격차 D (폰트 매핑) 영역 연장 - 별도 issue 등록 권고: "HWP5 변환본 paragraph height 과대 측정 — HWP3 대비 약 2배" 본 task Stage 2 fix (60/64 alignment, 64 페이지 유지) 가 최선 — PR 진행 권고. Refs edwardkim#1035 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Stage 1~3 종결: - Stage 1: 진단 — PR edwardkim#1009 휴리스틱 over-split + alignment 악화 재현 - Stage 2: PR edwardkim#1009 base + Task edwardkim#1035 narrow 가드 (0.85→0.95, aux 제거) → alignment 37.5% → 93.75% (60/64) + sample16-hwp5 64 유지 - Stage 3: case-specific p21 fix 시도 — fundamental tension 단언 성공 기준 C1~C7 모두 충족 (작업지시자 한컴 정답지 시각 검증 포함). 잔존 미정합 (p21 alignment + p23 overflow) 의 본질 = HWP5 변환본 paragraph height 가 HWP3 의 약 2배 (font/spacing metric 차이). 별도 issue 등록 권고. closes edwardkim#1035 (alignment 부분 해결, paragraph height 본질 후속 issue) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
진단 test 로 sample16 pi=450 비교 단언: - HWP5 변환본 LineSegs.len() = 0 (모든 paragraph, encoder typeset 안 함) - CharShape base_size: HWP3 1000 → HWP5 1300 (+30%) - ParaShape spacing_before: HWP3 1132 → HWP5 2264 (×2) Height 산출 경로: - composer.rs:441 fallback: LineSegs 빈 경우 synth line_height=400 하드코딩, CHARS_PER_LINE=45 로 word wrap - layout/paragraph_layout.rs:1166 corrected_line_height: raw_lh(400) < max_fs(1300) → Percent: max_fs × ls_val/100 = 1300 × 1.6 = 2080 - HWP3 actual: raw_lh(1300) ≥ max_fs(1000) → no correction → 1300 Root cause = 2 요소: 1. per-line height: HWP5 corrected 2080 vs HWP3 actual 1300, 비율 ×1.6 2. 라인 수: HWP5 synth 4 (140/45) vs HWP3 actual 3, 비율 ×1.33 합산: ×1.6 × ×1.33 ≈ ×2.13 (관찰값 정합) Stage 2 권고 (A + B 결합): - A: composer fallback line_height = max_fs (per-line 정합) - B: CHARS_PER_LINE 45 → 50 (라인 수 정합) 결과 (HWP5 pi=450): 3 lines × 1300 HU = 3900 HU = HWP3 actual 정합 Refs edwardkim#1037 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR edwardkim#1036 (Task edwardkim#1035) 위에 paragraph height 과대 측정 정정 — composer fallback 경로의 2 요소 fix: Fix A: src/renderer/mod.rs corrected_line_height Percent 케이스 변경 - 종전: max_fs * ls_val / 100 (= 1.6× for ls_val=160) - 변경: max_fs (1.0×, HWP3 actual 동등) - 영향: raw_lh < max_fs (fallback case 한정). HWP3 actual 은 raw_lh ≥ max_fs 로 본 분기 미진입 — 무영향. Fix B: src/renderer/composer.rs CHARS_PER_LINE 45 → 50 - sample16 pi=450 (140 chars) HWP3 actual 3 lines 정합 (140/50 = 3 lines) - 종전 45 로는 140/45 = 4 lines 과다 (×1.33 라인 수 과대) 효과 단언 (Task edwardkim#1035 + Task edwardkim#1037 combined): - sample16 pi=450 paragraph height: 118.5 → 59.5 (HWP3 actual 동등) ✓ - p23 pi=460 처리: PartialParagraph (overflow) → FullParagraph h=111.5 ✓ - sample16-hwp5 페이지 수 64 유지 ✓ - alignment 정합률 60/64 → 58/64 (trade-off -2, 시각 정합 우선) 회귀 sweep (모든 fixture 무변동): - 변환본 9 종: sample/4/5/10/11/13/14/16/19-hwp5 + .hwpx (16/36/64/763/151/3/11/64/2/71) - HWP3 native + 일반 HWP5 (exam_*, aift, biz_plan): 무변동 - cargo test --lib: 1308 passed - cargo test --tests: FAILED 0 (전체 integration) - clippy / fmt --all: clean Refs edwardkim#1037 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
build_para_properties_json: margin/indent JSON 산식 raw_ps 직접 사용. is_hwp3_variant 분기로 HWP3 (effective first-line = margin_left + min(0, indent)) vs HWP5 변환본 (raw 직접 사용) 차별화. spacing 은 기존 그대로. 효과: sample16 p452 기준 HWP3/HWP5 변환본 dialog 모두 한컴 정합 (왼쪽 40, 오른쪽 10, 내어쓰기 20, 문단위 8.5). 페이지 수 64 한컴 정합 유지 (rendering 무변동). 회귀 0. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Stage 4 진단: 작업지시자 D 옵션 선택 (page break vpos==0 휴리스틱 + p23 overflow line_seg 합성 옵션 B') 정량 평가. - page break: Recall 31.6%, FP 4개 (부적합) - line_seg 합성: Task edwardkim#1010 Stage 2 회귀 (88 페이지 +24) + cross-correlation root cause 무관 입증 (시도 가치 낮음) 코드 변경 없음 (negative result). 잔존 2 이슈 별도 task 분리 결정. 최종 보고서 + orders 갱신 + Stage 4 보고서 추가. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…malize + Dialog 한컴 정합 fix @jangster77 (Taesup Jang) PR #1040 — closes #1037 (M100, v1.0.0). PR #1036 (Task #1035, 방금 머지) 잔존 본질 해결. 핵심: - HWP3 → HWP5 변환본 ParaShape margin/indent/spacing 2× quirk parser 단계 normalize - Dialog 4 필드 한컴 정합 (왼쪽 40 / 오른쪽 10 / 내어쓰기 20 / 문단위 8.5 — HWP3 + HWP5 변환본 모두 정합) - style_resolver variant_div 종전 4 (case-specific Task #1001) → uniform 2 단순화 - build_para_properties_json raw_ps 직접 사용 + is_hwp3_variant 분기 검증: - cargo test --release --lib: 1319 passed (PR #1036 회귀 가드 양립) - cargo test --release --tests: FAILED 0 (전체 통합) - cargo clippy --release --lib -D warnings: clean - cargo fmt --check: clean - 10 fixture BEFORE/AFTER diff = 0 (rendering 무변동 정량 입증) - 작업지시자 시각 판정 통과 (dialog 4 필드 한컴 정합) PR base bbd38e8 (PR #1033 머지 후) → origin/devel 402e0ce (PR #1036 머지 후 + docs) cherry-pick squash. 본질 3 코드 파일 + Task #1037 plans/working/report 7 문서 적용. 잔존 후속 (PR 본문 명시): p23 overflow + page_break_before 손실 별도 task 분리 권고.
|
PR #1040 cherry-pick squash merge 완료 (devel c6fb7f2). Task #1037 HWP5 변환본 ParaShape unit normalize + Dialog 한컴 정합 fix. 작업지시자 시각 판정 통과 + 10 fixture BEFORE/AFTER diff = 0 (rendering 무변동 PR 본문 명시 정확 입증) + 1319 lib + 통합 + clippy + fmt clean. 본 PR base (bbd38e8) 가 origin/devel (402e0ce = PR #1036 머지 후) 보다 multi-merge 상태였으나 본질 3 코드 파일 (parser/mod.rs + style_resolver.rs + formatting.rs) + Task #1037 plans/working/report 7 문서만 cherry-pick squash 적용. PR #1036 (Task #1035) 회귀 가드 (tests/issue_1035_alignment.rs) 양립. Dialog 4 필드 한컴 정합 (왼쪽 40 / 오른쪽 10 / 내어쓰기 20 / 문단위 8.5) — HWP3 + HWP5 변환본 모두 정합. PR #1036 alignment 60/64 + 페이지 수 64 완전 보존. 잔존 후속 (PR 본문 명시): p23 외곽선 overflow + HWP5 변환본 page_break_before 100% 손실 — 별도 task 분리 권고. 감사합니다, @jangster77. PR #1031/#1034/#1036/#1040 의 HWP3 sample16 정합 시리즈 모두 마무리. |
- mydocs/pr/archives/pr_1040_review.md (이동) - mydocs/pr/archives/pr_1040_report.md (최종 보고서 신규) - mydocs/plans/archives/task_m100_1037.md + task_m100_1037_impl.md (이동) - mydocs/orders/20260521.md PR #1040 항목 추가 PR #1040 (closes #1037, @jangster77 30번째 기여): HWP5 변환본 ParaShape unit normalize + Dialog 한컴 정합 fix. parser 단계 ParaShape /= 2 normalize + style_resolver variant_div 4 → uniform 2 + build_para_properties_json raw_ps 직접 사용 + is_hwp3_variant 분기. squash merge (devel c6fb7f2) + 10 fixture BEFORE/AFTER diff = 0 (rendering 무변동 정량 입증) + Dialog 4 필드 한컴 정합 시각 판정 통과 + WASM 4.90MB 동기화. PR #1036 alignment 60/64 + 페이지 수 64 완전 보존. HWP3 sample16 정합 시리즈 (PR #1031/#1034/#1036/#1040) 마무리.
Summary
HWP3 → HWP5 변환본 의 raw ParaShape 값이 한컴 변환기에 의해 2× scaled 저장되는 quirk 를 parser 단계 normalize + 문단모양 dialog margin/indent 표시 산식을 raw_ps 직접 사용 + HWP3/HWP5 변환본 unit semantic 차이 분기로 한컴 정답 정합 달성.
Stages
효과 (sample16 p452 / p97 동일 paragraph 비교)
작업지시자 시각 검증 — "(3) 원격지 재해복구센터(DR: Disaster Recovery) 구축" paragraph 에서 한컴/rhwp HWP3/rhwp HWP5 변환본 dialog 완전 정합 (왼쪽 30 / 오른쪽 0 / 첫줄 보통 / 줄간격 160% / 문단위 14.2 / 문단아래 0).
변경 파일
src/parser/mod.rssrc/renderer/style_resolver.rssrc/document_core/commands/formatting.rsStacked on PR #1036 (Task #1035)
본 PR 은 PR #1036 (Task #1035, base) 위에 적층. PR #1036 merge 후 rebase 또는 통합 검토 권고.
자동 검증
잔존 (별도 신규 이슈 등록 예정)
Test plan
Closes #1037
🤖 Generated with Claude Code