Skip to content

Task #459: 다단 후속 페이지 LINE_SEG vpos-reset 단 경계 미인식 수정#461

Closed
planet6897 wants to merge 55 commits into
edwardkim:develfrom
planet6897:local/devel
Closed

Task #459: 다단 후속 페이지 LINE_SEG vpos-reset 단 경계 미인식 수정#461
planet6897 wants to merge 55 commits into
edwardkim:develfrom
planet6897:local/devel

Conversation

@planet6897

Copy link
Copy Markdown
Contributor

요약

다단 구역이 여러 페이지에 걸칠 때, 첫 페이지가 아닌 후속 페이지의 좌측 단 → 우측 단 단 경계 인코딩(LINE_SEG.vertical_pos 리셋)이 무시되어 좌측 단 하단이 col_bottom 을 초과해 그려지던 버그를 수정.

samples/exam_kor.hwp 페이지 2 좌측 단의 pi=39 문단 4줄 중 마지막 2줄이 col_bottom 을 39px 초과해 그려지던 문제를 해결. HWP 원본의 LINE_SEG vpos 리셋 위치(ls[2])대로 좌측 단 2줄, 우측 단 5줄로 정확히 분할됨.

원인

on_first_multicolumn_page 가드는 state.rs:218reset_for_new_page() 에서 새 페이지 시작 시 false 로 리셋됨. 다단 구역이 페이지를 넘어가면 후속 페이지에서 flag = false → detect_column_breaks_in_paragraph 호출이 차단됨. 결과: HWP 가 LINE_SEG vpos 리셋으로 인코딩한 단 경계가 무시되고, 높이 기반 폴백이 사용되어 col_bottom 초과.

git log -G "on_first_multicolumn_page" 결과 최초 커밋 한 번만 나와 가드 도입 이유는 코드 주석/문서에 기록 없음. 초기 보수적 설계의 흔적으로 판단.

변경 파일

  • src/renderer/typeset.rs:856 (기본 페이지네이션 경로, TypesetEngine)
  • src/renderer/pagination/engine.rs:607 (RHWP_USE_PAGINATOR=1 fallback)

두 엔진 모두 동일 가드를 가지고 있어 양쪽 일관성 유지.

// 변경 전
let col_breaks = if st.col_count > 1 && st.current_column == 0 && st.on_first_multicolumn_page {
    Self::detect_column_breaks_in_paragraph(para)
} else {
    vec![0]
};

// 변경 후
// [Task #459] on_first_multicolumn_page 가드 제거: 다단 구역이 여러 페이지에 걸칠 때
// 후속 페이지에서도 LINE_SEG vpos-reset 으로 인코딩된 단 경계를 인식해야 함.
let col_breaks = if st.col_count > 1 && st.current_column == 0 {
    Self::detect_column_breaks_in_paragraph(para)
} else {
    vec![0]
};

안전성 분석

  • detect_column_breaks_in_paragraph 는 vpos 가 감소하는 경우에만 단 경계로 감지 → 단일 컬럼 문단이나 vpos-reset 이 없는 다단 문단에는 영향 없음 (col_breaks=[0] → 분기 진입하지 않음)
  • current_column == 0 조건은 유지 — 이미 우측 단에 있는 paragraph 는 단 경계 의미 없음
  • paginate_multicolumn_paragraph / typeset_multicolumn_paragraphadvance_column_or_new_page() 사용으로 후속 페이지에서도 단 진행 가능 (특별한 first-page 가정 없음)

검증 결과

exam_kor 페이지 2 (목표 케이스)

단 0 (좌측) 단 1 (우측)
변경 전 pi=39 lines=0..4 (4줄, 39px overflow) pi=39 lines=4..7 (3줄)
변경 후 pi=39 lines=0..2 (2줄) pi=39 lines=2..7 (5줄)
HWP 원본 ls[0..2] vpos=86417,88255 ls[2..7] vpos=0,1838,3676,5514,7352

수정 후 HWP 원본의 LINE_SEG 인코딩과 정확히 일치.

자동 해소된 추가 케이스

페이지 문단 vpos-reset 위치 결과
5 pi=157 ls[4] 0..4 / 4..15
8 pi=297 ls[5] 0..5 / 5..11

회귀 검증 (다단 샘플 5종)

