Skip to content

Task #573: 보기 셀 분수 단락 인라인 표 셀 paragraph 라우팅 정정 (closes #573)#575

Closed
planet6897 wants to merge 5 commits into
edwardkim:develfrom
planet6897:pr-task573
Closed

Task #573: 보기 셀 분수 단락 인라인 표 셀 paragraph 라우팅 정정 (closes #573)#575
planet6897 wants to merge 5 commits into
edwardkim:develfrom
planet6897:pr-task573

Conversation

@planet6897

Copy link
Copy Markdown
Contributor

Summary

  • 본질: `table_layout.rs` L1411,L1461 의 `has_table_ctrl` 가 block table (treat_as_char=false)inline TAC table (treat_as_char=true) 을 미구분 — 인라인 TAC 표 보유 셀 paragraph 가 ELSE 분기로 빠져 `layout_composed_paragraph` 호출 SKIP → "ㄷ. ", "이다." 등 surrounding text 미렌더 (exam_science.hwp 13/15/16/19번 보기 셀 분수 단락).
  • Stage 1 진단으로 사용자 보고 "오른쪽 편위" 의 실제 본질이 surrounding text 미렌더 임을 확정 (분수가 cell 좌단에 단독 노출되어 우측 편위로 인지).
  • 정정: `has_block_table_ctrl` 신설 (treat_as_char=false 만), L1461 조건 정정, L1844 inline TAC table branch 에 `inline_shape_position` 중복 emit 가드 추가 (Equation 의 L1800 패턴 재사용). 변경 LOC: +19/-2.

본질 정정 메커니즘

HWP 표준 룰:

  • block table (treat_as_char=false) → 텍스트 흐름 외 (별도 layout_table 호출)
  • inline TAC table (treat_as_char=true) → 텍스트 흐름 내 (line 안에 배치)

기존 코드는 둘을 미구분하여 inline TAC 표 보유 paragraph 도 텍스트 렌더 SKIP → 결함.

본 fix 후:

  • `!has_block_table_ctrl` → `layout_composed_paragraph` 호출 → surrounding text + inline 수식 + inline TAC 표 모두 `run_tacs` 경로에서 정상 배치
  • 인라인 TAC 표는 `paragraph_layout.rs` L1888-1903 에서 layout_table + `set_inline_shape_position` 등록
  • `table_layout` step 3 의 inline TAC table branch 는 `inline_shape_position` 확인 후 중복 emit 방지

핵심 정정 결과 (pi=68 cell[5] p[2] "ㄷ. 이다.")

항목 Before After
"ㄷ" 위치 미렌더 x=97.07 y=715.56 ✓
분수 (cell-clip-175) x 97.07 122.07 (ㄷ. 다음 위치)
"이다." 위치 미렌더 x=347.29-389 ✓

인접 효과 — Issue #572 자동 정정

