Skip to content

Commit c2024ec

Browse files
committed
Merge PR #1003 (closes #990): Task #990 빈 문단 위 treat-as-char 글상자 advance 이중 가산 정정
@planet6897 — Task #974(c3e3215, PR #1013 머지) 회귀 bisect 정확 진단 + has_full_para_item case-specific 가드. layout_shape_item()의 !has_real_text 분기에서 FullParagraph 항목 유무로 분기: - 있으면(빈 문단 호스트): result_y 재진행 생략 → 이중 가산(132.88→66.44px) 차단 - 없으면(선행 표 이어붙은 Shape, hy-001 pi=27): Task #974 동작 유지 PR #1005 격차 D revert(4e3ad58)의 scope 외("variant flag thread 후 variant-only 분기")를 variant 무관 일반 가드로 정밀 해결 — 두 케이스 양립. feedback_pr_supersede_chain + feedback_hancom_compat_specific_ over_general 권위 사례. 옵션 A: 3 본질 커밋 cherry-pick (d7663dd Stage 2 layout.rs PR #1005 영역 --theirs 충돌 해소, a4a3647 Stage 2 v2 has_full_para_item 정밀화 자동 보완, 97c4994 Stage 3 회귀 테스트 좌표 8건 정정) — 작성자 @planet6897 보존. 검증: cargo test 1307(lib) + 전체 통합 + issue_table_ vpos_01_page5_cell_hit_test 13 passed + clippy -D + fmt 0 + WASM 4.83MB (feedback_push_full_test_required 정합). sweep 10 fixture: hy-001 HWPX/HWP5 diff=0(Task #974 보존), table-vpos-01 1 diff(의도된 pi=34 30.84px 상향), sample16-hwp5/hwp3 외곽선만(텍스트 무변동), aift 2 diff (의도된 빈 문단 글상자 정정 효과), 일반 fixture diff=0. 작업지시자 비공개 샘플 PR로 시각 판정 생략 수용 결정. PR #1004(Task #990 + #991 통합) 가 본 PR 완전 포함 + Task #991 추가 — 본 PR 머지 후 #1004는 #991 부분만 재제출 안내 (feedback_small_batch_ release_strategy 정합).
2 parents b5d3834 + 1e33fb3 commit c2024ec

7 files changed

Lines changed: 423 additions & 60 deletions

File tree

