Skip to content

fix: 그룹 내 그림(Picture) 직렬화 구현#428

Closed
oksure wants to merge 1 commit intoedwardkim:develfrom
oksure:contrib/fix-group-picture-serialize
Closed

fix: 그룹 내 그림(Picture) 직렬화 구현#428
oksure wants to merge 1 commit intoedwardkim:develfrom
oksure:contrib/fix-group-picture-serialize

Conversation

@oksure
Copy link
Copy Markdown
Contributor

@oksure oksure commented Apr 28, 2026

요약

serialize_group_child()에서 ShapeObject::Picture 분기가 비어 있던 TODO를 구현합니다.

변경 내용

  • 그룹 도형 내 중첩 그림 개체 직렬화: SHAPE_COMPONENT + SHAPE_COMPONENT_PICTURE 레코드 추가
  • Chart/OLE 자식과 동일한 패턴 적용
  • ctrl_id 매직넘버 0x24706963tags::SHAPE_PICTURE_ID 상수 사용으로 가독성 개선

테스트

  • cargo test 891+ 테스트 전체 통과
  • cargo clippy -- -D warnings 경고 0

참고

그룹 내 그림이 포함된 HWP 파일을 열고 저장할 때 그림 데이터가 유실되는 문제를 해결합니다. 기존에는 serialize_group_child의 Picture 분기가 빈 구현이어서 저장 시 그룹 내 그림이 누락되었습니다.

그룹 도형 내 중첩 그림 개체가 직렬화되지 않던 TODO를
Chart/OLE와 동일한 패턴으로 구현:
- SHAPE_COMPONENT + SHAPE_COMPONENT_PICTURE 레코드 추가
- 기존 매직넘버 0x24706963 → tags::SHAPE_PICTURE_ID 상수 사용

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 28, 2026 22:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

serialize_group_child()에서 비어 있던 ShapeObject::Picture 분기를 구현해, 그룹 도형 내부에 포함된 그림(Picture)이 저장 시 누락되던 문제를 해결하려는 PR입니다.

Changes:

  • 그룹 도형 자식 Picture에 대해 SHAPE_COMPONENT + SHAPE_COMPONENT_PICTURE 레코드를 생성하도록 구현
  • 그룹 컨테이너의 자식 ctrl_id 목록에서 Picture 매직넘버(0x24706963)를 tags::SHAPE_PICTURE_ID 상수로 대체

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/serializer/control.rs
Comment on lines +1276 to +1288
ShapeObject::Picture(pic) => {
records.push(Record {
tag_id: tags::HWPTAG_SHAPE_COMPONENT,
level: comp_level,
size: 0,
data: serialize_shape_component(tags::SHAPE_PICTURE_ID, &pic.shape_attr, false),
});
records.push(Record {
tag_id: tags::HWPTAG_SHAPE_COMPONENT_PICTURE,
level: type_level,
size: 0,
data: serialize_picture_data(pic),
});
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그룹 자식 Picture 직렬화가 새로 추가됐지만 이를 검증하는 테스트가 없습니다. serializer/control에는 roundtrip 테스트가 이미 있으니, 그룹 도형에 Picture 자식을 포함한 Section을 serialize_sectionparse_body_text_section로 라운드트립했을 때 Picture가 누락되지 않고 bin_data_id 등 핵심 필드가 유지되는 케이스를 추가해 회귀를 방지하는 것이 좋습니다.

Copilot uses AI. Check for mistakes.
@edwardkim
Copy link
Copy Markdown
Owner

@oksure 님 PR 감사드립니다. serialize_group_child 의 Picture 분기 TODO 를 채워주신 점 + 0x24706963 매직넘버를 tags::SHAPE_PICTURE_ID 로 정리해 주신 점 모두 좋습니다. 코드 자체는 Chart/OLE 자식 패턴을 그대로 따라 매우 보수적이고, 호출하시는 serialize_picture_data / serialize_shape_component / serialize_common_obj_attr 도 이미 한컴 호환 정정이 적용된 함수들입니다.

다만 본 PR 의 본질은 HWP 저장 (직렬화) 경로 라 머지 전에 보강 부탁드릴 사항이 있습니다.

보강 요청 — 한컴 호환 검증 자료

1. 한컴 origin 기반 회귀 테스트 추가

본 저장소의 메모리 원칙 (feedback_self_verification_not_hancom) — rhwp 자기 라운드 트립 ≠ 한컴 호환 입니다. 자기검증 패턴 (Document::default + 수동 push → serialize → parse 같이 IR 을 자기가 만들고 자기가 정답 지정) 은 항상 참인 무의미한 테스트가 됩니다.

권장 패턴 (PR #400equation_roundtrip_from_hancom_origin_hwp_sample 참고):

// 한컴 origin 데이터 입력 (자체 IR 생성 회피)
let bytes = std::fs::read("samples/{한컴-origin-그룹내그림-샘플}.hwp")?;
let original = parse_hwp(&bytes)?;
let original_groups_with_pic = collect_groups_containing_picture(&original);
assert!(!original_groups_with_pic.is_empty());

// rhwp 직렬화 + 재파싱
let serialized = serialize_hwp(&original)?;
let reparsed = parse_hwp(&serialized)?;
let reparsed_groups = collect_groups_containing_picture(&reparsed);

// 한컴 origin 의 그룹 내 Picture 가 라운드트립에서 보존되는지
for (orig, rep) in original_groups_with_pic.iter().zip(reparsed_groups.iter()) {
    // 그림의 핵심 필드 (border_x/y, crop, raw_picture_extra, bin_data_id 등) 비교
}

핵심: 입력 IR 을 한컴 편집기가 만든 hwp 의 parse 결과로 사용. Document::default() + 수동 push 로 만든 IR 로 검증하면 항상 통과하는 무의미 테스트가 됩니다.

본 저장소 samples/ 의 그룹 + Picture 포함 한컴 origin 후보:

  • samples/hwpspec.hwp (1개 group 컨트롤)
  • samples/hwpctl_Action_Table__v1.1.hwp (1개 group 컨트롤)

또는 본인이 직접 한컴 편집기로 "그림 + 도형 → 그룹화" 한 hwp 를 samples/ 에 추가 가능합니다 (PR #397 / #400 작성자가 그렇게 하셨습니다).

2. 한컴 편집기 호환 검증

한컴 한글 2010 또는 2022 에서 다음 절차 검증:

1. samples 의 그룹 내 그림 포함 hwp 를 rhwp 로 parse → serialize → output/
2. output 의 hwp 를 한컴 편집기에서 열기
   - 파일 손상 메시지 없음 ✓
   - 그룹 내 그림이 정상 표시 ✓
   - 그림이 비정상 큰 크기 (425.20% 같은) 아님 ✓
3. 한컴 편집기에서 PDF 내보내기
4. PDF 첨부

본 저장소의 트러블슈팅 picture_save_hancom_compatibility.md 가 그림 저장 호환성 5가지 결함 (CommonObjAttr prevent_page_break / SHAPE_COMPONENT ctrl_id / 렌더링 행렬 / SHAPE_COMPONENT_PICTURE border/crop/extra / PARA_LINE_SEG) 정정 이력의 권위 문서입니다. 본 PR 이 호출하는 함수들에 모두 적용된 상태이지만, 그룹 내 Picture 흐름에서 실제 한컴 호환 보장은 직접 검증이 결정적입니다.

검증 게이트 통과 정황 (메인테이너 dry-run)

항목 결과
cargo test --lib 1062 passed (회귀 없음)
cargo test --test svg_snapshot 6/6 passed
cargo test --test issue_418 1/1 passed (Task #418 보존)
cargo clippy --lib -D warnings 0건

코드 자체는 머지 가능 상태이고, 한컴 호환 검증 자료만 보강되면 즉시 머지 진행하겠습니다.

메인테이너 노트

자동 회귀 테스트와 시각 검증의 관계 — 자동 테스트는 회귀 방지에 필수이지만, "자기가 만든 IR 로 자기 직렬화 결과를 검증" 하는 패턴은 무조건 참인 케이스라 의미가 없습니다. 한컴 origin 데이터를 입력으로 사용하거나 한컴 편집기 시각 검증이 결정적 게이트입니다. 본 PR 은 저장 경로라 후자가 핵심입니다.

언제든 도움 필요하시면 댓글로 알려주세요. 감사합니다.

edwardkim added a commit that referenced this pull request Apr 29, 2026
- mydocs/pr/pr_428_review.md (그룹 내 Picture 직렬화 정정, 트러블슈팅 사전 검토 + 호출 함수 정정 적용 확인 + 작성자 보강 요청 항목 정리)
- mydocs/orders/20260426.md (PR #428 작성자 보강 대기 행 추가)

핵심: 저장 경로 PR 이라 메모리 feedback_self_verification_not_hancom 원칙 적용
- 자기 라운드트립 ≠ 한컴 호환
- 한컴 origin 기반 회귀 테스트 (PR #400 패턴) + 한컴 편집기 호환 검증 자료 요청
- PR #428 OPEN 유지, 작성자 재제출 대기
@edwardkim
Copy link
Copy Markdown
Owner

처리 결과: cherry-pick 머지 (commit f436252 on local/devel).

@oksure 님의 IR 시리얼라이제이션 정정 흡수 — serialize_group_child()ShapeObject::Picture 분기 빈 TODO 구현.

정정 영역

  • 그룹 내 그림 직렬화: SHAPE_COMPONENT + SHAPE_COMPONENT_PICTURE 레코드 추가 (Chart / OLE 자식과 동일 패턴)
  • 매직 상수 정리: 0x24706963tags::SHAPE_PICTURE_ID (가독성 개선)

검증

  • cargo test --lib: 1086 passed ✅
  • svg_snapshot: 6/6, issue_418: 1/1, clippy: 0건

정합

본 PR 은 IR 시리얼라이제이션 영역 — 작은 정정 (단일 commit / 단일 파일 / +14-3) 이지만 그룹 내 그림이 포함된 HWP 파일 저장 시 그림 데이터 유실 결함의 정확한 본질 정정. Chart / OLE 자식과 일관 패턴.

본 PR close.

@edwardkim edwardkim closed this Apr 30, 2026
edwardkim added a commit that referenced this pull request Apr 30, 2026
@oksure (Hyunwoo Park) 의 IR 시리얼라이제이션 정정 흡수.
serialize_group_child 의 Picture 분기 빈 TODO 구현.

cherry-pick: 6d93573f436252 (author 보존)
검증: 1086 passed, svg_snapshot 6/6, issue_418 1/1, clippy 0건

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request Apr 30, 2026
본 사이클 본질:
- Task #501 (cell.padding 한컴 방어 로직 모방 정정, closes #501)
- PR #428 (oksure — 그룹 내 그림 직렬화)
- PR #494 (DanMeon — Paragraph::utf16_pos_to_char_idx 외부 노출, #484)
- PR #478 (planet6897 — 7 Task / 10 commits cherry-pick: #488/#490/#483/#489/#495/#480/#476)
- PR #498 (seo-rii — Canvas visual diff 파이프라인, relates #364)

미흡수 + 분리:
- 이슈 #502 (#495 잔존 — 문단 내 글상자 TextRun 처리)
- 이슈 #503 (#479 미흡수 — 한컴 2020 시각 판정 필수)

버전 갱신: Cargo.toml + npm/editor + rhwp-studio + rhwp-vscode 모두 0.7.8 → 0.7.9.
CHANGELOG (한/영) 갱신, rhwp-vscode/CHANGELOG.md 갱신.
README 기여자 감사 누적 갱신 (cskwork/DanMeon/oksure/planet6897/seanshin/seo-rii 추가).

검증: cargo build OK, cargo test --lib 1102 passed, cargo clippy 0건, WASM 빌드 정합.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request Apr 30, 2026
Release v0.7.9 — Task #501 cell.padding 한컴 방어 로직 + PR #428/#494/#478/#498 cherry-pick
edwardkim added a commit that referenced this pull request May 1, 2026
본 사이클:
- rhwp-chrome / Edge v0.2.2: 4 파일 버전 동기화 (manifest + package +
  dev-tools-inject + content-script — v0.2.0 hotfix 사례 정합)
- rhwp-firefox v0.2.2: 동일 영역, content-script.js 는 manifest 동적
  참조로 자동 정합

라이브러리 코어 v0.7.3 → v0.7.9 (4 사이클) 갱신 — Task #501 + PR
#428/#494/#478/#498 누적 + v0.7.6/v0.7.7/v0.7.8 사이클 흡수.

등록 문구:
- chrome-0.2.2_kor.md / chrome-0.2.2_eng.md (한/영) — Chrome/Edge
  공통 + AMO 등록 정보
- edge-0.2.2_reviewer_notes.md — Edge 파트너 센터 Notes for
  certification (1,918자, 2,000자 한계 내)
- chrome-0.2.1 한/영 등록 문구 백업

자기검열 grep (feedback_external_docs_self_censor 메모리 룰): 통과
AMO 4 함정 (feedback_amo_submission_gotchas 메모리 룰): 통과

빌드 환경: Node v22.18.0 (rolldown 호환).
빌드 결과:
- rhwp-chrome.zip 16 MB
- rhwp-firefox.zip 12.9 MB
- rhwp-source-0fb3e67.zip 47.9 MB (AMO 소스 제출)

3 스토어 제출 완료:
- Chrome Web Store (1~3 영업일 심사)
- Microsoft Edge Add-ons (1~2 영업일)
- Mozilla AMO (1~5 영업일)

.gitignore: rhwp-chrome/*.zip, rhwp-firefox/*.zip, rhwp-firefox/dist/
추가 (빌드 산출물 누적 차단)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request May 4, 2026
cherry-pick:
- 21fe401 (8dc75f6): fix: 그룹 내 그림(Picture) 직렬화 구현 + 라운드트립 테스트

본질:
- src/serializer/control.rs +13/-2 (serialize_group_child Picture 분기)
- src/serializer/control/tests.rs +79 (라운드트립 테스트 신규)
- 기존 단독 Picture 직렬화와 동일 패턴 적용
  · HWPTAG_SHAPE_COMPONENT (comp_level)
  · HWPTAG_SHAPE_COMPONENT_PICTURE (type_level)
- 다른 그룹 자식 (Line/Rectangle/Ellipse/Chart/OLE) 과 동일 구조

검증:
- cargo test --lib 1125 passed (신규 test_roundtrip_group_picture_child GREEN)
- 회귀 0 (issue_505/530/546/418/501/svg_snapshot)
- cargo clippy --lib 0 건

직렬화 영역 (저장 시 누락 정정), 시각 영향 없음 — B 처리 (라운드트립 테스트로 결정적 검증).

작성자: @oksure (Hyunwoo Park) — 세 번째 PR (PR #581/#582 후속)

PR #428 후속 — Copilot 리뷰 피드백 (라운드트립 테스트 부재) 반영.

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

본 PR 은 외부 컨트리뷰터 @oksure (Hyunwoo Park) 의 세 번째 PR (PR #581/#582 후속).

cherry-pick:
- 21fe401 (8dc75f6): fix: 그룹 내 그림(Picture) 직렬화 구현 + 라운드트립 테스트
  · src/serializer/control.rs +13/-2
  · src/serializer/control/tests.rs +79

본질: serialize_group_child 의 ShapeObject::Picture TODO 빈 분기 → 단독 Picture
직렬화와 동일 패턴 적용 (HWPTAG_SHAPE_COMPONENT + HWPTAG_SHAPE_COMPONENT_PICTURE).
PR #428 후속 (Copilot 리뷰 피드백 반영, 라운드트립 테스트 포함).

검증:
- cargo test --lib 1125 passed (신규 GREEN +1)
- test_roundtrip_group_picture_child 통과
- 회귀 0 (issue_505/530/546/418/501/svg_snapshot)
- cargo clippy --lib 0 건

작업지시자 의견 정합 (HWP 직렬화 영역, PR #553 close 시 명시).
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.

3 participants