증상
samples/21_언어_기출_편집가능본.hwp 페이지 12에서, 21번 본문 paragraph(pi=238) 안에 인라인으로 들어있는 작은 박스("배너지와 뒤플로")가 22번 문제 위쪽 빈 영역(y≈742px)에 잘못 그려진다. 박스 안 텍스트도 함께 그 위치로 쏠려, "왼쪽 박스 아래 '배너지와 뒤플로'"가 출력되는 것처럼 보인다.
부수 영향: 페이지 12 단 0 사용량 1012px vs 한컴 기준 1219px(diff=-206.8px) — 23번 paragraph가 단 끝(y=1166)으로 밀려 답안 일부가 잘림.
근본 원인
pi=238은 길이 871자, 26줄짜리 본문 paragraph로 페이지 11~12에 걸쳐 분할(PartialParagraph)된다.
- 인라인 박스("배너지와 뒤플로",
treat_as_char=true)는 char index 0(=line 0)에 있음.
- 페이지 11에서 paragraph_layout이 line 0을 처리하면서
tree.set_inline_shape_position(0, 238, 0, x, y)를 등록.
- 그러나
PageRenderTree.inline_shape_positions는 페이지마다 새로 생성됨(render_tree.rs:730) — 페이지 11에서 등록한 좌표는 페이지 12 tree에는 없음.
- paginator가
PageItem::Shape { pi=238 }을 페이지 12에도 등록(원인 위치 추적 필요 — Shape의 vpos가 reset된 페이지 12 좌표계 매핑 결과로 추정).
- 페이지 12
layout_column_shapes_pass가 박스를 그리려고 get_inline_shape_position() 호출 → None → compute_object_position fallback (shape_layout.rs:218).
- Shape 위치가 "가로/세로=문단 오프셋=0,0"이라 paragraph 238의 페이지 12 시작 y(742.45)에 박스를 다시 그림.
디버그 검증
페이지 11:
[inline_shape] para=238 x=616.11 y=1313.28 ← 등록됨
(layout_shape para=238 호출 없음 — 페이지 11 PageItem::Shape에 미등록)
페이지 12:
[layout_shape] para=238 para_y=742.45 inline_pos=None ← 잘못된 fallback
수정 방향 후보
- A: paginator가 인라인 박스의
PageItem::Shape를 박스가 속한 line이 그려지는 페이지에 등록하도록 수정.
- D: 페이지 N에서 inline_pos=None이면서 paragraph가 이전 페이지에서 시작된 PartialParagraph인 경우 박스 렌더 스킵.
- C:
treat_as_char Shape는 paragraph_layout에서 직접 렌더하고 별도 PageItem::Shape 등록 자체를 제거.
D를 임시 차단으로 적용 후 A 또는 C를 본질 수정으로 추진.
영향 파일
src/renderer/layout.rs:3149 (para_y = para_start_y.get(...).unwrap_or(col_area.y))
src/renderer/layout/shape_layout.rs:218 (inline_pos None fallback)
src/renderer/render_tree.rs:730 (페이지별 맵)
- paginator(인라인 Shape의 PageItem::Shape 등록 위치 — 추적 필요)
증상
samples/21_언어_기출_편집가능본.hwp페이지 12에서, 21번 본문 paragraph(pi=238) 안에 인라인으로 들어있는 작은 박스("배너지와 뒤플로")가 22번 문제 위쪽 빈 영역(y≈742px)에 잘못 그려진다. 박스 안 텍스트도 함께 그 위치로 쏠려, "왼쪽 박스 아래 '배너지와 뒤플로'"가 출력되는 것처럼 보인다.부수 영향: 페이지 12 단 0 사용량 1012px vs 한컴 기준 1219px(
diff=-206.8px) — 23번 paragraph가 단 끝(y=1166)으로 밀려 답안 일부가 잘림.근본 원인
pi=238은 길이 871자, 26줄짜리 본문 paragraph로 페이지 11~12에 걸쳐 분할(PartialParagraph)된다.treat_as_char=true)는 char index 0(=line 0)에 있음.tree.set_inline_shape_position(0, 238, 0, x, y)를 등록.PageRenderTree.inline_shape_positions는 페이지마다 새로 생성됨(render_tree.rs:730) — 페이지 11에서 등록한 좌표는 페이지 12 tree에는 없음.PageItem::Shape { pi=238 }을 페이지 12에도 등록(원인 위치 추적 필요 — Shape의 vpos가 reset된 페이지 12 좌표계 매핑 결과로 추정).layout_column_shapes_pass가 박스를 그리려고get_inline_shape_position()호출 →None→compute_object_positionfallback (shape_layout.rs:218).디버그 검증
수정 방향 후보
PageItem::Shape를 박스가 속한 line이 그려지는 페이지에 등록하도록 수정.treat_as_charShape는 paragraph_layout에서 직접 렌더하고 별도 PageItem::Shape 등록 자체를 제거.D를 임시 차단으로 적용 후 A 또는 C를 본질 수정으로 추진.
영향 파일
src/renderer/layout.rs:3149(para_y = para_start_y.get(...).unwrap_or(col_area.y))src/renderer/layout/shape_layout.rs:218(inline_pos None fallback)src/renderer/render_tree.rs:730(페이지별 맵)