Skip to content

Task #1006: 쪽 테두리 포맷별 분리 + cover logo overlap 해소#1011

Closed
jangster77 wants to merge 2 commits into
edwardkim:develfrom
jangster77:local/task1006
Closed

Task #1006: 쪽 테두리 포맷별 분리 + cover logo overlap 해소#1011
jangster77 wants to merge 2 commits into
edwardkim:develfrom
jangster77:local/task1006

Conversation

@jangster77

@jangster77 jangster77 commented May 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

PR #956 (paper_based=true 전역) → #987 (attr 존중 복원) 의 outline 회귀 사이클 종결. HWP3/HWP5/HWPX 모두 PaperBased contract 로 통합 + 머리말 !header_inside clip 제거 (꼬리말 clip 은 유지).

작업지시자 Hancom Office close-up 시각 판정 기반:

핵심 변경

파일 변경
src/model/page.rs PageBorderFill::basis 필드 + PageBorderBasis enum
src/parser/hwp3/mod.rs basis = PaperBased 주입 (#987 정정)
src/parser/body_text.rs (HWP5) basis = PaperBased 주입 (#956 정합)
src/parser/hwpx/section.rs (HWPX) basis = PaperBased 주입 (#956 정합)
src/renderer/layout.rs attr bit 0 단일 해석 → basis 필드 직접 사용
src/renderer/layout.rs !header_inside clip 제거, !footer_inside clip 유지

추가 fixture:

  • samples/test-image.hwp / samples/test-image.hwpx — 그림 wrap 옵션 4종 (자리차지/글앞으로/어울림/글뒤로) 시각 검증용

회귀 사이클 종결

Task/PR 접근 sample16 시험지 변환본 logo 페이지 번호
task877 paper_based = (attr & 0x01) != 0 회귀 회귀 -
#920 paper_based = (attr & 0x01) == 0 회귀 회귀 -
#956 paper_based = true 전역 회귀(잘못된 재판정) overlap -
#987 bfid 정정 + attr 존중 body 재판정(오판단) 일부 ✓ 회귀(#1006) -
#1006 포맷별 basis + 모두 PaperBased + selective clip 외곽선 바깥 ✓

clip 정책

  • !header_inside: clip 제거 — 외곽선이 paper-spacing edge 까지 확장하여 cover logo 가 outline 내부에 위치. 그림 이동 시 외곽선 shrink 회귀 해소.
  • !footer_inside: clip 유지 — 외곽선 bottom 을 body_area 하단으로 클립하여 페이지 번호가 외곽선 바깥 (꼬리말 영역) 에 위치. 한컴 viewer 정합.

spec 정의 (attr bit 1/2) 와 일부 다르지만 한컴 실제 동작 정합 우선.

Test plan

  • cargo build --release 통과
  • cargo test --release --lib: 1306 passed
  • cargo clippy --release -- -D warnings: 0 warnings
  • cargo fmt --check: clean
  • HWP3/HWP5 sample16 cover: paper-edge outline (top y=17.88) — logo 내부 포함 ✓
  • sample16-hwp5 페이지 번호: 외곽선 bottom y=1045.83 위에 위치, 페이지 번호 영역 외부 ✓
  • 시험지 (HWP5): paper-edge outline, footer clip 적용 ✓
  • 그림 이동 시 외곽선 shrink: 회귀 없음 (header clip 제거) ✓
  • 5 sample 페이지 수 회귀 없음

본 PR 범위 외 (별도 follow-up issue 등록 예정)

  • test-image.hwp paragraph 텍스트 라벨 (자리차지/글앞으로/어울림/글뒤로) 누락 — wrap=TopAndBottom + 글뒤로/글앞으로/어울림 혼재 paragraph 의 텍스트 렌더링 결함 (별도 root cause)

Closes #1006

🤖 Generated with Claude Code

PR edwardkim#956 (paper_based=true 전역) → edwardkim#987 (attr 존중 복원) 의 회귀 사이클
종결. 작업지시자 Hancom Office close-up 시각 판정 반영하여 HWP3/HWP5/HWPX
모두 PaperBased contract 로 통합, 머리말/꼬리말 conditional clip 제거.

핵심 변경:
- PageBorderFill::basis 신규 필드 (BodyBased / PaperBased enum)
- HWP3 parser: basis=PaperBased (edwardkim#987 body-based 재판정 정정 — close-up
  비교에서 logo 가 outline 내부 top-left 위치 확인)
- HWP5/HWPX parser: basis=PaperBased (edwardkim#956 정합 유지)
- renderer: attr bit 0 단일 해석 X → basis 필드 직접 사용
- header_inside/footer_inside conditional clip 제거 — 머리말 객체 (logo)
  존재 여부에 따라 외곽선이 줄어드는 회귀 (그림 이동 시 shrink) 해소

검증:
- HWP3/HWP5 sample16 cover: paper-edge outline (18.93, 17.88)~ 동일
- 시험지 (HWP5): paper-edge outline (26.45, 75.59)~ — edwardkim#956 baseline 유지
- 1303 tests passed, 0 clippy warnings
- 8 sample 페이지 수 회귀 없음 (hwp3-sample10/14/16/16-hwp5, exam_kor,
  aift, biz_plan, 3-09월_교육_통합_2022)

fixture 추가:
- samples/test-image.hwp / .hwpx — 그림 wrap 옵션 4종
  (자리차지/글앞으로/어울림/글뒤로) 시각 검증용

회귀 사이클 종결:
- task877: paper_based = (attr & 0x01) != 0 — sample16 ✓ 시험지 회귀
- edwardkim#920: paper_based = (attr & 0x01) == 0 — 시험지 ✓ sample16 회귀
- edwardkim#956: paper_based = true 전역 — sample16 회귀 (잘못된 재판정)
- edwardkim#987: bfid 정정 + attr 존중 — 변환본 logo overlap 회귀
- edwardkim#1006: 포맷별 basis + 모두 PaperBased + clip 제거 — 모든 sample ✓

Closes edwardkim#1006

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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 — paper_based outline 회귀 사이클 종결 (task877→#920#956#987#1005#1006). 단일 attr & 0x01 비트 해석 모호성을 PageBorderBasis
enum + parser 단계 명시 주입(HWP3/HWP5/HWPX 모두 PaperBased)으로 책임
분리 — interpretation → parser, 사용 → renderer.

clip 정책 변경: !header_inside clip 제거 (cover logo paper-edge 정합),
!footer_inside clip 유지 (페이지 번호 외곽선 바깥 유지). 작업지시자
Hancom Office close-up 시각 판정 기반 — spec(attr bit 1/2) ≠ 한컴 실제
동작, 한컴 정합 우선 명문화.

옵션 A: 본질 커밋 aa8160c cherry-pick (작성자 Taesup Jang 보존, 충돌
없음). 검증: cargo test 1307 + clippy -D + fmt 0 + WASM 4.83MB. sweep
7 fixture: 일반 5종(sample10/exam_kor/exam_math/aift/biz_plan) diff=0
무회귀, sample16-hwp5/hwp3 외곽선만 paper-edge 이동 (텍스트 무변동).
작업지시자 시각 판정 통과.

매직넘버 감사: 신규 0 / 제거 3 (attr & 0x01 ×2, attr & 0x02). 잔존
footer_inside = attr & 0x04 (layout.rs:979) 일관성 정리는 별도 issue
권고. test-image fixture 추가로 그림 wrap 4종 회귀 가드 영구화.

후속: footer_inside 일관성, test-image paragraph 텍스트 라벨 누락
(별도 root cause). #1009 (보류) 컨트리뷰터 rebase 후 재제출 대기.
@edwardkim

Copy link
Copy Markdown
Owner

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

검증:

  • cargo test --release --lib 1307 passed / clippy -D / fmt 0 / WASM 4.83MB
  • sweep 7 fixture (BEFORE devel ↔ AFTER): 일반 5종(sample10, exam_kor, exam_math, aift, biz_plan) 전부 diff=0 무회귀, sample16-hwp5/hwp3 외곽선만 paper-edge 이동 (텍스트 무변동, 비-도형 diff=0)
  • 작업지시자 시각 판정 통과 (변환본 cover logo overlap 해소 + HWP3 외곽선 paper-edge 정합 + 페이지 번호 외곽선 바깥 유지)

매직넘버 감사: 신규 0 / 제거 3 (attr & 0x01 ×2, attr & 0x02). PageBorderBasis enum 도입으로 매직넘버 개선 PR입니다. 잔존 footer_inside = attr & 0x04 (layout.rs:979) 일관성은 별도 issue로 정리 권고드립니다.

paper_based outline 회귀 사이클(task877→#920#956#987#1005#1006) 종결 + 작업지시자 Hancom Office close-up 시각 판정 권위 명문화 + test-image fixture 영구화 — 매우 견고한 마무리 PR입니다. @jangster77 #997~#1011 연속 시리즈 감사합니다.

@edwardkim edwardkim closed this May 19, 2026
edwardkim pushed a commit that referenced this pull request May 19, 2026
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 #1011 과 동일 — devel
merge 시 중복 add 자동 해소)

Closes #1012

Co-Authored-By: Claude Opus 4.7 <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 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 pushed a commit that referenced this pull request May 20, 2026
HWP3 외곽선 paper-edge 정합 회귀 정정 (PR #1003 cherry-pick --theirs
사고 복원). CI 전부 pass + 본 환경 git 검증으로 PR #1011 baseline
(850cfb5) build_page_borders 영역과 byte-identical 복원 확인 +
작업지시자 시각 판정 사실 확인 → merge 수용.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim pushed a commit that referenced this pull request May 20, 2026
PR #1003 cherry-pick `--theirs` 자동 충돌 해소가 PR #1011 의
PageBorderBasis 통합 contract 를 PR #987 시절 attr & 0x01 비트
로직으로 revert 한 사고 — HWP3 native (attr=0) 만 회귀 노출.
layout.rs 4 hunk 복원으로 PR #1011 baseline (850cfb5) 정합.

본 환경 git 검증: build_page_borders 영역 byte-identical 복원.
작업지시자 시각 판정 통과 (HWP3 sample16 cover paper-edge 정합).

Co-Authored-By: Claude Opus 4.7 (1M context) <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