Task #643: 페이지 분할 드리프트 정정 (5축 정합) — closes #643#644
Conversation
본 케이스: samples/2022년 국립국어원 업무계획.hwp 6페이지 마지막 줄
(' 및 점자 해당 분야 전문인력 확보 어려움') 이 다음 페이지로 부당
분리되던 회귀를 정정. HWP 원본 정합 회복.
Root cause 4축:
1. pagination/engine.rs: fit 산식이 마지막 줄의 트레일링 line_spacing
을 누적 → 잔여 공간 산정 왜곡 (+12-13 HU/문단)
2. typeset.rs: LAYOUT_DRIFT_SAFETY_PX=10px band-aid 가 fit 정정 후 과함
3. layout.rs VPOS_CORR: 백워드 보정 차단 (1.0px) 으로 누적 layout
drift 회복 불가능
4. layout.rs VPOS_CORR end_y: sb_N 미차감 → layout 의 sb_N 추가와
합쳐져 line 0 위치가 sb_N 만큼 아래로 시프트
수정:
- pagination/engine.rs:846-867: fit 루프 + part_line_height 산식
마지막 줄 lh-only 적용 (트레일링 ls 제외)
- typeset.rs:876: LAYOUT_DRIFT_SAFETY_PX 10 → 4 축소
- layout.rs:1504-1521: VPOS_CORR 백워드 허용 1.0 → 8.0px,
end_y 산식에서 curr_sb 차감
회귀 검증:
- 1221 테스트 통과 (회귀 0)
- task554_no_regression_2022_kuglip: 페이지 수 40 → 38 (의도된 정정,
본 케이스 fits + 후속 압축으로 HWP 원본 정합)
- issue_147_aift_page3 golden SVG: 본문 y 좌표 -6.67px 시프트 정정
(pi 누적 sb 드리프트 해소) — UPDATE_GOLDEN
잔존 사항:
- LAYOUT_OVERFLOW 진단 메시지 9.7px 남음 (paragraph y_out 기준,
실제 visible content line bottom = 1025.7 ≤ body 1028.0 fits).
진단 메시지는 record_overflow 로 기록만, 액션 없음.
4축 드리프트 누적 모델 분해 + 좁은 정정으로 HWP 원본 정합 회복. 1221 테스트 통과 (회귀 0). 페이지 수 40→38 (의도된 정정). 잔존 LAYOUT_OVERFLOW 진단 메시지 (trailing ls 영역) 는 후속 이슈 권장.
본 케이스: samples/2022년 국립국어원 업무계획.hwp 페이지 3 (body page 1)
마지막 항목 pi=39 ('국어사전 정보보완심의회 운영을 통한 국어사전 정보 수정
및 보완') 가 부당하게 다음 페이지로 분리되던 회귀를 정정.
Root cause:
typeset.rs:566 의 Task edwardkim#404 heading-orphan 가드가 para_h_px 누적 (트레일링
line_spacing 포함) 으로 vpos_end 산정 → ~10 HU 과대 → vpos_overflow 오판정.
HWP 시멘틱은 페이지 끝에서 lh 만 fit 검사 (트레일링 ls 미적용).
수정:
- typeset.rs:566 vpos_end 산식: para.line_segs.last() 의 vpos+lh 직접 사용
(트레일링 ls 자연 제외).
회귀 검증:
- 1221 테스트 통과 (회귀 0)
- task554_no_regression_2022_kuglip: 페이지 수 38 → 35 (의도된 정정)
- tests/issue_643.rs: 페이지 번호 의존성 제거 (페이지 변동에 강건)
본 케이스 PDF 정합 (body page 1 마지막 항목 pi=39) 회복.
stream/devel 위로 rebase 한 결과, Task edwardkim#643 의 페이지 분할 드리프트 정정으로 인한 좌표 시프트가 두 테스트와 충돌: 1. tests/issue_598_footnote_marker_nav.rs:60 - samples/footnote-01.hwp 두 번째 본문 각주 마커 y 좌표 - bbox y: 694.3 → 660.9 (-33.4px) - 테스트 hit_test y: 698.0 → 670.0 (새 bbox 내 중앙) 2. tests/golden_svg/issue-147/aift-page3.svg - aift.hwp page 3 본문 y -6.67px 시프트 정정 결과 갱신 - UPDATE_GOLDEN=1 으로 재생성 (post-Task edwardkim#630 + post-Task edwardkim#643) cargo test --release: 1221+ 테스트 전부 통과 (회귀 0). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bf2063c to
4028ea0
Compare
연관 PR (
|
| 순서 | PR | Issue | 본질 | 결함 위치 |
|---|---|---|---|---|
| 1 | #644 (본 PR) | #643 | 페이지 분할 드리프트 5축 정합 | 6 페이지 마지막 줄 (40→35 페이지로 정정) |
| 2 | #714 | #712 | u32 음수 vert_offset 게이트 | 31 페이지 상단 12x5 표 침범 |
| 3 | #715 | #713 | 인트라-로우 분할 orphan(<25px) 가드 | 31 페이지 하단 row 8 sliver 분할 |
권장 merge 순서: #644 → #714 → #715. 각 PR 은 베이스가 stream/devel 이며 상호 conflict 0 (merge-tree 점검 완료).
통합 검증: stream/devel + 3 PR 통합 빌드에서 cargo test --release 1252 passed, 0 failed.
closes #643 5 commits 단계별 보존 (옵션 B): - 016b417 Stage 0/1: 수행/구현 계획서 + RED 테스트 - 247203e Stage 2-4: 4축 정정 (pagination fit / SAFETY_PX / VPOS_CORR) - 338fe56 Stage 5: 최종 보고서 - 2345d39 후속: Task #404 vpos_end 트레일링 ls 제외 (축 5) - c1129da 후속: rebase + golden SVG 정합 본 환경 검증: - 1221 테스트 ALL PASS (failed 0건) - task554 sweep 12/12 ✅ - 페이지 수 정합: 40 → 35 (HWP/PDF 정합 회복) PR: #644 컨트리뷰터: @planet6897 (12번째 사이클)
PR #644 (Task #643): 페이지 분할 드리프트 정정 (5축 정합) — closes #643 - merge commit: 42bb794 (옵션 B — 5 commits 단계별 보존) - 결정적 검증 1221 테스트 ALL PASS - 페이지 수 정합 회복: 2022년 국립국어원 업무계획.hwp 40 → 35 - WASM 빌드 + 작업지시자 시각 검증 통과 별건 결함 분리: - Issue #716 신규 — samples/20250130-hongbo.hwp page 1 LAYOUT_OVERFLOW_DRAW - devel 과 PR-merged devel 의 page 1 SVG md5 동일 → PR #644 도입 회귀 아님 - Task #332 Stage 4b 잔존 영역 (Stage 5 미수행) 산출물: - mydocs/pr/archives/pr_644_review.md - mydocs/pr/archives/pr_644_report.md - mydocs/orders/20260508.md 갱신
|
@planet6897 님 12번째 사이클 PR 감사합니다. 본 환경 검증 결과: 결정적 검증 (1221 테스트): ALL PASS
페이지 수 정합 회복: 5축 분해의 본질: 처리: 옵션 B — 5 commits 단계별 보존 머지 + WASM 빌드 + 메인테이너 시각 판정 게이트 통과.
별건 결함 분리: 메인테이너 시각 검증 영역에서 처리 보고서: closes #643 |
본질: HwpUnit=u32 영역의 signed 캐스트 누락 결함.
`vertical_offset` 음수 (예: -1796 HU) 의 unsigned 비트표현 = 0xFFFFF8FC =
4294965500u32. `> 0` 게이트가 unsigned 양수로 통과 → 후속 `as i32` 캐스트
에서 음수 적용 → 표가 위로 점프, 직전 인라인 표 영역 침범.
비-Partial 경로 (table_layout.rs:1069+) 에는 `raw_y.max(y_start)` 클램프
영역으로 음수 무력화. Partial 경로 (table_partial.rs:59-78) 에는 클램프
부재 영역 → 결함 노출.
영향 샘플: samples/2022년 국립국어원 업무계획.hwp 영역의 12x5 일정 표 영역
(작업지시자 안내 영역의 페이지 31, 본 환경 영역 35 페이지 영역의 동적 페이지
탐색):
- pi=585: 1x3 인라인 TAC 제목 표 ("붙임 / / 과제별 추진일정")
- pi=586: 12x5 일정 표 (vert=문단 -1796 HU 음수)
- 결함: pi=586 외곽 상단이 pi=585 안쪽으로 ~15.94 px 침범
- 정정 후: 침범 0 px (PDF 권위 정합)
정정 (signed 비교 14 라인):
- src/renderer/layout/table_partial.rs:59-78 (Partial 경로, 본질):
let vert_off_signed = table.common.vertical_offset as i32;
&& vert_off_signed > 0
- src/renderer/layout.rs:2687+ (비-Partial 경로 게이트 동기):
&& (t.common.vertical_offset as i32) > 0
영향 좁힘 (feedback_hancom_compat_specific_over_general):
- is_continuation=true 분할 표 연결 페이지 영역 무영향
- vertical_offset >= 0 영역 (signed 양수/0) 무영향
- 비-TopAndBottom wrap / TAC 표 영역 무관
회귀 가드 (tests/issue_712.rs +88 LOC, 신규):
- 동적 페이지 탐색 영역 — 페이지네이션 변동 영역 견고 (PR #644 / PR #711
머지 영역 자동 적응)
- pi=586 외곽 상단 ≥ pi=585 외곽 하단 (0.5 px 허용 오차)
검증:
- cargo test --release: lib 1173 + 통합 ALL GREEN, failed 0
- cargo test --release --test issue_712: 1 PASS (회귀 가드)
- cargo test --release --test svg_snapshot: 8/8 (form-002 PR #706 영역 보존)
- cargo test --release test_705: 6/6 (PR #711 영역 보존)
- cargo test --release test_634: 8/8 (가드 갱신 후 보존)
- cargo clippy --release: 신규 경고 0
- 광범위 sweep 7 fixture / 170 페이지 / 회귀 0
Closes #712
Co-Authored-By: Jaeook Ryu <jaeook.ryu@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
본질
`samples/2022년 국립국어원 업무계획.hwp` 의 두 케이스로 발견된 누적 드리프트 모델 을 5축으로 분해하여 좁은 정정.
케이스 1 (page 6)
pi=80 (' 및 점자 해당 분야 전문인력 확보 어려움') 마지막 줄이 페이지 6 → 7 로 부당 분리.
케이스 2 (page 3)
pi=39 ('국어사전 정보보완심의회 운영을 통한 국어사전 정보 수정 및 보완') 가 페이지 3 → 4 로 부당 분리.
Root Cause (5축 누적 드리프트)
핵심 통찰
수정
1. pagination fit 산식 (Stage 2)
fit 루프의 마지막 줄은 lh-only 적용 (트레일링 ls 제외).
2. LAYOUT_DRIFT_SAFETY_PX 축소 (Stage 3)
10 → 4px. 축 1 정정 후 보수적 마진 축소 가능.
3. VPOS_CORR 백워드 허용폭 확장 (Stage 3)
1.0 → 8.0px. 문단 사이 trailing line_spacing 영역 내에서 안전 백워드 보정.
4. VPOS_CORR end_y sb 차감 (Stage 3)
vpos_end 에서 curr_sb 사전 차감 → layout 의 sb 추가와 정합.
5. Task #404 vpos_end 산식 정정 (후속)
`para.line_segs.last()` 의 `vpos + line_height` 직접 사용 (트레일링 ls 자연 제외).
검증
회귀 테스트 (1221 / 1221 통과)
PDF 정합 검증
페이지 수 변화
`2022년 국립국어원 업무계획.hwp`: 40 → 35 페이지 (HWP/PDF 원본 정합 회복).
잔존 사항
LAYOUT_OVERFLOW 진단 메시지 ~9px 잔존 (paragraph y_out 기준, visible content fits). `record_overflow` 는 진단 기록만 수행, 렌더링 액션 없음. 추후 LAYOUT_OVERFLOW 임계 정책 통합 시 재검토 권장.
산출물
Test plan
closes #643