작업지시자 보고 item ① (#572 — page 1 header sub-tables LEFT-shift) 도 본 fix 의 인접 효과로 자동 정정:

```
exam_science page 1 header (외곽 1×1 표 셀 p[3] 의 sub-tables):
Before: "성" x=86.39 (cell 좌단)
After: "성" x=152.39 (Justify slack 분배 → 중앙 정렬에 가까워짐)
```

이전 routing (step 3 for-ctrl loop) 은 sub-tables 좌측 직배치. 새 routing (layout_composed_paragraph) 은 paragraph alignment + Justify slack 으로 분배.

Test plan

  • `cargo test --lib` — 1125 passed, 0 failed
  • `cargo test --test svg_snapshot` — 6/6 passed
  • `cargo clippy --release --lib` — 본 변경 신규 경고 0 (사전 결함 2건 변경 전후 동일)
  • 광범위 fixture sweep — 9 fixture / 152 페이지 (60 byte-identical)
  • exam_science.hwp 4 페이지 의도된 정정 (Page 1 header item ① / Page 2 pi=61 / Page 3 13/16번 / Page 4 19번)
  • 작업지시자 시각 판정 (`output/svg/exam_science_task573/*.svg`)
  • 비의도 영향 8 페이지 시각 판정 (21_언어 1, exam_eng 1, exam_kor 1, aift 5)
  • rhwp-studio web Canvas 시각 판정 (WASM)

산출 문서

  • 수행계획: `mydocs/plans/task_m100_573.md`
  • Stage 1 진단 (코드 무수정): `mydocs/working/task_m100_573_stage1.md`
  • Stage 2 구현계획: `mydocs/plans/task_m100_573_impl.md`
  • Stage 3 구현+검증: `mydocs/working/task_m100_573_stage3.md`
  • 최종 보고서: `mydocs/report/task_m100_573_report.md`

선행 task

본 PR 은 셀 paragraph 메커니즘 (별개 결함). 위 둘과 같은 코드 영역 인접하나 분기 경로 다름.

closes #573
연관 #572 (시각 판정 후 자동 close 검토)

🤖 Generated with Claude Code

planet6897 added 5 commits May 4, 2026 15:43
작업지시자 보고 — exam_science.hwp 13/15/16/19번 보기 셀 내부 분수 단락
("ㄴ. [분수] 이다.", "제 N 이온화 에너지" 등) 인라인 2x1 표가 셀 안에서
우측 편위. Task edwardkim#568 fix(PR edwardkim#570) 는 본문 paragraph narrow segment_width
조합만 정정 → 셀 paragraph (sw=full cell width) 미진입.

3 가설 (Stage 1 진단 필요):
A — Last line + Justify 의 x_start 산식
B — 셀 halign / paragraph alignment 미적용
C — run_tacs 의 인라인 표 char_offset 결함

Stage 1 진입 승인 요청.
가설 A/B/C 모두 부정. 신규 가설 D 확정:
cell paragraph 의 inline 표 + inline 수식 동시 보유 단락에서 surrounding
text (예: 'ㄷ. ', '이다.') 가 SVG 에 미렌더. 분수 cell content + inline
수식만 렌더되어 분수가 cell 좌단에 단독 노출 → 사용자 '오른쪽 편위' 인지는
실제로는 '좌측 텍스트 누락'.

대조 매트릭스 (pi=68 cell[5]):
  p[0] (ㄱ.) inline 수식만 1개  → 정상
  p[1] (ㄴ.) inline 수식만 1개  → 정상
  p[2] (ㄷ.) inline 표 1 + 수식 1 → surrounding text 미렌더

Task edwardkim#565/edwardkim#568 와 별개 결함 — cell paragraph 는 layout_composed_paragraph
직행 (top-level guard 미통과). run_tacs loop 의 인라인 표 처리 분기에서
surrounding text run emit 누락 가능성.

Stage 2 진입 승인 요청 (구현 계획서, 코드 분기 추적).
Stage 2 trace 로 본질 결함 위치 확정:
- table_layout.rs L1411: has_table_ctrl 가 block + inline TAC 표를 구분 안 함
- L1461: has_table_ctrl=true 면 layout_composed_paragraph 호출 SKIP
- → 인라인 TAC 표 보유 cell paragraph 의 surrounding text 미렌더

정정 안 A 권고:
1. L1411: has_table_ctrl → has_block_table_ctrl (treat_as_char=false 만)
2. L1461: 조건 변경 → IF 분기에서 layout_composed_paragraph 호출
3. L1844 inline TAC table branch 에 inline_shape_position 중복 가드 추가
   (Equation 의 기존 가드 패턴 L1800 재사용)

기대 효과:
- p[2] (TAC 표 + 수식) → has_block_table_ctrl=false → 텍스트 정상 렌더
- 인라인 TAC 표는 layout_composed_paragraph 의 run_tacs 에서 렌더 +
  set_inline_shape_position 등록 → step 3 의 중복 가드가 skip

추정 LOC: +15/-3. 회귀 위험: L2040/2151 등 다른 has_table_ctrl 사용처
의미 점검 필요 (Stage 3 첫 빌드 후 확정).

Stage 3 진입 승인 요청.
본질 정정 — has_table_ctrl 가 block + inline TAC 표를 미구분하던 결함:
- L1411: has_block_table_ctrl 신설 (treat_as_char=false 만)
- L1461: 조건 변경 (!has_block_table_ctrl 시에만 layout_composed_paragraph 호출)
- L1844 inline TAC table branch: inline_shape_position 중복 가드 추가
  (Equation 의 L1800 가드와 동일 패턴 재사용)
- L2040 if has_table_ctrl 보존 (any table 의 vpos 보정 동일 필요)

이 fix 로 인라인 TAC 표 보유 셀 paragraph 의 surrounding text (예: 'ㄷ. ',
'이다.') 가 layout_composed_paragraph 의 run_tacs 에서 정상 렌더되며,
인라인 TAC 표는 동 함수의 paragraph_layout 경로 (L1888-1903) 에서 렌더
되고 set_inline_shape_position 등록. table_layout step 3 의 inline TAC
branch 는 등록 확인 후 중복 emit 방지.

검증:
- cargo test --lib 1125 통과 (회귀 0)
- svg_snapshot 6/6 통과
- clippy: 신규 경고 0 (사전 결함 2건 변경 전후 동일)
- 광범위 sweep 9 fixture 152 페이지: 60 페이지 byte-identical, 92 페이지 변경
  - exam_science 4 (의도된 정정 — 13/15/16/19번 보기 셀 분수 + Page 1 header item ①)
  - 21_언어/exam_eng/exam_kor/aift 8 (시각 판정 필요)

핵심 정정 (pi=68 cell[5] p[2] 'ㄷ. 이다.'):
- 'ㄷ' x=97.07 y=715.56 (BEFORE: 미렌더)
- 분수 cell-clip-175 x=122.07 (BEFORE: x=97.07)
- '이다.' x=347.29-389 (BEFORE: 미렌더)

인접 효과: Page 1 header item ① (issue edwardkim#572) 자동 정정 효과 — Stage 4
시각 판정 후 close 가능 여부 결정.

변경 LOC: src/renderer/layout/table_layout.rs +19 / -2.
Stage 3 보고서: mydocs/working/task_m100_573_stage3.md.

Stage 4 진입 승인 요청.
본 task 산출물:
- mydocs/report/task_m100_573_report.md (최종 보고서)
- mydocs/orders/20260504.md (Issue edwardkim#568/edwardkim#572/edwardkim#573/edwardkim#574 행 추가, 검토 사항 보강)

검증 요약:
- pi=68 cell[5] p[2] 'ㄷ. 이다.' surrounding text 정상 렌더 (BEFORE: 미렌더)
- 분수 위치 정정 (x=97.07 → 122.07 — ㄷ. 텍스트 다음)
- cargo test --lib 1125 / svg_snapshot 6/6 / clippy 신규 0
- 광범위 sweep 9 fixture 152 페이지: 60 byte-identical, 92 변경
  (의도된 정정 4 + 시각 판정 필요 88)

인접 효과 (Issue edwardkim#572):
- Page 1 header sub-tables LEFT-shift 자동 정정
- '성' x=86.39 → 152.39 (Center alignment 결과)
- 시각 판정 후 edwardkim#572 자동 close 가능

작업지시자 시각 판정 + close + local/devel merge 승인 요청.
edwardkim added a commit that referenced this pull request May 5, 2026
PR #575 (Task #573, @planet6897 PR / Jaeook Ryu commit author) 1차 검토:
- 본질 결함: table_layout.rs::has_table_ctrl 가 block table
  (treat_as_char=false) 와 inline TAC table (treat_as_char=true) 을
  미구분 → 인라인 TAC 표 보유 셀 paragraph 가 ELSE 분기로 빠져
  layout_composed_paragraph SKIP → 'ㄷ. ', '이다.' surrounding text 미렌더
- Stage 1 정밀 진단 통찰: 사용자 보고 "오른쪽 편위" → 실제 본질
  "surrounding text 미렌더"
- 본질 정정: has_block_table_ctrl 신설 (treat_as_char=false 만) +
  inline_shape_position 중복 emit 가드 (Equation L1800 패턴 재사용)
- 인접 효과: Issue #572 (Page 1 header sub-tables LEFT-shift) 자동 정정
- PR mergeable=CONFLICTING (PR base 시점 차이 추정),
  본질 cherry-pick (7d5075b) 충돌 0
- 본 환경 임시 검증: cargo test --lib --release 1131 passed (회귀 0) /
  clippy 0건

권장 처리: 옵션 A — 핀셋 cherry-pick + 결정적 검증 + 광범위 sweep +
WASM + 작업지시자 시각 판정 + Issue #572 자동 close 검토.
edwardkim added a commit that referenced this pull request May 5, 2026
…ixture 1,614 페이지 회귀 0 + exam_science 4 페이지 의도된 정정
edwardkim added a commit that referenced this pull request May 5, 2026
…paragraph 라우팅 정정 — @planet6897 / Jaeook Ryu 1 commit + 시각 판정 ★ 통과)

PR #575 (Task #573, @planet6897 PR / Jaeook Ryu commit author):
- 본질 결함: table_layout.rs::has_table_ctrl 가 block table
  (treat_as_char=false) 와 inline TAC table (treat_as_char=true) 을
  미구분 → 인라인 TAC 표 보유 셀 paragraph 가 ELSE 분기로 빠져
  layout_composed_paragraph SKIP → 'ㄷ. ', '이다.' surrounding text 미렌더
- Stage 1 정밀 진단: 사용자 보고 "오른쪽 편위" → 실제 본질
  "surrounding text 미렌더"
- 본질 정정: has_block_table_ctrl 신설 (treat_as_char=false 만) +
  inline_shape_position 중복 emit 가드 (Equation L1800 패턴 재사용)
- 인접 효과: Issue #572 (Page 1 header sub-tables LEFT-shift) 자동 정정
- 단일 파일 본질 (table_layout.rs +19/-2)

검증:
- cargo test --lib --release 1131 passed (회귀 0)
- svg_snapshot 6/6 / issue_546 1 / issue_554 12 / clippy 0 / build --release
- WASM 4,571,604 bytes (PR #570 baseline +703 bytes — table_layout.rs +19/-2 정합)
- 광범위 페이지네이션 회귀 sweep: 164 fixture (158 hwp + 6 hwpx) /
  1,614 페이지 / 페이지 수 회귀 0
- exam_science byte 차이: 4 페이지 모두 의도된 정정
  (page 1 Issue #572 인접 효과 / page 2 pi=61 / page 3 13/16번 / page 4 19번)
  PR 본문 100% 재현

시각 판정 ★ 통과 — 메인테이너 시각 검증 완료.

closes #573, 연관 #572 자동 close 검토 예정.
@edwardkim

Copy link
Copy Markdown
Owner

@planet6897 @jangster77 님,

본 PR 의 본질 commit (7d5075bf) 핀셋 cherry-pick 후 devel merge 완료되었습니다 (cb8d0a8).

처리 결과

본질 cherry-pick

  • 7d5075bf Stage 3 본질 정정 (src/renderer/layout/table_layout.rs +19/-2)
  • 충돌 0건 (PR mergeable=CONFLICTING 표시는 PR base 시점 차이, 본질은 깨끗 적용)
  • author Jaeook Ryu (@jangster77) 보존

결정적 검증

광범위 페이지네이션 회귀 sweep (본 환경 자동)

통계 결과
총 fixture 164 (158 hwp + 6 hwpx — samples/ 폴더 전체)
총 페이지 (devel baseline) 1,614
총 페이지 (cherry-pick 후) 1,614
fixture 별 페이지 수 차이 0

→ block / inline TAC 케이스 분리 + 인접 효과 (Issue #572) 의 광범위 안전성 정량 입증.

exam_science byte 차이 (PR 본문 100% 재현)

페이지 정정 영역
page 1 Page 1 header (Issue #572 인접 효과 자동 정정 — sub-tables 위치 정합)
page 2 pi=61 (Task #565/#568 인접 영역)
page 3 보기 셀 분수 단락 13/16번 (Task #573 권위 영역)
page 4 보기 셀 분수 단락 19번 (Task #573 권위 영역)

단일 본질 정정으로 4 페이지 모든 결함 + Issue #572 동시 정합 회복.

시각 판정 (★ 게이트)

작업지시자 시각 판정 결과:

메인테이너의 시각 판정 통과입니다.

핵심 정정 영역 (PR 본문 측정):

정밀 진단 + 인접 효과의 본질

Stage 1 진단의 통찰 — 사용자 보고 "오른쪽 편위" 의 실제 본질이 surrounding text 미렌더 였다는 진단 정합. 단일 본질 정정 (has_block_table_ctrl 신설 + layout_composed_paragraph 호출 라우팅 정정) 이 두 결함 (Task #573 + Issue #572) 동시 해결로 이어진 우수한 케이스. feedback_v076_regression_origin (표면 증상 → 실제 본질 추적) + feedback_hancom_compat_specific_over_general (block / inline TAC 케이스별 명시 가드) + feedback_rule_not_heuristic (HWP 표준 룰 treat_as_char 직접 사용) 모두 정합.

Issue #572 자동 close 검토

본 PR 의 인접 효과로 Issue #572 (Page 1 header sub-tables LEFT-shift) 가 자동 정정 — 시각 판정으로 정합 확인됨. 함께 close 처리 예정.

선행 PR 와 연계

세 PR 의 본질이 인접하나 각각 별개 분기 경로 — 메모리 룰 feedback_per_task_pr_branch 정합 (Task 별 단일 본질 PR).

처리 보고서: mydocs/pr/archives/pr_575_report.md (작성 후 push 됩니다).

본 PR 도 두 분의 협업 흐름의 우수한 사례입니다. Stage 1 정밀 진단으로 표면 증상 → 실제 결함 본질을 추적해서 단일 본질 정정으로 두 결함 (Task #573 + Issue #572) 을 동시 해결한 패턴이 본 사이클의 최고 수준 PR 이었습니다. 감사합니다.

@edwardkim edwardkim closed this May 5, 2026
edwardkim added a commit that referenced this pull request May 5, 2026
- 처리 보고서 추가: mydocs/pr/archives/pr_575_report.md
  PR #575 (Task #573, @planet6897 / @jangster77) 핀셋 cherry-pick
  1 commit + 결정적 검증 + WASM 4,571,604 bytes + 광범위 페이지네이션
  sweep (164 fixture / 1,614 페이지 / 회귀 0) + 시각 판정 ★ 통과
- 인접 효과: Issue #572 (Page 1 header sub-tables LEFT-shift)
  자동 정정 + 수동 close
- 검토 보고서 archives 이동:
  mydocs/pr/pr_575_review.md → mydocs/pr/archives/pr_575_review.md
- 5/5 orders 갱신: PR #575 항목 추가 (본 사이클 최고 수준 PR 사례)
edwardkim added a commit that referenced this pull request May 5, 2026
edwardkim added a commit that referenced this pull request May 5, 2026
…m 이미지 1라인 오프셋 정정 — @planet6897 / Jaeook Ryu 1 commit + 시각 판정 ★ 통과)

PR #580 (Task #577, @planet6897 PR / Jaeook Ryu commit author):
- 본질 결함: 셀 내부 비-TAC TopAndBottom + vert_rel_to=Para Picture 의
  anchor 시점 좌표로 para_y (advance 후) 사용 →
  image_y - cell_y = pad_top(3.78) + line_height(15.32) = 19.10 px
  (cell-clip ~10.81 px 초과)
- 본질 정정: text_wrap=TopAndBottom AND vert_rel_to=Para 양 조건에만
  para_y_before_compose 사용 (HWP IR anchor 시점 정합) +
  compute_object_position 자체 무변경 (다른 호출처 회귀 차단)
- 단일 파일 본질 (table_layout.rs +22/-3)
- 정량 측정: image_y - cell_y 19.10 → 3.78 px / LAYOUT_OVERFLOW
  exam_science 9.5→3.4 / mel-001 8건→0건

검증:
- cargo test --lib --release 1131 passed (회귀 0)
- svg_snapshot 6/6 / issue_546 1 / issue_554 12 / clippy 0 / build --release
- WASM 4,571,643 bytes (PR #575 baseline +39 bytes — table_layout.rs +22/-3 정합)
- 광범위 페이지네이션 회귀 sweep: 164 fixture (158 hwp + 6 hwpx) /
  1,614 페이지 / 페이지 수 회귀 0
- exam_science byte 차이: page 1/4 의도된 정정 (page 2/3 byte-identical)
- mel-001 byte 차이 0 (LAYOUT_OVERFLOW 정정이 SVG byte 단위는 무영향,
  clip 영역 안으로만 이동)

시각 판정 ★ 통과.

closes #577.
edwardkim added a commit that referenced this pull request May 5, 2026
v0.7.9 후속 patch 사이클 (5/4 ~ 5/6).

## 신규 기능

- **CLI 바이너리 릴리즈** (Issue #608/#612, @almet 의 요청)
  - 4 플랫폼 GitHub Release 자산 첨부 (Linux x86_64 / macOS x86_64+aarch64 /
    Windows x86_64) + SHA-256 체크섬
- **PNG raster backend** (PR #599, @seo-rii) — render P4 단계
  - native Skia 기반 PageLayerTree → PNG export, native-skia feature gate
  - **AI 파이프라인 + VLM 연동 도입** (메인테이너 후속 정정):
    - --vlm-target claude (1568 longest edge / 1.15 MP, Claude Vision 정합)
    - --scale / --max-dimension (자동 scale 계산)
    - export-png CLI 명령 + 매뉴얼 (한글 + 영문 dual)
    - 한글 폰트 fallback chain + char 단위 fallback (공백 두부 정정) +
      --font-path 동적 로딩

## 외부 PR cherry-pick (13 PR / 7 컨트리뷰터)

- @planet6897 / Jaeook Ryu (협업): PR #587/#589/#561/#564/#570/#575/
  #580/#584/#592/#593/#567
- @oksure (Hyunwoo Park): PR #600 (closes #513)
- @seo-rii: PR #599 (refs #536)
- @cskwork / @johndoekim / @nameofSEOKWONHONG / @jangster77 — 사이클 누적

## 메인테이너 정정

Skia 폰트 영역 5개 정정 (한글 fallback / font-path / char-fallback /
VLM 옵션 / export-png CLI).

## 인프라

- CI 빌드 안정성 (Cargo.toml [[example]] required-features)
- 광범위 페이지네이션 회귀 sweep 도구 (164 fixture / 1,614 페이지 자동)

## 후속 이슈

- #613 (VLM 프리셋 확장)
- #614 (DPI 메타데이터)
- #615 (pua_oldhangul.rs U+F53A 한컴 정합)
- #598 (rhwp-studio 각주 삭제, 외부 컨트리뷰터 공개)

## 잔여 PR (v0.7.11 후속 patch)

PR #601, #602 (@oksure) / PR #607 (@dicebattle) / PR #609 (@jangster77,
Task #604) / PR #611 (@kihyunnn).

상세: CHANGELOG.md (한글) / CHANGELOG_EN.md (영문).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants