Skip to content
Merged
Prev Previous commit
Merge origin/devel: PR #266 #284 #285 반영
# Conflicts:
#	mydocs/orders/20260424.md
  • Loading branch information
edwardkim committed Apr 24, 2026
commit 5f05eb164fef7d7c77c5a70518e9b29beff81ac8
104 changes: 103 additions & 1 deletion mydocs/orders/20260424.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,107 @@
### 교훈
범위를 좁게 정하고 시작한 타스크에서 연쇄 발견한 2건의 구조적 버그 (error.rs Debug 누출, main.ts UI 전달 누락) 를 "범위 외" 로 밀어내지 않고 함께 고친 판단이 옳았음. 이를 제외했다면 **"에러 메시지 개선했는데 사용자는 아무 변화 못 느낌"** 결과가 되어 사용자 경험 개선 0 이 되었을 것. Root cause 를 사용자 가시 지점까지 끝까지 추적하는 원칙 재확인.

## 2. Task #267 — right tab 3경로 선행 공백 처리 통일
## 2. Task #280 — 수식 SVG 렌더링 폰트 스택 재정렬

### 배경

작업지시자 제보: `samples/equation-lim.hwp` (`lim _{h→0} {f(2+h)-f(2)} over h`) 가 한컴 PDF 대비 "폰트가 볼드, 크기가 다름". 5단계로 수행.

### 조사 (이 타스크의 실질적 가치)

"크기가 다르다" 는 인상이 PDF 콘텐츠 스트림(`BT /F1 110 Tf ... lim ... BT /F1 92 Tf ... f ...`)에서 `lim=110pt` vs 본문=92pt 로 보여 "함수명 1.2x 확대 규칙" 의심으로 출발. 그러나:

- `exam_math.hwp` 내 16개 수식의 bbox 높이 비교 → `"b= log 2"` = 1125 HWPUNIT (font_size * 1.02) 로 단순 수식과 동일
- **함수명 확대 규칙 없음** 을 데이터로 확정
- PDF 의 110/92 차이는 HyhwpEQ 폰트의 ASCII 글리프(l,i,m) vs PUA 수식 글리프(f,h,(,)) em 박스 차이를 HWP 엔진이 보정한 것

이 판단 오류를 피한 것이 이번 타스크의 핵심 — 1.2x 배율을 잘못 적용했으면 오히려 다른 수식들이 깨졌을 것.

### 변경 범위

- **코드** `src/renderer/equation/svg_render.rs` + `canvas_render.rs` 각 1줄:
- `EQ_FONT_FAMILY` / `set_font` 에서 **`Cambria Math` 제거** (Windows 볼드 인상의 근본 원인)
- `'Pretendard'` 제거 (산세리프, 수식 부적합)
- `'STIX Two Text'`, `'Times New Roman'`, `'Times'` 추가 (클래식 세리프 폴백 체인)
- 최종 스택: `'Latin Modern Math', 'STIX Two Text', 'STIX Two Math', 'Times New Roman', 'Times', serif`
- `Latin Modern Math` 첫 번째 유지 → `svg.rs:332` 의 폰트 임베딩 파이프라인 호환
- **샘플** `samples/equation-lim.{hwp,pdf}` 커밋 (재현용)

### 검증

- `cargo test --lib equation`: **48 passed / 0 failed**
- `cargo test --test svg_snapshot`: 3 passed
- `cargo clippy --lib -- -D warnings`: clean
- `cargo check --target wasm32-unknown-unknown --lib`: clean
- 시각 회귀: `equation-lim.hwp` before/after/pdf 비교 + `exam_math.hwp` 5개 페이지 육안 → "볼드 인상" 해소, 레이아웃 변화 없음
- p013 에서 `lim`, `sin`, `ln`, `∫` 가 본문과 동일 크기로 렌더링됨 재확인 (함수명 1.2x 규칙 없음 재증명)

### 산출물

- `mydocs/plans/task_m100_280{,_impl}.md`
- `mydocs/working/task_m100_280_stage{1,2,3,4}.md` + 시각 비교 PNG 다수
- `mydocs/report/task_m100_280_report.md`

### 후속 이슈

- **#283** — 괄호 `(` `)` SVG path 폭이 폰트 글리프 대비 과대 (Phase 2, 별도 이슈 등록 → 오늘 처리 완료)

### 교훈

"PDF 콘텐츠 스트림의 숫자(110 vs 92)" 같은 단일 근거로 스케일 규칙을 추정하지 않고, **샘플 bbox 데이터 다수 교차 비교로 가설 검증** 후 수정 범위 결정. 결과적으로 1줄 수정으로 제보 해결.

## 3. Task #283 — 수식 괄호 path → 글리프 전환 (#280 Phase 2)

### 배경

#280 의 폰트 재정렬 후에도 파렌 `(` `)` 가 얇은 moon 으로 남아 폰트 글리프와 불일치. 박스 할당폭 4.40px 중 실제 곡선은 1.54px (31%), 나머지 69% 가 whitespace → 글자와 gap 벌어져 어색함.

### 조사 (단계 1·2)

Times `(` 실측: advance 4.89 (em 0.333), bbox 5.0, 폭 꽉 참. 현재 rhwp path 는 단일 제어점 quadratic Bezier — 수학적으로 대칭 moon 형상만 생성. **6개 변형 프로토타입(보수/강화 A+C · 글리프 B · 극단 2개) 을 Chrome 렌더로 비교** → path 튜닝 5개 모두 moon 극복 실패, **B_glyph 만 폰트와 일관된 타이포그래피**.

### 선정

**옵션 B (글리프 전환 + 임계치 분기)**:
- `body.height / fs ≤ 1.2` + `(`/`)` → `<text>(</text>` (Times advance 4.89 안에 글리프 자연 배치)
- `> 1.2` → 기존 path 유지 (분수·sum·행렬 감쌈)
- Matrix arm 은 항상 path (변경 없음)

### 변경 범위

- **코드** `src/renderer/equation/layout.rs:832` — `paren_w: fs * 0.3 → fs * 0.333` (Times advance 매치)
- **코드** `src/renderer/equation/svg_render.rs` `LayoutKind::Paren` arm — 높이 + 글리프 종류 분기 (`<text>` / path)
- **코드** `src/renderer/equation/canvas_render.rs` `LayoutKind::Paren` arm — 동일 분기 (`ctx.fill_text` / path)
- **테스트** `test_paren_svg` 갱신 (path → text assertion), `test_paren_stretch_svg` 신규 (스트레치 path 보전 확인)

### 검증

- `cargo test --lib equation`: **49/49** (신규 스트레치 테스트 포함)
- `cargo test --test svg_snapshot`: 3 passed
- `cargo clippy --lib --bins --tests`: 에러 없음
- `cargo check --lib --target wasm32-unknown-unknown`: clean
- `cargo test --lib` 전체: 950 pass / 14 fail (기존 CFB writer, #280 단계 확인 완료)
- 실측: `equation-lim.svg` `<path>` **4건 → 0건**, `<text>(/)</text>` **4건 신규**
- 시각 회귀: AFTER ≈ PDF 레퍼런스 (`compare.png` 3면 비교)
- exam_math.hwp 20페이지 중 4개 샘플링 — 텍스트 높이 글리프 / 스트레치 path 분기 올바름

### 산출물

- `mydocs/plans/task_m100_283{,_impl}.md`
- `mydocs/working/task_m100_283_stage{1,2,3,4}.md` + 단계별 SVG/PNG 산출물
- `mydocs/report/task_m100_283_report.md`

### 후속 과제 후보 (범위 밖)

- 기타 괄호 `{`·`[`·`|` 글리프 전환 (동일 패턴 확장)
- 스트레치 path 품질 개선 (cubic Bezier/다중 세그먼트로 재설계)

### 교훈

1. **path 튜닝 3안을 모두 프로토타입** 해 본 것이 결정적 — "제어점 이동으로 어떻게든 된다" 가설에 갇히지 않고 데이터로 "수학적 한계" 확정. "시각 비교 1회로 글리프 명확히 우세" 로 판단 단순화.
2. **폰트 글리프가 있는데 path 로 재구현하지 말자** — 50년간 다듬어진 Times `(` 를 40줄 Bezier 로 이기려는 싸움은 구조적으로 불리. 도메인 자원(폰트) 을 존중.

## 4. Task #267 — right tab 3경로 선행 공백 처리 통일

### 배경
KTX.hwp 목차 2페이지에서 소제목 페이지 번호가 ~9.33px 우측으로 밀리는 버그.
Expand All @@ -72,6 +172,8 @@ right tab 처리 코드가 3경로로 분산되어 있고 탭 직후 선행 공

### 종료
- [#265](https://github.com/edwardkim/rhwp/issues/265) — HWP 3.0 파일 감지 + 친절한 에러 메시지로 해결
- [#280](https://github.com/edwardkim/rhwp/issues/280) — 수식 SVG 폰트 스택 재정렬 (Cambria Math 제거 → Times New Roman 폴백)
- [#283](https://github.com/edwardkim/rhwp/issues/283) — 수식 괄호 path → 글리프 전환 (#280 Phase 2)

### PR 제출·대기
- [PR #273](https://github.com/edwardkim/rhwp/pull/273) — Task #267 right tab 정렬 수정, 머지 대기
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.