Fix #412: 다단 우측 단 단행 문단 줄간격 누락 (vpos 보정 anchor 도입)#414
Closed
planet6897 wants to merge 76 commits into
Closed
Conversation
증상: 모든 페이지가 page_num=1로 고정. 원인: typeset.rs/engine.rs 의 finalize_pages 가 NewNumber 컨트롤을 'nn_pi <= first_para' 조건으로 매 페이지마다 재적용. 수정: - PageNumberAssigner 신설 (consumed set + 단조 카운터) - "처음 등장" 판정: PartialParagraph(start_line==0), PartialTable(!is_continuation), 그 외 항상 인정 - typeset.rs / pagination/engine.rs 양쪽이 동일 함수 사용 검증: - 회귀 테스트 2건 통과 (기본 / RHWP_USE_PAGINATOR=1) - 단위 테스트 6건 통과 - 전체 cargo test 1006+49 회귀 0 - PDF 페이지 5/10/20/30 푸터와 정확 일치 - exam_kor/exam_math/21_언어 spot check 회귀 0 closes edwardkim#353
CI 환경에 'samples/2022년 국립국어원 업무계획.hwp' 가 없을 때 panic 대신 정상 skip 하도록 수정 (read 실패 시 eprintln 후 return).
PR edwardkim#366 (@planet6897) 의 코드 변경은 체리픽으로 흡수했으나, plans/working/report 문서는 Task edwardkim#361 (이미 v0.7.7 에 적용) 의 문서로 이미 대체되어 중복. M05x 섹션 (orders) 도 Task edwardkim#361 처리 항목과 중복되므로 정리. - 코드 흡수: PageNumberAssigner 모듈 + Paginator 경로 정정 + 회귀 테스트 (commit 6cd97f0, fa10ead) - 문서 제거: task_m05x_353 plans/working/report (Task edwardkim#361 문서로 대체) - orders: M05x 섹션 정리 (Task edwardkim#361 의 edwardkim#361 항목과 통합) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#366 의 결함이 이미 v0.7.7 의 Task edwardkim#361 로 정정되어 있어, PR 의 다음 가치를 체리픽 방식으로 흡수: - PageNumberAssigner 모듈 (TypesetEngine + Paginator 통합) - Paginator 경로의 동일 정정 - 회귀 테스트 (tests/page_number_propagation.rs 2건 + 단위 6건) 검증: 1014 lib passed, 6 svg_snapshot, 2 회귀 + 6 단위 테스트 통과, 샘플 페이지 수 + LAYOUT_OVERFLOW 무변화 (Task edwardkim#361 효과 유지). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#366 의 코드 가치 (PageNumberAssigner 모듈 + Paginator 정정 + 회귀 테스트) 체리픽 방식 흡수. 작성자 attribution 보존. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
form-002.hwpx 10쪽 등에서 볼드 지정 한글 문구가 표시되지 않던 문제 해소. SVG 출력은 정상이나, 폴백 체인의 모든 한글 세리프 패밀리가 표준 리눅스 환경에 미설치되어 generic serif → 자동 한글 폴백 경로로 떨어지면서 일부 렌더러에서 bold variant 매칭 실패. 시스템에 설치된 Noto Serif CJK KR(Bold 포함)을 체인에 추가. - generic_fallback 의 한글/영문 세리프 분기 두 곳에 'Noto Serif CJK KR' 추가 - test_generic_fallback 기대 문자열 갱신 - 골든 스냅샷 3건 갱신 (폰트 체인 문자열 변경분만) closes edwardkim#370
v1(Noto Serif CJK KR 추가) 후 macOS Chrome 환경에서 여전히 볼드 미표시. 원인: 폴백 체인이 AppleMyungjo(macOS 기본 설치, Regular only)에서 매칭 종료되어 뒤에 있는 Noto Serif CJK KR에 도달하지 못함. Chrome on macOS는 CJK 글리프에 대해 font-weight 합성을 잘 수행하지 않음. Nanum Myeongjo (macOS 10.9+ 기본 설치, Bold variant 보유)를 AppleMyungjo 앞에 삽입하여 macOS에서 진짜 Bold 매칭 성공. - generic_fallback 한글/영문 세리프 분기 두 곳에 'Nanum Myeongjo' 추가 - test_generic_fallback 기대 문자열 갱신 - 골든 스냅샷 3건 갱신 refs edwardkim#370
PR edwardkim#371 (Task edwardkim#370): 한글 세리프 폴백 체인에 Nanum Myeongjo + Noto Serif CJK KR 추가. form-002.hwpx 10쪽 한글 볼드 미표시 정정. 처리 방식: 정상 머지 (cherry-pick 으로 작성자 attribution 보존). 검증: 1014 lib + 6 svg_snapshot + 2 page_number 통과, 모든 샘플 회귀 0, form-002 폰트 체인 정상 적용 확인. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#371 (@planet6897) 처리 완료 보고서. cherry-pick 머지로 작성자 attribution 보존. 1014 lib + 6 svg_snapshot 통과, 모든 샘플 회귀 0, form-002 SVG 폰트 체인 적용 확인. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
generic_fallback 의 한글/영문 세리프 분기에 Nanum Myeongjo + Noto Serif CJK KR 추가. form-002.hwpx 10쪽 한글 볼드 미표시 정정. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HWPX의 charPr.shadeColor 가 IR/TextRunStyle.shade_color 까지 정상 보존됨에도 SVG 렌더러의 draw_text 가 해당 필드를 사용하지 않아 형광펜 배경이 출력되지 않는 문제를 수정한다. web_canvas.rs:1271-1279 와 동일 로직(텍스트 폭 × 1.2 배 폰트 크기 영역에 <rect> 출력)으로 통일. samples/hwpx/hwpx-h-02.pdf 9쪽의 12개 강조 구문(거주자, 외국법인, 증권을 취득 등) 민트색(#CDF2E4) 배경이 SVG 출력에 정상 표시됨을 확인. closes edwardkim#372
PR edwardkim#373 (Task edwardkim#372): SVG 렌더러 형광펜 배경(charPr.shadeColor) 누락 정정. svg.rs::draw_text 에 <rect> 배경 출력 추가 (html / web_canvas 동일 패턴 이식). 검증: cargo test --lib 1014 passed, svg_snapshot 6/6, hwpx-h-02 9쪽 형광펜 rect 9건 정상 출력, 7 핵심 샘플 회귀 0. orders 갱신 (edwardkim#372 항목 추가). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
svg.rs::draw_text 에 charPr.shadeColor 기반 <rect> 배경 출력 추가. html.rs / web_canvas.rs 와 동일 패턴 이식. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#360 (Task edwardkim#356) 의 검증용 PDF (컨트리뷰터 환경, 37쪽) 와 작업지시자의 한컴 프로그램 출력 PDF (35쪽) 의 페이지네이션 차이 발견. 한컴 자체의 환경 의존성 가능성을 시사하는 발견으로 검증 자료 보존: - saved/pr360-edward.hwp: 동일 HWP 파일 (md5 일치) - saved/pr360-edward.pdf: 작업지시자 한컴 출력 (35쪽) PR edwardkim#360 의 PDF (samples/2022년 국립국어원 업무계획.pdf, 37쪽) 와 비교 가능. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PDF 와 함께 한컴 입력 HWP 도 검증 자료로 보존. .gitignore 의 /saved/*.hwp 패턴에 예외 추가. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#374 (Task edwardkim#362): kps-ai p56 외부 표 안 콘텐츠 클립 회귀 정정 PR. 본 결함은 메인테이너 Task edwardkim#362 (8 항목 누적: vpos 가드, PartialTable nested 분할, Square wrap 어울림, hide_empty_line 등) 로 v0.7.7 에 정정 완료. 이슈 edwardkim#362 도 CLOSED. PR edwardkim#374 의 vpos clamp 접근 (`vpos.min(remaining_room)`) 은 측정 의존 일반화 시멘틱으로 메인테이너의 nested 가드 (`has_nested_table` 분기) 보다 회귀 위험. 흡수 가치 없음 → close. PR edwardkim#360 검토 문서도 함께 commit (회신 대기 중). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#360 정황에서 발견: 동일 HWP 의 한컴 PDF 페이지 수가 환경별로 다름 (컨트리뷰터 37쪽 vs 작업지시자 35쪽). 페이지 분할 자체가 환경 의존적. 결정: PDF 가 정답지로서 신뢰성이 입증되기 전까지 검증 기준으로 수용 불가. 변경: - CONTRIBUTING.md: PR 검증의 PDF 한계 + 신뢰 기준 명시 - mydocs/troubleshootings/hancom_pdf_environment_dependency.md: 트러블슈팅 - mydocs/feedback/issue_253_environment_dependency_review.md: 영향 분석 연계 조치: - 이슈 edwardkim#253 (한컴 PDF Visual Diff 파이프라인) close - 메모리 등록: feedback_pdf_not_authoritative.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#360 (close) 처리 과정에서 수집한 한컴 PDF 환경 의존성 검증 자료. samples/: - 2022년 국립국어원 업무계획.hwp: PR edwardkim#360 의 핵심 결함 재현 샘플 (md5 일치 확인) - 2022년 국립국어원 업무계획.pdf: 컨트리뷰터 macOS 한글 Viewer 출력 (37쪽) - 2022년 국립국어원 업무계획.txt: 보조 자료 saved/: - pr360-planet-win-hancom2022.pdf: 컨트리뷰터 윈도우 한컴2022 편집기 출력 (35쪽) - 작업지시자 출력 (saved/pr360-edward.pdf, 35쪽) 과 페이지 수 일치 - Windows 한컴 편집기의 일관성 입증 자료 PR edwardkim#360 의 검증 정황은 Wiki 페이지 "한컴 PDF 환경 의존성" 에 정리됨. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR edwardkim#385 (Task edwardkim#363): DocumentCore::build_page_render_tree + get_bin_data public API + Serialize derive. native bridge (alhangeul-macos) use case 지원. cherry-pick 으로 작성자 attribution 보존 (4 commit). orders 수동 통합. 검증: 1014 → 1016 passed (+2 신규 테스트), svg_snapshot 6/6, clippy / wasm32 check 통과. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…postmelee) DocumentCore 에 build_page_render_tree + get_bin_data public API 추가. Serialize derive 로 native bridge JSON 직렬화 지원. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 수행계획서 task_m100_391.md, 구현계획서 task_m100_391_impl.md 추가 - exam_eng.hwp baseline 측정: 11페이지 (기대 8), 단독 1-item 단 3곳 발생 - tests/exam_eng_multicolumn.rs 추가: page_count == 8 단일 검증 - Red 확인: 11 != 8 panic closes 단계 1, 다음: 단계 2 (typeset.rs vpos-reset 가드 is_last_column 조건 추가)
- src/renderer/typeset.rs:805,815 누적 공식을 col_count 로 분기 * 단단 (col_count == 1): fmt.total_height (k-water-rfp p3 edwardkim#359 보존) * 다단 (col_count > 1): fmt.height_for_fit (exam_eng 8p 복원) - next_will_vpos_reset 가드는 유지 (단단 edwardkim#359 효과 + 다단 safety_margin 보조) 검증: - cargo test --lib: 1014 passed - cargo test --test exam_eng_multicolumn: 1/1 Red → Green - cargo test --test svg_snapshot / issue_301: 통과 - cargo clippy --lib -- -D warnings: 통과 회귀: - exam_eng: 11 → 8p (목표) - k-water-rfp: 27p, overflow 0 유지 (edwardkim#359 보존) - kps-ai/aift (1단): 무변화 - exam_kor: pre-edwardkim#359 상태 (24p, overflow 30) 로 복원, 잔존 overflow 는 별개 이슈
- cargo test 1014 lib + 모든 통합 테스트 통과 - 11 샘플 회귀 비교 표 (pre-edwardkim#359 / current devel / my fix 3 상태) - exam_eng 8p 단독 단 패턴 해소 확인 - SVG 출력 (output/svg/task391/{exam_eng,k-water-rfp,exam_kor}/) — 작업지시자 시각 판정 자료
- 최종 보고서 mydocs/report/task_m100_391_report.md 작성 - CHANGELOG.md [Unreleased] 항목 추가 - mydocs/orders/20260427.md edwardkim#391 완료 항목 추가 - WASM 빌드 통과 (rhwp_bg.wasm 3.9MB, rhwp.js 222KB) closes edwardkim#391
…et6897) PR edwardkim#392 (Task edwardkim#391): 다단 섹션 누적 공식 회귀 정정. Task edwardkim#359 정정 후속의 exam_eng 11p → 8p 회귀를 col_count > 1 구조 분기로 정정. cherry-pick 으로 작성자 attribution 보존 (4 commit). 작업지시자 시각 판정 통과. 검증: 1016 passed, svg_snapshot 6/6, exam_eng_multicolumn 1/1, 단단 샘플 모두 무변화 (edwardkim#359/edwardkim#361/edwardkim#362 효과 보존). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Task edwardkim#359 정정 후속의 exam_eng 8→11p 회귀를 col_count > 1 분기로 정정. 단단 (k-water-rfp) 효과 보존 + 다단 (exam_eng) 정상 단 채움 복원. 작업지시자 시각 판정 통과. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
closes edwardkim#402 검증 결과: - 7쪽: 표 + 파이 차트 겹침 해소 (PDF 일치) - 8쪽: 파이 차트 정상 배치 - cargo test 1023 passed, 0 failed - 10개 대표 샘플 LAYOUT_OVERFLOW 카운트 회귀 없음 - 페이지 수 27→30 (분할로 인한 정상 증가)
기존 task_404.md(영문 줄바꿈 역공학 미실행 초안)는 archives로 이동. 신규 task_404 = orphan heading vpos 기반 분할 추가.
TypesetState.page_first_vpos 필드 추가 + typeset_section 메인 루프에 진단 로그 삽입. 타겟 샘플 분석 결과: - pi=83 가설 확정: vpos overflow=886 HU, curr_h=906.6/avail=933.5 (cumulative fit) + next pi=84 표 190.9px fit 불가 → orphan - False positive 41건 중 40건은 wrap-around 페이지에서 vpos↔px 비율 어긋남 (페이지 8 pi=57 TAC 그림 + 빈 문단 19개) Stage 2 전략 재정의: heading-orphan 패턴 (current fit + next block 못 fit + vpos overflow + single column) 4조건 모두 만족 시 push. 단순 vpos overflow check은 다수 회귀 위험.
typeset_section 메인 루프에 vpos 기반 보정 추가. 5개 조건 AND (current fits + vpos overflow + next substantial + next doesn't fit + single column non-wrap) 으로 false positive 차단. 설계 변경: page_top_vpos 는 TypesetState 필드 대신 current_items 첫 item 의 para_index 로 즉시 계산 (typeset_paragraph 내부 페이지 flush 와 동기 안 되는 문제 회피). 검증: - pi=83 heading 이 페이지 9 → 페이지 10 으로 이동 (pi=84/85 표와 함께 배치) - 1073개 테스트 모두 통과 - 10개 샘플 LAYOUT_OVERFLOW: 회귀 없음 + 타겟 -15, kps-ai -1 개선
SVG 시각 검증으로 pi=83 "(7) 다수 기부자 현황" 이 페이지 10 첫 본문 라인으로 이동하고 후속 표 pi=84/85 와 함께 배치됨을 확인. 검증 기준 충족: 1. 페이지 9 SVG 에 pi=83 heading 미표시 2. 페이지 10 SVG 가 pi=83 + pi=84/85 표 함께 표시 3. 회귀 테스트 1073개 모두 통과 4. 10개 샘플 LAYOUT_OVERFLOW 회귀 없음 + 2개 샘플 개선 closes edwardkim#404
21페이지 2x1 표가 차트 아래로 ~400px 밀려나는 결함 분석. TopAndBottom Picture(vert=Para) 다음 문단의 vpos 보정에서 lazy_base 산출 시 차트 높이가 이중 반영되는 문제 진단. prev_has_overlay_shape 가드를 Control::Picture (non-TAC) + TopAndBottom/vert=Para 케이스로 확장하는 3단계 계획 수립.
차트 그림(pi=172, 170×111mm, TopAndBottom, vert=Para) 다음 문단의 vpos 보정에서 lazy_base가 차트 높이(31470 HU)만큼 낮게 산출되어 pi=174 (2x1 표) 가 y=948 → 표 자체 높이 합산 후 1049.7 로 밀려나 LAYOUT_OVERFLOW 21.8px 발생. 후속 17개 빈 문단(pi=175~191)도 연쇄 overflow + pi=192 (10x5 표) overflow 521.7px. 베이스라인: 1023 lib + 6 svg_snapshot 통과, LAYOUT_OVERFLOW 19건.
…opAndBottom/vert=Para) 기존 가드는 Control::Shape + InFrontOfText|BehindText 만 검사하여 Picture (그림) 컨트롤과 TopAndBottom 케이스를 처리하지 못함. Picture (non-TAC) 분기 추가 + TopAndBottom + vert_rel_to=Para 케이스 포함하도록 확장. 한컴이 후속 문단 vpos에 개체 높이를 반영하는 경우 sequential y_offset 이 이미 개체 바닥까지 진행된 상태에서 lazy_base 산출 시 prev_pi 텍스트 vpos_end 만 쓰면 차트 높이만큼 이중 점프 발생. 21페이지 LAYOUT_OVERFLOW 19건 -> 1건 (잔여는 별개 페이지네이션 결함). 2x1 표가 차트 바로 아래로 정상 위치 (PDF 21페이지와 일치). 1023 lib + 6 svg_snapshot 통과, 6개 샘플 무회귀.
cargo test --release 전체 10개 스위트 100% 통과 (1023 lib + 6 svg_snapshot + 통합 테스트, 실패 0). 10개 샘플 LAYOUT_OVERFLOW 비교: 6개 샘플 무회귀, 타겟 샘플 22→4 (-18) 개선. closes edwardkim#409
Task edwardkim#409 — prev_has_overlay_shape 가드를 Control::Picture (non-TAC) + TopAndBottom/vert=Para 케이스로 확장하여 차트 다음 문단/표가 차트 높이만큼 추가 점프하는 결함 해결. LAYOUT_OVERFLOW: 19 -> 1 (21페이지), 22 -> 4 (전체 문서). 1023 lib + 6 svg_snapshot + 통합 테스트 100% 통과. 6개 다른 샘플 무회귀.
prev_has_overlay_shape 가드를 Control::Picture (non-TAC) + TopAndBottom/vert=Para 케이스로 확장. LAYOUT_OVERFLOW: 22 -> 4, 21페이지 19 -> 1. 1023 lib + 6 svg_snapshot + 통합 테스트 100% 통과.
이슈 edwardkim#409 재오픈. v1 (layout 측 수정) 후 잔여: pi=191 헤딩 + pi=192 (10x5 표) 가 21페이지에 묶여 22페이지 SVG 에서 누락되는 결함. 근본 원인: typeset.rs::typeset_section 의 controls 루프가 비-TAC Picture/Shape 의 높이를 current_height 에 누적하지 않아 chart (419.6px) 가 페이지네이션에 미반영. Pagination 추정 used=803.3px (실제 layout y=1275.9px) → 모두 21페이지 packing. Stage 4: 컨트롤 루프 분기 확장 (TopAndBottom + vert=Para). Stage 5: 회귀 검증 + 통합 최종 보고서.
typeset.rs::typeset_section 의 controls 루프에 비-TAC + TopAndBottom + vert=Para 인 Picture/Shape 의 height + margin.bottom 을 current_height 에 누적하는 분기 추가. layout 의 calc_shape_bottom_y 와 동일한 산식. 22페이지에 (4) 헤딩 + 10x5 표 + 연령대별 차트 + 2x1 표가 PDF 와 동일하게 정상 출력. chart 관련 LAYOUT_OVERFLOW 전건 해소 (대상 샘플 4 -> 1, 잔여 1건은 본 변경과 무관한 기존 결함). 1023 lib + 6 svg_snapshot 통과, 6개 다른 샘플 무회귀.
전체 cargo test --release 11개 스위트 100% 통과 (실패 0). 6개 다른 샘플 LAYOUT_OVERFLOW 무회귀. 타겟 샘플 22 -> 1 (chart 관련 전건 해소). PR 초안을 v1 (layout) + v2 (pagination) 통합본으로 갱신. closes edwardkim#409
typeset.rs::typeset_section controls 루프에 비-TAC + TopAndBottom + vert=Para Picture/Shape 의 height + margin.bottom 을 current_height 에 누적. 22페이지 (4) 헤딩 + 10x5 표 정상 표시. LAYOUT_OVERFLOW (대상 샘플): v1 4 -> v2 1 (chart 관련 전건 해소). 1023 lib + 6 svg_snapshot + 9개 통합 = 11개 스위트 100% 통과. 6개 다른 샘플 무회귀.
typeset.rs::typeset_section 의 비-TAC TopAndBottom + vert=Para Picture/Shape 높이를 current_height 에 누적. 22페이지에 (4) 헤딩 + 10x5 표 정상 출력 (PDF 일치). 대상 샘플 LAYOUT_OVERFLOW 22 -> 4 (v1) -> 1 (v2). 11개 테스트 스위트 100% 통과, 6개 다른 샘플 무회귀. closes edwardkim#409
23페이지 차트(pi=208, TAC Picture, lh=23700 HU)가 SVG에서 24페이지로 밀리는 결함. 차트 시작 y=721.37 (vpos 1460593 -> +626.87px) 가 본문 안이지만 끝 1037.37 이 본문 1028 보다 9.37px 초과. PDF/HWP는 atomic (분할 불가 단일-line TAC) 항목에 대해 top-fit 시멘틱 사용 — 시작점이 본문 안이면 현재 페이지 배치 하고 하단 일부는 하단 여백(15mm)으로 흘림 허용. 우리는 strict bottom-fit 으로 판정 -> split -> 1-line 못 쪼갬 -> next page. Stage 6: typeset_paragraph 의 fit 분기에 atomic TAC top-fit 추가 Stage 7: 회귀 검증 + 통합 최종 보고서 v3
typeset_paragraph 의 fit 분기에 atomic TAC top-fit 추가. 단일 라인 + TAC Picture/Shape 항목은 시작점이 본문 안이고 끝이 60px (약 1.6cm) 이내 초과면 현재 페이지에 배치. HWP 의 atomic 항목 top-fit 시멘틱 (시작점이 본문 안이면 배치하고 하단 일부는 하단 여백으로 흘림 허용) 을 구현. 23페이지 차트(pi=208, lh=316px) 가 PDF 와 동일하게 표 아래에 정상 배치. 24페이지는 차트가 빠지고 정상 후속 콘텐츠로 시작. 대상 샘플 LAYOUT_OVERFLOW 동일 1건 유지 (chart 정상 배치 이므로 overflow 미발생). 6개 다른 샘플 무회귀. 1023 lib + 6 svg_snapshot 통과.
cargo test --release 11개 스위트 100% 통과 (실패 0). 6개 다른 샘플 무회귀. 타겟 샘플 LAYOUT_OVERFLOW: 22 -> 4 -> 1 -> 1 (chart 정상 배치). 21~24페이지 PDF 대조 전건 일치: - 21: 2x1 표 차트 직하 - 22: (4) 헤딩 + 10x5 표 - 23: 막대 차트 하단 - 24: 2x1 표 -> (6) 헤딩 -> 파이차트 closes edwardkim#409
typeset.rs::typeset_paragraph 의 fit 분기에 atomic TAC top-fit 추가. 단일 라인 + TAC Picture/Shape 항목은 시작점이 본문 안이고 끝이 60px 이내 초과면 현재 페이지에 배치 (HWP 시멘틱). 23페이지 차트(pi=208) 가 표 아래 정상 배치, 24페이지가 2x1 표 -> (6) 헤딩 -> 파이차트로 정상 시작 (PDF 일치). 11개 테스트 스위트 100% 통과, 6개 다른 샘플 무회귀.
23페이지 차트 정상 배치 + 24페이지 정상 콘텐츠 시작 (PDF 일치). 21~24 페이지 PDF 대조 전건 일치. closes edwardkim#409
- 수행 계획서, 구현 계획서, Stage 1 보고서 작성 - layout.rs:1422 분기에 RHWP_VPOS_DEBUG 진단 로그 추가 (env-gated) - 6개 샘플 page/lazy × applied/skip 분포 측정 - page_false 케이스를 4개 카테고리로 분류: A) 다단 우측 단 base≈7000 (target, 28건) ← fix 대상 B) vpos reset base≥60000 (합법 스킵, 20건) ← fix 후도 SKIP 유지 C) base=0 미세 drift (17건) ← 영향 없음 D) lazy_false 미세 drift ← 영향 없음 closes part of edwardkim#412 (Stage 1)
…irst_vpos 사용
핵심 변경 (layout.rs):
1. col_anchor_y = body_wide_reserved 푸시 직후 y_offset 캡처
- 첫 PageItem 의 실제 렌더링 y = vpos_page_base 좌표에 해당
- col_area.y 는 일반적으로 vpos=base 와 일치하지 않아 부정확
2. vpos_end 결정에 curr_first_vpos 우선 사용
- HWP 가 spacing_after 를 다음 paragraph first vpos 에 인코딩하므로
prev.vpos+lh+ls 보다 정확
- vpos reset 시에는 prev 기반 fallback
3. page_path / lazy_path 분리:
- page_path: col_anchor_y + (vpos_end - base) * scale
- lazy_path: col_area.y + (vpos_end - base) * scale (기존 유지)
검증 결과 (exam_eng.hwp):
- p1 우측 단 item 7 ①~⑤ 22.55 px 균일 (원래 보고된 버그 해결)
- p1 좌측 단 item 1 ①~⑤ 21.89 px 균일
- p2 우측 단 item 20 ①~⑤ 19.92 px 균일
- p2 우측 단 item 18 ①→② 잔존 (overlay shape bypass — 별도 task)
회귀:
- cargo test 6/6 통과
- golden snapshot: aift-page3 약 3.68 px shift (single ls 적용) — 의도된 개선,
issue edwardkim#147 본래 검증 목적과 무관해 골든 갱신
- issue-157: anchor 도입 후 자동 정상화
closes part of edwardkim#412 (Stage 2)
검증 대상 (7개 샘플 합계 268페이지): - exam_eng (8p), exam_kor (24p), exam_math (20p) - k-water-rfp (28p), 2025년 기부·답례품 (30p) - aift (78p), kps-ai (80p) 검증 결과: - cargo test 6/6 통과 - 단단 문서: 영향 없음 - 다단 문서: page_path 보정 정상화 (exam_kor 12건 false→true) - 시각 회귀 미관찰 (samples 1페이지 시각 비교 7건) 잔존 이슈: - exam_eng p2 item 18 ①→② (overlay shape bypass) → 별도 task 로 추적 권고 closes part of edwardkim#412 (Stage 3)
- mydocs/report/task_m100_412_report.md 작성 - mydocs/orders/20260428.md: edwardkim#412 항목 완료 갱신 closes edwardkim#412
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
layout.rsvpos 보정 공식이col_area.y와vpos_page_base의 좌표 의미를 혼동했던 부분을 정리closes #412
원인
layout.rs:1392-1430의 vpos 보정 공식:col_area.y가 vpos=0 좌표를 의미한다고 가정한 공식이지만,body_wide_reserved(페이지 너비 글상자/표) 푸시가 있는 다단 레이아웃에서 첫 항목은col_area.y가 아닌 푸시 적용 후 위치에서 시작.다단 우측 단처럼
vpos_page_base가 큰 경우, 보정값col_area.y + (vpos_end - base) * scale이 sequentialy_offset보다 항상 작아져 조건 검사를 통과하지 못하고 스킵 → 단행 문단의 trailing line_spacing 이 누락된 채로 렌더.변경 사항
src/renderer/layout.rs:anchor 캡처:
build_single_column진입 시 body_wide_reserved 푸시 직후의y_offset을col_anchor_y로 보존. 첫 PageItem 의 실제 렌더 y =vpos_page_base좌표에 대응.vpos_end 정밀화:
prev_seg.vpos + lh + ls대신 현재 paragraph 의 first seg vpos 를 우선 사용. HWP 가 paragraph spacing_after 를 다음 paragraph 의 first vpos 에 인코딩하므로 더 정확. vpos reset(0) 또는 prev 보다 작아진 경우 prev 기반 fallback.page_path / lazy_path 분리:
col_anchor_y + (vpos_end - base) * scalecol_area.y + (vpos_end - base) * scale(lazy_base 가 sequential y_offset 으로부터 역산되어 col_area.y 기준이 일관)진단 코드 (env-gated):
RHWP_VPOS_DEBUG=1시 보정 분기 동작 추적용 eprintln.검증 결과
원래 보고된 버그 (exam_eng p1 우측 단 item 7)
추가 수정
분포 변화 (exam_eng)
→ 모든 page_path 보정이 정상 발동.
회귀 검증 (7개 샘플 268페이지)
잔존 이슈 (별도 task 권고)
exam_eng p2 우측 단 item 18 ①→② (Δ=15.33, 기대 19.93):
prev_has_overlay_shape+prev_tac_seg_applied두 가드로 차단Test plan
단계별 산출물
mydocs/plans/task_m100_412.mdmydocs/plans/task_m100_412_impl.mdmydocs/working/task_m100_412_stage1.mdmydocs/working/task_m100_412_stage2.mdmydocs/working/task_m100_412_stage3.mdmydocs/report/task_m100_412_report.md