mydocs/orders/20260520.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,37 @@ test --tests 전체 통합 테스트 필수 (`feedback_release_manual_required`
208208
- [x] **`3ed82975`** — tests/issue_826.rs fmt 정정 (사고로 PR #1021 source 흡수)
209209
- 사고 정정 → PR #1021 처리로 KTX golden 정합 → CI 회복
210210
- `feedback_release_manual_required` / `feedback_v076_regression_origin` 강화 사례
211+
212+
---
213+
214+
### PR #1003 — Task #990: 빈 문단 위 treat-as-char 글상자 advance 이중 가산 정정 (외부 기여 @planet6897, closes #990)
215+
216+
- [x] PR 정보 + 사이클 점검 (@planet6897 15+ PR, #1002 CLOSED → #1003 재제출, #1004/#1024 시리즈 OPEN)
217+
- [x] devel 동기화 (`b5d38346`) + 본질 커밋 3개 식별 (Stage 2 + Stage 2 v2 + Stage 3)
218+
- [x] PR #1004와 영역 관계 확인 (#1004#1003 완전 포함 + #991#1003 먼저 머지 권고)
219+
- [x] Task #974 (c3e32151, 본 환경 PR #1013) 회귀 + PR #1005 격차 D scope 외 후속 분석
220+
- [x] 검토 문서 `pr_1003_review.md` → 작업지시자 옵션 A 승인
221+
- [x] cherry-pick 3 순차 (`d7663dd4` Stage 2 — layout.rs PR #1005 영역 충돌 `--theirs`, `a4a3647a` Stage 2 v2 has_full_para_item 정밀화, `97c49944` Stage 3 회귀 테스트 좌표 8건 정정) — 작성자 @planet6897 보존
222+
- [x] 검증 (`feedback_push_full_test_required` 정합): cargo test 1307 (lib) + 전체 통합 테스트 + **issue_table_vpos_01_page5_cell_hit_test 13 passed** + clippy -D + **fmt 0**
223+
- [x] sweep 10 fixture (BEFORE devel ↔ AFTER): hy-001 HWPX/HWP5 **diff=0**(Task #974 보존), table-vpos-01 1 diff(의도된 pi=34 30.84px 상향), sample16-hwp5/hwp3 외곽선만(텍스트 무변동), aift 2 diff(의도된 빈 문단 글상자 정정 효과), 일반 fixture diff=0
224+
- [x] 산출물 `output/poc/pr1003/{before,after}/` 규약 배치
225+
- [x] WASM 빌드 (Docker, 4.83MB) + rhwp-studio 동기화
226+
- [x] **작업지시자 결정 — 비공개 샘플 PR로 시각 판정 생략 수용** (회귀 가드 + sweep + cargo test 정량 입증)
227+
- [x] no-ff merge → devel push
228+
- [x] PR #1003 close + 이슈 #990 close
229+
- [x] 검토/보고서 archives 이동, 임시 브랜치 정리
230+
- [x] PR #1004 안내 (#1003 머지 후 #991 부분만 재제출)
231+
232+
핵심: bisect로 Task #974 `c3e32151` 회귀 정확 진단 + has_full_para_item
233+
case-specific 가드로 PR #1005 격차 D scope 외 후속 정밀 해결
234+
(`feedback_pr_supersede_chain` 권위). 빈 문단 호스트(FullParagraph 있음)는
235+
result_y 재진행 생략, 선행 표 이어붙은 Shape(hy-001 pi=27)는 Task #974
236+
동작 유지 — 두 케이스 양립. 영구 회귀 가드 `issue_table_vpos_01_page5_
237+
cell_hit_test` 13 passed + sweep hy-001 diff=0 입증.
238+
239+
신규 메모리 `feedback_push_full_test_required` (PR #1020 사고 기반) 정합 —
240+
cargo test --tests 전체 + fmt 모두 실행. 작업지시자 비공개 샘플 PR
241+
시각 판정 생략 수용 결정. PR #1004 후속 안내 (`feedback_small_batch_
242+
release_strategy` 정합).
243+
244+
보고서: `mydocs/pr/archives/pr_1003_report.md`
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# PR #1003 처리 보고서 — Task #990: 빈 문단 위 treat-as-char 글상자 advance 이중 가산 정정
2+
3+
- 처리일: 2026-05-20
4+
- 컨트리뷰터: [@planet6897](https://github.com/planet6897) (Jaeuk Ryu)
5+
- 결정: **옵션 A (수용)** — 작업지시자 승인 + **비공개 샘플 기반 PR로 시각 판정 생략 수용**
6+
- 머지: (no-ff, local/devel → devel)
7+
- closes #990
8+
9+
## 1. 결정 사유
10+
11+
@planet6897 15+ PR 핵심 컨트리뷰터. Task #974 (`c3e32151`, 본 환경 PR #1013) 회귀 정정 — bisect 정확 + `has_full_para_item` case-specific 가드 + PR #1005 격차 D scope 외 후속 정밀 해결. 작업지시자 명시 "비공개 샘플로 테스트 한 것으로 시각 판정 없이 수용" — `tests/issue_table_vpos_01_page5_cell_hit_test` 13 passed + sweep 정량 입증.
12+
13+
## 2. 처리 내역 (3 본질 커밋 cherry-pick, 모두 작성자 @planet6897)
14+
15+
| 커밋 (cherry-pick 후) | 내용 |
16+
|------|------|
17+
| `d7663dd4` (Stage 2) | 빈 문단 위 글상자 advance 이중 가산 제거 (v1: y_offset 조건) — layout.rs 충돌 `--theirs` 해소 |
18+
| `a4a3647a` (Stage 2 v2) | `has_full_para_item` 정밀화 (FullParagraph 항목 유무) — 충돌 없음 |
19+
| `97c49944` (Stage 3) | 검증 + table-vpos 회귀 테스트 좌표 8건 정정 — 충돌 없음 |
20+
21+
**충돌 해소**: `src/renderer/layout.rs` 1개 (PR #1005 격차 D revert와 동일 영역) → Stage 2 `--theirs` 적용 후 Stage 2 v2가 정밀 가드로 자동 보완.
22+
23+
## 3. 변경 본질
24+
25+
### Root cause (PR 본문, bisect)
26+
27+
Task #974 commit `c3e32151` (본 환경 PR #1013 머지) 가 `layout_shape_item()``Control::Shape` 분기를 신규 추가하면서 발생:
28+
- 빈 문단 호스트는 `FullParagraph` PageItem 의 `layout_paragraph()` 가 이미 LINE_SEG advance(`lh+ls`) 마침
29+
- `Shape` PageItem 분기가 `result_y = shape_y + line_advance.max(shape_h)` 로 또 advance → **이중 가산 (66.44 → 132.88px)**
30+
31+
### Fix — `has_full_para_item` case-specific 가드
32+
33+
`layout_shape_item()``!has_real_text` 분기에서 해당 문단에 `PageItem::FullParagraph` 가 발행되었는지 판별:
34+
35+
- **있으면 (빈 문단 호스트)**: 글상자를 호스트 문단 시작에 배치 + `result_y` 재진행 생략 → 이중 가산 제거
36+
- **없으면 (선행 표 등에 이어 붙은 Shape, hy-001 pi=27 등)**: Task #974 동작 유지
37+
38+
Task #974`set_inline_shape_position` 등록 의도 보존.
39+
40+
### PR #1005 격차 D scope 외 후속 (핵심 인사이트)
41+
42+
PR #1005 격차 D revert (`4e3ad587`) 가 동일 영역을 `result_y = shape_y + line_advance.max(shape_h)` 단순 복원 (table-vpos-01 회귀 차단) + "variant flag thread 후 variant-only 분기 (PR #1005 scope 외)" 명시. **본 PR #1003 이 variant 무관 일반 가드 (`has_full_para_item`) 로 두 케이스 양립**`feedback_pr_supersede_chain` + `feedback_hancom_compat_specific_over_general` 정합.
43+
44+
### 회귀 가드 좌표 정정
45+
46+
`tests/issue_table_vpos_01_page5_cell_hit_test.rs` 8건 좌표 정정 — `pi=33` (빈 문단 + treat-as-char 도형) 정정으로 `pi=34` 표 30.84px 상향 이동. 기존 stale 값 = 커밋 `c2d2157d`#974 버그 레이아웃에 박제. PR 본문 명시.
47+
48+
## 4. 자기 검증 (`feedback_push_full_test_required` 정합)
49+
50+
| 항목 | 결과 |
51+
|------|------|
52+
| `cargo test --release --lib` | 1307 passed |
53+
| `cargo test --release --tests` | 전체 통합 테스트 통과 (FAILED 0) |
54+
| `cargo test --release --test issue_table_vpos_01_page5_cell_hit_test` | **13 passed** (좌표 8건 정정 정확성 입증) |
55+
| `cargo clippy --release --lib -D warnings` | 통과 |
56+
| `cargo fmt --check` | exit 0 |
57+
| WASM 빌드 (Docker) | 4.83 MB, rhwp-studio/public 동기화 |
58+
59+
## 5. sweep 검증 (10 fixture, BEFORE devel `b5d38346` ↔ AFTER)
60+
61+
| Fixture | 결과 | 판정 |
62+
|---------|------|------|
63+
| **hy-001 HWPX/HWP5 (Task #974 동작 보존 핵심)** | **diff=0** | ✅ Task #974 의도 보존 (PR 본문 약속 정합) |
64+
| **table-vpos-01 HWPX/HWP** | 4 same, 1 diff | 의도된 변경 (pi=33→pi=34 30.84px 상향, 회귀 가드 좌표 정정 정합) |
65+
| **sample16-hwp5/hwp3** | 외곽선만 이동, **텍스트 무변동** (비-도형 diff=0) | ✅ PR #1005 격차 D revert 정밀화 효과 |
66+
| **aift** (page 25/36) | 2 diff | 의도된 변경 (빈 문단 위 글상자 advance 정정으로 후속 paragraph 위치 정합) |
67+
| exam_kor / biz_plan / 복학원서 | diff=0 | ✅ 무회귀 |
68+
69+
## 6. 작업지시자 결정 — 시각 판정 생략 수용
70+
71+
작업지시자 명시: "이번 PR은 비공개 샘플로 테스트 한 것으로 메인테이너의 시각판정없이 수용". 근거:
72+
- 비공개 fixture로 PR 본질 RED 재현 + 정정
73+
- 영구 회귀 가드 `issue_table_vpos_01_page5_cell_hit_test` 13 passed
74+
- sweep 무회귀 입증 (hy-001 보존, sample16 외곽선만, 의도된 변동 fixture만 diff)
75+
- cargo test 전체 통합 + clippy + fmt + WASM 빌드 통과
76+
- PR #1005 후속 정밀 해결 (`feedback_pr_supersede_chain` 정합)
77+
78+
## 7. PR #1004 안내 (후속 처리)
79+
80+
PR #1004 (Task #990 + #991 통합, +1292/-26, 23 files) 가 본 PR을 완전 포함. 본 PR 머지 후 **#1004 는 Task #991 부분만 재제출 필요** — 컨트리뷰터 안내. `feedback_small_batch_release_strategy` 정합.
81+
82+
## 8. 메모리 룰 정합
83+
84+
- `feedback_contributor_cycle_check`@planet6897 15+ PR 핵심 컨트리뷰터, #1002#1003 재제출, #1004/#1024 시리즈
85+
- `feedback_small_batch_release_strategy`#1003 작은 단위 먼저 머지 → #1004 #991 부분만 재제출 안내
86+
- `feedback_hancom_compat_specific_over_general``has_full_para_item` case-specific 가드 (Task #974 의도 보존)
87+
- `feedback_pr_supersede_chain` — PR #1005 격차 D revert 후속 정밀 해결 (권위 사례)
88+
- `feedback_fix_scope_check_two_paths` — 빈 문단 호스트 + 선행 표 Shape 두 경로 양립
89+
- `feedback_diagnosis_layer_attribution` — bisect 로 Task #974 `c3e32151` root cause 정확 진단
90+
- `feedback_v076_regression_origin` — Task #974 회귀 정확 식별
91+
- `feedback_visual_judgment_authority` — 비공개 픽스처 부재 → 영구 회귀 가드 + sweep 정량 + 작업지시자 결정 생략 수용
92+
- `feedback_self_verification_not_hancom` — 비공개 픽스처 + PR 본문 자기 보고 + sweep 보완
93+
- **`feedback_push_full_test_required`** (신규, 2026-05-20) — cargo test --tests 전체 + fmt --check 필수 정합
94+
- `project_output_folder_structure` — sweep 산출물 output/poc/pr1003 배치
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# PR #1003 검토 — Task #990: 빈 문단 위 treat-as-char 글상자 advance 이중 가산 정정
2+
3+
- 작성일: 2026-05-20
4+
- 컨트리뷰터: [@planet6897](https://github.com/planet6897) (Jaeuk Ryu)
5+
- PR: https://github.com/edwardkim/rhwp/pull/1003
6+
- base/head: `devel``planet6897:pr-task990` (cross-repo fork)
7+
- 연결 이슈: closes #990 (빈 문단 위 treat-as-char 글상자 advance 이중 가산)
8+
- 규모: +470 / -24, 8 files (소스 1 + 회귀 테스트 1 + 문서 6)
9+
- mergeable: **CONFLICTING**
10+
- 본질 커밋: 3개 (`69d71897` Stage 2 + `eec4781f` Stage 2 v2 + `d53e31b4` Stage 3) — 모두 작성자 @planet6897
11+
12+
## 1. 컨트리뷰터 사이클
13+
14+
@planet6897 = 15+ PR 핵심 컨트리뷰터. 동시 OPEN PR **3건** (#1003 + #1004 + #1024). #1002(closes #990 동일 이전 제출) **CLOSED**#1003 재제출. devel = `b5d38346` (#1021 머지 포함).
15+
16+
## 2. ⚠️ PR #1004 와의 관계 (선후 결정 핵심)
17+
18+
| PR | 영역 | 규모 |
19+
|----|------|------|
20+
| **#1003** | Task #990 단독 | +470/-24, 8 파일 |
21+
| **#1004** | Task #990 + Task #991 (분할 표 렌더링) | +1292/-26, 23 파일 |
22+
23+
**#1004#1003 을 완전 포함 + Task #991 추가**. `feedback_small_batch_release_strategy` 정합 (작은 단위 우선) → **#1003 먼저 머지 → #1004#991 부분만 재제출** 권고.
24+
25+
## 3. 본질 변경
26+
27+
### Root cause (PR 본문)
28+
29+
bisect 결과 Task #974 commit `c3e32151` ("Fix textbox picture rendering", 본 환경 PR #1013 머지) 가 `layout_shape_item()``Control::Shape` 분기를 신규 추가하면서 발생:
30+
31+
- 빈 문단 호스트는 `FullParagraph` PageItem 의 `layout_paragraph()` 가 이미 LINE_SEG advance(`lh+ls`) 마침
32+
- `Shape` PageItem 분기가 `result_y = shape_y + line_advance.max(shape_h)` 로 또 advance → 이중 가산 (132.88px = 66.44px × 2)
33+
34+
### Fix — `has_full_para_item` case-specific 가드
35+
36+
`layout_shape_item()``!has_real_text` 분기에서 해당 문단에 `PageItem::FullParagraph` 가 발행되었는지 판별:
37+
38+
- **있으면 (빈 문단 호스트)**: 글상자를 호스트 문단 시작에 배치 + `result_y` 재진행 생략 → 이중 가산 제거
39+
- **없으면 (선행 표 등에 이어 붙은 Shape, 예: `hy-001` pi=27)**: Task #974 동작 유지
40+
41+
### 회귀 가드 좌표 정정
42+
43+
`tests/issue_table_vpos_01_page5_cell_hit_test.rs``table-vpos-01.hwp` 5쪽 `pi=33` (빈 문단 + treat-as-char 도형) 이 본 정정과 동일 코드 경로. 이중 가산 재발 시 셀 hit-test 실패. `pi=33` 정정으로 `pi=34` 표가 30.84px 상향 이동 → inner 11x3 좌표 8건 정정 (기존 stale 값 = 커밋 `c2d2157d`#974 버그 레이아웃에 박제).
44+
45+
## 4. PR #1005 격차 D 와의 관계 (핵심 인사이트)
46+
47+
PR #1005 (Task #1001 종합 fix) 의 **격차 D 후속 정정 커밋 `4e3ad587`** 이 동일 영역(`layout_shape_item``result_y` 계산) 을 revert 함. PR #1005 보고서 명시: "격차 D breathing room 은 variant flag 를 layout 까지 thread 한 후 variant-only 분기 적용 (PR #1005 scope 외)".
48+
49+
**본 PR #1003 이 PR #1005 격차 D scope 외 분리의 정밀 해결**:
50+
- PR #1005 (격차 D revert): `result_y = shape_y + line_advance.max(shape_h)` 단순 복원 (table-vpos-01 회귀 차단)
51+
- PR #1003: `has_full_para_item` 조건으로 분기 — 빈 문단 호스트만 차단, 선행 표 이어붙은 Shape 는 Task #974 동작 유지
52+
53+
variant 무관 일반 가드 (`has_full_para_item`) 로 두 케이스 양립 — `feedback_hancom_compat_specific_over_general` 정합.
54+
55+
## 5. 검토 의견
56+
57+
### 강점
58+
59+
1. **bisect 정확** — Task #974 `c3e32151` 회귀 식별 + 박제 stale 값 명시 (회귀 가드 좌표 정정 근거)
60+
2. **case-specific 가드**`has_full_para_item` 조건으로 두 케이스(빈 문단 호스트 vs 선행 표 Shape) 분리 + Task #974 의도 보존 명시
61+
3. **PR #1005 격차 D scope 외 후속** — variant 무관 일반 가드로 정밀 해결. PR #1005 보고서의 후속 영역 합치
62+
4. **광범위 sweep** — 14 샘플 회귀 0 (PR 본문), hy-001 Task #974 동작 보존 + `issue_table_vpos_01_page5_cell_hit_test` 영구 회귀 가드
63+
5. **회귀 가드 좌표 정정 명시** — stale 값 인정 + 정정 레이아웃 정합 명시 (메인테이너 검증 시 좌표 8건 정합 확인 가능)
64+
6. cargo test 1483 + clippy 0 + fmt clean (PR 본문)
65+
66+
### ⚠️ 핵심 쟁점
67+
68+
#### (A) PR #1004 와 영역 중복 — 선후 결정
69+
70+
#1004#1003 을 완전 포함 + Task #991 추가. `feedback_small_batch_release_strategy` 정합 → **#1003 먼저 머지 권고** (작은 단위, 단일 책임). #1004#991 부분만 재제출.
71+
72+
#### (B) CONFLICTING — devel 적층 (PR #1005/#1018/#1019 보류/#1020/#1021)
73+
74+
devel 에 PR #1005 격차 D revert(`4e3ad587`) 포함. `layout.rs` 의 동일 영역(`layout_shape_item`) 변경 충돌 가능. cherry-pick 시 해소 필요 — PR #1005 revert + PR #1003 case-specific 가드를 결합한 형태 가능 (논리적 양립).
75+
76+
#### (C) 회귀 가드 좌표 정정 — 8건
77+
78+
`tests/issue_table_vpos_01_page5_cell_hit_test.rs` 8건 좌표 정정. PR 본문 stale 값 명시이나 sweep 으로 cell_hit_test 통과 + 다른 fixture 무회귀 확인 필수.
79+
80+
#### (D) 비공개 픽스처
81+
82+
PR 본문 "비공개 문서로 RED 재현, 비공개 자료라 커밋 안 함" — `feedback_self_verification_not_hancom` / `feedback_visual_judgment_authority` 보완. `tests/issue_table_vpos_01_page5_cell_hit_test` 영구 회귀 가드가 대체 역할. 작업지시자 시각 판정 게이트.
83+
84+
#### (E) `feedback_push_full_test_required` 정합 (신규 메모리, 2026-05-20)
85+
86+
cargo test --tests 전체 통합 테스트 + fmt --check 필수 — PR 본문 1483 (lib + integration) 명시 확인.
87+
88+
### 확인 필요 (검증 단계)
89+
90+
1. cherry-pick 3 커밋 순차 — layout.rs PR #1005 영역 충돌 해소 (PR #1003 case-specific 가드로 양립)
91+
2. `cargo test --release --lib` 1307 + `cargo test --release --tests` 전체 통합 + clippy -D + fmt 0 (push 전 필수)
92+
3. **광범위 sweep** — hy-001 (Task #974 동작 보존), table-vpos-01 (회귀 가드), sample16-hwp5 (PR #1005 변환본), 일반 fixture 회귀 부재
93+
4. WASM + 작업지시자 시각 판정 — table-vpos-01 cell_hit_test + 일반 무회귀
94+
95+
## 6. 처리 옵션
96+
97+
- **옵션 A (수용 — 권고)**: bisect 정확 + case-specific 가드 + PR #1005 후속 정밀 해결. 작업지시자 시각 판정 통과 시. #1004 와 영역 중복 → #1003 먼저 머지 후 #1004 재제출 안내
98+
- **옵션 B (수정 요청)**: 다른 fixture 회귀 또는 #1005 와 양립 충돌 시 — 조건 강화 또는 영역 좁힘 요청
99+
- **옵션 C (close)**: 본질 결함 시. 해당 낮음 (실제 결함 + 정확한 진단)
100+
101+
## 7. 메모리 룰 정합
102+
103+
- `feedback_contributor_cycle_check`@planet6897 15+ PR 핵심 컨트리뷰터, #1002#1003 재제출, #1004/#1024 시리즈
104+
- `feedback_small_batch_release_strategy`#1003 < #1004 → 작은 단위 먼저 권고
105+
- `feedback_hancom_compat_specific_over_general` — case-specific 가드 (`has_full_para_item`) 정합
106+
- `feedback_pr_supersede_chain`#1005 격차 D revert 후속 정밀 해결
107+
- `feedback_fix_scope_check_two_paths` — 빈 문단 호스트 + 선행 표 Shape 두 경로 양립
108+
- `feedback_diagnosis_layer_attribution` — bisect 로 Task #974 `c3e32151` root cause 정확 진단
109+
- `feedback_v076_regression_origin` — Task #974 회귀 정확 식별
110+
- `feedback_visual_judgment_authority` — 비공개 픽스처 부재 → 영구 회귀 가드 + 작업지시자 시각 판정 보완
111+
- `feedback_self_verification_not_hancom` — 비공개 픽스처 + PR 본문 자기 보고 + sweep 보완
112+
- `feedback_push_full_test_required` (신규) — cargo test --tests 전체 + fmt --check 필수
113+
- `project_output_folder_structure` — sweep 산출물 output/poc/pr1003 배치
114+
115+
## 8. 권고
116+
117+
**옵션 A 조건부** — bisect 정확 + case-specific 가드 + PR #1005 후속 정밀 해결 우수. 검증 단계에서 (1) cherry-pick 3 커밋 layout.rs 충돌 해소, (2) cargo test --lib + --tests + clippy + fmt 전체 검증, (3) sweep (hy-001 + table-vpos-01 + sample16-hwp5 + 일반), (4) WASM + 작업지시자 시각 판정 통과 시 cherry-pick no-ff merge. #1004 는 본 PR 머지 후 #991 부분 재제출 안내.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Task #990 Stage 2 완료보고서 — 정정 (GREEN)
2+
3+
**이슈**: [#990](https://github.com/edwardkim/rhwp/issues/990)
4+
**브랜치**: `local/task990`
5+
6+
---
7+
8+
## 1. 정정 내용
9+
10+
`src/renderer/layout.rs``layout_shape_item()``!has_real_text`
11+
(treat-as-char 글상자가 빈 문단 위에 놓인) 분기:
12+
13+
| 항목 | 변경 전 | 변경 후 |
14+
|------|---------|---------|
15+
| `shape_y` | `y_offset` (선행 FullParagraph 진행 후 값) | `para_start_y[para_index]` (호스트 문단 시작) |
16+
| `result_y` | 무조건 `shape_y + line_advance.max(shape_h)` 재진행 | `y_offset <= para_start` (FullParagraph 미선행 = 글상자 단독) 인 경우에만 진행. 선행 FullParagraph 가 이미 LINE_SEG advance 를 마친 경우 재진행 없음 |
17+
18+
`FullParagraph` PageItem 의 `layout_paragraph()` 가 빈 호스트 문단의 LINE_SEG
19+
(`lh + ls`)만큼 이미 advance 했으므로, `Shape` PageItem 은 위치만 등록하고
20+
재진행하지 않는다. Task #974(`c3e32151`)가 추가한 `set_inline_shape_position`
21+
등록 자체는 보존 — 이중 가산만 제거.
22+
23+
## 2. RED → GREEN
24+
25+
```
26+
변경 전: issue #990 box y=[344.08, 476.96, 609.84] advance=[132.88, 132.88] FAILED
27+
변경 후: issue #990 box y=[344.08, 410.52, 476.96] advance=[ 66.44, 66.44] ok
28+
```
29+
30+
박스 advance 132.88px → **66.44px** (LINE_SEG 1회분 `4983 HU`). 박스↔본문 줄
31+
비율 = 66.44 / 34.67 = **1.92** — 한컴 PDF 비율(1.92)과 정확히 일치.
32+
33+
`export-svg``LAYOUT_OVERFLOW page=3 overflow=215.9px` 경고도 해소.
34+
35+
## 3. Task #974 의도 보존 검증
36+
37+
textbox 관련 테스트 4건 전부 통과:
38+
39+
```
40+
test test_hy001_textbox_inline_pictures_render_for_hwp_and_hwpx ... ok (Task #974 회귀 테스트)
41+
test test_task78_rectangle_textbox_inline_images ................. ok
42+
test test_textbox_render_tree_debug .............................. ok
43+
test test_624_textbox_inline_shape_y_on_line2_p2_q7 .............. ok
44+
```
45+
46+
## 4. 시각 검증
47+
48+
`samples/issue-990-tac-box.hwpx` 4쪽 SVG — 글상자 3개가 한컴 PDF 와 동일하게
49+
밀착 배치(`※ 본 사업은 …` ×3) 후 `2. 추진배경 및 필요성` 이어짐.
50+
51+
## 5. 다음 단계 (Stage 3)
52+
53+
전체 `cargo test` 0 회귀, 광범위 `export-svg` 차분, `cargo clippy`/`fmt`.

0 commit comments

Comments
 (0)