Conversation
Updates the requirements on [skia-safe](https://github.com/rust-skia/rust-skia) to permit the latest version. - [Release notes](https://github.com/rust-skia/rust-skia/releases) - [Commits](rust-skia/rust-skia@0.93.1...0.97.0) --- updated-dependencies: - dependency-name: skia-safe dependency-version: 0.97.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.10 to 8.0.11. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.0.11/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.11 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [workbox-window](https://github.com/googlechrome/workbox) from 7.4.0 to 7.4.1. - [Release notes](https://github.com/googlechrome/workbox/releases) - [Commits](GoogleChrome/workbox@v7.4.0...v7.4.1) --- updated-dependencies: - dependency-name: workbox-window dependency-version: 7.4.1 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@types/chrome](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chrome) from 0.1.40 to 0.1.42. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chrome) --- updated-dependencies: - dependency-name: "@types/chrome" dependency-version: 0.1.42 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
…tudio/devel/vite-8.0.11 chore(deps-dev): bump vite from 8.0.10 to 8.0.11 in /rhwp-studio
…tudio/devel/workbox-window-7.4.1 chore(deps-dev): bump workbox-window from 7.4.0 to 7.4.1 in /rhwp-studio
…tudio/devel/types/chrome-0.1.42 chore(deps-dev): bump @types/chrome from 0.1.40 to 0.1.42 in /rhwp-studio
Bumps [puppeteer-core](https://github.com/puppeteer/puppeteer) from 24.42.0 to 24.43.0. - [Release notes](https://github.com/puppeteer/puppeteer/releases) - [Changelog](https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md) - [Commits](puppeteer/puppeteer@puppeteer-core-v24.42.0...puppeteer-core-v24.43.0) --- updated-dependencies: - dependency-name: puppeteer-core dependency-version: 24.43.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
…tudio/devel/puppeteer-core-24.43.0 chore(deps-dev): bump puppeteer-core from 24.42.0 to 24.43.0 in /rhwp-studio
…fe-0.97.0 chore(deps): update skia-safe requirement from 0.93.1 to 0.97.0
Updates the requirements on [resvg](https://github.com/linebender/resvg) to permit the latest version. - [Release notes](https://github.com/linebender/resvg/releases) - [Changelog](https://github.com/linebender/resvg/blob/main/CHANGELOG.md) - [Commits](linebender/resvg@0.45.0...v0.47.0) --- updated-dependencies: - dependency-name: resvg dependency-version: 0.47.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
chore(deps): update resvg requirement from 0.45 to 0.47
Bumps [vite-plugin-pwa](https://github.com/vite-pwa/vite-plugin-pwa) from 1.2.0 to 1.3.0. - [Release notes](https://github.com/vite-pwa/vite-plugin-pwa/releases) - [Commits](vite-pwa/vite-plugin-pwa@v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: vite-plugin-pwa dependency-version: 1.3.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
…tudio/devel/vite-plugin-pwa-1.3.0 chore(deps-dev): bump vite-plugin-pwa from 1.2.0 to 1.3.0 in /rhwp-studio
macOS Option+Arrow (단어 이동), Option+Shift+Arrow (단어 선택), Option+Backspace/Delete (단어 삭제) 구현. - CursorState.moveToWordBoundary() 메서드 추가 - 한글/영문/숫자/공백/구두점 문자 클래스 기반 경계 탐지 - 본문 및 표 셀 내부 모두 지원 - Alt+Arrow가 기존 Alt 단축키 핸들러에 잡히지 않도록 가드 추가
1. Alt+Backspace/Delete 주석: 'Backspace' → 'Backspace/Delete' 2. moveToWordBoundaryInCell: getTextInCell(0, 9999) 전체 fetch 대신 getCellParagraphLength로 길이 확인 후 필요 구간만 슬라이스
작업지시자 시각 검증 영역 발견: 'Alt+Delete 만 동작하지 않습니다.' 본질: shortcut-map.ts:97 영역 영역 Alt+Delete → table:delete-col 매핑 (5/10 이전 등록) 영역 영역 일반 편집 영역 영역 dispatcher.dispatch 영역 영역 silently fail (canExecute=inTable 차단) + return → switch (e.key) case 'Delete' 영역 영역 도달 부재 → 단어 삭제 미동작. 정정: Alt 조합 단축키 가드 영역 영역 Alt+Delete 영역 영역 표 안/외 분기 추가: - 표 안 + Alt+Delete: table:delete-col (칸 지우기, 기존 동작 보존) - 표 외 + Alt+Delete: 다음 단어 삭제 (PR #794 본질) - Alt+Backspace: 이전 단어 삭제 (항상) - Alt+Arrow: 단어 이동 (항상) PR #740 자기 정정 패턴 정합.
PR #746 (Ctrl/Cmd+Arrow 줄/문서 시작·끝) 후속 영역 영역 Issue #223 의 다음 단계. 4 단축키: - Option+←/→: 단어 단위 커서 이동 - Option+Shift+←/→: 단어 단위 선택 확장 - Option+Backspace: 이전 단어 삭제 - Option+Delete: 다음 단어 삭제 신규 인프라 — CursorState.moveToWordBoundary: - 본문 (getTextRange) + 표 셀 (getTextInCell) 양 경로 지원 - 문자 클래스 5종 (공백/한글/Latin/Digit/Punct) - 슬라이스 50 char cap (성능 가드) 본 환경 자기 정정 commit (7c0418f) — Alt+Delete 영역 영역 충돌 정정: - shortcut-map.ts:97 영역 영역 Alt+Delete → table:delete-col 매핑 (이전 등록) 영역 영역 일반 편집 영역 영역 dispatcher silently fail + return → 단어 삭제 미동작. - 정정: 표 안/외 분기 (옵션 1 작업지시자 결정): - 표 안 + Alt+Delete: table:delete-col (칸 지우기, 기존 동작 보존) - 표 외 + Alt+Delete: 다음 단어 삭제 (PR #794 본질) - Alt+Backspace / Alt+Arrow: 항상 단어 삭제/이동 검증: - tsc --noEmit ✅ - cargo test --release ALL GREEN - 광범위 sweep 170/170 same - WASM 4.68 MB 재빌드 - 작업지시자 시각 검증 ✅ 통과 (자기 정정 후) Part of #223
드래그 중 hitTest 결과가 anchor와 다른 셀(또는 본문)을 가리키면 커서 이동을 무시하여 셀 내부 선택이 유지되도록 수정. 원인: 셀 내부의 빈 영역(텍스트 라인 아래)을 드래그하면 hitTest가 본문 레벨 위치를 반환하여 셀↔본문 혼합 선택이 발생하고, updateSelection에서 렌더링이 생략되는 문제.
표 셀 내부 텍스트 드래그 선택 시 선택 하이라이트 미렌더링 결함 정정 (Issue #669). 본질: 드래그 중 hitTest 가 셀 내부 빈 영역에서 본문 레벨 위치 반환 → anchor(셀) ↔ focus(본문) 혼합 → updateSelection() 영역 영역 selectionRenderer.clear() 호출 → 선택 미렌더링. 정정 (input-handler.ts:1014 updateTextSelectionDragFromPointer 래퍼 안 +14): - anchor 셀 내부일 때 hit 가 같은 셀 컨텍스트 (parentParaIndex/controlIndex/cellIndex 모두 일치) 가 아니면 cursor.moveTo 건너뜀 - 셀 내 선택 유지 본 환경 충돌 수동 해결: HEAD (devel) 영역 영역 PR #718 (Task #661) updateTextSelectionDragFromPointer 래퍼 사용 영역 영역 incoming 의 onMouseMove 영역 영역 직접 hit + moveTo 영역 영역 비대칭. 본 환경 영역 영역 셀 가드 영역 영역 input-handler.ts 의 래퍼 안 적용 (PR #718 정합성 보존). 검증: - tsc --noEmit ✅ - cargo test --release ALL GREEN - 광범위 sweep 170/170 same - WASM 4.68 MB 재빌드 - 작업지시자 웹 에디터 시각 검증 ✅ 통과 closes #669
…ract (P11) P11 단계 — P9 영역 영역 text replay parity 후속 영역 영역 Text IR v2 compatibility contract 추가. Skia native raster Issue #536 트래킹 단계적 진전: P4 #599 → P5 #626 → P6 #720 → P8 #761 → P9 #769 → P11 #797 중요: 본 PR 은 GlyphRun 을 기본 경로로 만드는 PR 이 아니라 TextRun v2 compatibility contract 를 완성하는 PR. 4 본질 원칙: - Compatibility first — 모든 backend 가 TextRun fallback 으로 렌더링 가능 - Additive schema — schemaMinorVersion + feature negotiation (기존 consumer 미파괴) - Source traceability — text_sources + TextRun.source span - Placement/cluster metadata — paintStyle/projectionKind/orientation/placement/clusterBasis/clusters/legacyVisuals 신규 인프라: - PaintOp::{CharOverlap, TextControlMark, TabLeader, TextDecoration} — explicit visual ops - PageLayerTree.text_sources + TextSourceTable (export-local) - TextRun.source span + 7 신규 metadata - schemaMinorVersion + resourceTableMinorVersion + feature negotiation - docs/text-ir-v2.md migration contract Renderer 정정 — 4 backend 동기 (feedback_image_renderer_paths_separate 권위 사례): - svg_layer.rs / canvas.rs / skia/renderer.rs / web_canvas.rs — 신규 special visual op skip (double-painting 방지) Non-goals (Still designing): - GlyphRun eligibility / font resource table / cluster basis / fallback diagnostics — P12+ 분리 검증: - cargo build/test/clippy --release ALL GREEN (clippy -D warnings) - native-skia 28/28 PASS (PR #769 인프라 보존) - 광범위 sweep 7 fixture / 170 페이지 / 회귀 0 (Compatibility first 원칙 입증) - 시각 판정 면제 (작업지시자 결정 — contract 정합 단계 + 결정적 검증 + sweep 통과) Refs #536
- Global anchors, relative isNearStructure base, norm-hash pins - rightToLeftPara from alignment into buildControlDiffs slot matching Co-authored-by: Cursor <cursoragent@cursor.com>
… 반영) - upstream devel 기준에서 삭제됐던 compare/history UI 파일 복원 + main 기준 session/compare-debug/history 모듈 추가 - diff-engine stash 변경과 WasmBridge 비교용 API(hasLoadedDocument, refreshLayout, getDocumentInfo, stable_id, 표/도형 서명) 정합 - PageInfo.pageNumber 선택 필드 추가 Co-authored-by: Cursor <cursoragent@cursor.com>
- edit:compare-documents / edit:document-history 등록 (CompareSessionStore 공유) - index.html 편집 메뉴·찾기 스플릿·툴바 버튼 반영 - shortcut-map: Alt+Shift+V, Ctrl+Shift+H Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
PR #799 의 5번째 commit 에 잘못 staging 된 *.actual.svg 5 파일 제거: - tests/golden_svg/form-002/page-0.actual.svg - tests/golden_svg/issue-147/aift-page3.actual.svg - tests/golden_svg/issue-157/page-1.actual.svg - tests/golden_svg/issue-267/ktx-toc-page.actual.svg - tests/golden_svg/table-text/page-0.actual.svg *.actual.svg 는 테스트 실행 시 생성되는 임시 출력 파일로, golden (*.svg) 와 비교만을 위한 산출물이다. 저장소에 포함되지 않아야 한다.
## 본질 `4bb11289 fix: 쪽테두리 종이기준/본문기준 bit 해석 반전 정정 (closes #920)` 의 `paper_based = (attr & 0x01) == 0` 비트 해석이 hwp3-sample16 / 시험지 등 다수 sample 에서 회귀. ## 분석 5+ samples (sample16, 시험지, biz_plan, 국립국어원, text-align-2, pua-test) 의 한컴 viewer 실측: - attr bit 0 = 0/1 양쪽 다 paper-based outline 렌더 - HWPX textBorder=PAPER/CONTENT 양쪽 다 paper-based - fillArea="PAPER" 공통 → bit 0 은 outline 위치 결정 비트 아님 (text wrap interaction 등 다른 의미). ## Fix `paper_based = true` 강제 (한컴 viewer 실측 정합). 회귀 history 코멘트 기록. `RHWP_DEBUG_PAGE_BORDER` 환경변수 영구화 (attr 추적 진단 도구). ## 잔존 회귀 (별도 task 분리) - Issue 2 — sample16 page 18 본문 다음 페이지 밀림 (장기 typeset 결함, 회귀 commit 없음) - Issue 3 — 시험지 page 1 문9 vertical 처짐 (HWP5 column layout) 본 task #952 범위는 Issue 1 (외곽선) 만 해결. ## 검증 - cargo test --release --lib: 1288 passed, 0 failed - sample16 HWP3/HWP5/HWPX page 17 외곽선: paper-based (x=18.93~774.77) ✓ task877 baseline 정합 - 시험지 (3-11월) HWP5/HWPX page 1 외곽선: paper-based (x=26.45~767.25) ✓ 한컴 정합 ## 추가 fixture (samples + pdf) - samples/3-09월_교육_통합_2022.{hwp,hwpx}, 3-09월_교육_통합_2023.{hwp,hwpx} - samples/3-10월_교육_통합_2022.{hwp,hwpx}, 3-11월_실전_통합_2022.{hwp,hwpx} - pdf/3-09월_교육_통합_2022.pdf 외 3개 — 한컴 2022 권위 PDF Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jangster77 — Issue #952 Issue 1: 페이지 외곽선 paper/body 잘못 분류 회귀. 회귀 source: 4bb1128 fix (#920) 의 paper_based = (attr & 0x01) == 0 비트 반전. 회귀 history: task877 (!= 0, sample16 정합/시험지 회귀) → #920 (== 0, 시험지 정합/sample16 회귀) → 본 PR (true, 모든 sample 한컴 정합). 진단: 5+ samples 한컴 viewer 실측 — attr 0/1, textBorder PAPER/CONTENT 양쪽 다 paper-based. bit 0 은 outline 위치 결정 비트 아님 (text wrap interaction 등 별 의미). 본질 (src/renderer/layout.rs +16/-2): - paper_based = true 강제 (#920 회귀 코드 대체) - RHWP_DEBUG_PAGE_BORDER 환경변수 진단 영구화 - 회귀 history 코멘트 영구 보존 (재회귀 방지) 추가: 시험지 fixture 8 (HWP/HWPX) + 한컴 2022 권위 PDF 4 (회귀 가드) + 문서 4. 본 PR 범위 외 (별도 task 분리, PR 본문 명시): - Issue 2: sample16 page 18 본문 밀림 (typeset multi-TAC cursor over-advance) - Issue 3: 시험지 문9 vertical 처짐 (HWP5 column) 자기 검증: cargo test --release --lib 1288 passed / clippy 통과 / 광범위 sweep 7 fixture / 169 페이지 / 169 same / 0 diff / WASM 4.4 MB 재빌드 시각 판정: 작업지시자 시각 검증 통과 (sample16 + 시험지 page border paper-based, 한컴 2022 PDF 권위) CI: ✅ Build & Test + CodeQL + Canvas visual diff 연속 5 PR 1번째 (#956 → #958 → #961 → #963 → #964, @jangster77 순차 처리)
- mydocs/pr/archives/pr_956_review.md (paper-based outline 회귀 분석) - mydocs/pr/archives/pr_956_report.md (옵션 A 처리 결과 + 동기화 선행) - mydocs/orders/20260517.md PR 처리 섹션 추가 (컨트리뷰터 Task #952 작업 일지 보존) 핵심: - 사전 동기화 (5/11→5/17 +19 commits FF, feedback_release_sync_check) - 회귀 source 4bb1128 (#920) bit 반전 → paper_based=true 강제 - 5+ samples 한컴 실측 정합 (추측보다 실측) - sweep 169/169 same + 작업지시자 시각 판정 통과 - Issue #952 OPEN 유지 (Issue 2/3 별도 task, 연속 PR #958 후속)
…loses #957) `samples/hwp3-sample16.hwp` page 18 의 "나. 주요 과업내용" 후 본문 paragraphs (pi=395~401 "○ 통합모델...") 이 다음 페이지로 밀려 시각 누락. 한컴 viewer 는 같은 페이지 표시. `RHWP_DEBUG_TAC_CURSOR` 추적 결과: ``` Shape pi=394 ci=1 y_in=767.3 y_out=1197.9 dy=430.6⚠️ FullPara pi=395 y_in=1197.9 (body 외 영역) ``` `src/renderer/layout.rs:3470-3475` (layout_shape_item 의 Bottom caption advance): - pi=394 ci=1 picture 의 caption: `dir=Bottom width=0 paras=1 text=""` (빈 caption) - 빈 caption 임에도 layout 이 `cap_bottom = cap_y + caption_h` 계산 - pic_y = 767.3 (has_prior_tac 로 갱신된 잘못된 para_start_y) - image_bottom = 767.3 + 411.89 (pic_h) = 1179.19 - cap_y = 1179.19, caption_h = 18.7 (empty paragraph default line height) - cap_bottom = 1197.89 → result_y +430.6 phantom advance - 다음 paragraph (pi=395) 가 1197.89 부터 시작 → body 외 emit 빈 caption 시 result_y advance skip — `paragraphs[*].text` 가 모두 무의미 문자 + `controls.is_empty()` 시 advance 분기 미진입. `RHWP_DEBUG_TAC_CURSOR` 환경변수 영구화 (paragraph item 별 y_offset 추적 진단 도구). - cargo test --release --lib: 1288 passed, 0 failed, 2 ignored - sample16 page 18: pi=395~401 본문 같은 페이지 정상 emit (한컴 viewer page 16 정합) - hwp3-sample14 (Task #864 영역, non-empty caption "Cut&Paste 할 영역" + empty 다수): 정상 - hwp3-sample10/11/13, exam_kor/math: 회귀 없음 | 영역 | 영향 | |------|------| | Empty caption picture | result_y advance 제거 (회귀 fix) | | Non-empty caption picture | 영향 없음 | | Caption None | 영향 없음 | | Caption Top direction | 영향 없음 | - 원 issue #952 + PR #956 — Issue 1 (페이지 외곽선 paper/body) 해결 - archive/task936 — 본 영역 이전 fix 시도 history (미완) - PR #918 — 본 영역 시도 history (close) - 잔존 — 원 #952 의 Issue 3 (HWP5 시험지 page 1 문9 vertical) 별도 task Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jangster77 — Issue #957 (Issue #952 영역 영역 Issue 2 분리 task): sample16 page 18 "나. 주요 과업내용" 후 본문 (pi=395~401) 다음 페이지 밀림. Root cause (RHWP_DEBUG_TAC_CURSOR 추적): pi=394 ci=1 picture 의 빈 caption (dir=Bottom width=0 paras=1 text="") 영역 영역 phantom +430.6px 누적 → pi=395 가 body 외 영역 emit → 다음 페이지 밀림. 본질 (src/renderer/layout.rs): caption_is_empty 가드 — caption 모든 paragraph 영역 영역 무의미 문자 (≤U+001F, U+FFFC) + controls.is_empty() 시 result_y advance skip. RHWP_DEBUG_TAC_CURSOR 진단 영구화 (PR #956 RHWP_DEBUG_PAGE_BORDER 패턴 정합). 영역 좁힘: 빈 caption + Bottom 한정 — non-empty/None/Top 영향 없음. 본 환경 충돌 수동 해결: - mydocs/orders/20260517.md — 본 환경 PR #956 처리 섹션 + PR #958 Task #957 작업 일지 양측 보존 통합 - src/renderer/layout.rs — PR #956 (paper_based :770) + PR #958 (caption :3491) 다른 영역 auto-merge (양립 확인) 자기 검증: cargo test --release --lib 1288 passed / clippy 통과 / 광범위 sweep 7 fixture / 169 페이지 / 169 same / 0 diff / WASM 4.4 MB 재빌드 시각 판정: 작업지시자 시각 검증 통과 (sample16 page 18 본문 같은 페이지, sample14/10/11/13 + PR #956 page border 회귀 부재) CI: ✅ Build & Test + CodeQL + Canvas visual diff 연속 5 PR 2번째 (#956 ✅ → #958 → #961 → #963 → #964)
- mydocs/pr/archives/pr_958_review.md (빈 caption phantom advance 분석) - mydocs/pr/archives/pr_958_report.md (옵션 A 처리 결과) - mydocs/orders/20260517.md PR #958 행 추가 핵심: - pi=394 ci=1 picture 빈 caption phantom +430.6px (RHWP_DEBUG_TAC_CURSOR 추적) - caption_is_empty 가드 + Bottom 한정 (케이스별 명시) - PR #956 + #958 layout.rs 양립 확인 (paper_based :770 + caption :3491) - sweep 169/169 same + 작업지시자 시각 판정 통과 - Issue #957 close, Issue #952 OPEN 유지 (Issue 3 잔존, 연속 PR #961 후속)
…p — 시험지 page 1 문9 정합 (closes #959) `samples/3-11월_실전_통합_2022.hwp` page 1 우측 단의 문9 가 한컴 viewer 보다 ~250px 아래 처짐. `RHWP_DEBUG_TAC_CURSOR` 추적 결과: ``` Shape pi=69 ci=0 y_in=709.4 y_out=983.4 dy=274.0⚠️ ... pi=70~72 (빈 줄) ... FullPara pi=73 y_in=1043.5 ... (문9 line) ``` pi=69 picture (16786×20400 HU = 59.2×72.0mm, **height 272px**): - horz_rel_to=Column, h_offset=79.5mm (300px), 정렬=Center - vert_rel_to=Para, wrap=TopAndBottom, tac=false `compute_object_position` 계산: - pic_emit_x = col_area.x + (col_width - pic_width)/2 + h_offset = 399 + (360-224)/2 + 300 = 767 - col_area right = 759.7 → **picture 가 column 우측 외부 emit** 한컴 viewer 는 column flow 에 reservation 하지 않음 (PDF 분석: 우측 단에 picture 표시 안 됨). rhwp 는 picture height 만큼 cursor advance → 문9 처짐. `src/renderer/layout.rs:3500-3556`: horz_rel_to=Column picture 의 emit x 사전 계산. pic_emit_x >= col_area.x + col_area.width 시 result_y = saved_y_offset (advance skip). `RHWP_DEBUG_TAC_CURSOR` 환경변수 영구화 (paragraph item 별 y_offset 추적 진단 도구). - cargo test --release --lib: 1288 passed, 0 failed - 시험지 (3-11월) page 1 문9: y=1061 → y=805 ✓ 한컴 PDF 정합 - pi=69 ci=0 dy: 274 → 18 (line advance만) ✓ - 시험지 4종 (3-09월 2022/2023, 3-10월 2022, 3-11월 2022) page 1: 정상 - exam_kor page 18 (Square wrap picture, Task #722 영역): 정상 - exam_math/eng/hwp3-sample10/11/13: 정상 | 영역 | 영향 | |------|------| | horz_rel_to=Column + col 외부 emit picture | result_y advance 제거 (회귀 fix) | | horz_rel_to=Column + col 내부 emit picture | 영향 없음 (Fix 조건 미진입) | | horz_rel_to=Paper/Page picture | 영향 없음 (is_paper_based 분기) | | horz_rel_to=Para picture | 영향 없음 (Column 검사 false) | | TAC picture | 영향 없음 (별도 분기) | 본 task page 2 시각 검증 중 multi-line equation off-by-one 결함 발견 → 별도 issue #960 (Fix C 와 무관 pre-existing). - 원 issue #952 + PR #956 — Issue 1 (페이지 외곽선) 해결 - PR #958 — Issue 2 (sample16 page 18 본문 누락) 해결 - 본 PR #959 — Issue 3 (시험지 page 1 문9 vertical) 해결 - 신규 issue #960 — page 2 multi-line equation off-by-one (별도) PR #956 와 중복 가능 (먼저 머지되는 PR 가 가져감): - samples/3-09월_교육_통합_2022.{hwp,hwpx} 외 7개 - pdf/3-09월_교육_통합_2022.pdf 외 3개 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… column 외부 emit advance skip @jangster77 — Issue #959 (Issue #952 영역 영역 Issue 3 분리 task): 시험지 (3-11월) page 1 우측 단 문9 ~250px 처짐. Root cause (RHWP_DEBUG_TAC_CURSOR 추적): Shape pi=69 ci=0 picture (horz_rel_to=Column, h_offset=79.5mm, Center) 영역 영역 pic_emit_x=767 > col_area right=759.7 → picture 좌측 edge column 외부, 한컴 PDF 우측 단 미표시. 그럼에도 cursor 274px advance → 문9 처짐. 본질 (src/renderer/layout.rs:3537): saved_y_offset — horz_rel_to=Column picture pic_emit_x 가 col_area 우측 초과 시 result_y = saved_y_offset (advance skip, :3566). 영역 좁힘: horz_rel_to=Column + col 외부 한정 — col 내부/Paper/Page/Para/TAC 영향 없음. 본 환경 충돌 수동 해결: - mydocs/orders/20260517.md — 본 환경 PR #956/#958 처리 표 + PR #961 Task #959/#960 작업 일지 양측 보존 통합 - src/renderer/layout.rs — auto-merge: PR #956 paper_based=true :770 + PR #958 caption_is_empty :3491 + PR #961 saved_y_offset :3537 3 정정 양립 - 시험지 fixture 8 + PDF 4 — PR #956 머지 영역 영역 동일 content (devel 보존) 자기 검증: cargo test --release --lib 1288 passed / clippy 통과 / 광범위 sweep 7 fixture / 169 페이지 / 169 same / 0 diff / WASM 4.4 MB 재빌드 시각 판정: 작업지시자 시각 검증 통과 (시험지 page 1 문9 y=805 한컴 PDF 정합, 시험지 4종 + exam_kor p18 + PR #956/#958 회귀 부재) CI: ✅ Build & Test + CodeQL + Canvas visual diff Issue #952 종결 — Issue 1 (#956) + Issue 2 (#958) + Issue 3 (#961) 모두 해결. 잔존: Issue #960 (page 2 multi-line equation off-by-one, pre-existing, 별도) 연속 5 PR 3번째 (#956 ✅ → #958 ✅ → #961 → #963 → #964)
- mydocs/pr/archives/pr_961_review.md (column picture advance skip 분석) - mydocs/pr/archives/pr_961_report.md (옵션 A 처리 결과 + Issue #952 종결) 핵심: - pi=69 ci=0 horz_rel_to=Column picture col 외부 emit (RHWP_DEBUG_TAC_CURSOR) - saved_y_offset advance skip + col 외부 한정 (케이스별 명시) - PR #956/#958/#961 layout.rs 3 정정 양립 (:770 + :3491 + :3537) - sweep 169/169 same + 작업지시자 시각 판정 통과 - Issue #952 종결 (Issue 1/2/3 모두 해결: #956/#958/#961) - 잔존 Issue #960 (page 2 equation off-by-one, 별도 task)
… formula off-by-one 해소 (closes #960) `samples/3-11월_실전_통합_2022.hwp` page 2 문14 (pi=117) 의 cases formula (multi-line equation g(x)={cases x...f(x)}) 가 line 0 영역 (y=329) 에 emit (예상 line 1 ~y=347, 한컴 PDF 정합) — header text 와 시각 overlap. `RHWP_DEBUG_PARA_TAC` 추적 결과: pi=117 text 에 FFFC (object replacement char) 없음. `find_control_text_positions` (model/paragraph.rs:817-838) 의 char_offsets gap 분석: - utf16 gap [60, 76] = 15 → 1 control at codepoint position 30 (= `\n`) compose_lines 의 line 1 chars range = [23, 30) — **position 30 (=\n) 제외**. `paragraph_layout.rs:1724-1727` filter: ```rust .filter(|(pos, _, _)| *pos >= run_char_pos && (*pos < run_char_end || (is_last_run && *pos == run_char_end))) ``` cases (pos=30) for line 1 (run_char_pos=23, run_char_end=30): - pos < 30 ❌, is_last_run ❌ (line 1 은 paragraph 의 last line 아님) - → cases 가 line 1 run_tacs 에서 누락 → shape_layout 의 default y (=329) 에 emit `src/renderer/layout/paragraph_layout.rs:1719-1736`: ```rust // [Task #960] has_line_break line 의 마지막 run 도 run_char_end 위치 의 TAC 포함. // HWP3 의 char_offsets gap 분석으로 매핑된 control 위치가 `\n` 문자에 떨어지면, // 그 line 의 chars range [start, end) 에서 end 가 `\n` 위치이므로 누락. let allow_end_tac = is_last_run || (comp_line.has_line_break && is_last_run_of_line(run_idx)); let run_tacs: Vec<(usize, f64, usize)> = tac_offsets_px.iter() .filter(|(pos, _, _)| *pos >= run_char_pos && (*pos < run_char_end || (allow_end_tac && *pos == run_char_end))) ... ``` - cargo test --release --lib: 1288 passed, 0 failed - 시험지 page 2 문14 cases formula y: 329 → 352 ✓ (line 1 정상) - TAC_LINE pi=117 line 1 run_tacs: [] → [(7, 177.85, 3)] ✓ - LAYOUT_OVERFLOW count: 41 → 41 (회귀 0) - exam_kor/math/eng, sample10~14, 시험지 4종: 시각 회귀 0 | 영역 | 영향 | |------|------| | has_line_break + end-position control | 정상화 (이전 누락 → line 내 inline emit) | | has_line_break 없는 line | 영향 없음 (조건 미진입) | | 일반 TAC control (line 안쪽) | 영향 없음 | 본 task Stage 4 시각 검증 중 발견: - 문14 의 <보기> textbox (pi=118 InFrontOfText TAC 사각형 + 내부 글상자) 의 inline 수식 + ㄱㄴㄷ prefix scramble - Fix 적용 전/후 동일 (pre-existing, Fix 와 무관) - → 별도 issue #962 등록 - 원 issue #952 + PR #956 (Issue 1 외곽선) - PR #958 (Issue 2 sample16 page 18) - PR #961 (Issue 3 시험지 page 1 문9 vertical) - 본 PR (Issue 4 cases formula off-by-one) - 신규 issue #962 — page 2 보기 textbox 별도 task samples/pdfs (시험지 hwp/hwpx, pdf) 는 PR #956 에서 추가되므로 본 PR 에 포함 안 함. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jangster77 — Issue #960 (Issue #952 영역 영역 Issue 4, PR #961 page 2 검증 중 발견): 시험지 (3-11월) page 2 문14 (pi=117) cases formula 가 line 0 (y=329) 에 emit → header text 와 overlap. Root cause (RHWP_DEBUG_PARA_TAC 추적): char_offsets gap 분석 영역 영역 cases (ci=3) → position 30 (= \n 위치). compose_lines line 1 chars [23,30) 에서 position 30 제외 → is_last_run && pos == end 만 허용 → line 1 (last line 아님) 누락 → line 0 (header) emit → overlap. 본질 (src/renderer/layout/paragraph_layout.rs:1730): allow_end_tac = is_last_run || (comp_line.has_line_break && is_last_run_of_line(run_idx)) — has_line_break line 의 마지막 run 도 end position TAC 포함. RHWP_DEBUG_PARA_TAC 진단 영구화. 영역 좁힘: has_line_break + end-position 한정 — has_line_break 없는 line / 일반 TAC (line 안쪽) 영향 없음. 본 환경 충돌 수동 해결: mydocs/orders/20260517.md (--ours 본 환경 PR 처리 표 보존 + Task #960/#962 작업 일지 갱신). paragraph_layout.rs auto-merge (devel 변경 부재, PR #956/#958/#961 은 layout.rs — 다른 파일, 4 정정 양립). 자기 검증: cargo test --release --lib 1288 passed / clippy 통과 / 광범위 sweep 7 fixture / 169 페이지 / 168 same / 1 diff (exam_math_017.svg). exam_math page 18 inline equation line 매핑 변화 — 작업지시자 한컴 2020 에디터 직접 확인 영역 영역 **의도된 정정 확정** (이전 잘못된 line emit → 정정 후 올바른 line, 시험지 page 2 cases 와 동일 본질). WASM 4.4 MB 재빌드. 시각 판정: 작업지시자 시각 검증 통과 (시험지 page 2 cases y=352 한컴 PDF 정합 + exam_math page 18 의도 확정 + 회귀 부재) CI: Build & Test pending (devel merge commit 재트리거) — 본 환경 자기 검증 보완 잔존: Issue #962 (page 2 보기 textbox scramble, pre-existing, 별도 task) 연속 5 PR 4번째 (#956 ✅ → #958 ✅ → #961 ✅ → #963 → #964)
- mydocs/pr/archives/pr_963_review.md (TAC line 매핑 off-by-one 분석) - mydocs/pr/archives/pr_963_report.md (옵션 A + exam_math p18 sweep diff 의도 확정) - mydocs/orders/20260517.md PR #963 행 추가 핵심: - pi=117 cases formula position 30 (\n) off-by-one (RHWP_DEBUG_PARA_TAC) - allow_end_tac (has_line_break line 마지막 run end-position TAC 포함) - PR #956/#958/#961 (layout.rs) + #963 (paragraph_layout.rs) 4 정정 양립 - sweep 168/169 same + exam_math p18 diff 1건 → 작업지시자 한컴 2020 직접 확인 의도 확정 - Issue #960 close, Issue #962 잔존 (별도 task, 연속 PR #964 후속)
…ox content scramble 해소 (closes #962) `samples/3-11월_실전_통합_2022.hwp` page 2 문14 <보기> textbox (pi=118 InFrontOfText TAC 사각형 + 내부 글상자) 의 inline 수식이 각각 2번 emit → ㄱㄴㄷ prefix + 본문 + 수식 시각 overlap. `RHWP_DEBUG_PARA_TAC` + SVG 분석: - 보기 textbox 영역 (y 440-540, x 400-760) 의 equation transforms: **12 개** (예상 6 × 2 duplicates) - Set 1 (gap 위치, 정상): paragraph_layout 의 inline TAC 처리 (paragraph_layout.rs:2078+) - Set 2 (textbox 좌측 edge x=406): shape_layout 두번째 loop 의 Equation branch (shape_layout.rs:1609) 원래 두번째 loop 의 의도: paragraph_layout 미지원 이전의 legacy fallback. 현재 paragraph_layout 가 textbox 내부 inline TAC 를 정상 처리하므로 중복 emit 발생. `src/renderer/layout/shape_layout.rs:1609-1675`: ```rust Control::Equation(eq) => { let eq_w = hwpunit_to_px(eq.common.width as i32, self.dpi); let eq_h = hwpunit_to_px(eq.common.height as i32, self.dpi); // [Task #962] 글상자 내부 paragraph 의 inline equation 은 paragraph_layout 가 // 정확한 gap 위치 (text 사이) 에 emit. 본 두번째 loop 는 legacy fallback. let equiv_cell_ctx = CellContext { parent_para_index: para_index, path: { /* parent_cell_path + textbox entry */ }, }; if tree.get_inline_shape_position( section_index, pi, ctrl_idx_in_para, Some(&equiv_cell_ctx) ).is_some() { // paragraph_layout 가 이미 emit — inline_x 만 advance inline_x += eq_w; } else { // legacy fallback (기존 emit 분기 유지) ... } } ``` - cargo test --release --lib: 1288 passed, 0 failed - 시험지 page 2 보기 textbox equations: 12 → 6 ✓ (duplicates 제거) - 시각: ㄱ. h(1)=3 / ㄴ. 함수 h(x)는... / ㄷ. 함수 g(x)가... ✓ 한컴 PDF 정합 - LAYOUT_OVERFLOW count: 325 → 325 (회귀 0) - exam_kor/math/eng, sample14, 시험지 4종: 시각 회귀 0 | 영역 | 영향 | |------|------| | textbox 내부 inline Equation (paragraph_layout 등록 case) | duplicate 제거 (회귀 fix) | | textbox 내부 inline Equation (legacy fallback) | 영향 없음 (else 분기 유지) | | textbox 내부 Shape/Picture/Table | 본 fix 미대상 | | textbox 외부 standalone equation | 영향 없음 | - 원 issue #952 + PR #956 (Issue 1 외곽선) - PR #958 (Issue 2 sample16 page 18) - PR #961 (Issue 3 시험지 page 1 문9 vertical) - PR #963 (Issue 4 cases formula off-by-one) - 본 PR (Issue 5 보기 textbox duplicate equation) 원 #952 의 5 issue 모두 해결 → close 가능. samples/pdfs (시험지) 는 이전 PR (#956/#961) 에서 추가되므로 본 PR 에 포함 안 함 (중복 방지). layout.rs 변경은 PR #958/#961 영역 — 본 PR 에 포함 안 함. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jangster77 — Issue #962 (Issue #952 영역 영역 Issue 5, PR #963 page 2 검증 중 발견): 시험지 (3-11월) page 2 문14 <보기> textbox inline 수식 각각 2번 emit → scramble. Root cause (SVG 분석): 보기 textbox 영역 영역 equation 12개 (6×2 duplicates): - Set 1 (정상, gap 위치): paragraph_layout inline TAC (paragraph_layout.rs:2078+) - Set 2 (duplicate, textbox 좌측 edge): shape_layout 두번째 loop legacy fallback paragraph_layout 가 현재 textbox 내부 inline TAC 정상 처리 → legacy fallback 중복. 본질 (src/renderer/layout/shape_layout.rs:1620): Equation branch emit 전 get_inline_shape_position (equiv_cell_ctx — parent_cell_path + textbox entry) 확인 → paragraph_layout 등록 시 inline_x += eq_w 만 (duplicate 차단), 미등록 시 legacy fallback 유지. 영역 좁힘: paragraph_layout 등록 case 한정 — legacy fallback / Shape/Picture/Table / standalone 영향 없음. 본 환경 충돌 수동 해결: mydocs/orders/20260517.md (--ours 본 환경 PR 처리 표 보존 + Task #962 작업 일지 갱신). shape_layout.rs auto-merge (devel 변경 부재). PR #956/#958/#961 (layout.rs) + #963 (paragraph_layout.rs) + 본 PR (shape_layout.rs) — **5 정정 모두 다른 파일, 양립 확인**. devel merge commit (93dfe0a/3d1cdf31) cherry-pick 제외 — 본질 682875f 만. 자기 검증: cargo test --release --lib 1288 passed / clippy 통과 / 광범위 sweep 7 fixture / 169 페이지 / 169 same / 0 diff / WASM 4.4 MB 재빌드 시각 판정: 작업지시자 시각 검증 통과 (시험지 page 2 보기 textbox 12→6, ㄱ/ㄴ/ㄷ 한컴 PDF 정합 + 회귀 부재) CI: ✅ Build & Test + CodeQL + Canvas visual diff 원 Issue #952 의 5 분리 결함 완결: #952 Issue 1 (#956) + Issue 2 (#958) + Issue 3 (#961) + #960 (#963) + #962 (본 PR) 연속 5 PR 완결 (@jangster77: #956 → #958 → #961 → #963 → #964)
- mydocs/pr/archives/pr_964_review.md (textbox inline equation duplicate 분석) - mydocs/pr/archives/pr_964_report.md (옵션 A + Issue #952 5 분리 결함 완결) - mydocs/orders/20260517.md PR #964 행 + 연속 5 PR 총평 핵심: - 보기 textbox equation 12개 (Set 1 paragraph_layout + Set 2 shape_layout legacy duplicate) - get_inline_shape_position (equiv_cell_ctx) 확인 영역 영역 duplicate 차단 - PR #956~#964 5 정정 다른 파일 양립 (layout.rs×3 + paragraph_layout.rs + shape_layout.rs) - sweep 169/169 same + 작업지시자 시각 판정 통과 - 원 Issue #952 의 5 분리 결함 완결 (#956/#958/#961/#963/#964) - @jangster77 연속 5 PR 완결
… 박스 외부 텍스트 표시 해소 (closes #965, ports PR #918 Stage 33-A) `samples/hwp3-sample16.hwp` page 18 (한컴 page 16) 의 WMF 다이어그램 (주전산센터 목표시스템 구성안) 내부 박스의 한글 텍스트 ("PE6450", "기록서버", "Windows 서버군", "Unix 서버군" 등) 가 박스 외부로 벗어남. `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 `src/wmf/converter/svg/mod.rs` 3 영역 (~60 lines): 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 }; ``` ```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` 잘못된 보정 제거. META_TEXTOUT 동일 baseline 보정 (ext_text_out 와 일관성). PR #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 #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>
…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 후속)
- 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 후속
… inflate 해소 (closes #967) ## 본질 `samples/hwp3-sample18.hwp` (HWP3) 페이지 수 rhwp 69 vs 한컴 67 — **+2 inflate**. ## Root cause `dump-pages` 분석: - Page 2: pi=27 "(빈)" 1개만 (24px), vpos=69356 HU - Page 14: pi=164 "(빈)" 1개만 (25.6px), vpos=69836 HU - pi=28, pi=165 (다음 paragraph) 에 [쪽나누기] (column_type::Page) 빈 paragraph 가 이전 page 잔여 공간 초과 (page 1: body 935px, used 934.2px, 빈 24px → over) → 별도 page 분기 → +1 inflate × 2. `src/renderer/typeset.rs:555-584` 의 `next_will_vpos_reset` 가드: ```rust let next_force_break = next_para.column_type == ColumnBreakType::Page || next_para.column_type == ColumnBreakType::Section; if next_force_break { false // ← 다음 force_break 시 false (hwp-multi-001 회귀 차단 목적) } ``` → pi=28/165 의 [쪽나누기] → next_force_break=true → next_will_vpos_reset=false → 단독 빈페이지 차단 가드 미발동 → pi=27/164 단독 page 생성. ## Fix `src/renderer/typeset.rs:584-604`: 기존 next_will_vpos_reset 가드 직후 별도 분기 추가. ```rust } else if !st.current_items.is_empty() && para_idx + 1 < paragraphs.len() { // [Task #967] 빈 paragraph 직후 force page break (쪽나누기) case 가드 let next_para = ¶graphs[para_idx + 1]; let next_force_break = next_para.column_type == ColumnBreakType::Page || next_para.column_type == ColumnBreakType::Section; let is_curr_empty = para.text.is_empty() && para.controls.is_empty(); if next_force_break && is_curr_empty { continue; // 빈 paragraph skip — 단독 page 차단 } } ``` 기존 next_will_vpos_reset 의 next_force_break 제외 조건 (hwp-multi-001 회귀 차단) **보존**. ## 검증 - cargo test --release --lib: 1288 passed, 0 failed, 2 ignored - sample18.hwp 페이지 수: 69 → 67 ✓ (한컴 정합) - 다중 sample 회귀 검증 (16 sample): - sample, sample10/11/13/14/16/19/4/5, table_test*, multi-table-001/002, exam_kor/math/eng: 모두 변경 없음 - **hwp-multi-001 (회귀 차단 case): 변경 없음 ✓** (기존 가드 보존 확인) ## 영향 | 영역 | 영향 | |------|------| | 빈 paragraph + 다음 [쪽나누기] | skip → +1 page inflate 제거 (회귀 fix) | | 비-빈 paragraph + 다음 [쪽나누기] | 영향 없음 | | 빈 paragraph + 다음 일반 paragraph | 영향 없음 (기존 가드) | | hwp-multi-001 (회귀 차단) | 영향 없음 | ## 관련 - 닫힌 issue #927 — sample16 페이지 수 inflate (본 fix 와 무관) - 잔존: HWPX sample18-hwp5.hwpx +7 inflate (별도 issue, HWPX 특화 pagination) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@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)
- mydocs/pr/archives/pr_968_review.md (빈 paragraph + 쪽나누기 v2 정밀화 분석) - mydocs/pr/archives/pr_968_report.md (옵션 A + fixture 부재 작업지시자 결정 + PR 시리즈 총평) - mydocs/orders/20260518.md 신규 PR 처리 섹션 + @jangster77 PR 시리즈 총평 핵심: - next_force_break 가드 미발동 root cause + v2 정밀화 (overflow 한정, aift.hwp 회귀 해소) - typeset.rs auto-merge (devel Task #836 Endnote 보존 + PR #968 :585 분기 양립) - cargo test 전체 + sweep 169/169 same + 기존 HWP3 샘플 시각 판정 통과 - samples/hwp3-sample18.hwp 부재 → 작업지시자 결정 회귀 부재 입증 + PR 본문 신뢰 - Issue #967 close, @jangster77 PR 시리즈 (7 PR #956~#968) 완결 - 잔존: HWPX sample18-hwp5 +7 inflate + sample18 fixture 추가 권장
버전 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>
…t check 복구) Task #1058 Stage 16 (adaa0b0) 에서 추가된 신규 파일이 rustfmt 정합 미통과 — devel CI #970 (sha=749048c9) Format check 실패. cargo fmt 적용으로 정정. 본 환경 cargo fmt --check 전체 exit 0 검증. 본 정정은 PR #1057 처리 진행 전 devel CI 회복 위한 단독 commit. 다른 처리분 (PR #1054/#1059 누적 + 예정 PR #1057) 은 별도 누적 push 계획 (작업지시자 결정 "본 PR 처리분 누적 후 push"). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
"안녕하세요! 지난번 #799 제안이 v0.7.12 릴리즈에 성공적으로 반영된 것을 확인했습니다. 프로젝트에 도움이 되어 기쁩니다! 다만 제가 당시 에디터(Cursor)의 Git 이메일 설정을 누락하는 바람에, 수동으로 통합된 커밋에 제 깃허브 계정이 제대로 연동되지 않아 Contribution 기록(Contributors 명단 및 프로필 잔디)이 남지 않은 것을 뒤늦게 확인했습니다. 혹시 괜찮으시다면 제 깃허브 계정이 Contributors에 정식으로 기록될 수 있도록, README.md에 기여자 명단을 추가하는 PR이나 가벼운 문서 보완 PR을 하나 더 올려도 괜찮을까요? |
기여자 명단에 누락된 점 사과드립니다. 기여자 명단에 @xogh3198 님을 추가하도록 하겠습니다. |
|
Participant 등록해 주셔서 감사합니다. 확인해 보니 기존 PR 커밋 author가 원인은 로컬 Git user.email 설정 오류였고 이메일설정을 수정하였습니다 이미 merge된 #571,#799 커밋의 author rewrite는 히스토리 변경 부담이 있어 대신 compare/이력 기능 관련 README·안내 문구 등 |
v0.7.12 PATCH 릴리즈
v0.7.11 (
a9dcdee3) → devel. 외부 기여자 PR 시리즈 흡수 + @jangster77 7-PR 시리즈 (#956~#968) 완결.핵심 변경
검증
cargo test --releaseALL GREEN (lib 1288 + integration svg_snapshot 8 + tab_cross_run 1)🤖 Generated with Claude Code