Skip to content

Task #770: shortcut 페이지 2~7 헤더 TAC 표 후속 LINE_SEG 정합#771

Closed
planet6897 wants to merge 4 commits into
edwardkim:develfrom
planet6897:pr-task770
Closed

Task #770: shortcut 페이지 2~7 헤더 TAC 표 후속 LINE_SEG 정합#771
planet6897 wants to merge 4 commits into
edwardkim:develfrom
planet6897:pr-task770

Conversation

@planet6897

Copy link
Copy Markdown
Contributor

Summary

  • 본질: TAC 호스트 paragraph 가 다중 LINE_SEG 보유 시 (예: shortcut.hwp pi=36 페이지 2 "파일" 헤더 = 1x1 TAC 표 + 후속 빈 라인) 후속 LINE_SEG 의 lh+ls 가 advance 에 누락되어 본문이 위쪽으로 압축
  • 결함: rhwp 의 tac_seg_applied 분기 (layout.rs:2585+) 가 line_segs.get(control_index) 만 처리. paragraph 의 후속 LINE_SEG 의 lh+ls 가 advance 에 미반영
  • 정정: src/renderer/layout.rs:2599-2628tac_seg_applied 분기에 3중 가드 추가 후 paragraph_vpos_end 까지 y_offset advance 보장
  • PDF 정합: 페이지 2 헤더~본문 거리 ~21 → ~47 px (hwp_used 47.1 정합)

Root cause

LINE_SEG 차이

paragraph LINE_SEGs first.lh last.lh vpos_end (px) advance (Before)
pi=1 (페이지 1) 1 2332 2332 31.1 31.09 ✓
pi=36 (페이지 2) 2 1200 2332 47.1 31.09 ❌
pi=81 (페이지 3) 2 1200 (ls=480) 2332 (ls=480) 53.5 37.49 ❌

→ 다중 LINE_SEG paragraph 의 후속 line 의 lh+ls 가 advance 에 누락 (16+ px 부족).

패턴 식별

  • shortcut pi=36: ColumnDef + 1x1 TAC 헤더 표 + 후속 빈 line. ls[0].lh < ls[1].lh (1200 < 2332)
  • Textmail pi=0: ColumnDef + 11x3 표 + 2x1 표. ls[0].lh > ls[1].lh (55830 > 9460)

last.lh > first.lh 가드 가 헤더 패턴 단독 식별자.

정정

src/renderer/layout.rs:2599-2628 tac_seg_applied 분기에 3중 가드 추가:

let has_column_def = para.controls.iter().any(|c|
    matches!(c, Control::ColumnDef(_)));
if has_column_def {
    if let (Some(first_seg), Some(last_seg)) = (
        para.line_segs.first(),
        para.line_segs.last(),
    ) {
        if last_seg.vertical_pos > first_seg.vertical_pos
            && last_seg.line_height > first_seg.line_height
        {
            let para_vpos_end = last_seg.vertical_pos
                + last_seg.line_height
                + last_seg.line_spacing.max(0);
            let target_y = para_y_for_table
                + hwpunit_to_px(para_vpos_end, self.dpi);
            if target_y > y_offset {
                y_offset = target_y;
            }
        }
    }
}

3중 가드 의의:

  1. has_column_def: ColumnDef 동반 (다단 영역 진입 paragraph)
  2. last.vpos > first.vpos: 다중 LINE_SEG
  3. last.lh > first.lh: 헤더 line 0 < 후속 line 1 패턴 (헤더 표 단독 식별)

검증

RED → GREEN

$ cargo test --test issue_770 -- --nocapture

[issue_770] page_index=1 body_y=56.69 pi=37_y=103.79 offset=47.09 (expected_min=40)
test issue_770_page2_body_paragraph_below_header_zone ... ok

→ pi=37 ('새 문서') offset 31.09 → 47.09 (hwp_used 47.1 정합).

회귀 (cargo test --release)

test result: ok. 1217 passed; 0 failed; 2 ignored;
  • 통합/스냅샷/issue 테스트 회귀 0
  • 골든 SVG 7개 PASS
  • test_539 / test_548 / test_exam_math_page_count PASS

광범위 (205 샘플)

메트릭 Before After Δ
샘플 수 205 205
LAYOUT_OVERFLOW_DRAW 226 228 +2 (shortcut만)
LAYOUT_OVERFLOW 354 358 +4 (shortcut만)

샘플별 변경:

  • shortcut.hwp (페이지 2/3 헤더 표 정합): DRAW 12→14, FLOW 13→17 — 본문 정합 후 column 잔여 변화 (의도된 차이)
  • 그 외 204 샘플: 변동 없음 ✓

shortcut.hwp 단독 영향. Newspaper / 단일 LINE_SEG / 가드 3 미통과 paragraph (Textmail.hwp 등) 회귀 0.

PDF 정합

PDF 페이지 2 (pdf/basic/shortcut-2022.pdf): 헤더 ('파일') ~ 본문 ('새 문서') 거리 ≈ 60 px
rhwp (Before): 21 px (40 px 압축)
rhwp (After): ~47 px (PDF 정합 근접, hwp_used 와 일치)

Test plan

  • cargo test --test issue_770 PASS (RED → GREEN)
  • cargo test --release 1217 passed, 0 failed (회귀 0)
  • 골든 SVG 회귀 0
  • 205 샘플 광범위: shortcut.hwp 만 변경 (의도된 정정)
  • PDF 권위 (한글 2022) 페이지 2 시각 정합 확인

closes #770

🤖 Generated with Claude Code

planet6897 and others added 4 commits May 10, 2026 13:34
shortcut.hwp 페이지 2~7 헤더 zone (1x1 TAC 표 + 후속 PartialParagraph)
이 hwp_used (47-53 px) 보다 13-33 px 짧음. 본문이 위쪽으로 압축
(PDF 권위 대비 ~40 px).

가설 (정적 분석):
- H1: PartialParagraph (line 1..2) y advance 누락
- H2: Table PageItem 이 paragraph height 전체 점유
- H3: ColumnDef 동반 paragraph 의 특수 처리

Stage 2 instrument 로 가설 확정 → Stage 3 정정.

ref edwardkim#770

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tests/issue_770.rs 신규. 페이지 2 의 pi=37 ('새 문서') 가 body 상단으로부터
최소 40 px 아래 등장 단언.

RED 결과 (의도된 FAIL):
  body_y=56.69 pi=37_y=87.79 offset=31.09 (expected_min=40)
  → 헤더 zone 31.09 px (hwp_used 47.1 보다 16 px 부족)

ref edwardkim#770

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

본질 (instrument 측정):
- pi=36 (페이지 2 "파일" 헤더): 다중 LINE_SEG (ls[0] vpos=0 lh=1200,
  ls[1] vpos=1200 lh=2332). vpos_end=47.1 px 정합 필요한데 layout
  advance 31.09 px (16 px 부족) — 후속 LINE_SEG 의 lh 누락.
- pi=1 (페이지 1 헤더): 단일 LINE_SEG → 영향 없음 (정합).

정정: layout.rs::layout_table_item 의 tac_seg_applied 분기에 3중 가드
추가:
  1. has_column_def (ColumnDef 동반)
  2. last.vpos > first.vpos (다중 LINE_SEG)
  3. last.lh > first.lh (헤더 line 0 < 후속 line 1 패턴)

가드 통과 시 paragraph_vpos_end (= last_seg.vpos + lh + ls) 까지
y_offset advance 보장.

검증:
  RED → GREEN: pi=37 offset 31.09 → 47.09 (hwp_used 47.1 정합)
  cargo test: 1217 passed, 0 failed
  광범위 205 샘플: shortcut.hwp 만 변경 (DRAW +2, FLOW +4)

ref edwardkim#770

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
본질: TAC 호스트 paragraph 가 다중 LINE_SEG 보유 시 (예: pi=36 등 1x1
헤더 표 + 후속 빈 라인) 후속 LINE_SEG 의 lh+ls 가 advance 에 누락되어
본문이 위쪽으로 압축 (PDF 권위 대비 ~40 px).

정정: src/renderer/layout.rs:2599-2628 의 tac_seg_applied 분기에 3중
가드 추가:
  1. has_column_def (ColumnDef 동반)
  2. last.vpos > first.vpos (다중 LINE_SEG)
  3. last.lh > first.lh (헤더 line 0 < 후속 line 1 패턴)

가드 통과 시 paragraph_vpos_end 까지 y_offset advance 보장.

검증:
  RED → GREEN: pi=37 offset 31.09 → 47.09 (hwp_used 47.1 정합)
  cargo test: 1217 passed, 0 failed (회귀 0)
  광범위 205 샘플: shortcut.hwp 만 변경 (의도된 정정)
  PDF 정합: 페이지 2 헤더~본문 거리 ~21 → ~47 px

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

closes edwardkim#770

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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