Task #1016: Resolve image payloads in PaintOp::Image#1018
Closed
postmelee wants to merge 1 commit into
Closed
Conversation
edwardkim
added a commit
that referenced
this pull request
May 19, 2026
edwardkim
added a commit
that referenced
this pull request
May 19, 2026
…PaintOp::Image @postmelee — 이미지 변환(BMP/PCX→PNG) + 워터마크 JPEG→baked PNG 판정이 5+ renderer 별 사본(svg/canvas/web_canvas/skia/paint/json)에 분산되어 있던 것을 LayerBuilder 단계 단일 image_resolver::resolve_image_payload() 진입점으로 통합. 결과를 ResolvedImagePayload 로 패키지하여 PaintOp::Image.resolved: Option<Box<...>> 옵션 필드에 부착 (schema minor 12→13, 하위호환). 모든 renderer 는 resolved payload 소비만 — 재판정 없음. 옵션 A: 본질 커밋 3aeaa5b cherry-pick (작성자 postmelee 보존, orders/20260520.md --ours 1건 충돌 해소). 검증: cargo test 1307 + cargo test --test issue_938 3건(overlay/svg/PageLayerTree resolved watermark contract) + clippy -D + fmt 0 + WASM 4.83MB. 광범위 sweep 10 fixture (BEFORE devel ↔ AFTER): 복학원서(워터마크), sample16-hwp5/hwp3, hy-001 HWPX/HWP5, exam_kor/math, aift, biz_plan, test-image — **전부 diff=0** (SVG 출력 100% 동일). 광범위 표면(24파일, 7개 renderer 경로)에도 시각 결과 완전 보존 — feedback_image_renderer_ paths_separate 본질적 해소 + 시각 호환성 100% 모범 사례. 작업지시자 시각 판정 생략 통과 (sweep diff=0 정량 입증). PR scope 좁힘: z-order replay 일반화는 #1017로 분리 (PR 본문 명시). @postmelee 후속 #1019 (Task #975 PageBackground fill + RealPic watermark tone) OPEN 시리즈 연속.
Owner
|
옵션 A로 devel에 반영했습니다 (본질 커밋 3aeaa5b cherry-pick, 작성자 메타데이터 보존, orders/20260520.md --ours 1건 충돌 해소). 검증:
이슈 #1016은 Refs 관계로 OPEN 유지합니다 (workflow 일반화 진행 상황 추적용). #1019 후속 검토 대기합니다. |
16 tasks
edwardkim
added a commit
that referenced
this pull request
May 20, 2026
… + LAYOUT_OVERFLOW 42→12 @planet6897 분할 표 시리즈 마무리 (#1003 + #1004 머지 후 발전형, devel 최신 기준 재구성으로 MERGEABLE). RowCut 이산 모델(cell_units + advance_row_cut 단일 권위 함수)로 페이지네이터·렌더러 측정 통합 — PR #1004 휴리스틱 정정 일반화. closes #1022 — LAYOUT_OVERFLOW 42→12 (71% 감소) 정량 측정. v2 trailing-ls 조건부 복원 (issue_598 회귀 자정) — lazy_base_corrected >= 0 조건부 가드로 vpos≠0 시작 컬럼 보정 + IR 정확 추적 케이스 비보정. 복학원서 본문 시작 band 196→214=PDF 일치 PR 본문 명시 (본 환경 미발동, 후속 관찰). 옵션 A: 본질 squash commit bc1cd4d cherry-pick (작성자 Jaeook Ryu 보존, 충돌 없음). 검증: cargo test 1308(lib) + 전체 통합 + pagination 15 + wasm_api 160 + clippy -D 전체(--lib 미한정 CI 패턴) + fmt --all --check (feedback_push_full_test_required + CI 패턴 정합). sweep 10 fixture: hy-001/table-vpos-01/복학원서 diff=0, sample16-hwp5 13/64 + sample16-hwp3 2/64 + aift 27/74 + exam_kor 16/20 + biz_plan 3/6 광범위 변동 (분할 표 영역 의도된 효과). WASM 4.84MB. 작업지시자 결정 "그대로 A로" — 광범위 변동 시각 판정 생략 머지. 정량 측정(LAYOUT_OVERFLOW 71% 감소) + 회귀 가드(issue_598/svg_snapshot) + CI 검증 항목 통과로 게이트 대체. golden 갱신: issue-617 + form-002 (PR 본문 명시 issue-677은 PR 적용 후 출력=현재 golden binary identical 로 갱신 불필요). feedback_pr_supersede_chain 권위 사례 — 작은 단위(#1003) + 부분(#1004) + 발전형(#1024) 순차 적층 → 단일 권위 모델 일반화. feedback_image_renderer_ paths_separate 본질 정합 (PR #1018 image_resolver 패턴).
This was referenced May 20, 2026
edwardkim
pushed a commit
that referenced
this pull request
May 20, 2026
… 4 hunk 복원 PR #1003 (closes #990) 의 cherry-pick `--theirs` 충돌 해소가 PR #1011 (closes #1006) 의 PageBorderBasis 통합 contract 를 PR #987 시절 attr 비트 해석으로 무심코 revert. HWP3 native (attr=0) 만 paper_based=false 로 판정되어 외곽선이 body-edge 로 좁아진 시각 회귀 발생. Bisect 단언 (border_top y): - 850cfb5 (PR #1011): 17.88 (paper-edge, 기준선) - 71aedda (PR #1015): 17.88 - 84246b2 (PR #1018): 17.88 - 27c05d5 (PR #1020): 17.88 - b5d3834 (PR #1021): 17.88 - c2024ec (PR #1003): 55.64 ← 회귀 도입 - 65c8e69 (devel HEAD): 55.64 Fix: src/renderer/layout.rs 4 hunk 복원 - 변경 A: page_number_baseline_y() — (attr & 0x01) → matches!(basis, PaperBased) - 변경 B: build_page_borders() — 동일 + 주석 + 디버그 로그 (bit1/bit2/footer_inside) - 변경 C: footer_inside clip 복원 — 페이지 번호 외곽선 바깥 위치 (PR #1011) - 변경 D: `(bx, mut by, bw, mut bh)` — footer clip 의 by/bh 수정 위함 Parser 측 PR #1011 변경 (basis=PaperBased 주입) 은 PR #1003 cherry-pick 시 보존됨. fix 는 renderer (layout.rs) 한정 단일 파일. 검증 (Stage 2 별도 보고): - 3 포맷 paper_based=true 단언 (RHWP_DEBUG_PAGE_BORDER) - HWP3 sample16 border_top y=17.88 복원 - HWP5/HWPX 변환본 무변동 (17.88 유지) - cargo test --release --lib 1307 passed - cargo clippy --release --lib -- -D warnings clean - cargo fmt --check clean Refs #1029 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced May 21, 2026
Closed
8 tasks
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.
왜 변경했나
#976은 워터마크성 JPEG를 한컴 참고 톤의 baked PNG로 바꾸는 문제를 해결했지만, 해당 처리가 renderer별 경로에 남아 있으면 PageLayerTree / native Skia / browser CanvasKit 전환 과정에서 같은 이미지가 서로 다른 payload로 replay될 수 있습니다.
이 PR은 이미지 포맷 변환과 워터마크 bake 판단을 renderer 내부가 아니라
PaintOp::Image생성 단계로 올립니다. renderer들은 더 이상 각자 원본ImageNode를 재판정하지 않고, 이미 resolved 된 visual payload를 공유해 replay합니다.무엇을 변경했나
src/renderer/image_resolver.rs추가ImageNode에 반영하는 helperPaintOp::Image에resolved: Option<Box<ResolvedImagePayload>>추가ResolvedImageKind::{FormatConverted, BakedWatermark}ResolvedImagePayload { data, mime, kind, suppress_effects }LayerBuilder에서RenderNodeType::Image를 낮출 때 resolver 호출bakedWatermark:true12 -> 13PaintOp::Image.resolved를 사용하도록 정리tests/issue_938.rs에 PageLayerTree resolved watermark 회귀 테스트 추가범위 제외
작업 중 native Skia PNG export에서
wrap=behindText워터마크가 글 내용 위에 보이는 문제가 확인됐습니다.이는 이 PR의 image payload 문제가 아니라 PageLayerTree replay z-order / compositor 정책 문제입니다. #976의 baked watermark PNG는 transparent PNG가 아니라 opaque PNG이므로, 사각형이 보이지 않으려면
background -> behindText image -> flow text -> inFrontOfText image순서로 합성되어야 합니다.따라서 #1016의 완료 조건은 "renderer들이 같은 resolved image payload를 공유한다"는 contract로 좁혔고, z-order replay 일반화는 #1017로 분리했습니다.
관련 이슈
Refs #1016
Follows #976
Related #1017
테스트
cargo fmt --all -- --check통과cargo test통과cargo clippy -- -D warnings통과통과한 추가 검증:
cargo checkcargo test --test issue_938cargo test --test issue_516cargo test --test issue_514cargo test --test svg_snapshotnpm --prefix rhwp-studio testcargo check --features native-skiacargo test --features native-skia --no-runcargo test --features native-skia skia --libcargo run --features native-skia --bin rhwp -- export-png samples/복학원서.hwp -p 0 -o output/task1016-stage4docker-compose --env-file .env.docker run --rm wasmnpm --prefix rhwp-studio run buildgit diff --check확인 결과:
image ops: 2, wrap=behindText: 2, mime png: 2, mime jpg: 0output/task1016-stage4/복학원서.png,794 x 1123,175080 bytesrhwp-studio/dist/생성,rhwp_bg-*.wasm포함참고:
npm ci중 기존 의존성에서 deprecated package 경고와 moderate vulnerability 1건이 보고됐습니다. lockfile 기준 설치는 성공했고 build도 통과했습니다.vite build중 CanvasKit의fs/pathbrowser externalization 경고와 500 kB 초과 chunk 경고가 출력됐습니다. build는 성공했습니다.스크린샷
별도 첨부 없음.
문서
mydocs/plans/task_m050_1016.mdmydocs/plans/task_m050_1016_impl.mdmydocs/working/task_m050_1016_stage1.mdmydocs/working/task_m050_1016_stage3.mdmydocs/working/task_m050_1016_stage4.mdmydocs/report/task_m050_1016_report.md