fix: CharShape start_pos 를 UTF-16 stream offset 으로 해석 (closes #915)#1047
Closed
HaimLee-4869 wants to merge 1 commit into
Closed
fix: CharShape start_pos 를 UTF-16 stream offset 으로 해석 (closes #915)#1047HaimLee-4869 wants to merge 1 commit into
HaimLee-4869 wants to merge 1 commit into
Conversation
…im#915) edwardkim#915: table-in-tbox.hwp p2 표 셀 "충남중부권지사" 가 휴먼명조 1pt(1.33px) 로 렌더되는 결함. 원인: composer 의 split_by_char_shapes 가 CharShape.start_pos 를 visible char index 로 해석한다(edwardkim#884). 이 해석은 인라인 제어자가 문단 중간에 있어 char_offsets 에 gap 이 생기는 문단에서 start_pos 가 가시문자 수 범위를 넘어 판정되어 char_shape 가 통째 누락된다. 한편 paragraph_layout / line_breaking 은 start_pos 를 stream offset 으로 해석하고 있어, composer 와 경로 간 불일치 상태이기도 했다. edwardkim#884 는 table-in-tbox.hwp p1 footer "충남중부권지사장" 의 char_shape 적용을 근거로 visible-index 해석을 도입한 것으로 보인다. 해당 footer 를 한컴2024 글자모양 패널로 재측정한 결과 HY수평선B 16pt 였고, start_pos 를 UTF-16 stream offset 으로 해석하면 footer(HY수평선B 16pt)와 edwardkim#915 양쪽이 모두 한컴과 정합한다. split_by_char_shapes 의 start_pos 매핑을 stream offset 으로 맞춰 composer 를 paragraph_layout / line_breaking 과 일관시켰다 — char_offsets 에서 start_pos 이상인 첫 가시문자가 char_shape 적용 시작점. 검증 (한컴2024 글자모양 패널 대조): - table-in-tbox p1 footer "충남중부권지사장": HY수평선B 16pt - table-in-tbox p2 "충남중부권지사": 휴먼명조 1pt → 정상 - KTX 목차 "Ⅰ" 휴먼명조 16pt / "사업 개요" HY헤드라인M 15pt - cargo test 전체 49 스위트 / clippy / fmt 통과 tests/issue_915_charshape_cell_font_size.rs: edwardkim#915 회귀 가드 신규. tests/issue_884_charshape_diagnostic.rs: footer 단언을 한컴 실측값(HY수평선B)으로 갱신. tests/golden_svg/issue-{157,267,617,677}: stream offset 해석 결과로 갱신. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
edwardkim
added a commit
that referenced
this pull request
May 20, 2026
…ffset 해석 통일 — PR #913 revert @HaimLee-4869 5번째 기여. CharShape.start_pos 해석을 UTF-16 stream offset (해석 A) 로 통일 — PR #913 (closes #884, @planet6897, commit 9f81351) 의 visible char index (해석 B) 해석을 한컴 2024 글자모양 패널 실측 4 케이스 권위로 명시적 revert. 본질: - src/renderer/composer.rs split_by_char_shapes 의 start_pos lookup 을 char_offsets.iter().position(|&off| off >= cs.start_pos) 로 변경 — char_offsets[i] 가 가시문자 i 의 stream offset 이므로 start_pos 이상인 첫 가시문자가 char_shape 적용 시작점. - fallback active-shape 조회: find_active_char_shape_visible → find_active_char_shape (line_stream_start = char_offsets[text_start]). - 결과: composer ↔ paragraph_layout.rs / line_breaking.rs 의 4 경로가 모두 해석 A 로 일관. 한컴 2024 글자모양 패널 실측 4 케이스 (해석 A 정답): | 위치 | 한컴 패널 | 해석 A (본 PR) | 해석 B (PR #913) | |------|----------|----------------|------------------| | table-in-tbox p1 footer "충남중부권지사장" | HY수평선B 16pt | ✅ | 26pt ❌ | | table-in-tbox p2 "충남중부권지사" | 정상 | ✅ | 휴먼명조 1pt ❌ #915 | | KTX 목차 "Ⅰ" | 휴먼명조 16pt | ✅ | 18.7pt ❌ | | KTX 목차 "사업 개요" | HY헤드라인M 15pt | ✅ | 18.7pt ❌ | PR #913 의 오진 원인: - footer "충남중부권지사장" 의 "26pt" 판정이 HY수평선B 굵은 글꼴 + 로고 옆 배치로 인한 육안 착시 — 한컴 패널 실측은 16pt. - composer 만 해석 B 로 바꿔서 paragraph_layout/line_breaking 와 불일치 상태 (path 불일치). - 인라인 제어자가 문단 *중간* 에 있는 문단에서 start_pos 가 char_offsets gap 만큼 부풀려져 char_shape 통째 누락 → #915 (table-in-tbox p2 "충남중부권지사" 1.33px). 회귀 가드 (4 가드 영구화): - tests/issue_884_charshape_diagnostic.rs 갱신 — 단언 반전 (footer "충" HY수평선B 검증, 한컴 실측 기반). - tests/issue_915_charshape_cell_font_size.rs 신규 — 한글 음절 < 5px 부재 휴리스틱 (정상 ≥5px, 결함 ≈1.33px). - tests/issue_874_ktx_toc_page_number_right_align.rs (PR #1026) 양립 — KTX 페이지번호 정합 유지. - tests/svg_snapshot.rs 8/8 (issue-157/267/617/677 골든 4 갱신, table_text/form_002/aift/render_deterministic 보존). 검증 (본 환경): - cargo test --release --lib **1319 passed** - cargo test --release --tests 모든 통합 passed (0 FAILED) - cargo test --release --test issue_884_charshape_diagnostic **2/2 passed** - cargo test --release --test issue_915_charshape_cell_font_size **1/1 passed** - cargo test --release --test issue_874_ktx_toc_page_number_right_align **1/1 passed** - cargo test --release --test svg_snapshot **8/8 passed** - cargo fmt --all --check clean - sweep 8 fixtures (277 SVGs): 53 diff (광범위 stream offset 정합, table-in-tbox/KTX/hwp3-sample16/exam_kor/exam_math/aift) / 페이지 수 회귀 부재 / biz_plan 무영향 - **table-in-tbox p2 정량 입증**: font-size="1.3333" → font-size="16" - WASM Docker 빌드 4.89MB + rhwp-studio 동기화 - 작업지시자 시각 판정 통과 (한컴 2024 패널 실측 4 케이스 권위) `feedback_visual_judgment_authority` 모범 사례 — PR #913 의 "★ 시각 판정 통과" 도 정량적 한컴 패널 실측 권위로 정정 가능 (측정 우위). `reference_authoritative_hancom` — Windows 한컴 편집기 글자모양 패널이 1차 권위. `feedback_pr_supersede_chain` — PR #913 (오진 정합) → PR #1047 (실측 정정) 의 supersede 패턴. PR #913 머지 commit `9f81351a` 의 4 경로 중 composer 만 해석 B 였음 → path 일관성 복원. closes #915 Co-Authored-By: HaimLee-4869 <j_haim4869@naver.com>
Owner
|
Merged via cherry-pick (commit d84e7f5, author @HaimLee-4869 보존) into devel 본 환경 검증 통과: cargo test 1319 + 통합 + 회귀 가드 4 (issue_884 2/2 + issue_915 1/1 + issue_874 1/1 + svg_snapshot 8/8) + sweep 53 diff (광범위 stream offset 정합) + WASM 4.89MB + 작업지시자 시각 판정. PR #913 (closes #884, @planet6897, commit 9f81351) 의 visible char index 해석을 한컴 2024 글자모양 패널 실측 4 케이스 권위로 revert. composer ↔ paragraph_layout/line_breaking path 일관성 복원 + #915 결함 (table-in-tbox p2 1.33px → 16px) 해소.
closes #915 |
edwardkim
added a commit
that referenced
this pull request
May 20, 2026
… revert) PR #1047 (closes #915) 머지 후속 처리: - mydocs/pr/archives/pr_1047_review.md (검토 문서 archives 이동) - mydocs/orders/20260521.md (PR #1047 entry 추가) - rhwp-studio/public/{rhwp.d.ts,rhwp.js,rhwp_bg.wasm} (WASM 4.89MB 동기화) @HaimLee-4869 5번째 기여 — PR #913 revert (한컴 2024 글자모양 패널 실측 4 케이스 권위로 visible char index → UTF-16 stream offset 해석 통일). composer ↔ paragraph_layout/line_breaking 4 경로 일관성 복원. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
edwardkim
added a commit
that referenced
this pull request
May 21, 2026
samples/table-in-tbox.hwp 의 글상자 클릭 동작이 한컴 UX 와 정합되도록 정정. 표 UX 패턴 (isTableBorderClick / enterTableObjectSelection / Esc 처리) 을 글상자에 일반화하여 적용. 한컴 UX 정합: - 글상자 외곽 경계선 (tolerance 5px) → 객체 선택 - 글상자 내부 (텍스트/빈 영역/안 표) → 즉시 텍스트 편집 진입 - 글상자 안 표 셀 → cursor 정상 진입 (글상자 가로채기 제거) - Esc → 가장 안쪽 컨테이너부터 escape stack (안 표 → 글상자 안 본문 → 글상자 객체 → 본문 자연 전이) 본질 (7 코드 갭 정확 식별): Native (Rust) — 4 파일: - src/document_core/queries/cursor_rect.rs: TextBoxBboxInfo struct + collect_runs Rectangle/Ellipse/Path 노드 메타 수집 + hit_test 우선순위 (hit_cell → clicked_cell → textbox_hit → hit_body) + format_textbox_entry + 0.5 inline Shape 분기 글상자 fall-through (break) - src/document_core/queries/cursor_nav.rs: resolve_table_by_path 가 path 중간 항목 Shape (글상자) 면 text_box.paragraphs traverse, 5 ShapeObject variants (Rectangle/Ellipse/Polygon/Arc/Curve) 지원 - src/document_core/commands/table_ops.rs: get_shape_bbox_native 신규 (Rectangle/Ellipse/Path 노드 검색, getTableBBox 동등 패턴) - src/wasm_api.rs: getShapeBBox 공개 API Studio (TypeScript) — 4 파일: - rhwp-studio/src/engine/input-handler.ts: isShapeBorderClickByRef (sec/ppi/ci 시그니처, getShapeBBox + 5px tolerance) + findShapeByOuterClick - rhwp-studio/src/engine/input-handler-mouse.ts: 글상자 클릭 흐름 정정 (외곽 경계선만 객체 선택, 내부 즉시 cursor 진입, picHit shape 분기 외곽만 객체 선택) + 객체→편집 전환 (객체 선택 + 내부 클릭 → 편집) - rhwp-studio/src/engine/input-handler-keyboard.ts: Esc 우선순위 정정 (nestingDepth >= 2 + isTextBox → 표 객체 선택 우선) - rhwp-studio/src/engine/cursor.ts: enterTableObjectSelection cellPath.length >= 2 면 isTextBox 상태에서도 허용 + moveOutOfSelectedTable 글상자 안 표 → 외부 이동 시 isTextBox 유지 (escape stack 자연 전이) - rhwp-studio/src/core/wasm-bridge.ts: getShapeBBox 메서드 검증: - cargo test --release --lib **1319 passed** - cargo test --release --tests 모든 통합 passed (issue_852/874/915/1008/919) - cargo test --release --test issue_919_textbox_hit_test **5/5 passed**: textbox_inner_text_hit / textbox_inner_empty_hit / textbox_outside_hit / get_shape_bbox_returns_correct_dimensions / inner_table_cell_in_textbox_has_two_path_entries - cargo fmt --all --check clean - TypeScript tsc --noEmit 0 errors - WASM Docker 빌드 **4.90MB** (PR #1047 4.89MB + getShapeBBox API 추가) + rhwp-studio 동기화 - 작업지시자 시각 판정 통과 (2 라운드: 글상자 진입 + Esc escape stack) 작업지시자 시각 판정 권위 (`feedback_visual_judgment_authority`): - 1차 (글상자 진입) 통과 후 작업지시자 추가 지적 "글상자 내에 위치한 표의 셀 hitTest까지 성공입니다. 여기서 esc 키를 누르면 표가 선택되어야 하는데 글상자가 선택됩니다" → Stage 2.5 추가 정정 - 콘솔 에러 `renderTableObjectSelection 실패: controls[2]가 표가 아닙니다` 진단 → resolve_table_by_path 의 path traverse 일반화 추가 정정 비범위 (후속): - 머리말/꼬리말 안 글상자 (본 task 본문만) - 글상자 안 글상자 중첩 재귀 (본 PR 일부 지원: cellPath traversal) - 도형 (직사각형/원) 의 hit_test 동일 UX (본 task 는 글상자 한정) closes #919 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced May 21, 2026
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.
요약
#915 — table-in-tbox.hwp 2페이지 표 셀 "충남중부권지사" 가 휴먼명조 1pt(1.33px)로 렌더되는 결함 수정.
원인
composer 의 split_by_char_shapes 가 CharShape.start_pos 를 visible char index 로 해석한다(#884).
이 해석은 인라인 제어자가 문단 중간에 있어 char_offsets 에 gap 이 생기는 문단에서 start_pos 가
가시문자 수 범위를 넘어 판정되어 char_shape 가 통째 누락된다. 한편 paragraph_layout /
line_breaking 은 start_pos 를 stream offset 으로 해석하고 있어 경로 간 불일치 상태이기도 했다.
#884 는 table-in-tbox.hwp 1페이지 footer "충남중부권지사장" 을 근거로 visible-index 해석을
도입한 것으로 보인다. 해당 footer 를 한컴2024 글자모양 패널로 재측정한 결과는 아래와 같다.
한컴2024 글자모양 패널 실측 대조
(한컴은 pt, SVG font-size 는 px — px = pt × 96/72.)
start_pos 를 UTF-16 stream offset 으로 해석하면 footer 와 #915 양쪽이 모두 한컴과 정합한다.
변경
검증
Closes #915