Skip to content

fix: hit_test_header_footer 영역이 본문 침범 정정 (closes #595)#645

Open
johndoekim wants to merge 3 commits intoedwardkim:develfrom
johndoekim:fix/issue-595-header-bbox-bleed
Open

fix: hit_test_header_footer 영역이 본문 침범 정정 (closes #595)#645
johndoekim wants to merge 3 commits intoedwardkim:develfrom
johndoekim:fix/issue-595-header-bbox-bleed

Conversation

@johndoekim
Copy link
Copy Markdown
Contributor

Summary

exam_math.hwp 의 수식을 더블클릭했을 때 1페이지만 정상, 2페이지부터 오동작 (Issue #595). 본질은 hit_test_header_footer_native 가 사용하는 Header 노드 bbox 가 자식 (단 구분선 line) 까지 확장되어 본문 영역을 머리말로 잘못 인식 → onDblClick 의 머리말 분기가 picture selection 분기보다 먼저 실행되어 수식 편집기 진입 차단.

옵션 A 정정cursor_rect.rs::hit_test_header_footer_native 가 build_page_tree 의 Header/Footer 노드 bbox 대신 layout.header_area / layout.footer_area (PageDef margin 으로 계산된 정확한 영역) 로 hit 판정. 단일 함수 (+20/-13 LOC), 렌더링 동작 무영향, expand_bbox_to_children 의도 보존.

본질 결함 위치

src/renderer/layout.rs::build_header (line 928) 의 expand_bbox_to_children 호출이 머리말 자식 노드 — 특히 단 구분선 line paraIdx=0 ci=2 (h≈1227px) — 의 bbox 까지 Header 영역으로 확장:

페이지 정정 전 Header hit y 범위 실제 머리말 영역
page 0 (1p) 60.0 ~ 145.0 0 ~ 147 (정상)
page 1 (2p) 60.0 ~ 1355.0 0 ~ 147 (본문 80% 침범)
page 2~ 60.0 ~ 1355.0 0 ~ 147

page 0 vs page 1+ 차이: page 0 의 단 구분선은 ci=5 로 Body 자식, page 1+ 부터 ci=2 로 Header 자식 → page 0 만 정상.

정정 영역

src/document_core/queries/cursor_rect.rs::hit_test_header_footer_native 단일 함수.

- let tree = self.build_page_tree(page_num)?;
- for child in &tree.root.children {
-     let is_header = matches!(child.node_type, RenderNodeType::Header);
-     ...
-     if x >= child.bbox.x && x <= child.bbox.x + child.bbox.width
-         && y >= child.bbox.y && y <= child.bbox.y + child.bbox.height
-     { ... }
- }

+ let (page_content, _, _) = self.find_page(page_num)?;
+ let layout = &page_content.layout;
+ let h = &layout.header_area;
+ if x >= h.x && x <= h.x + h.width && y >= h.y && y <= h.y + h.height {
+     // ... hit ...
+ }
+ let f = &layout.footer_area;
+ if x >= f.x && x <= f.x + f.width && y >= f.y && y <= f.y + f.height {
+     // ... hit ...
+ }

부수 효과: build_page_tree 호출 제거 → mousedown 마다 호출되던 트리 빌드 비용 제거.

의도 보존: expand_bbox_to_children 은 무수정 — 머리말 표 셀 내 Shape 클리핑 방지 의도 (#42 영역) 보존.

검증 (정정 전 → 정정 후)

검증 정정 전 정정 후
tests/issue_595.rs (5 케이스, 신규) 3 fail / 2 pass 5 pass
본문 hit:false sweep (164 fixture / 1684p) 1652 / 32 fail 1684 / 0 fail (+32 본질 정정)
머리말 hit (margin_header > 0, 1356p) 1329 / 27 fail 1356 / 0 fail (+27 부수 개선)
꼬리말 hit (margin_footer > 0) 1383 / 16 fail 1383 / 16 fail (회귀 0, 별도 영역)
cargo test --lib --release (baseline) 1141 passed (회귀 0)
cargo clippy --release (lib) (baseline) clean
cargo build --release (baseline) clean
WASM 빌드 (Docker) (baseline) 4,531,883 bytes clean

메인테이너 시각 판정 영역: 작업지시자 직접 환경 (1365×1018, zoom=1.0) 에서 정정 전 결함 재현 (page 2 본문 빈 공간 더블클릭 → 머리말 편집 모드 진입) + 정정 후 정상 동작 (수식 더블클릭 → 수식 편집기 진입) 모두 ★ 통과 확인. 진행 환경: macOS + Chrome.

회귀 위험성 점검

관련 이슈 (CLOSED):

이슈 영역 회귀 위험
#236 PageAreas::from_page_def 머리말/본문 영역 공식 0 — 본 정정이 #236 정정의 영역을 일관 활용 (정확성 강화)
#42 머리말/꼬리말 내 Picture 렌더링 0 — 렌더링 무영향
#36 머리말 표 셀 안 이미지 미렌더링 0expand_bbox_to_children 의도 보존
#340 exam_math 13페이지 머리말 누출 0 — typeset 무영향

관련 함수: hit_test_in_header_footer_native (편집 모드 텍스트 hit), get_active_hf_info, find_section_for_page 무수정 — 회귀 위험 0.

TS 측 호출처 (hitTestHeaderFooter 호출 단 2곳):

  • input-handler-mouse.ts:494 (onMouseDown 머리말 모드 탈출용) — 정정 후 hit:false 정확 → 모드 탈출 정확 (개선)
  • input-handler-mouse.ts:784 (onDblClick 모드 진입용) — 본 정정 본질 영역

광범위 회귀 sweep 정량

samples/ 전체 167 fixture / 1687 페이지 (PR #642 기준 baseline) 정정 전후 비교:

  • 머리말 영역 hit:true (margin_header > 0): 27 fail → 0 fail (+27 부수 개선)
  • 꼬리말 영역 hit:true (margin_footer > 0): 동일 (16 fail, 1 fixture hwpctl_Action_Table 한정 — 별도 영역, 본 정정과 무관)
  • 본문 중앙 hit:false: 32 fail → 0 fail (+32 본질 정정 — exam_math.hwp / exam_math_no.hwp)

검증 도구는 examples/inspect_595_regression.rs 로 영구 보존 (향후 hit_test_header_footer 영역 회귀 차단 가드).

단계별 진행 (Hyper-Waterfall 정합)

Stage 산출물 본 PR commit
Stage 1 본질 진단 + tests/issue_595.rs (5 케이스) + 광범위 sweep + 정정 영역 후보 분석 24a267d
Stage 2 본질 정정 (cursor_rect.rs) + 회귀 sweep 도구 (inspect_595_regression.rs) + WASM 빌드 + 시각 판정 ★ 통과 33fc7ac
Stage 3 최종 보고서 + 회귀 위험성 점검 (관련 이슈/함수/호출처) 938631f

각 단계는 작업지시자 단계별 승인 + 시각 판정 후 진행. 단계별 보고서는 mydocs/working/task_m100_595_stage{1,2}.md + mydocs/report/task_m100_595_report.md 참조.

별도 발견 (참고만, 본 PR 영역 아님)

광범위 sweep / e2e 진단 중 발견된 본 이슈와 본질이 다른 영역. 정정 전후 동일 (회귀 0), 사용자 시각 검증 안 됨, 한컴 호환 진단 필요 → 이슈 등록 보류:

  • 그리드 모드 (zoom ≤ 0.5) 좌표 결함input-handler-mouse.tspageLeft 단일 컬럼 가정 vs 그리드 pageLefts[i] 불일치
  • hwpctl_Action_Table__v1.1.hwp 꼬리말 hit:false — landscape + marginBottom=0 양식의 PageAreas::from_page_def footer_area.height = 0

Test plan

  • cargo test --lib --release (1141 passed, 회귀 0)
  • cargo clippy --release (clean)
  • cargo build --release (clean)
  • cargo test --release --test issue_595 (5 passed)
  • WASM 빌드 (Docker, 4,531,883 bytes)
  • 작업지시자 시각 판정 ★ 통과 (1365×1018, zoom=1.0, macOS + Chrome — 정정 전 결함 재현 + 정정 후 정상 모두 확인)
  • (메인테이너) 본 환경 재검증 + e2e (rhwp-studio/e2e/issue-595.test.mjs) 시각 판정

본 PR 영역

  • src/document_core/queries/cursor_rect.rs — 본질 정정 (+20/-13 LOC)
  • tests/issue_595.rs — 회귀 차단 가드 (5 케이스, 신규)
  • examples/inspect_595.rs / examples/inspect_595_regression.rs — 진단/회귀 sweep 도구 (영구 보존)
  • rhwp-studio/e2e/issue-595.test.mjs — e2e 진단 (1365×1018 사용자 환경 모사 + zoom 변동 시나리오)
  • mydocs/plans/task_m100_595{,_impl}.md — 수행/구현 계획서
  • mydocs/working/task_m100_595_stage{1,2}.md — 단계별 보고서
  • mydocs/report/task_m100_595_report.md — 최종 보고서

closes #595

johndoekim and others added 3 commits May 7, 2026 01:48
본질 결함 위치 식별: src/renderer/layout.rs::build_header (line 928)
의 `expand_bbox_to_children` 호출이 머리말 자식 노드 (단 구분선 line
paraIdx=0 ci=2 h≈1227px) 의 bbox 까지 Header 영역으로 확장 →
hit_test_header_footer_native 가 본문 좌표를 머리말 hit 으로 잘못 인식 →
onDblClick 의 머리말 분기가 picture selection 분기보다 먼저 실행되어
수식 편집기 진입 차단.

발현: page 0 (1p) Header hit 60~145 정상 / page 1+ (2p~) 60~1355 결함
(본문 영역 80% 침범). 페이지 0 vs 1+ 차이 = 단 구분선 line 의 controlIdx
소속 차이 (page 0 ci=5 Body 자식 / page 1+ ci=2 Header 자식).

산출물:
- tests/issue_595.rs (5 케이스, 정정 전 3 fail / 2 pass)
- examples/inspect_595.rs (Header bbox sweep + 광범위 fixture sweep)
- rhwp-studio/e2e/issue-595.test.mjs (1365×1018 사용자 환경 e2e 진단)
- mydocs/plans/task_m100_595.md / task_m100_595_impl.md
- mydocs/working/task_m100_595_stage1.md

광범위 sweep (164 fixture / 1684 페이지): 영향 2 fixture / 32 페이지
(1.9%) — exam_math.hwp / exam_math_no.hwp 만 발현. 매우 특수한 양식
(머리말에 단 구분선 line 자식 포함). 정정 회귀 위험 매우 낮음.

이슈 본문 정오표: 이슈 가설 (a)/(b)/(c) 모두 TS 측 좌표 영역으로
한정되어 본질 좁히기 부족. 실제 결함은 Rust 측 build_page_tree 영역
(이슈 점검 범위 밖). 사용자 추가 단서 "hover 시 손바닥 표시는 뜨는데
클릭 반응 없음" 으로 dblclick 흐름의 다른 분기 (머리말 검사) 까지
진단 영역 확장.

Stage 2 정정 옵션 A 권장: hit_test_header_footer_native 에서
layout.header_area 로 hit 판정 (단일 함수 영역, 렌더링 동작 무영향,
회귀 위험 최소).

별도 발견: zoom ≤ 0.5 그리드 모드 좌표 결함 (input-handler-mouse.ts
의 pageLeft 단일 컬럼 가정) — 본 이슈와 별개 영역 / 별도 task 분리
검토.

refs edwardkim#595

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
본질 정정: src/document_core/queries/cursor_rect.rs::hit_test_header_footer_native
가 build_page_tree 의 Header/Footer 노드 bbox (expand_bbox_to_children 으로
자식 단 구분선 line 까지 확장됨) 대신 layout.header_area / layout.footer_area
(PageDef margin 으로 계산된 정확한 영역) 로 hit 판정.

LOC: +20 / -13 (단일 함수). build_page_tree 호출 제거 → mousedown 마다
호출되던 비싼 트리 빌드 비용 제거 (부수 효과).

검증 (모두 정정 전 → 정정 후):
- tests/issue_595.rs: 3 fail / 2 pass → 5 pass
- 본문 false-positive sweep: 32p → 0p
- 머리말 hit 정확화: +27p 부수 개선
- 꼬리말 hit: 동일 (회귀 0)
- cargo test --lib --release: 1140 passed (회귀 0)
- cargo clippy --release: clean
- WASM 빌드: 4,531,883 bytes
- 작업지시자 직접 시각 판정 ★ 통과 (정정 전 결함 / 정정 후 정상 모두 확인)

회귀 검증 도구: examples/inspect_595_regression.rs (영구 보존, 향후
hit_test_header_footer 영역 회귀 차단 가드).

별도 발견:
- 꼬리말 hit:false 16p (hwpctl_Action_Table__v1.1.hwp 1 fixture) — 정정 전후
  동일, 본 task 영역 밖
- zoom <= 0.5 그리드 모드 좌표 결함 — input-handler-mouse.ts 의 pageLeft
  단일 컬럼 가정, 본 이슈 별개 영역
모두 별도 issue/task 분리 검토.

refs edwardkim#595

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
본 task 종결 — Issue edwardkim#595 (exam_math.hwp 2페이지부터 수식 더블클릭
hitTest 오동작) 본질 정정 + 광범위 회귀 sweep + 작업지시자 시각 판정 ★
통과 + 이슈 본문 정오표 코멘트 등록 (#issuecomment-4389951401).

회귀 위험성 영역 점검 — 관련 CLOSED 이슈 (edwardkim#236 PageAreas 영역 공식 /
edwardkim#42 머리말 Picture 렌더링 / edwardkim#36 머리말 표 셀 이미지 / edwardkim#340 머리말 누출)
모두 회귀 위험 0. 본 정정이 edwardkim#236 정정의 영역을 일관 활용 (정확성
강화). 관련 함수 (hit_test_in_header_footer_native, get_active_hf_info,
find_section_for_page) 무수정. TS 측 호출처 단 2곳 (input-handler-mouse.ts
L494 onMouseDown / L784 onDblClick) 모두 정정 후 동작 정확.

보조 메모 영역 (본 task 분리) — 그리드 모드 (zoom ≤ 0.5) 좌표 결함 +
hwpctl_Action_Table 꼬리말 hit:false. 정정 전후 동일 (회귀 0) + 사용자
시각 검증 안 됨 + 한컴 호환 진단 필요 → 본 사이클 영역 밖, 등록 보류.
향후 사용자 시각 검증 또는 한컴 호환 비교로 결함 확정 시 별도 task 진입.

산출물:
- mydocs/report/task_m100_595_report.md (최종 보고서)

mydocs/orders/yyyymmdd.md 는 메인테이너 영역 (PR edwardkim#558 패턴 정합) — 본
PR 에서 제외, 메인테이너 PR 처리 후속에서 작성.

본 task 단계별 commit:
- Stage 1 (54c0af2): 본질 진단 + 재현 단위 테스트 + 광범위 sweep
- Stage 2 (0d20917): hit_test_header_footer 영역 정정 + 회귀 sweep
- Stage 3 (본 commit): 최종 보고서 + 회귀 위험성 점검

closes edwardkim#595

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant