Skip to content

Layout Phase 0~2 + 옛한글 PUA + 누적 task fix (Task #435~#528, #549/#550)#551

Closed
planet6897 wants to merge 248 commits into
edwardkim:develfrom
planet6897:devel
Closed

Layout Phase 0~2 + 옛한글 PUA + 누적 task fix (Task #435~#528, #549/#550)#551
planet6897 wants to merge 248 commits into
edwardkim:develfrom
planet6897:devel

Conversation

@planet6897

Copy link
Copy Markdown
Contributor

Summary

156 commits / 39 task accumulating since e585b589 (PR #538 처리 후속). 주요 변경:

Layout 리팩터링 (Phase 0~2)

옛한글 PUA → KS X 1026-1 자모 변환

Layout/렌더링 fix (Task #435~#516)

분석 only (close, source 변경 없음)

Test plan

Notes

  • pre-existing clippy 결함 2건 (table_ops.rs::edit_table_caption_unwrap, object_ops.rs::edit_picture_caption_unwrap) 은 본 PR 머지 후 별도 task 등록 권고.
  • main 브랜치 v0.7.3 머무름 → 본 PR 머지 후 별도 main 릴리즈 결정 필요 (작업지시자).

🤖 Generated with Claude Code

planet6897 and others added 30 commits April 29, 2026 11:54
exam_kor.hwp 24페이지 → 20페이지 정합 작업 1단계.

- 페이지별 단별 used/hwp_used/diff CSV (output/debug/task435/)
- 회귀 대상 5문서 페이지 수 (exam_kor 24, exam_eng 8, k-water-rfp 28, hwpspec 177, synam-001 35)
- RHWP_TYPESET_DRIFT 출력 캡처 (pi=0.30, pi=1.25 split 진단)
- compute_body_wide_top_reserve_for_para 산정 경로 추적

핵심 진단: col 1 reserve 306.1px (HWP 실제 94.5px 대비 +211.6px 과대).
원인: Paper-rel 좌표를 body-rel 변환 없이 그대로 reserve 에 누적.
Stage 2 에서 typeset.rs:2127-2172 의 VertRelTo::Paper 분기 정정.

수행계획서/구현계획서/Stage 1 보고서 포함.
compute_body_wide_top_reserve_for_para 의 VertRelTo::Paper 분기에서
body-rel 변환 누락 정정. body 와 일부만 겹치는 (header→body 침범)
케이스에서 Paper-rel 좌표를 그대로 reserve 에 누적하던 버그 수정.

수정 전 reserve = shape_y_offset(paper) + h + outer_bottom = 306.1 px
수정 후 reserve = max(0, shape_top_abs - body_top) ... = 94.4 px

결과:
- exam_kor.hwp: 24 → 22 페이지 (page 2, 15 orphan 해소)
- pi=0.30, pi=1.25 split → FullParagraph
- 회귀: exam_eng 8, k-water-rfp 28, hwpspec 177, synam-001 35 유지
- cargo test: 1062 passed

Stage 3 에서 일반 페이지 누적 -100~-300px 정정 (22 → 20).
원래 가설 ("표/도형 후 컬럼 잔여 공간 산정 부족") 재검토.
RHWP_TYPESET_DRIFT 분석 결과 diff 메트릭은 typeset cur_h 누적
(height_for_fit, trail_ls 제외) vs hwp_used (last line vpos+lh)
의 좌표계 차이를 측정하는 것일 뿐, "rhwp 가 채울 수 있는데 못 채운
잔여 공간" 이 아님을 확인.

실제 22→20 페이지 단축 장애물:
1. 섹션 1 페이지 14: Square wrap 표 + col 0 over-fill (1225>1211)
   → col 1 under-use (64px)
2. 섹션 1 페이지 15: 단일 컬럼 출력 (단정의는 2단인데 단 1 누락)
3. 섹션 2 페이지 18: pi=11 split + pi=13 [단나누기] orphan-like

3가지 전부 해결 시 22→19 가능 (목표 20 도달).

옵션 A/B/C 결정 필요 (현 상태 종료 / Stage 4 확장 / Stage 4 부분).
옵션 A 종료: 24→22 페이지 (Stage 2 col 1 reserve 정정).
잔여 22→20 미달성, 3가지 별도 메커니즘 (Square wrap over-fill,
단일 컬럼 출력 버그, col 0 cur_h over-advance) 별도 task 분리 권고.

edwardkim#393 (옵션 A) 본 task Stage 2 로 적용 완료, close 가능.
수행계획서(task_m100_439.md) + 단계1 진단 보고서.

핵심 발견:
- 이슈 가설의 engine.rs:702-711 는 fallback 경로 (RHWP_USE_PAGINATOR=1).
  기본 활성 엔진은 typeset.rs::TypesetEngine.
- 실제 버그 위치: typeset.rs::place_table_with_text (1400-1467).
  engine.rs 의 !is_wrap_around_table 가드 (engine.rs:1349, 1422) 누락.
- 페이지 14 col 0 used=1225.8 (본문 1211.3 초과 +14.5) 정확히 재현.

코드 변경 없음 — 임시 디버그 코드는 모두 revert.
place_table_with_text 의 정확한 cur_h 누적 추적 (디버그 후 revert):
- Square wrap 4 표가 pre_height + table_total 합산 → +244.88 px 과다
- HWP 의도: max(호스트 텍스트, 표 + v_offset) 만 누적

수정안: typeset.rs::place_table_with_text 에서
  current_height += max(pre_height, v_off + table_total) (Square wrap 시)

코드 변경 없음 — 임시 디버그 println 모두 revert.
typeset.rs::place_table_with_text 에서 Square wrap (어울림) 표일 때
current_height 누적을 pre_height + table_total → max(pre_height, v_off + table_total)
로 변경.

호스트 문단 텍스트와 어울림 표는 같은 수직 영역을 공유하므로
더 큰 쪽만 한 번 누적해야 HWP layout 의도와 일치.
PageItem 자체는 PartialParagraph + Table 모두 push (layout 렌더링 보존).

검증:
- 페이지 14 col 0 used 1225.8 → 1036.1 px (≤ 1211.3 충족)
- exam_kor.hwp 22 → 20 페이지 (목표 ≤ 21 충족)
- 회귀 샘플 6 종 (exam_eng/math, 21언어, aift, 2010-01-06, biz_plan) 페이지 수 동일
- cargo test 1066 개 모두 통과
- SVG 렌더링 정상

closes edwardkim#439
Stage 4 회귀 검증 결과:
- 149 개 sample HWP 전수 페이지 수 비교: exam_kor 만 22→20 변경, 148개 동일
- cargo test 1066 passed
- DoD 전부 충족

본 task 완료. closes edwardkim#439.
typeset.rs::place_table_with_text 의 Square wrap 표 누적 정책을
pre_height + table_total → max(pre_height, v_off + table_total) 로 변경.

효과:
- exam_kor.hwp 페이지 14 col 0 used 1225.8 → 1036.1 px (over-fill 해소)
- exam_kor.hwp 22 → 20 페이지
- 149 개 sample 중 exam_kor 만 변화, 148 개 동일 (회귀 0건)
- cargo test 1066 passed

closes edwardkim#439
…문제 수정

- 수행/구현 계획서 + Stage 1·2 보고서 작성
- src/renderer/layout.rs: paragraph border merge 그룹을 col_area 바닥/꼭대기로 클램프
- exam_kor p2/5/8/15 의 세로 구분선이 PDF 와 일치하는 길이로 정상화
  (p8: 1671 → 1425, 246px 단축, 페이지 바깥 침범 해소)
- vpos-reset 미존중으로 인한 텍스트 자체의 overflow 는 별도 이슈로 분리
- snapshot 갱신: tests/golden_svg/issue-267/ktx-toc-page.svg
  (invisible 구조 rect 의 height 5.34px 변화, 가시 변화 없음)
페이지 번호 박스가 column divider line 과 붙어 보이는 문제 해결.

원인: 꼬리말 paragraph 의 vert=Para + wrap=TopAndBottom 표가 paragraph
top 에 배치되어 본문 바닥과 같은 y 에 위치. HWP 의 실제 동작은 첫 라인의
line_height/2 만큼 아래에 anchor 되어 본문과 시각적 갭 형성.

수정: layout_header_footer_paragraphs 에서 해당 조건의 첫 paragraph 표는
y_offset 에 line_height/2 (px) 를 더하여 배치.

검증 (exam_kor.hwp 20p):
- 박스 top y: 1422.93 → 1439.47 (PDF 380.6mm 와 일치)
- column line - 박스 갭: 0px → 16.3-17.0px (PDF 16.0px 와 일치)
- column line 길이/위치는 PDF 자연 그대로 유지 (p1 1131px, p2+ 1226px)
- cargo test --release: 1117 passed, 0 failed
이슈 edwardkim#445 의 두 시각적 결함 (paragraph border 페이지 바깥 침범 + 페이지
번호 박스가 column line 에 붙음) 모두 PDF 와 일치하도록 수정 완료.

승인 후 local/devel 머지 + edwardkim#445 close 예정.
- 수행계획서 (mydocs/plans/task_m100_452.md): 옵션 A 선언, 4단계 분해
- 구현 계획서 (mydocs/plans/task_m100_452_impl.md): paragraph_layout.rs:2511-2520
  is_para_last_line 분기 제거, is_cell_last_line 만 보존
- Stage 1 보고서 (mydocs/working/task_m100_452_stage1.md):
  - exam_kor pi=1.line9↔pi=2.line0 step = 15.34px (버그) ↔ 단락내 24.51px
  - 10종 샘플 페이지 수 baseline 캡처 (/tmp/task_452_baseline/)
  - 21_언어 p1 col 1 pi=26+보기①②③ fit 확인 (edwardkim#332 회귀 baseline)
- orders 갱신: 버그 섹션 edwardkim#452 항목 추가
… + golden 갱신

- src/renderer/layout/paragraph_layout.rs:2511-2519: is_para_last_line 분기
  제거. is_cell_last_line(셀 내) 만 trailing 제외 보존, 본문 단락은 모든 줄에서
  y += lh + ls 통일. pagination/engine.rs 의 current_height 누적과 정합.
- 검증: exam_kor 1페이지 pi=1.line9↔pi=2.line0 step = 15.34 → 24.50 px
  (단락내 step 과 동일). cargo test --lib 1066 passed.
- golden SVG 2건 baseline 갱신 (Task edwardkim#332 에서 갱신된 것을 본 정합으로 재갱신):
  - tests/golden_svg/issue-147/aift-page3.svg
  - tests/golden_svg/issue-157/page-1.svg
- LAYOUT_OVERFLOW 메시지: 페이지 마지막 단락의 trailing ls (~10.9 px)
  가 col_bottom 을 살짝 넘으나 빈 공간이므로 시각 무영향. pagination
  engine 의 effective_trailing 처리로 페이지 분배는 유지.
paragraph_layout.rs:2511-2520 의 is_para_last_line 분기 제거. 본문 단락
모든 줄에서 y += lh + ls 통일 → pagination/engine.rs 의 current_height
누적과 정합. is_cell_last_line(셀 내) 만 trailing 제외 보존.

효과: exam_kor pi=1.line9↔pi=2.line0 step 15.34→24.50 px (단락내 step 과
동일, PDF 정합). 10종 샘플 페이지 수 변동 0. Task edwardkim#332 회귀 0 (21_언어
p1 col 1 pi=26+보기①②③ fit 유지). cargo test --lib 1066 passed +
svg_snapshot 6/6 (issue-147/157 baseline 재갱신).

closes edwardkim#452
paragraph_layout 의 skip_text_for_inline_shape 분기 제거. 인라인 글상자가 있는
줄에서 외부 문단 본문이 통째로 스킵되던 버그를 수정.

원인: skip_text_for_inline_shape 가 글상자 내부 텍스트와 외부 문단 본문 텍스트를
혼동하여, 외부 본문(글상자 좌·우의 일반 텍스트)도 함께 스킵하고 있었음.
글상자 자체와 내부 텍스트는 shape_layout 의 inline_shape_position 경로로 별도
렌더되므로 외부 본문을 항상 렌더해도 중복되지 않는다.

검증: samples/exam_kor.hwp 페이지 2 좌측 단 line 2 의 본문 39자(척사파의 ...
거스를) 가 글상자 좌·우로 분리 렌더되어 복원됨. 페이지 수 20 유지, 전체
테스트 1117 passed.
Stage 3 회귀 검증 결과 (1117 tests passed, 페이지 수 회귀 0).
Stage 4 최종 결과보고서 및 PR 메시지(`mydocs/report/task_m100_455_pr.md`) 작성.
오늘할일에 Task edwardkim#455 항목 추가.
`on_first_multicolumn_page` 가드는 새 페이지 시작 시 false 로 리셋되어
다단 구역이 여러 페이지에 걸칠 때 후속 페이지에서
`detect_column_breaks_in_paragraph` 호출이 차단됨. HWP 원본의 LINE_SEG
vpos 리셋 위치가 무시되어 좌측 단 하단이 col_bottom 을 초과해 그려지던
버그.

수정: `typeset.rs:856` (기본 경로) + `pagination/engine.rs:607`
(RHWP_USE_PAGINATOR=1 fallback) 의 가드에서 `on_first_multicolumn_page`
조건 제거.

검증:
- exam_kor p2 pi=39 0..4/4..7 → 0..2/2..7 (HWP 원본 정합)
- exam_kor LAYOUT_OVERFLOW 36 → 16 (페이지 5/8 의 동일 메커니즘 자동 해소)
- 다단 샘플 4종 (exam_eng/math/science/social) 페이지 수 + SVG byte 동일
- cargo test --release 1120 passed, 0 failed

closes edwardkim#459
planet6897 and others added 3 commits May 3, 2026 16:56
본질: PR edwardkim#506 의 layout_wrap_around_paras 호출이 비-TAC Picture wrap=Square
host 의 호스트 자기 텍스트를 두 곳에서 중복 emit → (1) 시각 결함 [edwardkim#525
표면 증상] + (2) 페이지네이션 inflation [본 edwardkim#546 표면 증상] 두 표면이
동일 root cause.

Task edwardkim#525 정정 (Picture Square wrap 의 wrap-around 호출 두 곳 모두 제거)
이 본 회귀 자동 해소.

검증:
- 2dbbd07 (edwardkim#525 push 직전 origin/devel) = 6 페이지 / p2 = 2 items 회귀 잔존
  직접 확인
- 현재 devel HEAD f5ad122 = 4 페이지 / p2 = 37 items / 1133.6 px = v0.7.9
  baseline 65e275d 정합

edwardkim#524 + edwardkim#525 역할 분담:
- edwardkim#524: 그림 anchor 위치 본질 정정 (typeset.rs)
- edwardkim#525: wrap-around 호출 중복 본질 정정 (layout.rs)

본 task 코드 변경 0 — 분석 보고서 + orders 갱신만.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…본질 정정으로 자동 해소, 코드 변경 0)
edwardkim added a commit that referenced this pull request May 3, 2026
cherry-pick (PR #551 의 248 commits / 50+ task 중 본질 6 commits 만):
- ce6ecac (d24a896): Task #525 수행 계획서
- c9b897d (ba680bc): Task #525 Stage 1 진단
- 5e6ce95 (68f109b): Task #525 구현 계획서
- 51e8612 (35c6c00): Task #525 Stage 2 정정 (layout.rs +14 / -69)
- 22dcd2d (78af341): Task #525 Stage 3 회귀 검증
- 79d10e6 (ec9fe47): Task #525 Stage 4 최종 보고서

검증:
- cargo test --lib 1113 passed
- cargo test --test issue_546/530/505/418/501 회귀 0
- cargo test --test svg_snapshot 6/6 passed
- cargo clippy --lib 0 건
- WASM 4,441,878 bytes (-626 from Task #546 시점) + studio 동기화

광범위 fixture sweep (Task #546 시점 ↔ Task #525 cherry-pick 후):
- 7 fixture / 113 페이지 byte-identical (회귀 0)
- exam_science 2 페이지 의도된 정정 (호스트 텍스트 dup emit 해소)

시각 판정 (작업지시자 한컴 2010/2020):
- 통과 ("#525 에서 해결하고자 한 문제 해결된 것을 시각 판정 통과했습니다")

Task #546 양립 확인 — 두 정정이 다른 영역 (typeset.rs vs layout.rs).

산출물:
- mydocs/pr/pr_551_review.md (검토)
- mydocs/pr/pr_551_report.md (처리 결과)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 3, 2026
…e wrap 호스트 텍스트 중복 emit 정정 — cherry-pick @planet6897 6 commits)

본 PR 은 외부 컨트리뷰터 @planet6897 (Jaeuk Ryu) 의 두 번째 PR (PR #538 후속).
fork devel 누적 (248 commits / 50+ task) 이라 작업지시자 결정으로 본질 Task #525 만
cherry-pick. 작업지시자도 인지하고 있던 결함의 root cause 정확 식별.

cherry-pick (6 commits):
- Task #525 수행 계획서 / Stage 1 진단 / 구현 계획서 / Stage 2 정정 / Stage 3 회귀 검증 / Stage 4 보고서
- 코드 변경: src/renderer/layout.rs (+14 / -69 LOC, net -55)

본질: layout_wrap_around_paras 가 비-TAC Picture wrap=Square host 의 호스트
paragraph 자기 텍스트를 PageItem::FullParagraph 정상 경로 외에 두 곳에서 추가
emit (layout.rs:3093 layout_shape_item + :3496 layout_column_shapes_pass) →
같은 줄을 다른 col_w 정렬로 distinct x 위치 emit → 시각 중첩.

정정: Picture Square wrap 의 wrap-around 호출 두 곳 모두 제거. Table Square
wrap 호출 (layout.rs:2555) 은 의도된 동작 유지. paragraph_layout.rs:822/973 의
has_picture_shape_square_wrap 분기가 LINE_SEG.cs/sw 기반으로 그림 옆 (좁은) +
그림 아래 (넓은) 모두 처리.

검증:
- cargo test --lib 1113 passed
- cargo test --test issue_546/530/505/418/501 회귀 0
- cargo test --test svg_snapshot 6/6 통과
- cargo clippy --lib 0 건
- WASM 4,441,878 bytes (-626 from Task #546 시점) + rhwp-studio 동기화

광범위 fixture sweep:
- 8 fixture / 113 페이지 byte-identical (회귀 0)
- exam_science 2 페이지 의도된 정정 (dup emit 해소)

시각 판정 (작업지시자 한컴 2010/2020 직접): 통과.

Task #546 양립 확인 — 두 정정이 다른 영역 (typeset.rs current_height vs
layout.rs layout_wrap_around_paras 중복 호출).

PR #551 의 다른 영역 (242 commits / ~50 task) 은 별도 처리 결정 — 컨트리뷰터에게
다음 PR 전 fork devel 동기화 + task 별 분리 PR 안내 예정.
@edwardkim

Copy link
Copy Markdown
Owner

@planet6897 님의 PR 중 Task #525 본질만 cherry-pick 으로 devel 에 반영했습니다 (devel `165df21`).

처리 결정 — Task #525 우선 cherry-pick

본 PR 의 248 commits / 50+ task 중 Task #525 (비-TAC Picture wrap=Square 호스트 텍스트 중복 emit) 만 우선 cherry-pick.

작업지시자도 인지하고 있던 결함의 root cause 정확 식별 + 영향 광범위 (7 샘플 170 페이지 중 37 페이지 / 205 dup-instances) + 작은 코드 변경 (`layout.rs` +14 / -69 LOC) 으로 정합한 정정.

머지된 commits (6)

author 는 @planet6897 으로 보존되었습니다.

검증

  • `cargo test --lib` 1113 passed
  • `cargo test --test issue_546/530/505/418/501` 회귀 0
  • `cargo test --test svg_snapshot` 6/6 통과
  • `cargo clippy --lib` 0 건
  • WASM 4,441,878 bytes + rhwp-studio 동기화

광범위 fixture sweep (Task #546 시점 ↔ Task #525 cherry-pick 후):

  • 8 fixture / 113 페이지 byte-identical (회귀 0)
  • exam_science 2 페이지 의도된 정정 (dup emit 해소)

시각 판정 (작업지시자 한컴 2010/2020)

✅ 통과 — Task #525 의 본질 (호스트 paragraph 텍스트 중복 emit) 정정 효과 시각 확인 완료.

본 환경 Task #546 양립 확인

본 환경에는 PR #538 처리 후 별도로 등록된 Task #546 (`82e41ba` revert 로 exam_science 페이지네이션 회귀 정정) 이 적용되어 있습니다. Task #525 와 Task #546다른 영역의 다른 본질 (Task #546 = typeset.rs current_height / Task #525 = layout.rs layout_wrap_around_paras 중복 호출) 이라 두 정정이 함께 작동.

처리 보고서: `mydocs/pr/archives/pr_551_report.md`

본 PR 의 다른 영역 (제외) — 242 commits / ~50 task

본 cherry-pick 범위 외의 task 들 (Task #517~#523 Layout 리팩터링 / #528 옛한글 PUA / #524 Square wrap 그림 anchor / #547+#548 셀 인라인 TAC Shape / #435~#516 다수 등) 은 본 PR 처리 범위 외. 별도 검토 후 결정.

컨트리뷰터께 다시 부탁드리는 사항

PR #538 close 시 안내드린 fork devel 동기화 가 본 PR 에서도 미적용 상태 (PR base/head 가 fork 의 devel 그대로) 였습니다. 또한 PR 본문의 "main v0.7.3" 표현은 잘못된 정보 (현재 main 은 v0.7.9 `0fb3e675`) 입니다.

다음 PR 작업 전에 본 환경 `devel` 동기화 + `main` 정합 점검 부탁드립니다:

```bash

본 repo 에 upstream 등록 (1회)

git remote add upstream https://github.com/edwardkim/rhwp.git

devel 동기화

git checkout devel
git fetch upstream
git pull --ff-only upstream devel
git push origin devel

main 정합 확인 (현재 v0.7.9)

git fetch upstream main:main
git log main --oneline -3
```

또한 task 별 분리 PR 권장합니다 — PR #538 (50+ task) / PR #551 (50+ task) 의 큰 묶음은 (1) PR 검토 시간이 매우 큼, (2) 충돌 위험이 큼, (3) 본 PR 처럼 본질만 cherry-pick 하면 다른 영역의 작업이 누락될 위험이 있습니다. task 1~3개 단위로 작은 PR 을 자주 보내주시는 게 더 정합한 워크플로우입니다.

@planet6897 님의 진단 깊이와 정정 정합성은 매우 인상적입니다 — 단지 PR 형식만 정합하게 분리해 주시면 더 빠르게 머지가 가능합니다.

@edwardkim edwardkim closed this May 3, 2026
edwardkim added a commit that referenced this pull request May 3, 2026
- mydocs/pr/pr_551_{review,report}.md → archives/
- mydocs/orders/20260503.md 갱신 (PR #551 머지 추가)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 3, 2026
Stage 4 cherry-pick 시 충돌 (issue-147 / issue-157) 을 theirs 로 채택 후
UPDATE_GOLDEN=1 cargo test --test svg_snapshot 으로 본 환경 코드 기준
golden 재생성. svg_snapshot 6/6 통과.

본 환경의 Task #525 정정 (이미 cherry-pick) 영역과 PR #551 head 의 다른
정정 영역의 차이로 인한 충돌 해소 — UPDATE_GOLDEN 메커니즘이 본 환경
정합 출력으로 자동 갱신.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 3, 2026
…s + fixup)

cherry-pick 8 commits + 1 fixup (UPDATE_GOLDEN 재생성):
- 7eb14ea (ef33a7a): 수행계획서 v1
- 2c70ec4 (33351e1): 구현계획서 v1
- 93a3e4e (532c9b3): Stage 1 본질 발견 + v2
- 07a79a5 (c3f6a95): Stage 2 KTUG 매핑 + 변환 함수 (pua_oldhangul.rs +5773)
- 44338f6 (a15847c): Stage 3 PUA → 자모 변환 적용 (composer + svg + web_canvas)
- (Stage 4) (e37acdc): Source Han Serif K Old Hangul subset (golden 충돌 → theirs)
- 124266a (0687cfc): Stage 4 hotfix 한컴 책괄호 + 예시 마커
- 823beca (654a4ad): Stage 5 최종 보고서
- 442982c (fixup): golden SVG 본 환경 코드 기준 재생성

검증:
- cargo test --lib 1118 passed
- cargo test --test issue_546/530/505/418/501 회귀 0
- cargo test --test svg_snapshot 6/6 passed
- cargo clippy --lib 0 건
- WASM 4,543,430 bytes (+101,552 from PR #551 시점, 매핑표 + 폰트 subset 반영)
- exam_kor p17 PUA 잔존 0 + Hangul Jamo 102 (PR #551 보고와 일치)

작업지시자 시각 판정 통과 ("깨져보이던 옛한글이 정상적으로 매핑됩니다").

부수 발견 (별도 이슈):
- 이슈 #555 — 옛한글 PUA → 자모 변환 후 폰트 매트릭스 (글자폭/줄간격) 계산 갱신
- 본 cherry-pick 의 Stage 3 (Option A) 의 인덱싱 불변성 trade-off

본 환경 Task #509 (작업지시자 임시 정정) 는 Task #528 의 5660 매핑에 자연 흡수.

산출물:
- mydocs/pr/pr_551_review_v2_528.md (검토)
- mydocs/pr/pr_551_v2_528_report.md (처리 결과)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 3, 2026
…026-1 자모 변환 — @planet6897 8 commits + UPDATE_GOLDEN fixup)

본 cherry-pick 으로 옛한글 PUA 처리의 임시 정정 (작업지시자 Task #509,
12 매핑) → 본질 정정 (Task #528, 5660 매핑 + Source Han Serif K subset)
교체.

cherry-pick 8 commits + 1 fixup:
- 수행계획서 v1 + 구현계획서 v1
- Stage 1 본질 피벗 (Hangul Jamo Extended → HanCom Hanyang-PUA)
- Stage 2 KTUG Hanyang-PUA 매핑 표 (5660 entries 자동 생성)
- Stage 3 PUA → KS X 1026-1 자모 변환 (Option A — 렌더러 시점)
  · src/renderer/composer.rs (display_text 필드 + convert 함수)
  · src/renderer/svg.rs / web_canvas.rs (draw_text 시점 변환)
- Stage 4 Source Han Serif K subset (234 KB woff2, SIL OFL 1.1)
  · web/fonts/SourceHanSerifK-OldHangul-subset.woff2 + OFL.txt
  · golden SVG 5건 cosmetic 갱신 (font-family chain 추가)
- Stage 4 hotfix 책괄호 (《 》) + 예시 마커 (▸) 매핑
- Stage 5 최종 보고서
- fixup: golden SVG 본 환경 코드 기준 재생성 (UPDATE_GOLDEN)

자료원: KTUG HanyangPuaTableProject (Public Domain) + Source Han Serif K
(Adobe + Google, OFL 1.1).

검증:
- cargo test --lib 1118 passed
- cargo test --test issue_546/530/505/418/501 회귀 0
- cargo test --test svg_snapshot 6/6 passed
- cargo clippy --lib 0 건
- WASM 4,543,430 bytes + rhwp-studio 동기화

exam_kor p17 PUA 잔존 0 + Hangul Jamo 102 (PR #551 Stage 5 보고와 정확히 일치).

작업지시자 시각 판정 통과 ("깨져보이던 옛한글이 정상적으로 매핑됩니다").

후속 이슈 (별도 task 분리):
- 이슈 #555: 옛한글 PUA → 자모 변환 후 폰트 매트릭스 (글자폭/줄간격) 계산 갱신
  · Stage 3 의 Option A (인덱싱 불변성) trade-off — 매트릭스 계산이 PUA
    char 1글자 기준 유지, 자모 시퀀스와 정합 안 됨

closes #528 #512
@edwardkim

Copy link
Copy Markdown
Owner

@planet6897 님, PR #551Task #528 (옛한글 PUA → KS X 1026-1 자모 변환) 도 핀셋 cherry-pick 으로 devel 에 추가 반영했습니다 (devel `3638038`).

작업지시자의 평가:

기존에 PUA 처리를 급한대로 작업지시자가 했지만, 그쪽에서 해결하지 못한걸 이 컨트리뷰터가 한 것으로 판단합니다.

본 환경의 임시 정정 (Task #509, 12 매핑) 을 본질 정정 (Task #528, 5660 매핑 + Source Han Serif K subset) 으로 교체. 작업지시자 시각 판정 통과 ("깨져보이던 옛한글이 정상적으로 매핑됩니다").

머지된 commits (8 + 1 fixup)

  • 수행계획서 / 구현계획서 / Stage 1 본질 피벗 / Stage 2 KTUG 매핑 / Stage 3 변환 적용 / Stage 4 폰트 + Stage 4 hotfix / Stage 5 보고서
  • fixup: golden SVG 본 환경 코드 기준 재생성 (UPDATE_GOLDEN, golden SVG 2건 충돌 해소)

author 는 @planet6897 으로 보존되었습니다.

검증

후속 이슈 등록

작업지시자 시각 판정 중 발견된 후속 결함:

폰트 매트릭스 계산도 이에 따라 갱신되어야 겠네요.

이슈 #555 — 옛한글 PUA → 자모 변환 후 폰트 매트릭스 (글자폭/줄간격) 계산 갱신.

본 cherry-pick 의 Stage 3 (Option A — 렌더러 시점 변환, 인덱싱 불변성 유지) 의 trade-off 영역. 별도 task 로 진행하겠습니다.

이슈 close

컨트리뷰터께 감사

KTUG 권위 자료 발굴 + Source Han Serif K (OFL) 라이선스 정합 + 자동 생성 스크립트 + Stage 1 본질 피벗 (Hangul Jamo Extended → HanCom Hanyang-PUA) 의 진단 깊이가 매우 인상적이었습니다. 작업지시자가 임시로 처리했던 PUA 영역의 본질 정정을 권위 자료 기반으로 정합하게 완성해 주셨습니다.

Task #525 (이전 cherry-pick) + Task #528 (본 cherry-pick) 두 본질 정정이 본 사이클에 반영되었습니다. PR #551 의 다른 영역 (~50 task) 은 별도 검토 후 결정하겠습니다 — 그 사이 다음 PR 작업 시 fork devel 동기화 (`git pull --ff-only origin devel`) 와 task 별 분리 PR 부탁드립니다.

처리 보고서: `mydocs/pr/archives/pr_551_v2_528_report.md`

edwardkim added a commit that referenced this pull request May 3, 2026
- mydocs/pr/pr_551_{review_v2_528,v2_528_report}.md → archives/
- mydocs/orders/20260503.md 갱신 (PR #551 Task #528 핀셋 머지 + 신규 이슈 #555 추가)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
planet6897 added a commit to planet6897/rhwp that referenced this pull request May 4, 2026
…y-pick @planet6897 1 commit)

옵션 A2 채택 — `05beb208` (Task edwardkim#544 v2 Stage 2) 단독 cherry-pick.
B1 진단 결과 본 devel 의 Task edwardkim#479 미적용 trailing-ls 모델 확인 →
당초 옵션 A3 (edwardkim#552 + v2 + v3) 의 모델 전환 위험 회피 → 최소 fix 채택.

- mydocs/pr/pr_551_review_v3_544_a2.md (검토 문서)
- mydocs/pr/pr_551_v3_544_a2_report.md (처리 보고서)
- mydocs/orders/20260504.md (오늘할일 신규)

closes edwardkim#544

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
planet6897 added a commit to planet6897/rhwp that referenced this pull request May 4, 2026
… (옵션 A2 — passage 글상자 우측 시프트 정정 — @planet6897 1 commit)

작업지시자 보고: "21_언어_기출_편집가능본.hwp 1/2/4/5/7/8/11/13/14 페이지
글상자가 오른쪽으로 밀려있음".

이슈 edwardkim#544 (closed) 재오픈 후 PR edwardkim#551 잔존 cherry-pick. 당초 옵션 A3
(edwardkim#552 + v2 + v3) 검토했으나 B1 진단 결과 본 devel 의 Task edwardkim#479 미적용
(pre-edwardkim#479 trailing-ls 항상 가산 모델) 확인 → edwardkim#552/v3 cherry-pick 시
모델 전환 위험. 옵션 A2 (`05beb208` 단독, edwardkim#547+edwardkim#544(1) 통합) 채택.

본질 정정 (paragraph_layout.rs):
1. box_x = col_area.x / box_w = col_area.width (margin 미적용,
   paragraph border outline = col_area 전체).
2. inner_pad 분기 제거 (visible-stroke + bs=0 인 경우 margin_left =
   box_margin_left + inner_pad_left 이중 적용 → 단일 적용).

측정 (페이지 4 [7~9]):
- 박스 left x: 128.51 → 117.17 (PDF 117.0)
- 박스 width: 402.5 → 425.17 (PDF 425.1)
- 본문 첫 글자 '평' x: 153.12 → 128.51 (PDF 128.5)
- 9 박스 (col 0/1) 모두 정합

검증:
- cargo test --lib 1120 / test_544+test_547 +2 GREEN / 회귀 0건
- clippy 0 신규 (pre-existing 2건 동일 baseline)
- 5 샘플 58 페이지 광범위 sweep: 38 differ (의도된 paragraph border
  정합 변경, visible-stroke paragraph text -11.33 px 좌측 시프트 의도)
- 회귀 검출 가능 영역 (비-border paragraph text) 0 변경
- 작업지시자 시각 판정 통과

cherry-pick 1 commit:
- 457d5f3 Task edwardkim#544 v2 Stage 2 (`05beb208` from @planet6897)

처리 보고서: mydocs/pr/pr_551_v3_544_a2_report.md
검토 문서: mydocs/pr/pr_551_review_v3_544_a2.md

closes edwardkim#544

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
planet6897 added a commit to planet6897/rhwp that referenced this pull request May 4, 2026
- mydocs/pr/pr_551_review_v3_544_a2.md → archives/
- mydocs/pr/pr_551_v3_544_a2_report.md → archives/
- mydocs/orders/20260504.md: 처리 상태 갱신 (devel merge f6039f3 push + 이슈 edwardkim#544 close)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
planet6897 added a commit to planet6897/rhwp that referenced this pull request May 4, 2026
- mydocs/pr/pr_task548_review.md
- mydocs/pr/pr_task548_report.md
- mydocs/orders/20260504.md: Task edwardkim#548 사이클 추가

새 PR 등록 (PR edwardkim#551 잔존 누적 회피 — feedback_no_pr_accumulation
메모리 적용 첫 사례).

closes edwardkim#548

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim pushed a commit that referenced this pull request May 4, 2026
…1 commit)

옵션 A2 채택 — `05beb208` (Task #544 v2 Stage 2) 단독 cherry-pick.
B1 진단 결과 본 devel 의 Task #479 미적용 trailing-ls 모델 확인 →
당초 옵션 A3 (#552 + v2 + v3) 의 모델 전환 위험 회피 → 최소 fix 채택.

- mydocs/pr/pr_551_review_v3_544_a2.md (검토 문서)
- mydocs/pr/pr_551_v3_544_a2_report.md (처리 보고서)
- mydocs/orders/20260504.md (오늘할일 신규)

closes #544

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim pushed a commit that referenced this pull request May 4, 2026
- mydocs/pr/pr_551_review_v3_544_a2.md → archives/
- mydocs/pr/pr_551_v3_544_a2_report.md → archives/
- mydocs/orders/20260504.md: 처리 상태 갱신 (devel merge f6039f3 push + 이슈 #544 close)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 4, 2026
…v2 + Task #555)

cherry-pick (작업지시자 옵션 A — 7 commits 모두):
- a30dca7 (457d5f3): Task #544 v2 Stage 2 paragraph border 좌표/inset
- f30b352 (b146b83): PR #551 Task #544 핀셋 처리 보고서 + 검토 문서
- (skip) (f6039f3): merge commit — 이미 적용된 영역
- f45f6a0 (f807378): PR #551 Task #544 처리 후속 archives 이동
- af556a5 (096b573): Task #555 수행/구현 + Stage 1 진단
- f44a721 (beade38): Task #555 Stage 2-4 옛한글 PUA 폰트 매트릭스 정정 (옵션 A)
- 4af03b7 (eac36f2): Task #555 최종 보고서

검증:
- cargo test --lib 1123 passed (Task #555 단위 테스트 +3 GREEN)
- cargo test --test issue_546/530/505/418/501 회귀 0
- cargo test --test svg_snapshot 6/6 passed
- cargo clippy --lib 0 건
- WASM 4,585,998 bytes (+42,568 from Task #528, Task #544 v2 + #555 반영) + studio 동기화

작업지시자 시각 판정 (web Canvas):
- "웹 에디터에서 옛한글 매트릭스 개선이 시각적으로 확인되었습니다.
   아직 미진한 점이 있지만 분할 정복 전략에 맞는 접근법입니다."

본 PR 의 본질:
- Task #555 (closes #555): 옛한글 PUA → 자모 변환 후 폰트 매트릭스 갱신
  · effective_text_for_metrics 헬퍼 + 호출처 10건 패치
  · 13 fixture 481 페이지 481/481 byte-identical (PR 본문)
  · Conservative fix (현재 visual 영향 없음, 잠재적 결함 차단)
- Task #544 v2: paragraph border 좌표/inset 산식 (PR #560 사이클 영역, 본 환경 처음 적용)

컨트리뷰터 메모리 룰 적용 정합:
- feedback_no_pr_accumulation, feedback_per_task_pr_branch
- feedback_essential_fix_regression_risk, feedback_rule_not_heuristic

산출물:
- mydocs/pr/pr_562_report.md (처리 결과)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 4, 2026
…PUA 폰트 매트릭스 — @planet6897 6 commits) — closes #555

본 PR 은 외부 컨트리뷰터 @planet6897 (Jaeuk Ryu) 의 PR. Task #528 후속 결함
(이슈 #555: 옛한글 PUA → 자모 변환 후 폰트 매트릭스 갱신) 정정.

작업지시자 결정으로 옵션 A (7 commits 모두 cherry-pick) 진행 — Task #555 의
본질 외에 PR #551 Task #544 v2 처리 영역 (PR #560 사이클 영역) 도 함께 본
환경에 적용.

cherry-pick (6 commits + merge commit 1건 skip):
- Task #544 v2 Stage 2: paragraph border 좌표/inset 산식 정정
  · paragraph_layout.rs box_x/w 산식 + inner_pad 분기 제거
- PR #551 Task #544 핀셋 처리 보고서 + 검토 + archives
- Task #555: 옛한글 PUA → 자모 변환 후 폰트 매트릭스 갱신 (3 commits)
  · effective_text_for_metrics 헬퍼 (composer.rs)
  · 호출처 10건 패치 (composer / layout / table_layout)
  · Task #555 단위 테스트 +3 GREEN

본질 (Task #555):
- Task #528 의 Option A (렌더러 시점 변환) 의 인덱싱 불변성 trade-off 로
  run.text 가 PUA char 1글자 보존 → 폰트 매트릭스가 자모 시퀀스와 정합 안 됨
- effective_text_for_metrics(run) = run.display_text.as_deref().unwrap_or(&run.text)
  fallback 패턴 + 호출처 10건 패치
- Conservative fix: 13 fixture 481 페이지 481/481 byte-identical (PR 본문)

검증:
- cargo test --lib 1123 passed (Task #555 단위 테스트 +3 GREEN)
- cargo test --test issue_546/530/505/418/501 회귀 0
- cargo test --test svg_snapshot 6/6 passed
- cargo clippy --lib 0 건
- WASM 4,585,998 bytes + rhwp-studio 동기화

시각 판정 (작업지시자):
- "웹 에디터에서 옛한글 매트릭스 개선이 시각적으로 확인되었습니다.
   아직 미진한 점이 있지만 분할 정복 전략에 맞는 접근법입니다."

미진한 영역은 향후 별도 task 로 분할 정복 정합.

컨트리뷰터의 메모리 룰 적용 정합:
- feedback_no_pr_accumulation: 새 PR 로 등록 (PR #551 잔존 누적 회피)
- feedback_per_task_pr_branch: 별도 fork branch (pr-task555)
- feedback_essential_fix_regression_risk: 481 페이지 광범위 sweep
- feedback_rule_not_heuristic: 단일 fallback 패턴
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