Skip to content

Task #1012: wrap 옵션 paragraph 라벨 텍스트 y 위치 정정#1015

Closed
jangster77 wants to merge 6 commits into
edwardkim:develfrom
jangster77:local/task1012
Closed

Task #1012: wrap 옵션 paragraph 라벨 텍스트 y 위치 정정#1015
jangster77 wants to merge 6 commits into
edwardkim:develfrom
jangster77:local/task1012

Conversation

@jangster77

Copy link
Copy Markdown
Collaborator

Summary

  • test-image.hwp page 1 의 paragraph 라벨 (자리차지/글앞으로/어울림/글뒤로) 이 Picture 영역 내부에 그려져 시각 overlap 되는 문제 해결
  • paragraph_layout.rs 의 spacing_before 처리 로직에서 spacing_before=0 인 경우 line_seg.vpos 가 무시되던 결함의 fallback 추가
  • 라벨 y 위치 143.6 → 346px (Picture 영역 아래) ✓

Root cause

paragraph_layout.rs::layout_composed_paragraph (line 982-1000) 의 spacing_before 처리 분기:

  • 기존: spacing_before > 0 인 경우만 vpos 클램프 분기 진입
  • test-image.hwp pi=0: spacing_before=0 → 분기 SKIP → line_seg.vpos=15180 HU (=202.4px) 무시
  • 결과: 텍스트가 body_top 에 그려짐 (Picture[2] TopAndBottom y=132~334 영역 내부)

핵심 fix

// [Task #1012] paragraph 첫 line vpos > 0 인데 spacing_before=0 으로
// 위 블록 진입 안한 경우 — line_seg.vpos 를 직접 y 에 가산하여 텍스트가
// wrap shape 아래로 위치하도록 함. start_line==0 + column-top +
// para_index==0 으로 한정.
if start_line == 0 && spacing_before == 0.0 && is_column_top && para_index == 0 {
    let vpos0_px = para
        .and_then(|p| p.line_segs.first())
        .map(|ls| hwpunit_to_px(ls.vertical_pos, self.dpi))
        .unwrap_or(0.0);
    if vpos0_px > 0.0 {
        y += vpos0_px;
    }
}

변경 파일

파일 변경
src/renderer/layout/paragraph_layout.rs spacing_before=0 + column-top + vpos > 0 case fallback
samples/test-image.hwp / .hwpx 그림 wrap 옵션 4종 fixture (PR #1011 과 동일 — devel merge 시 중복 add 자동 해소)
mydocs/plans/task_m100_1012*.md, mydocs/working/...stage1/2.md, mydocs/report/... 수행/구현 계획서, Stage 보고서, 최종 보고서

z-order 부 결함 — 자동 해소

Stage 1 진단 시 발견한 z-order 결함 (모든 image 가 모든 text 뒤 push) 은 본 fix 후 시각 무관:

  • text y=346 / image y=86~334 → 시각 영역 완전 분리
  • BehindText image 가 text 를 가릴 가능성도 사라짐

Test plan

  • cargo build --release 통과
  • cargo test --release --lib: 1306 passed
  • cargo clippy --release -- -D warnings: 0 warnings
  • cargo fmt --check: clean
  • test-image.hwp page 1: 라벨이 그림 아래 y=346 위치, 시각 overlap 없음
  • 회귀 sweep: hwp3-sample16 (64), exam_kor (20), aift (74), biz_plan (6), hwpspec (175) — 모두 페이지 수 보존

Closes #1012

🤖 Generated with Claude Code

jangster77 and others added 4 commits May 19, 2026 21:23
test-image.hwp page 1 의 paragraph 라벨 (자리차지/글앞으로/어울림/글뒤로)
이 한컴 viewer 와 다르게 표시되는 문제 해결.

Root cause: paragraph_layout.rs::layout_composed_paragraph 의 spacing_before
처리 로직이 spacing_before > 0 인 경우만 line_seg.vpos 클램프 분기 진입.
test-image.hwp pi=0 의 spacing_before=0 → vpos=15180 HU 무시 → 텍스트가
body_top 에 그려져 Picture 영역 (TopAndBottom wrap) 내부 시작.

Fix: spacing_before=0 + column-top + para_index==0 + line_seg.vpos > 0 case
의 fallback 추가 — y += vpos0_px 로 텍스트가 wrap shape 아래로 push.

검증:
- 라벨 텍스트 y: 143.6 → 346px (Picture 영역 아래) ✓
- 각 라벨이 대응 그림 아래 정렬 ✓
- z-order 부 결함 자동 해소 (text vs image 영역 시각 분리)
- 1306 tests passed, 0 clippy warnings
- 5 sample 회귀 없음 (hwp3-sample16, exam_kor, aift, biz_plan, hwpspec)

fixture 추가: samples/test-image.hwp / .hwpx (PR edwardkim#1011 과 동일 — devel
merge 시 중복 add 자동 해소)

Closes edwardkim#1012

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@edwardkim edwardkim self-requested a review May 19, 2026 13:28
@edwardkim edwardkim added the enhancement New feature or request label May 19, 2026
@edwardkim edwardkim added this to the v1.0.0 milestone May 19, 2026
edwardkim added a commit that referenced this pull request May 19, 2026
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 19, 2026
@jangster77#1011 잔존 직접 해소. paragraph_layout.rs 의 기존 라인
990 분기(spacing_before > 0 일 때 vpos 클램프)와 대칭 보완 add-only 14
줄 fallback. spacing_before=0 + vpos>0 + 4중 AND 가드(start_line==0 +
is_column_top + para_index==0) 케이스에 line_seg.vpos 를 y 에 직접 가산.
test-image.hwp pi=0 (TopAndBottom Picture + 인라인 wrap) 라벨이 Picture
영역 아래 정합 위치(y=143.6→346)로 이동.

옵션 A: 본질 커밋 b808b99 cherry-pick (작성자 Taesup Jang 보존, 충돌
없음, fixture test-image.hwp/.hwpx 는 #1011 머지로 이미 존재 — binary
identical 자동 해소). 검증: cargo test 1307 + clippy -D + fmt 0 + WASM
4.83MB. sweep 10 fixture (BEFORE devel ↔ AFTER): 타깃 test-image diff=1
(의도 변경), wrap shape 보유 4종(sample16-hwp5/hwp3, hy-001 HWPX/HWP5)
+ 일반 4종(exam_kor/math/aift/biz_plan) 전부 diff=0 — 쟁점 A(공통 경로
8+ 호출 사이트)/B(다른 wrap 모드) 회귀 0 입증. 작업지시자 시각 판정
통과.

z-order 부 결함도 본 fix 후 text/image y 영역 분리로 자동 해소.
@edwardkim

Copy link
Copy Markdown
Owner

옵션 A로 devel에 반영했습니다 (본질 커밋 b808b99 cherry-pick, 작성자 메타데이터 보존, 충돌 없음).

검증:

  • cargo test --release --lib 1307 passed / clippy -D / fmt 0 / WASM 4.83MB
  • sweep 10 fixture (BEFORE devel ↔ AFTER): test-image 타깃 diff=1 (의도된 라벨 y=143.6→346), wrap shape 보유 4종(sample16-hwp5/hwp3, hy-001 HWPX/HWP5) + 일반 4종(exam_kor/math/aift/biz_plan) 전부 diff=0 — 공통 경로 layout_composed_paragraph 8+ 호출 사이트 + 다른 wrap 모드 회귀 0 입증
  • 작업지시자 시각 판정 통과 (라벨이 Picture 영역 아래로 정합 이동)

기존 라인 990 분기(spacing_before > 0)와 대칭 보완 add-only 14줄 + 4중 AND 가드(start_line==0 + spacing_before==0 + is_column_top + para_index==0)로 영역을 매우 좁힌 정밀한 fix입니다. #1011 잔존 직접 해소 + z-order 부 결함 자동 해소 — 견고한 후속 PR 감사합니다.

@edwardkim edwardkim closed this May 19, 2026
edwardkim pushed a commit that referenced this pull request May 20, 2026
… 4 hunk 복원

PR #1003 (closes #990) 의 cherry-pick `--theirs` 충돌 해소가 PR #1011
(closes #1006) 의 PageBorderBasis 통합 contract 를 PR #987 시절 attr 비트
해석으로 무심코 revert. HWP3 native (attr=0) 만 paper_based=false 로 판정되어
외곽선이 body-edge 로 좁아진 시각 회귀 발생.

Bisect 단언 (border_top y):
- 850cfb5 (PR #1011): 17.88 (paper-edge, 기준선)
- 71aedda (PR #1015): 17.88
- 84246b2 (PR #1018): 17.88
- 27c05d5 (PR #1020): 17.88
- b5d3834 (PR #1021): 17.88
- c2024ec (PR #1003): 55.64 ← 회귀 도입
- 65c8e69 (devel HEAD): 55.64

Fix: src/renderer/layout.rs 4 hunk 복원
- 변경 A: page_number_baseline_y() — (attr & 0x01) → matches!(basis, PaperBased)
- 변경 B: build_page_borders() — 동일 + 주석 + 디버그 로그 (bit1/bit2/footer_inside)
- 변경 C: footer_inside clip 복원 — 페이지 번호 외곽선 바깥 위치 (PR #1011)
- 변경 D: `(bx, mut by, bw, mut bh)` — footer clip 의 by/bh 수정 위함

Parser 측 PR #1011 변경 (basis=PaperBased 주입) 은 PR #1003 cherry-pick 시
보존됨. fix 는 renderer (layout.rs) 한정 단일 파일.

검증 (Stage 2 별도 보고):
- 3 포맷 paper_based=true 단언 (RHWP_DEBUG_PAGE_BORDER)
- HWP3 sample16 border_top y=17.88 복원
- HWP5/HWPX 변환본 무변동 (17.88 유지)
- cargo test --release --lib 1307 passed
- cargo clippy --release --lib -- -D warnings clean
- cargo fmt --check clean

Refs #1029

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 20, 2026
…격차 종합 정정

@jangster77 25+번째 PR (paper_based outline 시리즈 #1011/#1015/#1031
마무리 후 HWP3 sample16 정합 시리즈 진입). samples/hwp3-sample16.hwp
한컴 한글 정답지 비교 4 격차 종합 정정. src/parser/hwp3/ 격리 엄격
(HWP5/HWPX/renderer 무수정).

본문 가설 정반대 발견: 원본 이슈 가설(HWP5 변환본 gradient strip) 이
한컴 한글 정답지 시각 검증 결과 정반대로 판명 (gradient 가 정답, HWP3
회귀). issue body + 수행/구현계획서 v2 재작성 — feedback_visual_judgment_authority
모범 사례.

본질 (2 코드 + 1 test + 9 문서):
- 격차 A — HWP3 Shape gradient IR 매핑 (drawing.rs:792~830):
  HWP3 raw Hwp3DrawingObjectGradientAttr 가 이미 파싱되었으나 Fill IR
  구축에서 fill_type=Solid 하드코딩으로 데이터 무시. HWP5 doc_info.rs:404
  와 동일 contract 로 GradientFill 주입.
- 격차 B — Shape border LineType 2~7 → Solid normalize (drawing.rs:758~785):
  HWP3 raw style=0x0002 (LineType=2 Dash) 가 점선 렌더되나 한컴은 실선.
  sample16 한정 분포 — narrow fix 회귀 risk 0.
- 격차 C — HWP3 heading decoration 휴리스틱 strip (mod.rs:2870~2960):
  "═════■ 1.추진목적 ■═════" 형태 decoration 을 fixup_hwp3_heading_decoration
  + strip_heading_decoration 패턴 detection 으로 strip. 한컴 변환기 mimic.
- 격차 D-1 — CharShape dedupe (mod.rs:1869~1900):
  같은 start_pos 에 rep + inline shape change 양쪽 push 시 마지막
  (inline override) 유지.
- 격차 D-2 — 폰트명 매핑 (mod.rs:2570~2585, 2908~2924):
  "신명조"→"HY신명조" 등 5 legacy 매핑 + font.alt_name 원본 보존.
  HWP3 SVG 좌표가 HWP5 변환본과 byte-for-byte 일치.

검증 (본 환경):
- cargo test --release --lib 1319 passed
- cargo test --release --tests 모든 통합 passed
- cargo test --release --test issue_1008_gradient **4/4 passed**:
  hwp3_sample16_business_box_has_gradient, _border_solid,
  _heading_decoration_stripped, _font_name_mapped_to_hwp5_convention
- cargo fmt --all --check clean
- sweep 9 fixtures: hwp3-sample16 **44 diff** (의도된 본 PR 본질, 페이지
  수 64→64 불변) / 다른 8 fixtures (HWP5/HWPX 변환본 + sample10/11/sample
  + exam_kor/aift/biz_plan) **diff=0** — HWP3 격리 검증, PR #1031/#1032/
  #1033 회귀 부재
- SVG 본질 검증: cover <radialGradient id="grad1" #c8ccf8→#ffffff> 추가
  + 폰트 "신명조"→"HY신명조" 매핑
- WASM Docker 빌드 4.89MB + rhwp-studio 동기화
- 작업지시자 시각 판정 통과

squash 적용:
- PR base = 5263f53 (PR #1032 후 docs commit) — PR #1033 (01a8c75)
  미흡수
- cherry-pick 직접 머지 대신 본질 파일만 origin/devel 위에 squash
  적용 (src/parser/hwp3/{drawing.rs, mod.rs} + tests/issue_1008_gradient.rs
  + 문서 8 파일, 총 11 파일)
- 결과: PR #1033 영역 (src/renderer/*, advance_row_block_cut, is_block_split)
  자동 보존 + 본 PR 본질 적용

한계 (PR 본문 명시):
- 휴리스틱 (격차 C): HWP3 spec 미참조 패턴 detection — 의도된
  "═══...■...■═══" typography 회귀 risk. sweep diff=0 으로 1차 입증
- 폰트 매핑 5 legacy 한정: 다른 명칭 발견 시 확장 필요
- 공백 cosmetic 비범위: rhwp "1.추진목적" vs 한컴 "1. 추진목적" period
  뒤 공백 — HWP3 raw 부재, 한컴 자동 삽입

closes #1008

Co-Authored-By: Taesup Jang <tsjang@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants