Skip to content

fix: 동일 문단 내 두 번째 line의 inline 그림이 첫 line과 겹침 (#402)#406

Closed
planet6897 wants to merge 8 commits into
edwardkim:develfrom
planet6897:local/task402
Closed

fix: 동일 문단 내 두 번째 line의 inline 그림이 첫 line과 겹침 (#402)#406
planet6897 wants to merge 8 commits into
edwardkim:develfrom
planet6897:local/task402

Conversation

@planet6897

Copy link
Copy Markdown
Contributor

Summary

같은 paragraph(treat_as_char=true)에 inline 컨트롤 2개 이상이 서로 다른 line_seg에 배치된 경우, 두 번째 이후 그림이 첫 번째와 같은 y 좌표에 그려져 표 위에 겹치고 페이지 영역을 초과하던 문제 수정.

샘플: samples/2025년 기부·답례품 실적 지자체 보고서_양식.hwpx 7쪽

수정 전 수정 후
7쪽 표 파이 차트가 위에 겹침 표만 정상 표시 (PDF 일치)
8쪽 시작 PartialTable 연속 파이 차트 정상 배치

원인

같은 paragraph에 inline 컨트롤(treat_as_char=true) 2개가 서로 다른 line_seg(ls[0]=표, ls[1]=그림)에 배치된 구조에서 두 가지 누락:

  1. 레이아웃의 y 좌표 결정 누락 (layout.rs::layout_shape_item)

    • 그림의 pic_ypara_start_y[para_index] 단일값에 고정.
    • 표가 먼저 처리되어 y_offset은 진행됐지만 para_start_y는 paragraph 시작 y에 머무름.
    • → 그림이 표 시작 위치에 겹침.
  2. 페이지네이션의 높이 누적 누락 (typeset.rs::typeset_table_paragraph)

    • inline TAC 그림이 PageItem::Shape로 push만 되고 current_height 누적 없음.
    • 그림 line의 높이(369px)가 페이지 사용량에 미반영 → 페이지 분할 미트리거.
    • → 7쪽에 표+그림이 함께 스케줄되어 SVG viewBox 초과·후속 항목 위치 어긋남.

변경 사항

src/renderer/layout.rs::layout_shape_item

control_index보다 앞선 인덱스에 같은 paragraph의 TAC 컨트롤이 존재하면 para_start_y를 진행된 y_offset으로 갱신. 단순 y_offset > existing + 1.0 비교만으로는 단일 inline 그림 케이스(FullParagraph + Shape 구조)를 잘못 갱신하므로, 선행 TAC 존재 여부를 추가 조건으로 사용.

src/renderer/typeset.rs::typeset_table_paragraph

기본 페이지네이션 엔진은 paginate_with_measured(engine.rs)가 아닌 TypesetEngine::typeset_section(typeset.rs)임을 진단 로깅으로 확인 (RHWP_USE_PAGINATOR=1일 때만 engine.rs로 fallback).

inline TAC 그림이 같은 paragraph에 선행 TAC 컨트롤을 가질 때:

  • 자기에 해당하는 line_segs[prior_tac_count]line_height + line_spacing을 line 높이로 산출
  • current_height + line_h > available_height + 0.5 이면 advance_column_or_new_page() 호출 → 다음 페이지로 분할
  • 분할 후 PageItem::Shape push, current_height += line_h

Test plan

  • cargo test --quiet — 1023 passed, 0 failed, 1 ignored
  • 타겟 샘플 7쪽 SVG 시각 비교 — 표만 표시, 파이 차트 겹침 없음 (PDF 일치)
  • 타겟 샘플 8쪽 SVG 시각 비교 — 파이 차트 정상 배치
  • 페이지 수 27 → 30 (분할에 의한 정상적 증가)
  • 10개 대표 샘플 LAYOUT_OVERFLOW 카운트 회귀 없음 (aift, biz_plan, endnote-01, equation-lim, exam_math, exam_kor, footnote-01, group-box, hwp_table_test, field-01)
  • WASM 빌드 (wasm-pack build --target web) 성공, rhwp-studio dev 서버에서 동작 확인

알려진 비범위

  • engine.rs::process_controls(현재 fallback 경로)의 동일 누락은 본 PR 수정 범위 밖. 추후 paginator 사용 시 동일 패치 필요. → 별도 이슈 추적 가능.
  • samples/2025년 기부·답례품 실적 지자체 보고서_양식.hwpx 9쪽 하단 헤딩 "(7) 다수 기부자 현황"이 후속 표(10쪽)와 분리되는 orphan heading 문제는 본 수정 전후 모두 동일하게 발생하는 기존 버그. → #404로 분리 등록.
  • cargo clippy 에러 2건(commands/table_ops.rs:1007, commands/object_ops.rs:298panicking_unwrap)은 base 브랜치에 이미 존재하는 기존 문제로 본 PR과 무관 (git stash 후 비교 빌드로 확인).

관련 문서

  • 수행계획서: mydocs/plans/task_402.md
  • 구현계획서: mydocs/plans/task_402_impl.md
  • Stage 1 (가설 확정): mydocs/working/task_402_stage1.md
  • Stage 2 (구현): mydocs/working/task_402_stage2.md
  • 최종 보고서: mydocs/report/task_402_report.md

커밋

Closes #402

- row_block_start/end 필드 + compute_row_blocks 헬퍼
- row_block_for / snap_to_block_boundary 메서드
- 신규 단위 테스트 7개 (rowspan 단일/겹침/비인접 + 폴백 + 스냅)

회귀 검증용 샘플 hwpx/pdf 동반 커밋.
- pagination/engine.rs::split_table_rows: pre-loop first_block_h, snap_to_block_boundary, cur/next 블록 단일성 가드
- typeset.rs::paginate_table: 동일 패턴 적용 (실제 SVG 내보내기 경로)
- 다중 행 블록이 페이지에 들어가지 않으면 블록 전체를 한 단위로 배치

본 샘플 검증: 1쪽에서 표 분할 사라지고 2쪽에 표 전체 시작.
cargo test --lib: 1023 passed.
- cargo test --tests: 1073 passed (lib 1023 + integration 50)
- svg_snapshot 골든 6건 통과 (table-text, issue-147/157/267, form-002, deterministic)
- cargo build --release 성공
- 본 샘플 외 다른 표 샘플 (table-vpos-01, 표-텍스트) 정상

closes edwardkim#398
같은 paragraph 안에 TAC 컨트롤이 2개 이상 있을 때 두 번째 이후
그림의 pic_y가 paragraph 시작 y로 고정되어 표와 겹침.

- pi=51 ci=0 (단독 그림): pic_y=94.49 (정상, 선행 TAC 없음)
- pi=57 ci=1 (Table 뒤 그림): pic_y=578.09 (버그, y_offset=919.40 사용해야)

선행 TAC 존재 여부가 핵심 판별 조건임을 확인. Stage 2 구현 방향 확정.
같은 paragraph에 TAC 컨트롤(표/그림/도형) 2개 이상이 서로 다른 line_seg에
배치된 경우, 두 번째 이후 inline 그림이 첫 번째와 같은 y 좌표에 그려져
겹침/오버플로 발생하던 문제 수정.

- layout.rs::layout_shape_item: 선행 TAC 컨트롤이 있으면 para_start_y를
  진행된 y_offset으로 갱신하여 그림 y 좌표를 표 아래로 정확히 배치.
- typeset.rs::typeset_table_paragraph: 선행 TAC 그림의 line_seg 높이를
  current_height에 누적하고, 페이지 초과 시 다음 페이지로 분할.

기본 페이지네이션 엔진은 typeset.rs(TypesetEngine). engine.rs는 현재
RHWP_USE_PAGINATOR=1 fallback 경로이므로 typeset.rs만 수정.

회귀 테스트: 1023 passed, 0 failed.
샘플 비교: 7쪽 표 + 파이 차트 겹침 해소, 파이 차트가 8쪽 정상 배치.
closes edwardkim#402

검증 결과:
- 7쪽: 표 + 파이 차트 겹침 해소 (PDF 일치)
- 8쪽: 파이 차트 정상 배치
- cargo test 1023 passed, 0 failed
- 10개 대표 샘플 LAYOUT_OVERFLOW 카운트 회귀 없음
- 페이지 수 27→30 (분할로 인한 정상 증가)
edwardkim added a commit that referenced this pull request Apr 28, 2026
- mydocs/pr/pr_406_review.md (옵션 A: Task #402 핵심 3 commits 분리 cherry-pick)
- mydocs/pr/pr_406_report.md (cherry-pick 머지 결정 + SVG/Canvas 양 경로 시각 판정 통과)
- mydocs/orders/20260426.md (#174/#175 close + PR #406 완료 행 추가)

검증: 1050 passed + svg_snapshot 6/6 + issue_418 1/1 + clippy 0 + WASM 4,115,251 bytes
@edwardkim

Copy link
Copy Markdown
Owner

@planet6897 님 PR 감사드립니다. 메인테이너가 cherry-pick 으로 devel 에 적용 완료했습니다.

처리

본 PR 의 8 commits 중 Task #398 (3 commits) 은 이미 PR #401 v2 cherry-pick 으로 devel 에 흡수되어 있어, Task #402 핵심 3 commits 만 분리 cherry-pick 했습니다 (작성자 attribution 보존):

devel 머지 commit: e258315

검증

시각 판정 (작업지시자 직접)

한컴 hwpx + PDF 정답지 vs rhwp 출력 비교:

devel (미적용) PR #406 적용
전체 페이지 수 27 30 (+3 분할 정상화)
7쪽 표 위 파이 차트 겹침 + 페이지 초과 표만 정상 (한컴 일치)
8쪽 (다음 표 연속) 파이 차트 정상 배치
  • SVG 내보내기: 통과 ✅
  • Canvas (rhwp-studio): 통과 ✅

이슈 #402 도 함께 close 됩니다. 9쪽 orphan heading 분리 등록한 #404 도 PR #408 로 진행 중인 점 확인했습니다 — 후속 검토 진행하겠습니다. 감사합니다.

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