Skip to content

Task #716: 빈 paragraph fix_overlay push 차단 (page 1 LAYOUT_OVERFLOW_DRAW)#719

Closed
planet6897 wants to merge 7 commits into
edwardkim:develfrom
planet6897:pr-task716
Closed

Task #716: 빈 paragraph fix_overlay push 차단 (page 1 LAYOUT_OVERFLOW_DRAW)#719
planet6897 wants to merge 7 commits into
edwardkim:develfrom
planet6897:pr-task716

Conversation

@planet6897
Copy link
Copy Markdown
Contributor

Summary

Root cause 분석 흐름

수행계획서의 정적 분석은 "음수 line_spacing(ls<0) 미반영" 으로 가설했으나, Stage 2 instrument (RHWP_TASK716_DEBUG=1) 실측 결과 line advance 자체는 정확히 ls 를 가산함을 확인. drift 의 진원지가 Task #9 fix_overlay_active 의 빈 paragraph push 임을 식별하여 가설을 갱신.

pi 종류 host ls (HU) table_bottom (px) y_in (px) push 누적
0 TAC 1x3 -600 149.93 (TAC 자체)
1 empty para 141.93 +8.00
2 TAC 1x4 -900 211.45 (TAC 자체)
3 empty para 199.45 +12.00

→ 누적 +20.00 px ≈ RED overflow +20.15 px (99.3% 일치).

검증

RED → GREEN

  • Stage 1 (RED): max_bottom=1048.19 overflow=+20.15 FAIL
  • Stage 3 (GREEN): max_bottom=1028.19 overflow=+0.15 PASS (허용 0.5 px 이내)

stderr 출력 비교

메시지 Before After 의미
LAYOUT_OVERFLOW_DRAW (시각 cropping) 발생 0건 본 결함 해소
LAYOUT_OVERFLOW (y_offset 누적) 31.3 px 11.3 px 잔존은 trailing ls (Task #452 영역)

회귀 (cargo test --release)

  • 1500+ 테스트 0 failed
  • 골든 SVG 7개 모두 PASS (form-002, issue-147, issue-157, issue-267, issue-617, table-text)

광범위 (169 샘플)

메트릭 Before After Δ
LAYOUT_OVERFLOW_DRAW 187 185 −2 (정정)
LAYOUT_OVERFLOW 279 277 −2 (부수 개선)
panic 0 0 0
페이지 수 변동 0 샘플

샘플별 정정:

  • 20250130-hongbo.hwp / 20250130-hongbo-no.hwp: DRAW 1→0 (본 결함 정정)
  • table-vpos-01.hwp / table-vpos-01.hwpx: FLOW 1→0 (부수 개선)
  • 그 외 165 샘플: 변동 없음

Test plan

  • cargo test --test issue_716 PASS (RED → GREEN)
  • cargo test --release 전체 0 failed
  • 골든 SVG 7개 회귀 0
  • 169 샘플 광범위: 페이지 수 변동 0, 신규 OVERFLOW 0, panic 0
  • hongbo page 0 SVG 시각 점검 (LAYOUT_OVERFLOW_DRAW 0건)

closes #716

🤖 Generated with Claude Code

planet6897 and others added 7 commits May 9, 2026 08:58
본질: 음수 line_spacing(ls<0) 미반영으로 layout y_offset forward drift
누적 → page 1 마지막 줄 (pi=15 line 2) 컬럼 하단 +20.1px 초과.

VPOS_CORR 4중 가드 (line 1402/1488-1494/1484/1536) 가 forward drift
회수를 막아 누적이 페이지 끝까지 잔존.

정정 방향: 하이브리드 C 안 (Source fix 좁게 + Recovery fix 보강)
- H2-1: lazy_base.max(0) — forward drift 시 절대 vpos 회복
- H2-2: trailing_ls 음수 허용
- H1: TAC 표 호스트 advance 에 host_ls 가산 (Stage 2 위치 확정)

ref edwardkim#716

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tests/issue_716.rs 신규 작성. samples/20250130-hongbo.hwp 페이지 0 의
모든 본문 TextLine 의 bbox 하단이 Body 하단(=col_bottom) 이내임을 단언.

RED 결과 (의도된 FAIL):
  body_bottom = 1028.04
  max_bottom  = 1048.19  (pi=15 line 2)
  overflow    = +20.15 px

이슈 본문 LAYOUT_OVERFLOW_DRAW (overflow=20.1 px) 정확 재현.

Body 하단은 RenderNodeType::Body 의 bbox 동적 산출 (하드코딩 회피).
머리말/꼬리말 영역은 traversal 컷오프.

ref edwardkim#716

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…rlay push

RHWP_TASK716_DEBUG instrument 4 위치로 page 0 drift 단계별 측정. 핵심
발견: line advance 자체는 음수 ls 를 정확히 가산. drift 의 진원지는
Task edwardkim#9 의 fix_overlay_active 블록 (layout.rs:1582-1595) 의 push.

산수 검증:
  pi=0 TAC(ls=-600) → table_bottom=149.93 → pi=1 push +8.00
  pi=2 TAC(ls=-900) → table_bottom=211.45 → pi=3 push +12.00
  합계: +20.00 px ≈ RED overflow +20.15 px

본질: TAC 표 후속 paragraph 가 표 위에 그려지는 것을 차단하는 push 가
빈 paragraph (text_len=0) 에까지 적용되어 drift 만 누적. 빈 paragraph 는
시각적으로 invisible 이라 push 가 의미 없음.

가설 갱신: H1/H2-1/H2-2 폐기, fix_overlay 의 빈 paragraph skip 가드
(H0) 단일 정정으로 변경.

ref edwardkim#716

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
본질: Task edwardkim#9 의 fix_overlay_active push 가 빈 paragraph (text_len=0)
까지 표 하단으로 push 하여 의미 없는 drift 만 +20 px (pi=1 +8 + pi=3 +12)
누적 → page 1 LAYOUT_OVERFLOW_DRAW.

src/renderer/layout.rs:1559-1582 의 push 분기에 is_empty_para 가드 추가.
빈 paragraph (text_len=0 또는 control/FFFC 만 존재) 는 push 대상에서
제외. 텍스트 paragraph 의 push 는 기존 동작 유지 (Task edwardkim#9 의도 보존).

RED 결과:
  Stage 1: max_bottom=1048.19 overflow=+20.15 px FAIL
  Stage 3: max_bottom=1028.19 overflow=+0.15 px PASS

stderr 비교:
  LAYOUT_OVERFLOW_DRAW: 발생 → **0건** (시각 cropping 차단)
  LAYOUT_OVERFLOW: 31.3px → 11.3px (trailing ls 잔존, 시각 영향 없음)

페이지 수 / 항목 수 / pagination 변동 없음.

ref edwardkim#716

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…VG 회귀 0

전체 1500+ 테스트 (lib unit 1157 + integration + svg_snapshot 7) 모두
PASS. 회귀 0건 확인.

골든 SVG 6개 샘플 (form-002, issue-147, issue-157, issue-267, issue-617,
table-text) 시각 출력 변화 없음.

본 샘플 RED test PASS:
  max_bottom=1028.19 overflow=+0.15 (허용 0.5 px 이내)

stderr:
  LAYOUT_OVERFLOW_DRAW: 발생 → **0건** (시각 cropping 차단)
  LAYOUT_OVERFLOW: 31.3 → 11.3 px (trailing ls 잔존, Task edwardkim#452 의도된 동작)

ref edwardkim#716

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
전체 169 샘플 (HWP + HWPX) before / after 비교:

LAYOUT_OVERFLOW_DRAW: 187 → 185 (−2, 모두 의도된 정정)
LAYOUT_OVERFLOW: 279 → 277 (−2, 부수 개선)
페이지 수 변동: 0건
panic: 0건

샘플별 차이:
  20250130-hongbo.hwp     DRAW 1→0, FLOW 1→1   (본 결함 정정)
  20250130-hongbo-no.hwp  DRAW 1→0, FLOW 1→1   (동일 패턴 정정)
  table-vpos-01.hwp/hwpx  DRAW 0→0, FLOW 1→0   (부수 개선)
  그 외 165 샘플          변동 없음

is_empty_para 가드는 좁고 안전한 정정으로 입증. Task edwardkim#9 의 본래 의도
(텍스트 paragraph push) 보존하면서 빈 paragraph 의 의미 없는 drift 만 차단.

ref edwardkim#716

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
본질: Task edwardkim#9 의 fix_overlay_active push 가 빈 paragraph (text_len=0)
까지 표 하단으로 push 하여 +20 px (pi=1 +8 + pi=3 +12) drift 누적
→ page 1 LAYOUT_OVERFLOW_DRAW.

정정: src/renderer/layout.rs:1559-1582 의 push 분기에 is_empty_para 가드
추가. 빈 paragraph (text 가 비어있거나 control/FFFC 만 존재) 는 push
대상 제외. Task edwardkim#9 의 텍스트 paragraph push 의도는 그대로 유지.

검증:
  Stage 1 RED: max_bottom=1048.19 overflow=+20.15 FAIL
  Stage 3 GREEN: max_bottom=1028.19 overflow=+0.15 PASS
  Stage 4 cargo test: 1500+ 테스트 0 failed, 골든 SVG 7개 PASS
  Stage 5 광범위: 169 샘플 페이지 수 변동 0, DRAW −2 (의도된 정정)

부수 개선: table-vpos-01.hwp/hwpx 의 LAYOUT_OVERFLOW 1건씩 함께 차감.

plans/task_m100_716{,_impl}.md → plans/archives/ 이동.

closes edwardkim#716

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 9, 2026
…YOUT_OVERFLOW_DRAW)

본질: Task #9 의 fix_overlay_active push 영역 의 빈 paragraph (text_len=0)
영역 push 로 의미 없는 drift 만 +20 px (pi=1 +8 + pi=3 +12) 누적 → page 1
마지막 줄 (pi=15 line=2) 이 컬럼 하단 +20.15 px 초과 시각 cropping.

본 환경 직접 재현:
  LAYOUT_OVERFLOW_DRAW: section=0 pi=15 line=2 y=1048.2 col_bottom=1028.0 overflow=20.1px
  LAYOUT_OVERFLOW: page=0, col=0, para=15, type=PartialParagraph, y=1059.4, bottom=1028.0, overflow=31.3px

→ 정정 후: LAYOUT_OVERFLOW_DRAW 부재 / LAYOUT_OVERFLOW 11.3 px (잔존, trailing ls 영역 별도).

Root cause 분석 흐름:
- 수행계획서 정적 분석 가설 ("음수 line_spacing 미반영") → Stage 2 instrument
  실측 결과 line advance 자체는 ls 가산 정확함 확인
- drift 진원지 = Task #9 fix_overlay_active 의 빈 paragraph push
  (pi=1 empty +8 px / pi=3 empty +12 px = +20.00 px ≈ overflow 20.15 px 99.3% 일치)

정정 (src/renderer/layout.rs:1562-1582, +13 LOC):
- is_empty_para 가드 추가 — text.is_empty() || control/FFFC 만
- !is_fixed && !is_empty_para 조건 영역 push 적용
- Task #9 의 텍스트 paragraph push 의도 (TAC 표 위 침범 차단) 그대로 유지
- fix_overlay_active 유지 (후속 비-empty paragraph push 가능)

영향 좁힘 (feedback_hancom_compat_specific_over_general):
- 텍스트 paragraph 영역 무영향 (Task #9 의도 유지)
- Fixed line spacing 영역 무영향 (is_fixed 가드)
- 비-fix_overlay_active 경로 무영향
- 빈 paragraph (text 부재 또는 control/FFFC 만) 영역만 차단

회귀 가드 (tests/issue_716.rs +91 LOC, 신규):
- page 0 body bbox 수집 + 모든 TextLine bbox 수집 (Header/Footer 제외)
- max_bottom <= body_bottom + 0.5 검증 (sub-pixel rounding 허용)

검증:
- cargo test --release: lib 1173 + 통합 ALL GREEN, failed 0
- cargo test --release --test issue_716: 1 PASS (회귀 가드)
- cargo test --release --test svg_snapshot: 8/8 (form-002 PR #706 영역 보존)
- cargo test --release --test issue_712/713: PASS (PR #714/#715 영역 보존)
- cargo clippy --release: 신규 경고 0
- 광범위 sweep 7 fixture / 170 페이지 / 회귀 0
- 본 환경 직접 측정: LAYOUT_OVERFLOW_DRAW 부재 ★

PR 본문 광범위 sweep (169 샘플):
- LAYOUT_OVERFLOW_DRAW 187 → 185 (−2 정정: hongbo + hongbo-no)
- LAYOUT_OVERFLOW 279 → 277 (−2 부수 개선: table-vpos-01 hwp/hwpx)
- 페이지 수 변동 0 샘플
- panic 0

Closes #716

Co-Authored-By: Jaeook Ryu <jaeook.ryu@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 9, 2026
- mydocs/pr/archives/pr_719_review.md (검토 문서)
- mydocs/pr/archives/pr_719_report.md (처리 보고서)
- mydocs/plans/archives/task_m100_716{,_impl}.md (PR commit 영역에 이미 archives 이동)
- mydocs/orders/20260509.md: PR #719 행 + 본 사이클 패턴 라인 추가

처리 결과:
- 옵션 A — 7 commits 단계별 보존 cherry-pick + no-ff merge (b8defa2)
- 시각 판정 면제 (결정적 검증 + 광범위 sweep + 직접 측정 통과)
- 본 환경 직접 측정: LAYOUT_OVERFLOW_DRAW 부재 확증 (BEFORE 20.1 px → AFTER 부재)
- 광범위 sweep 7 fixture / 170 페이지 / 회귀 0
- Issue #716 close 자동 정합

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@edwardkim
Copy link
Copy Markdown
Owner

@planet6897 PR 머지 완료되었습니다 (devel b8defa26, --no-ff merge).

처리 결과

검증

본 환경 직접 측정 + 정정 입증

→ 본 PR 본질 (시각 cropping) 100% 해소.

메모리 룰 정합

처리 보고서: mydocs/pr/archives/pr_719_report.md. 감사합니다.

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.

2 participants