Task #455: 인라인 글상자(tac=true + TextBox) 가 있는 줄의 외부 본문 텍스트 누락 수정#457
Closed
planet6897 wants to merge 26 commits into
Closed
Task #455: 인라인 글상자(tac=true + TextBox) 가 있는 줄의 외부 본문 텍스트 누락 수정#457planet6897 wants to merge 26 commits into
planet6897 wants to merge 26 commits into
Conversation
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 항목 추가.
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 제외 보존)
7 tasks
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
…pick @planet6897 2 commits)
edwardkim
added a commit
that referenced
this pull request
Apr 29, 2026
Owner
|
@planet6897 님 PR 감사드립니다. 메인테이너가 cherry-pick 으로 devel 에 적용 완료했습니다. 본 사이클 15번째 PR 입니다. PR #454 (Task #452) 머지 직후 Task #455 본질 2 commits 분리 처리. 처리작성자 attribution 보존 본질 2 commits 분리 cherry-pick:
devel 머지 commit: 검증
광범위 byte 비교10 샘플 / 305 페이지 SVG 비교: 292 동일, 13 차이 (4.3% 영향). 차이 분포: exam_* 11, synam-001 1, k-water-rfp 1. → PR #454 의 광범위 영향 (87%) 과 대조적 — Task #455 는 매우 정밀 정합 (특정 결함 영역만). 작성자 PR 본문 명시 (exam_kor 페이지 2 좌측 단 pi=33 line 2 본문 39자 복원) 와 정합. 시각 판정 정책본 PR 단독 시각 판정 보류 (PR #454 와 동일 정책). 후속 PR (#461 5 Tasks) 처리 후 통합 시각 검증 진행. 본 PR 의 좋은 점
이슈 #455 도 함께 close 됩니다. 다음 PR (#461 Task #459 + 4 Tasks) 처리도 같은 사이클로 이어가겠습니다. 감사합니다. |
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 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 머지 후 작업지시자 직접)
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
samples/exam_kor.hwp페이지 2 좌측 단의 문단 pi=33 line 2 에서 본문 39자가 누락되고 인라인 글상자 내부 "개화" 두 글자만 표시되던 버그 수정paragraph_layout.rs의skip_text_for_inline_shape분기 제거 — 글상자 내부 텍스트와 외부 문단 본문을 혼동해 외부 본문까지 통째로 스킵하던 로직shape_layout의inline_shape_position경로로 별도 렌더되므로 외부 본문을 항상 렌더해도 중복 없음증상 (수정 전 → 후)
수정 전 (좌측 단):
수정 후:
Root Cause
paragraph_layout.rs::layout_composed_paragraph의 tac 분기 처리 블록에서:여기서 스킵된 "텍스트" 는 글상자의 외부 문단 본문 이지 내부 ("개화") 가 아니다. 외부 본문은 글상자 좌·우를 흐르는 일반 텍스트이며 항상 렌더되어야 한다.
Fix
skip_text_for_inline_shape변수 + 두 곳의 가드 제거if !skip_text_for_inline_shape { ... }를 단순 블록{ ... }로 변경 (변수 스코프 보존)Test Plan
cargo build --release— 빌드 성공cargo test --release— 1117 passed, 1 ignored, 0 failedrhwp export-svg samples/exam_kor.hwp— 20 페이지, 좌측 단 pi=33 line 2 의 39자 정상 렌더 확인exam_kor.hwp20exam_eng.hwp82010-01-06.hwp6exam_math_8.hwp1biz_plan.hwp6draw-group.hwp1atop-equation-01.hwp1equation-lim.hwp1Known Minor Issue
본문 글자 baseline y=322.6, 글상자 내부 "개화" baseline y=321.4 — 1.2px 차이. 줄 높이가 5mm 글상자에 맞춰 1417 HU 로 늘어난 상황에서 baseline 정렬을 본문 폰트 기준으로 재계산하지 않아 생기는 미세 어긋남. 시각상 큰 문제는 아니나 별도 이슈로 분리 가능.
Files Changed
src/renderer/layout/paragraph_layout.rsmydocs/plans/task_m100_455.mdmydocs/plans/task_m100_455_impl.mdmydocs/working/task_m100_455_stage{1,2,3}.mdmydocs/report/task_m100_455_report.mdmydocs/report/task_m100_455_pr.mdmydocs/orders/20260429.mdCloses #455.