Skip to content

Task #643: 페이지 분할 드리프트 정정 (5축 정합) — closes #643#644

Open
planet6897 wants to merge 4 commits intoedwardkim:develfrom
planet6897:task643-pagination-drift-fix
Open

Task #643: 페이지 분할 드리프트 정정 (5축 정합) — closes #643#644
planet6897 wants to merge 4 commits intoedwardkim:develfrom
planet6897:task643-pagination-drift-fix

Conversation

@planet6897
Copy link
Copy Markdown
Contributor

본질

`samples/2022년 국립국어원 업무계획.hwp` 의 두 케이스로 발견된 누적 드리프트 모델 을 5축으로 분해하여 좁은 정정.

케이스 1 (page 6)

pi=80 (' 및 점자 해당 분야 전문인력 확보 어려움') 마지막 줄이 페이지 6 → 7 로 부당 분리.

케이스 2 (page 3)

pi=39 ('국어사전 정보보완심의회 운영을 통한 국어사전 정보 수정 및 보완') 가 페이지 3 → 4 로 부당 분리.

Root Cause (5축 누적 드리프트)

위치 증상
1 `pagination/engine.rs:846-852` fit 루프 마지막 줄의 트레일링 line_spacing 까지 누적 → 잔여 공간 산정 왜곡
2 `typeset.rs:876` 안전마진 축 1 의 band-aid 였으나 본 케이스 fit 결정 차단
3 `layout.rs:1521` VPOS_CORR backward 1.0px 만 허용 → 누적 layout drift 회복 불가
4 `layout.rs:1504` VPOS_CORR end_y sb_N 미차감 → layout 의 sb_N 추가와 합쳐져 line 0 위치 시프트
5 `typeset.rs:566` Task #404 vpos_end para_h_px 누적으로 vpos_end 산정 → 트레일링 ls 포함하여 ~10 HU 과대 → vpos_overflow 오판정

핵심 통찰

  • HWP: `vpos_(N+1) - vpos_N = lh_total + ls_total + sa_N + sb_(N+1)`
  • Layout: y_advance per pi = `sb_N + lh_total + ls_total`
  • → `sb_N ≠ sb_(N+1)` (예: 빈 문단 sb=0 인접) 시 차이 누적

수정

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 통과)

  • `tests/issue_643.rs` (신규): 본 케이스 (RED → GREEN) ✅
  • `task554_no_regression_2022_kuglip`: 페이지 수 40 → 35 (의도된 정정, HWP/PDF 정합)
  • `issue_147_aift_page3` golden SVG: 본문 y 좌표 -6.67px 시프트 정정 — UPDATE_GOLDEN
  • `test_544_passage_box_coords_match_pdf_p4`: 통과 (layout trailing_ls 정책 변경 없음)

PDF 정합 검증

  • `samples/2022년 국립국어원 업무계획.pdf` 와 비교
  • body page 1 (PDF "- 1 -") 마지막 항목 = pi=39 ✓
  • body page 7 (PDF "- 7 -") 마지막 항목 = pi=80 fits ✓

페이지 수 변화

`2022년 국립국어원 업무계획.hwp`: 40 → 35 페이지 (HWP/PDF 원본 정합 회복).

잔존 사항

LAYOUT_OVERFLOW 진단 메시지 ~9px 잔존 (paragraph y_out 기준, visible content fits). `record_overflow` 는 진단 기록만 수행, 렌더링 액션 없음. 추후 LAYOUT_OVERFLOW 임계 정책 통합 시 재검토 권장.

산출물

  • 코드: `src/renderer/pagination/engine.rs`, `src/renderer/typeset.rs`, `src/renderer/layout.rs`
  • 테스트: `tests/issue_643.rs` (신규), `tests/issue_554.rs` (갱신), `tests/golden_svg/issue-147/aift-page3.svg` (갱신)
  • 문서: `mydocs/plans/task_m100_643.md`, `task_m100_643_impl.md`, `mydocs/report/task_m100_643_report.md`
  • 커밋 4개

Test plan

  • cargo test --release (1221/1221 통과)
  • Native build (cargo build --release)
  • WASM build (docker compose run --rm wasm)
  • 본 케이스 시각 판정 (rhwp-studio dev server 에서 페이지 3, 6 확인)
  • 광범위 fixture sweep (메인테이너 환경)

closes #643

planet6897 added 4 commits May 6, 2026 16:36
본 케이스: 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) 회복.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant