Task #860 + #864: EMF/WMF image 렌더 + HWP3 picture caption 정정#869
Closed
jangster77 wants to merge 8 commits into
Closed
Task #860 + #864: EMF/WMF image 렌더 + HWP3 picture caption 정정#869jangster77 wants to merge 8 commits into
jangster77 wants to merge 8 commits into
Conversation
…dwardkim#860 본질: HWP3 sample14 (및 HWP5/HWPX 변환본) 의 그림 (bin_id=2, 149.9×41.9mm TAC) 내부 콘텐츠 누락. 한컴 한글 2022 PDF (권위) 와 시각 다름. 2 layers 본질 진단 (Stage A/B/C): 1차 본질 — BMP MIME 미지원: - rhwp 가 EMF/WMF 의 inner BMP image 를 `data:image/bmp;base64,...` 로 SVG embed. rsvg-convert / 브라우저 가 BMP MIME 미지원 → image 누락. - BMP 데이터 자체는 정상 (sips 직접 변환 시 terminal screenshot 표시). 2차 본질 — WMF SVG converter 의 viewBox 부족: - WMF binary 의 SetWindowExt (4231x1189) 가 actual element bbox 보다 작음 (image y=1536 + h=768 = 2304 > viewBox h=1189) → image 가 viewBox 밖 → rsvg-convert 가 잘라냄. - viewBox 를 1189 → 3000 으로 확장 시 image 정상 표시 (검증 완료). 정정: 1. src/emf/converter/player.rs:368 dib_to_bmp_data_url — BMP 데이터를 PNG 로 재인코딩 후 data:image/png URI 사용 (svg.rs:1118 / shape_layout.rs:1063 와 동일 정책). BMP decode 실패 시 fallback 으로 BMP URI 유지. 2. src/wmf/converter/svg/util.rs:20 Bitmap::as_data_url — 동일 BMP → PNG 변환 적용. 3. src/wmf/converter/svg/mod.rs:68-90 SVGPlayer::generate() — viewBox 자동 확장. element 들의 max(x+width, y+height) 까지 확장하여 actual bbox cover. helper: element_max_x, element_max_y, parse_attr_i32. 4. src/emf/tests.rs:712 test assert update — data:image/png 또는 BMP URI 둘 다 허용 (graceful degradation). 검증: - cargo test --release --lib: 1230 passed, 0 failed (회귀 0) - HWP3 sample14 page 2 시각: 박스 안 "If you leave me now / You'll take away the biggest part of me / Ooh-ooh, baby ase pl[c]don't go" 등 콘텐츠 정상 표시 (한컴 PDF 정합) - HWP5/HWPX 변환본 동일 정합 - hwp3-sample13, exam_eng 회귀 없음 (페이지 수 동일) 산출 보고서: - mydocs/working/task_m100_860.md (종합) - mydocs/working/task_m100_860_stage_a.md (본질 진단) - mydocs/working/task_m100_860_stage_b.md (정정 후보 평가) - mydocs/working/task_m100_860_stage_c.md (구현 + 추가 발견) - mydocs/plans/task_m100_860.md, _impl.md (계획서) 샘플 추가: samples/hwp3-sample13(-hwp5).{hwp,hwpx}, hwp3-sample14(-hwp5).{hwp,hwpx}, 권위 PDF: pdf/hwp3-sample{13,14}-hwp5-2022.pdf 잔여 결함 (별도 issue 등록 예정): - paragraph 순서 차이 (그림 + 캡션 paragraph 의 page boundary 처리) — 본 task 의 BMP 콘텐츠 결함과 독립적인 layout/pagination 결함 closes edwardkim#860 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…amework 선행: Task edwardkim#860 Stage A-C (commit 4908ab0) 의 BMP image 콘텐츠 fix. 잔여 결함 (그림 paragraph 의 element 순서) 본질 진단 + 부분 정정. 본질 진단 결과: - WMF SetWindowOrg: (329, 1536), Ext: (4231, 1189) 모두 positive (top-down) - Placeable BoundingBox: (329, 1536) ~ (4560, 2725) - element y 좌표: rect 1008, text 1205, image 1536 - 결함: rect/text y < origin_y (1536) → window 위쪽 밖 위치 (rhwp 는 캡션 outline 위, BMP 박스 아래 / 한컴 PDF 는 박스 위, 캡션 아래) 가설 검증: - H4 (그림 control 내 element 순서) ✓ 확정 - H5 (SetWindowExt y < 0 Cartesian) ✗ — sample14 는 positive - H6 (y-flip framework) — 도입 (현재 sample 미적용, 다른 sample 사용 예정) 적용한 정정: Fix 1 — Window::as_view_box() viewBox origin 적용: - 종전 (0, 0, x, y) → (origin_x, origin_y, x, y) - SetWindowOrg 의 origin 을 viewBox 시작점으로 사용 - WMF binary 의 좌표계 정합 Fix 2 — viewBox 양방향 자동 확장 (SVGPlayer::generate): - 종전: max(x+w, y+h) 까지 우/하 확장 - 추가: min(x, y) 까지 좌/상 확장 - element 가 viewBox 위쪽 밖에 있는 경우 (sample14 의 rect/text) 정상 표시 - helper: element_min_x, element_min_y, parse_attr_i32 Fix 3 — y-flip framework (도입, 현재 미적용): - Window::ext() 에서 SetWindowExt y < 0 (Cartesian, bottom-up) 감지 - y_inverted flag → generate() 가 <g transform="translate(0,vb_h) scale(1,-1)"> wrap - 본 sample14 는 y_inverted=false (positive y) — 다른 Cartesian sample 에서 작동 예정 검증: - cargo test --release --lib: 1230 passed, 0 failed (회귀 0) - HWP3 sample13 / exam_eng: WMF 미사용 (회귀 영향 없음) - HWP3 sample14: BMP image 콘텐츠 표시 + viewBox 정합 잔여 결함 (별도 task 권장): - element y 좌표 순서 자체가 한컴과 반대 (rhwp: rect/text 위 + image 아래 / 한컴: image 위 + rect/text 아래) - WMF binary 의 element 가 BoundingBox 밖에 위치하는 비정상 또는 좌표 처리 본질 차이. WMF spec 정밀 분석 + 좌표계 재설계 필요 - 본 task scope 보다 큼 → 별도 deep task 산출 보고서: - mydocs/working/task_m100_860_v2.md (Stage D 종합) - mydocs/working/task_m100_860_stage_d_a.md (Stage D 진단) - mydocs/plans/task_m100_860_v2.md, _impl.md (Stage D 계획서) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
본질 1 (WMF): 5개 image record handler (bit_blt, dib_bit_blt, dib_stretch_blt, stretch_blt, stretch_device_independent_bitmap) 의 image x/y 를 point_s_to_absolute_point 로 변환. text/polygon 과 동일 device 공간 정합. as_view_box 를 (0, 0, ext_x, ext_y) 로 revert (Task edwardkim#860 Stage D 미봉책 정정). element_max_y 에 text font-size 기반 viewBox 자동 확장 추가. 본질 2 (HWP3 caption): inline (TAC) picture caption 의 y_start 를 image_bottom (pic_y + max(baseline, pic_h)) 에 정합. paragraph_layout 의 baseline-aligned image 와 정합 (HWP3 sample14 page 3 "Cut&Paste 할 영역", page 4 "Visual Block 을 이용한 대소문자 변경" caption 가 image 에 가려지던 결함). 본질 3 (중복 emit): paragraph_layout 의 inline TAC picture emit 시 set_inline_shape_position 호출 추가. layout.rs 의 already_registered 체크 통과시켜 중복 emit (top-aligned + baseline-aligned 동시 출력) 방지. 추가: caption 렌더 후 result_y 를 caption bottom 까지 진행하여 다음 paragraph 와의 겹침 방지. dump 출력에 picture caption 정보 표시. 검증: cargo test 1230 passed (회귀 0), clippy 경고 0. hwp3-sample14 page 2/3/4 모두 한컴 PDF 시각 정합. closes edwardkim#864
7 tasks
edwardkim
pushed a commit
that referenced
this pull request
May 14, 2026
closes #864) PR #869 (@jangster77) GitHub diff 기반 cherry-pick. mydocs 거버넌스 산출물 제외 (PR #629 패턴 정합). Task #860 — BMP MIME 변환 (PNG 재인코딩) + viewBox 자동 확장 Task #864 — WMF image x/y point_s_to_absolute_point 변환 + HWP3 inline picture caption y_start 정합 + set_inline_shape_position 추가로 중복 emit 방지 + caption bottom까지 result_y 진행 (겹침 방지) + dump에 picture caption 정보 표시 fixture: hwp3-sample13/14 HWP3/HWP5/HWPX + PDF 권위 자료 검증: - cargo test --release --lib: 1246 passed (회귀 0) - cargo clippy: 경고 0 - SVG page 2/3/4 + 웹 에디터 시각 판정 ★ 통과 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Owner
|
검토 + cherry-pick 머지 완료. 감사합니다. 처리 결과
재검증
BMP→PNG 재인코딩 + WMF 좌표계 정합 + caption 위치 + 중복 emit 방지까지 다층 결함을 체계적으로 정리했습니다. 수고하셨습니다. |
edwardkim
pushed a commit
that referenced
this pull request
May 14, 2026
PR #875 (@jangster77) GitHub diff 기반 cherry-pick (Task #873 incremental만). mydocs 거버넌스 산출물 + PR #869 중복 영역 제외. 본질 1 (HWP5): BinDataType::Link abs_path → Picture.external_path 전달 parser/mod.rs populate_link_image_paths 후속 함수 추가 본질 2 (HWPX): content.hpf isEmbeded attribute 파싱 + image/* 수집 parser/hwpx/content.rs PackageItem.is_embedded + parser/hwpx/mod.rs Link 분기 검증: - cargo test --release --lib: 1247 passed (+1 신규, 회귀 0) - 웹 에디터 동작 판정 ★ 통과 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Summary
PR #863 (Task #860) 와 통합된 PR — Task #860 의 EMF/WMF image 렌더 정정에 더해, Task #864 의 WMF y 좌표 + HWP3 picture caption 위치 + inline image 중복 emit 을 모두 정정합니다.
Task #860: HWP3/HWP5/HWPX 의 EMF/WMF image 콘텐츠 렌더 정정 (closes #860)
Task #864: WMF y 좌표 + HWP3 picture caption + 중복 emit 정정 (closes #864)
본질 1 (WMF): 5개 image record handler (
bit_blt,dib_bit_blt,dib_stretch_blt,stretch_blt,stretch_device_independent_bitmap) 의 image x/y 를point_s_to_absolute_point로 변환. text/polygon 과 동일 device 공간 정합.as_view_box를(0, 0, ext_x, ext_y)로 revert (Task #860 Stage D 미봉책 정정).본질 2 (HWP3 caption): inline (TAC) picture caption 의 y_start 를 image_bottom (
pic_y + max(baseline, pic_h)) 에 정합.paragraph_layout의 baseline-aligned image 와 정합.본질 3 (중복 emit):
paragraph_layout의 inline TAC picture emit 시set_inline_shape_position호출 추가.layout.rs의already_registered체크 통과시켜 중복 emit (top-aligned + baseline-aligned 동시 출력) 방지.추가: caption 렌더 후
result_y를 caption bottom 까지 진행하여 다음 paragraph 와의 겹침 방지. dump 출력에 picture caption 정보 표시.Test plan
CLAUDE.md 규칙 준수
HWP3 전용 분기 0건. 모든 변경은 generic 모듈 (WMF format converter, 공통 renderer) 로 모든 포맷 (HWP3/HWP5/HWPX) 에 정합 동작.
Closes
🤖 Generated with Claude Code