샘플 페이지 수 (전→후) LAYOUT_OVERFLOW (전→후)
exam_kor.hwp 20 → 20 36 → 16
exam_eng.hwp 8 → 8 9 → 9
exam_math.hwp 20 → 20 0 → 0
exam_science.hwp 4 → 4 5 → 5
exam_social.hwp 4 → 4 4 → 4
  • exam_kor 에서 20 건 overflow 해소 (페이지 2/5/8 의 동일 메커니즘 자동 해소)
  • 다른 샘플들 SVG byte 동일 — 회귀 0
  • 페이지 수 모든 샘플에서 동일 유지

단위/통합 테스트

  • cargo test --release: 1120 passed, 0 failed
  • svg_snapshot, exam_eng_multicolumn, hwpx_roundtrip, issue_301, issue_418 등 모든 회귀 테스트 통과

후속 과제

  • exam_kor 잔여 16건 overflow 는 본 이슈와 별개 원인으로 추정 (다른 paragraph indices). 별도 이슈로 분류 필요.

관련 문서

  • 수행계획서: mydocs/plans/task_m100_459.md
  • 단계별 보고서: mydocs/working/task_m100_459_stage1.md
  • 최종 결과보고서: mydocs/report/task_m100_459_report.md

closes #459

planet6897 and others added 30 commits April 29, 2026 11:54
exam_kor.hwp 24페이지 → 20페이지 정합 작업 1단계.

- 페이지별 단별 used/hwp_used/diff CSV (output/debug/task435/)
- 회귀 대상 5문서 페이지 수 (exam_kor 24, exam_eng 8, k-water-rfp 28, hwpspec 177, synam-001 35)
- RHWP_TYPESET_DRIFT 출력 캡처 (pi=0.30, pi=1.25 split 진단)
- compute_body_wide_top_reserve_for_para 산정 경로 추적

핵심 진단: col 1 reserve 306.1px (HWP 실제 94.5px 대비 +211.6px 과대).
원인: Paper-rel 좌표를 body-rel 변환 없이 그대로 reserve 에 누적.
Stage 2 에서 typeset.rs:2127-2172 의 VertRelTo::Paper 분기 정정.

수행계획서/구현계획서/Stage 1 보고서 포함.
compute_body_wide_top_reserve_for_para 의 VertRelTo::Paper 분기에서
body-rel 변환 누락 정정. body 와 일부만 겹치는 (header→body 침범)
케이스에서 Paper-rel 좌표를 그대로 reserve 에 누적하던 버그 수정.

수정 전 reserve = shape_y_offset(paper) + h + outer_bottom = 306.1 px
수정 후 reserve = max(0, shape_top_abs - body_top) ... = 94.4 px

결과:
- exam_kor.hwp: 24 → 22 페이지 (page 2, 15 orphan 해소)
- pi=0.30, pi=1.25 split → FullParagraph
- 회귀: exam_eng 8, k-water-rfp 28, hwpspec 177, synam-001 35 유지
- cargo test: 1062 passed

Stage 3 에서 일반 페이지 누적 -100~-300px 정정 (22 → 20).
원래 가설 ("표/도형 후 컬럼 잔여 공간 산정 부족") 재검토.
RHWP_TYPESET_DRIFT 분석 결과 diff 메트릭은 typeset cur_h 누적
(height_for_fit, trail_ls 제외) vs hwp_used (last line vpos+lh)
의 좌표계 차이를 측정하는 것일 뿐, "rhwp 가 채울 수 있는데 못 채운
잔여 공간" 이 아님을 확인.

실제 22→20 페이지 단축 장애물:
1. 섹션 1 페이지 14: Square wrap 표 + col 0 over-fill (1225>1211)
   → col 1 under-use (64px)
2. 섹션 1 페이지 15: 단일 컬럼 출력 (단정의는 2단인데 단 1 누락)
3. 섹션 2 페이지 18: pi=11 split + pi=13 [단나누기] orphan-like

3가지 전부 해결 시 22→19 가능 (목표 20 도달).

옵션 A/B/C 결정 필요 (현 상태 종료 / Stage 4 확장 / Stage 4 부분).
옵션 A 종료: 24→22 페이지 (Stage 2 col 1 reserve 정정).
잔여 22→20 미달성, 3가지 별도 메커니즘 (Square wrap over-fill,
단일 컬럼 출력 버그, col 0 cur_h over-advance) 별도 task 분리 권고.

