fix: WMF SetTextAlign vertical bits 파싱 정정 + baseline y shift 정합 — WMF 박스 외부 텍스트 표시 해소 (closes #965, ports PR #918 Stage 33-A)#966
Closed
jangster77 wants to merge 5 commits into
Closed
Conversation
… 박스 외부 텍스트 표시 해소 (closes edwardkim#965, ports PR edwardkim#918 Stage 33-A) ## 본질 `samples/hwp3-sample16.hwp` page 18 (한컴 page 16) 의 WMF 다이어그램 (주전산센터 목표시스템 구성안) 내부 박스의 한글 텍스트 ("PE6450", "기록서버", "Windows 서버군", "Unix 서버군" 등) 가 박스 외부로 벗어남. ## Root cause `src/wmf/converter/svg/mod.rs:2191-2197` 의 SetTextAlign vertical bits 파싱: ```rust let align_vertical = [ VerticalTextAlignmentMode::VTA_BOTTOM, VerticalTextAlignmentMode::VTA_TOP, // VTA_TOP = 0x0000 ] .into_iter() .find(|a| record.text_alignment_mode & (*a as u16) == *a as u16) .unwrap_or(VerticalTextAlignmentMode::VTA_BASELINE); ``` `mode & VTA_TOP(=0x0000) == 0x0000` 가 **항상 true** → BASELINE/BOTTOM 인 mode 도 VTA_TOP 으로 잘못 매핑 → `ext_text_out` 에서 +ascent (~em × 0.8) shift → baseline 이 cell-top 보정만큼 아래로 → 박스 하단 라인 걸침. WMF spec [MS-WMF] 2.1.2.18: - TA_TOP = 0x0000 (default) - TA_BOTTOM = 0x0008 - TA_BASELINE = 0x0018 ## Fix `src/wmf/converter/svg/mod.rs` 3 영역 (~60 lines): ### set_text_align (~2186-2208) vertical bits (0x0018 mask) 값 기준 BASELINE → BOTTOM → TOP 우선순위 분기. ```rust let v_bits = record.text_alignment_mode & 0x0018; let align_vertical = if v_bits == 0x0018 { VerticalTextAlignmentMode::VTA_BASELINE } else if v_bits == 0x0008 { VerticalTextAlignmentMode::VTA_BOTTOM } else { VerticalTextAlignmentMode::VTA_TOP }; ``` ### ext_text_out (~813-833) baseline y shift 정합 ```rust match self.context_current.text_align_vertical { VerticalTextAlignmentMode::VTA_TOP => +ascent (em × 0.8) VerticalTextAlignmentMode::VTA_BOTTOM => -descent (em × 0.2) VerticalTextAlignmentMode::VTA_BASELINE => 0 _ => 0, } ``` 기존 `font.height < 0 => -font.height` 잘못된 보정 제거. ### text_out (~1541-1556) — PR edwardkim#918 미포함, 본 task 추가 META_TEXTOUT 동일 baseline 보정 (ext_text_out 와 일관성). ## PR edwardkim#918 와의 차이 PR edwardkim#918 (closed, 5082 additions) 의 Stage 33-A 핵심 height/baseline 보정만 단독 포팅. 제외: - LibreOffice emfio 포팅, WASM RasterPlayer, nested SVG inline embed, woff2 base64 임베드 제거, DX byte-aware indexing, POLYPOLYGON fill-rule PR edwardkim#918 close 사유 (다양한 부작용) 회피 + root cause fix 만 도입. + text_out baseline 추가. ## 검증 - cargo test --release --lib: 1288 passed, 0 failed - sample16 page 18 WMF 박스 내부 한글 텍스트 정상 위치 ✓ 한컴 viewer 정합 - WMF sample (sample14 page 0~8, sample4 page 1) PNG diff <1% (정상화 방향, 회귀 없음) ## 영향 | 영역 | 영향 | |------|------| | WMF BASELINE/BOTTOM 모드 텍스트 | 정상 위치 (회귀 fix) | | WMF TOP 모드 텍스트 | 기존 동작 (영향 없음) | | 비-WMF | 영향 없음 | | WASM 환경 | 정합 개선 예상 (Canvas2D 가 동일 SVG 사용) | Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
edwardkim
added a commit
that referenced
this pull request
May 17, 2026
…gn vertical bits 파싱 정정 @jangster77 — Issue #965: sample16 page 18 WMF 다이어그램 박스 내부 한글 텍스트 박스 외부 벗어남. Root cause (src/wmf/converter/svg/mod.rs:2208 set_text_align): mode & VTA_TOP(=0x0000) == 0x0000 항상 true → BASELINE/BOTTOM mode 도 VTA_TOP 오매핑 → +ascent shift → baseline 박스 하단 걸침. WMF [MS-WMF] 2.1.2.18 spec 정합. 본질 (svg/mod.rs 3 영역 ~60 lines): - set_text_align (:2208): v_bits = mode & 0x0018 마스킹 + 우선순위 BASELINE→BOTTOM→TOP - ext_text_out (:811): baseline y shift 정합 (VTA_BASELINE=0, BOTTOM=-em*0.2, TOP=+ascent) — font.height < 0 잘못된 보정 제거 - text_out (:1545): META_TEXTOUT 동일 보정 (PR #918 미포함, 본 PR 추가) PR #918 supersede: PR #918 (CLOSED 5/16, +5082/-74 거대 PR, 다양한 부작용 LibreOffice emfio/WASM RasterPlayer 등) → Stage 33-A root cause ~60 lines 만 단독 포팅. feedback_pr_supersede_chain (a) + feedback_small_batch_release_strategy 권위 사례. 본 환경 충돌 수동 해결: orders/20260517.md (--ours + Task #965 작업 일지 갱신). svg/mod.rs auto-merge — devel PR #860/#864 (5/16, EMF/WMF image 렌더) 변경 보존 + PR #966 정정 양립 확인. 자기 검증: cargo test --release --lib 1288 passed / clippy 통과 / 광범위 sweep 7 fixture / 169 페이지 / 169 same / 0 diff / WASM 4.4 MB 재빌드 시각 판정: 작업지시자 시각 검증 통과 (sample16 p18 WMF 박스 한글 텍스트 정상 + WMF sample14/4 + devel PR #860/#864 EMF/WMF 회귀 부재) CI: ✅ Build & Test + CodeQL @jangster77 연속 5 PR (#956~#964) 완결 후 추가 #966 (#968 후속)
Owner
|
@jangster77 머지 완료 (commit
본 환경 자기 검증:
본 환경 svg/mod.rs auto-merge — devel PR #860/#864 (EMF/WMF image 렌더) 변경 보존 + PR #966 정정 양립 확인. 수고하셨습니다. 추가 PR #968 이어서 진행하겠습니다. |
edwardkim
added a commit
that referenced
this pull request
May 17, 2026
- mydocs/pr/archives/pr_966_review.md (WMF SetTextAlign vertical bits 분석) - mydocs/pr/archives/pr_966_report.md (옵션 A + PR #918 supersede) - mydocs/orders/20260517.md PR #966 행 추가 핵심: - mode & VTA_TOP(=0) == 0 항상-true 버그 root cause - WMF [MS-WMF] 2.1.2.18 spec 정합 (v_bits 0x0018 mask) - PR #918 (CLOSED, +5082 거대 PR) → root cause ~60 lines 단독 포팅 - svg/mod.rs auto-merge (devel PR #860/#864 EMF/WMF image 렌더 보존) - sweep 169/169 same + 작업지시자 시각 판정 통과 - Issue #965 close, 추가 PR #968 후속
edwardkim
added a commit
that referenced
this pull request
May 17, 2026
@jangster77 — Issue #967: HWP3 sample18 페이지 수 rhwp 69 vs 한컴 67 (+2 inflate). 빈 paragraph (pi=27/164) 직후 [쪽나누기] (pi=28/165) → 빈 paragraph 별도 page 분기 → 단독 빈 페이지. Root cause (typeset.rs:555-584): next_force_break (쪽나누기) 시 next_will_vpos_reset 가드 미발동 (hwp-multi-001 회귀 차단 목적) → 빈 paragraph 단독 page 생성. 본질 (src/renderer/typeset.rs:585 별도 분기): next_force_break && is_curr_empty && empty_h_px > avail (overflow) 시에만 continue (skip → 단독 page 차단). fit 가능 시 정상 emit. v2 정밀화: v1 (조건 무관 skip) → aift.hwp snapshot 회귀 → v2 (overflow 한정) → aift.hwp 18 case 정상 emit + sample18 fix. feedback_hancom_compat_specific_over_general 권위 사례 (일반화 위험 발견 후 케이스별 정밀화). 영역 좁힘: 빈 paragraph + 쪽나누기 + overflow 한정 — fit 가능/비-빈/일반 paragraph/hwp-multi-001 영향 없음. 본 환경 cherry-pick 충돌 0건 — typeset.rs auto-merge (devel Task #836 Endnote :1064/1091 보존 + PR #968 :585 분기 양립). orders/20260518.md 신규 (5/18). devel merge commit 2개 cherry-pick 제외 — 본질 3c1ea87 만. 자기 검증: cargo test --release 전체 (lib 1288 + integration svg_snapshot 8) ALL GREEN + cargo clippy --release -D warnings 통과 + 광범위 sweep 7 fixture / 169 페이지 / 169 same / 0 diff (aift.hwp 74 same — v1 회귀 해소 입증) + WASM 4.4 MB 재빌드.⚠️ samples/hwp3-sample18.hwp 영역 영역 PR 미포함 + 본 환경 부재 — 작업지시자 결정 영역 영역 sweep 169/169 same + cargo test 전체 통과 영역 영역 회귀 부재 입증 + sample18 페이지 수 69→67 정합 영역 영역 컨트리뷰터 PR 본문 신뢰 (작업지시자 승인). CI: ✅ Build & Test + CodeQL + Canvas visual diff @jangster77 PR 시리즈 완결 (연속 5 PR #956~#964 + #966 + #968)
Closed
3 tasks
edwardkim
added a commit
that referenced
this pull request
May 17, 2026
버전 0.7.11 → 0.7.12 (Cargo.toml + rhwp-vscode/npm-editor/rhwp-studio package.json) CHANGELOG 갱신 (CHANGELOG.md / CHANGELOG_EN.md / rhwp-vscode/CHANGELOG.md) WASM 재빌드 산출물 동기화 (rhwp-studio/public/rhwp.js) @jangster77 7-PR 시리즈 (#956~#968) + Issue #952 5-결함 완결 + WMF #966 + HWP3 #968 + LTO #818 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
samples/hwp3-sample16.hwppage 18 의 WMF 다이어그램 (주전산센터 목표시스템 구성안) 내부 박스의 한글 텍스트 ("PE6450", "기록서버", "Windows 서버군" 등) 가 박스 외부로 벗어남.PR #918 (closed, 5082 additions) 의 Stage 33-A 핵심 height/baseline 보정 로직만 단독 포팅.
Root cause
`src/wmf/converter/svg/mod.rs:2191-2197` 의 SetTextAlign vertical bits 파싱:
`mode & VTA_TOP(=0x0000) == 0x0000` 가 항상 true → BASELINE/BOTTOM 인 mode 도 VTA_TOP 으로 잘못 매핑 → `ext_text_out` 에서 +ascent shift → baseline 이 cell-top 보정만큼 아래로 → 박스 하단 라인 걸침.
WMF spec [MS-WMF] 2.1.2.18:
Fix
`src/wmf/converter/svg/mod.rs` 3 영역 (~60 lines):
PR #918 와의 차이
PR #918 close 사유 (다양한 부작용) 회피 + root cause fix 만 도입.
검증
영향
Test plan
🤖 Generated with Claude Code