edwardkim#393 (옵션 A) 본 task Stage 2 로 적용 완료, close 가능.
수행계획서(task_m100_439.md) + 단계1 진단 보고서.

핵심 발견:
- 이슈 가설의 engine.rs:702-711 는 fallback 경로 (RHWP_USE_PAGINATOR=1).
  기본 활성 엔진은 typeset.rs::TypesetEngine.
- 실제 버그 위치: typeset.rs::place_table_with_text (1400-1467).
  engine.rs 의 !is_wrap_around_table 가드 (engine.rs:1349, 1422) 누락.
- 페이지 14 col 0 used=1225.8 (본문 1211.3 초과 +14.5) 정확히 재현.

코드 변경 없음 — 임시 디버그 코드는 모두 revert.
place_table_with_text 의 정확한 cur_h 누적 추적 (디버그 후 revert):
- Square wrap 4 표가 pre_height + table_total 합산 → +244.88 px 과다
- HWP 의도: max(호스트 텍스트, 표 + v_offset) 만 누적

수정안: typeset.rs::place_table_with_text 에서
  current_height += max(pre_height, v_off + table_total) (Square wrap 시)

코드 변경 없음 — 임시 디버그 println 모두 revert.
typeset.rs::place_table_with_text 에서 Square wrap (어울림) 표일 때
current_height 누적을 pre_height + table_total → max(pre_height, v_off + table_total)
로 변경.

호스트 문단 텍스트와 어울림 표는 같은 수직 영역을 공유하므로
더 큰 쪽만 한 번 누적해야 HWP layout 의도와 일치.
PageItem 자체는 PartialParagraph + Table 모두 push (layout 렌더링 보존).

검증:
- 페이지 14 col 0 used 1225.8 → 1036.1 px (≤ 1211.3 충족)
- exam_kor.hwp 22 → 20 페이지 (목표 ≤ 21 충족)
- 회귀 샘플 6 종 (exam_eng/math, 21언어, aift, 2010-01-06, biz_plan) 페이지 수 동일
- cargo test 1066 개 모두 통과
- SVG 렌더링 정상

closes edwardkim#439
Stage 4 회귀 검증 결과:
- 149 개 sample HWP 전수 페이지 수 비교: exam_kor 만 22→20 변경, 148개 동일
- cargo test 1066 passed
- DoD 전부 충족

본 task 완료. closes edwardkim#439.
typeset.rs::place_table_with_text 의 Square wrap 표 누적 정책을
pre_height + table_total → max(pre_height, v_off + table_total) 로 변경.

효과:
- exam_kor.hwp 페이지 14 col 0 used 1225.8 → 1036.1 px (over-fill 해소)
- exam_kor.hwp 22 → 20 페이지
- 149 개 sample 중 exam_kor 만 변화, 148 개 동일 (회귀 0건)
- cargo test 1066 passed

closes edwardkim#439
…문제 수정

- 수행/구현 계획서 + Stage 1·2 보고서 작성
- src/renderer/layout.rs: paragraph border merge 그룹을 col_area 바닥/꼭대기로 클램프
- exam_kor p2/5/8/15 의 세로 구분선이 PDF 와 일치하는 길이로 정상화
  (p8: 1671 → 1425, 246px 단축, 페이지 바깥 침범 해소)
- vpos-reset 미존중으로 인한 텍스트 자체의 overflow 는 별도 이슈로 분리
- snapshot 갱신: tests/golden_svg/issue-267/ktx-toc-page.svg
  (invisible 구조 rect 의 height 5.34px 변화, 가시 변화 없음)
페이지 번호 박스가 column divider line 과 붙어 보이는 문제 해결.

원인: 꼬리말 paragraph 의 vert=Para + wrap=TopAndBottom 표가 paragraph
top 에 배치되어 본문 바닥과 같은 y 에 위치. HWP 의 실제 동작은 첫 라인의
line_height/2 만큼 아래에 anchor 되어 본문과 시각적 갭 형성.

수정: layout_header_footer_paragraphs 에서 해당 조건의 첫 paragraph 표는
y_offset 에 line_height/2 (px) 를 더하여 배치.

검증 (exam_kor.hwp 20p):
- 박스 top y: 1422.93 → 1439.47 (PDF 380.6mm 와 일치)
- column line - 박스 갭: 0px → 16.3-17.0px (PDF 16.0px 와 일치)
- column line 길이/위치는 PDF 자연 그대로 유지 (p1 1131px, p2+ 1226px)
- cargo test --release: 1117 passed, 0 failed
이슈 edwardkim#445 의 두 시각적 결함 (paragraph border 페이지 바깥 침범 + 페이지
번호 박스가 column line 에 붙음) 모두 PDF 와 일치하도록 수정 완료.

승인 후 local/devel 머지 + edwardkim#445 close 예정.
- 수행계획서 (mydocs/plans/task_m100_452.md): 옵션 A 선언, 4단계 분해
- 구현 계획서 (mydocs/plans/task_m100_452_impl.md): paragraph_layout.rs:2511-2520
  is_para_last_line 분기 제거, is_cell_last_line 만 보존
- Stage 1 보고서 (mydocs/working/task_m100_452_stage1.md):
  - exam_kor pi=1.line9↔pi=2.line0 step = 15.34px (버그) ↔ 단락내 24.51px
  - 10종 샘플 페이지 수 baseline 캡처 (/tmp/task_452_baseline/)
  - 21_언어 p1 col 1 pi=26+보기①②③ fit 확인 (edwardkim#332 회귀 baseline)
- orders 갱신: 버그 섹션 edwardkim#452 항목 추가
… + golden 갱신

- src/renderer/layout/paragraph_layout.rs:2511-2519: is_para_last_line 분기
  제거. is_cell_last_line(셀 내) 만 trailing 제외 보존, 본문 단락은 모든 줄에서
  y += lh + ls 통일. pagination/engine.rs 의 current_height 누적과 정합.
- 검증: exam_kor 1페이지 pi=1.line9↔pi=2.line0 step = 15.34 → 24.50 px
  (단락내 step 과 동일). cargo test --lib 1066 passed.
- golden SVG 2건 baseline 갱신 (Task edwardkim#332 에서 갱신된 것을 본 정합으로 재갱신):
  - tests/golden_svg/issue-147/aift-page3.svg
  - tests/golden_svg/issue-157/page-1.svg
- LAYOUT_OVERFLOW 메시지: 페이지 마지막 단락의 trailing ls (~10.9 px)
  가 col_bottom 을 살짝 넘으나 빈 공간이므로 시각 무영향. pagination
  engine 의 effective_trailing 처리로 페이지 분배는 유지.
paragraph_layout.rs:2511-2520 의 is_para_last_line 분기 제거. 본문 단락
모든 줄에서 y += lh + ls 통일 → pagination/engine.rs 의 current_height
누적과 정합. is_cell_last_line(셀 내) 만 trailing 제외 보존.

효과: exam_kor pi=1.line9↔pi=2.line0 step 15.34→24.50 px (단락내 step 과
동일, PDF 정합). 10종 샘플 페이지 수 변동 0. Task edwardkim#332 회귀 0 (21_언어
p1 col 1 pi=26+보기①②③ fit 유지). cargo test --lib 1066 passed +
svg_snapshot 6/6 (issue-147/157 baseline 재갱신).

closes edwardkim#452
paragraph_layout 의 skip_text_for_inline_shape 분기 제거. 인라인 글상자가 있는
줄에서 외부 문단 본문이 통째로 스킵되던 버그를 수정.

원인: skip_text_for_inline_shape 가 글상자 내부 텍스트와 외부 문단 본문 텍스트를
혼동하여, 외부 본문(글상자 좌·우의 일반 텍스트)도 함께 스킵하고 있었음.
글상자 자체와 내부 텍스트는 shape_layout 의 inline_shape_position 경로로 별도
렌더되므로 외부 본문을 항상 렌더해도 중복되지 않는다.

검증: samples/exam_kor.hwp 페이지 2 좌측 단 line 2 의 본문 39자(척사파의 ...
거스를) 가 글상자 좌·우로 분리 렌더되어 복원됨. 페이지 수 20 유지, 전체
테스트 1117 passed.
Stage 3 회귀 검증 결과 (1117 tests passed, 페이지 수 회귀 0).
Stage 4 최종 결과보고서 및 PR 메시지(`mydocs/report/task_m100_455_pr.md`) 작성.
오늘할일에 Task edwardkim#455 항목 추가.
`on_first_multicolumn_page` 가드는 새 페이지 시작 시 false 로 리셋되어
다단 구역이 여러 페이지에 걸칠 때 후속 페이지에서
`detect_column_breaks_in_paragraph` 호출이 차단됨. HWP 원본의 LINE_SEG
vpos 리셋 위치가 무시되어 좌측 단 하단이 col_bottom 을 초과해 그려지던
버그.

수정: `typeset.rs:856` (기본 경로) + `pagination/engine.rs:607`
(RHWP_USE_PAGINATOR=1 fallback) 의 가드에서 `on_first_multicolumn_page`
조건 제거.

검증:
- exam_kor p2 pi=39 0..4/4..7 → 0..2/2..7 (HWP 원본 정합)
- exam_kor LAYOUT_OVERFLOW 36 → 16 (페이지 5/8 의 동일 메커니즘 자동 해소)
- 다단 샘플 4종 (exam_eng/math/science/social) 페이지 수 + SVG byte 동일
- cargo test --release 1120 passed, 0 failed

closes edwardkim#459
학생3 wrap host paragraph 의 텍스트가 학생1 등 일반 paragraph 보다
margin_left (11.33px) 만큼 더 들여쓰기 되던 문제 해결.

원인: layout_wrap_around_paras 가 wrap_area.x = col_area.x + wrap_cs 로
설정. wrap_cs (LINE_SEG.column_start) 는 paragraph margin_left 를 이미
포함한 값이지만, 이후 layout_composed_paragraph 가 col_area.x 에 다시
margin_left 를 추가하여 결과적으로 margin_left 가 이중 적용됨.

수정: wrap_area 의 x 를 host paragraph 의 margin_left 만큼 좌측으로
보정하고 width 도 그만큼 확장 (margin_right 포함). 이렇게 하면 후속
margin_left 추가가 wrap_cs 를 이미 보정한 값에 적용되어 정상 위치 산출.

inner_pad 는 stroke 가 있을 때 paragraph border 안쪽 여백이므로
wrap_cs 와 무관 — 보정 대상 아님 (이중 보정 시 wrap host 가 오히려
margin_left 만큼 좌측으로 튀어나옴, 첫 시도에서 확인).

검증: pi=33 학생3 wrap host x 좌표 151.17→139.84 (pi=30 학생1 과 일치).
1069 단위테스트 통과, 3종 샘플 회귀 0. 박스 우측 영향 없음.

Refs edwardkim#463
학생3 wrap host paragraph 가 일반 paragraph 보다 margin_left 만큼 더
들여쓰기 되던 문제 해결. wrap_area.x 를 host paragraph margin_left 만큼
좌측 보정 (wrap_cs 가 이미 margin_left 를 포함하므로 layout_composed_
paragraph 의 추가 margin_left 가 이중 적용되던 부작용 차단).
- paragraph_layout.rs 의 3개 ImageNode emit 사이트에 crop / original_size_hu 추출 추가
- exam_kor.hwp 15p 헤더 "국어 영역(A형)" → "국어 영역" 으로 정상 잘림
- HWP 스펙의 picture crop 정보는 picture_footnote.rs::layout_picture 에서만 처리되어
  인라인 TAC 그림 (예: 바탕쪽 셀 그림) 에서는 누락되어 비트맵 전체가 표시됨
- overlap=true 확장 master 가 active master 와 같은 apply_to 인 경우 active 대체
- exam_kor.hwp 16p/20p (sec 마지막 짝수) 좌측 헤더 "2"+"4" 겹침 해소
- 한컴 PDF 출력 동작 (마지막 쪽 전용 헤더로 대체) 과 일치
Task edwardkim#463 Stage 2 의 cell_ctx.is_none() 게이팅으로 셀 paragraph 의 invisible
border rect 가 본문 큐에서 제거됨. 4개 snapshot golden 이 이전 구조 (셀 paragraph
포함) 로 작성되어 있어 mismatch 발생. 시각 비교 결과 4건 모두 PNG 동일 (table-text 만
1px 폭 anti-aliasing 4/255 차이) 이라 golden 갱신이 적절.

- form-002/page-0.svg
- issue-157/page-1.svg
- issue-267/ktx-toc-page.svg
- table-text/page-0.svg
- para_border_ranges 튜플에 para_index 추가 (9 → 10 필드)
- build_single_column merge 그룹의 첫/마지막 paragraph index 추적
- sequential 인접 paragraph bf_id 검사로 partial_start/partial_end 보정
  - 그룹 첫 paragraph 의 prev paragraph 가 같은 bf_id 면 partial_start
  - 그룹 마지막 paragraph 의 next paragraph 가 같은 bf_id 면 partial_end
- 결과: cross-column / cross-page 박스 연속 시 inner 경계 stroke 미렌더

검증:
- exam_kor.hwp 6p 좌측 단 [18~21] 박스 하단 stroke 미렌더 (PDF 일치)
- exam_kor.hwp 6p 우측 단 박스 상하단 모두 미렌더 (양방향 연속)
- exam_kor.hwp 7p 좌측 단 박스 상단 미렌더 (페이지 경계 연속)
- exam_kor.hwp 14p 단일 박스 정상 닫힘 유지 (Task edwardkim#463 회귀 0)
- cargo test 1069 + svg_snapshot 6 통과
- 5종 샘플 회귀 0
- mydocs/report/task_m100_468_report.md 작성
- mydocs/orders/20260430.md 신설 (edwardkim#468 완료, edwardkim#464/edwardkim#465/edwardkim#466/edwardkim#467 대기)
…ot 경계 침범 수정

closes edwardkim#469

src/renderer/layout.rs paragraph border 그룹 렌더링에서 partial_start/
partial_end 박스가 col_top 위(헤더선) 또는 col_bot 아래(꼬리말선) 까지
침범하던 현상을 차단.

원인: L1740 `rect_y = y_start - top_pad` 가 cross-column 으로 이어진
partial 박스의 후속 부분에도 적용되어, y_start 가 col_top 으로 클램프된
이후 top_pad (border_spacing.top) 만큼 다시 위로 확장. exam_kor p2
우측 단 (나) 박스 좌·우 세로선이 헤더 가로선(y=196.55) 과 맞닿음.

수정: `effective_top_pad`/`effective_bot_pad` 도입.
- is_partial_start → effective_top_pad = 0
- is_partial_end   → effective_bot_pad = 0
이전/다음 컬럼에서 이미 inset 처리된 후속 부분은 col_top/col_bot 경계
안쪽에서만 그려지도록 한다.

검증:
- 신규 통합 테스트 test_469_partial_start_box_does_not_cross_col_top
- exam_kor p2 우측 단 (나) 박스 세로선 y1: 196.55 → 211.65 ✓
- 좌측 단 (가) 박스 영향 없음 (y1 = 242.41 유지)
- cargo test 1121 + svg_snapshot 6 모두 통과
edwardkim added a commit that referenced this pull request Apr 29, 2026
- mydocs/pr/pr_454_review.md (Task #452 cherry-pick 검토, 광범위 영향 87% 정황)

검증: 1069 passed + svg_snapshot 6/6 (golden 2건 갱신) + issue_418 1/1 + clippy 0
광범위 byte 비교: 305 중 266 차이 (87% 영향, paragraph_layout 변경)
시각 판정: 후속 PR (#457, #461) 처리 후 통합 검증 (작업지시자 결정)
본질: paragraph_layout::is_para_last_line 분기 제거 (셀 마지막 줄만 trailing 제외 보존)
closes edwardkim#470

Task edwardkim#321 cross-paragraph vpos-reset 가드가 `cv == 0` (정확히 0) 만 인정해
컬럼 헤더 오프셋 (cv=9014 등) 으로 시작하는 다단의 새 컬럼 reset 을 놓침.
21_언어_기출_편집가능본 1p 의 pi=10 ("적합성 검증이란…") 이 col 0 에 강제
삽입되어 56.2px overflow 발생.

수정: typeset.rs:415, 439 에 다단/단일 단 분기.
- 다단(col_count > 1): cv < pv && pv > 5000 (Task edwardkim#470, 컬럼 헤더 오프셋 인정)
- 단일 단:           cv == 0 && pv > 5000 (Task edwardkim#321 보수적 기준 유지,
                     hwpspec partial-table split 회귀 차단 / issue_418)

검증:
- 신규 통합 테스트 test_470_cross_paragraph_vpos_reset_with_column_header_offset
- 다단 샘플 OVERFLOW 11건 추가 해소
  21_언어_기출 13→10, exam_science 5→0, exam_social 4→1
- hwpspec(단일 단) OVERFLOW 45→45, issue_418 PASS (회귀 0)
- cargo test 1122 / 1122 PASS
edwardkim added a commit that referenced this pull request Apr 29, 2026
- mydocs/pr/pr_457_review.md (Task #455 cherry-pick 검토, 영향 범위 한정 4.3%)

검증: 1069 passed + svg_snapshot 6/6 + issue_418 1/1 + clippy 0
광범위 byte 비교: 305 중 13 차이 (4.3% 영향, exam_* 11 + synam-001 1 + k-water-rfp 1)
시각 판정: PR #461 처리 후 통합 검증 (작업지시자 결정)
본질: paragraph_layout::skip_text_for_inline_shape 가드 제거
edwardkim added a commit that referenced this pull request Apr 29, 2026
- mydocs/pr/pr_461_review.md (5 Tasks 분리 cherry-pick 검토, 광범위 영향 86% 정황)

검증: 1070 passed + svg_snapshot 6/6 (golden 4건 갱신) + issue_418 1/1 + clippy 0
광범위 byte 비교: 305 중 263 차이 (86% 영향, Task #463 깊은 누적 정정)
시각 판정: PR #454 + #457 + #461 통합 검증 (작업지시자 결정)

본질 5 Tasks:
- Task #459: 다단 후속 페이지 vpos-reset (PR #450 잔여 본질)
- Task #462: TAC Picture 인라인 line advance
- Task #463: 셀 leakage + 박스 geometry + 들여쓰기 + TAC crop + 바탕쪽 (Stage 1~8)
- Task #468: cross-column 박스 partial 플래그
- Task #469: cross-column partial 박스 col_top/col_bot 침범
edwardkim added a commit that referenced this pull request Apr 29, 2026
@edwardkim

Copy link
Copy Markdown
Owner

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

본 사이클 16번째 PR 입니다. PR 제목은 Task #459 만 명시되었으나 실제로는 5 Tasks 누적 (Task #459 + #462 + #463 + #468 + #469). 작업지시자 결정 (옵션 A) 으로 5 Tasks 모두 분리 cherry-pick 진행했습니다.

처리 — 15 commits 분리 cherry-pick

작성자 attribution 보존:

Task commits 본질
#459 829cb0b 다단 후속 페이지 LINE_SEG vpos-reset (PR #450 의 잔여 본질)
#462 427db1f TAC Picture 인라인 line advance
#463 2a074be~48fcf13 (10 commits) 셀 leakage + 박스 geometry + 들여쓰기 + TAC crop + 바탕쪽 (Stage 1~8)
#468 154b4e8, 5598fc1 cross-column 박스 partial 플래그
#469 ca31fb7 cross-column partial 박스 col_top/col_bot 침범

devel 머지 commit: bbea0c1

검증

광범위 byte 비교

10 샘플 / 305 페이지 SVG: 42 동일, 263 차이 (86% 영향).

차이 분포: kps-ai 66, aift 61, exam_* 45, synam-001 33, 2025년 기부 30, k-water-rfp 23, biz_plan 5.

→ Task #463 의 본문 외곽선 / 박스 geometry / wrap host 들여쓰기 / 바탕쪽 정정이 매우 광범위 영향.

통합 시각 검증 정책

PR #454 + #457 + #461 (3 PR / 7 Tasks) 모두 머지 후 작업지시자가 통합 시각 검증 진행 예정. 누적 정정 (paragraph_layout 통일 + 글상자 외부 본문 + 다단 vpos-reset + TAC line advance + 셀 leakage + 박스 geometry + 들여쓰기 + 바탕쪽 + cross-column) 모두 적용된 상태에서 한컴 정답지 비교가 작업 효율 + 위험 분산 양쪽에 부합.

후속 PR 작성 권장 사항

본 사이클 누적 정황을 보고 향후 PR 작성 시 권장:

  1. 자기 fork base 정기 rebase: origin/devel (cherry-pick 후) 로 rebase 하면 다음 PR 의 commits 누적 부담 감소 (현재 PR Task #459: 다단 후속 페이지 LINE_SEG vpos-reset 단 경계 미인식 수정 #461 의 53 commits 중 38 이 다른 PR 누적)
  2. PR 제목 ↔ 실제 commits 정합: 다중 Task 누적 시 PR 본문에 모든 Tasks 명시 권장 (현재는 Task 다단 후속 페이지에서 LINE_SEG vpos-reset 단 경계 미인식 #459 만 본문에 검증 자료, 나머지 4 Tasks 는 메인테이너 통합 검증 의존)
  3. Task exam_kor 14p: 본문 외곽선이 셀 단락 leakage 로 4개 박스로 쪼개짐 #463 같은 깊은 누적: Stage 별 분리 PR 권장 — 8 stages 가 한 Task 에 묶이면 검증 자료 부담 큼. 향후 비슷한 깊은 누적 정정 시 Stage 13 / Stage 48 두 PR 로 분리 가능

이 권장은 작성자에게 부담 안내가 아닌, 본 사이클 패턴 학습 자료입니다 — @planet6897 님은 이미 본 사이클 16 PR 처리하신 신뢰 컨트리뷰터로 패턴 인지 + 향후 PR 효율성 향상 가능.

이슈 #459 + Task #462/#463/#468/#469 모두 close 됩니다. 5 Tasks 의 본질 누적 정정 + PR #450 의 잔여 본질 (respect_vpos_reset) 직접 처리 모두 좋습니다. 감사합니다.

@edwardkim edwardkim closed this Apr 29, 2026
@planet6897 planet6897 deleted the local/devel branch April 30, 2026 00:02
edwardkim added a commit that referenced this pull request Apr 30, 2026
- mydocs/pr/pr_456_review.md (P2 cherry-pick 검토, SVG 100% byte 동일)

검증: 1075 passed (+5 Canvas parity test) + svg_snapshot 6/6 + issue_418 1/1 + clippy 0
WASM: 4,206,022 bytes (+19,741, paint 모듈 Canvas replay 추가)
광범위 byte 비교: 305/305 byte 동일 (SVG legacy 경로 0 영향) ✅

본질 (PR #419 의 P2):
- Canvas 렌더 경로를 PageLayerTree replay 로 전환
- legacy 경로는 renderPageCanvasLegacy 로 보존 (fallback)
- LayerBuilder leaf children 보존 정정
- Canvas parity test 추가 (CI 통합)

시각 판정: 통합 검증 (PR #454 + #457 + #461 + #456 머지 후 작업지시자 직접)
@planet6897 planet6897 restored the local/devel branch April 30, 2026 00:04
planet6897 added a commit to planet6897/rhwp that referenced this pull request Apr 30, 2026
devel 의 PR edwardkim#461 (Task edwardkim#459+edwardkim#462+edwardkim#463+edwardkim#468+edwardkim#469) 통합본과 local/devel 의
Task edwardkim#469+edwardkim#470+edwardkim#471 작업 충돌 해결.

해결 내용:
- src/renderer/layout.rs: ours (Task edwardkim#471 stroke_sig 비교 채택). devel 의
  bf_id 비교는 Task edwardkim#471 에서 정정한 결함이므로 ours 가 superset.
- src/renderer/layout/integration_tests.rs: ours (Task edwardkim#469/edwardkim#470/edwardkim#471
  통합 테스트 3건 모두 보존). devel 은 edwardkim#469 테스트만 포함.
- mydocs/orders/20260430.md: 양측 섹션 병합 (M100 박스 정합 + 잔존 이슈
  + PR 처리 PR edwardkim#450).

검증:
- cargo test 1072 + svg_snapshot 6 + issue_418 1 + 기타 PASS, FAIL 0.
jangster77 added a commit to jangster77/rhwp that referenced this pull request Apr 30, 2026
…Canvas→LayerTree 반영 (Task edwardkim#460 기반)

- upstream/devel 46 commits 병합 (PR edwardkim#446 set_field fix ~ PR edwardkim#456 Canvas→LayerTree)
- 소스 파일 자동 병합 성공 (layout.rs, paragraph_layout.rs, engine.rs)
- orders/20260430.md add/add 충돌만 수동 해소 (Task edwardkim#460 섹션 + PR edwardkim#450 섹션 통합)

Co-Authored-By: Claude Sonnet 4.6 <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.

2 participants