Repository navigation
fix(table): 저장 첫 프레임 경로의 위 캡션 표 원점에 캡션을 두 번 더하지 않는다 (#7732) - #8131
Closed
planet6897 wants to merge 8 commits into
Closed
planet6897 wants to merge 8 commits into
planet6897 wants to merge 8 commits into
Conversation
planet6897
force-pushed
the
fix/source-frame-top-caption-origin
branch
from
October 23, 2026 15:53
5906b14 to
a92ed55
Compare
한컴 Print PDF 를 raster 로 읽으면 0.1 mm 안팎(0.3~0.5 px) 표 괘선도 장치 한 칸을 채운다. Native Skia 는 선언 굵기 그대로 anti-alias 해 괘선 덮임이 20~45% 에 그쳐 실루엣에서 괘선이 빠졌다(issue1937 p49 간트 표 89.28). raster 대상에서 도형 획·직선(이중선 각 획 포함)·쪽 테두리의 굵기를 현재 canvas 변환의 장치 한 칸 이상으로 그린다. 합성 굵게의 윤곽 획이 쓰던 같은 규칙을 line_replay 의 공통 helper 로 옮겨 함께 쓴다. 조판 좌표·선언 굵기·점선 간격과 벡터(PDF·SVG)·WASM 출력은 바뀌지 않는다. - issue1937(edwardkim#8115 적층) p49 89.28 → 99.997, 90% 미만 25 → 23쪽 - samples 517문서(앞 40쪽) 쪽별 raw: 상승 396 · 하락 76(최대 -1.38) · 신규 90% 미만 0 - samples/basic/calendar_year.hwp 88.25 → 98.87(fresh WASM 93.80) - 회귀: tests/cases/skia_subpixel_stroke_hairline.rs (수정 전 실패, native-skia CI 등록)
…1937 p49·sungeo p34 수정 전후 review/overlay
…8125) ci.yml 의 Native Skia job 에 추가한 파일 게이트 test 를 classifier 의 NATIVE_SKIA_RUST_FILES 와 그 단위 검사 목록에도 올린다. 빠지면 그 파일만 고치는 PR 에서 Native Skia job 이 skip 되고, test_ci_impact_workflow 계약이 Lint 를 실패시킨다.
fork PR 은 .github/workflows 와 scripts/ci-impact-classifier.cjs 를 바꾸면 신뢰 CI 정책이 "Untrusted head changed the enforcement surface" 로 막는다. 새 파일을 CI 목록에 등록하는 대신, 이미 Native Skia job 과 classifier 에 등록된 tests/cases/native_fractional_glyph_origin.rs 의 하위 모듈로 같은 검사를 옮기고 ci.yml·classifier 변경은 base 로 되돌린다. 검사 내용은 그대로다.
Native Skia 의 floor_stroke_to_device 와 같은 PDF raster 의 얇은 선 규칙을 WASM Canvas2D 에 적용한다. 현재 canvas 변환의 역으로 장치 한 칸의 local 길이를 구해 도형 획과 선(단선·다중선)의 굵기 하한으로 쓴다. 조판 좌표·선언 굵기와 점선 간격(하한 전 굵기로 정함)은 바꾸지 않는다. - calendar_year 1쪽 fresh WASM raw 실루엣 94.37 → 98.88 (Native 98.87 과 같아짐). - sungeo 94쪽 fresh WASM: 상승 77 · 하락 0 · 불변 17, 90% 미만 쪽 수 그대로(p21·22, 별개 차이). - issue1937 18~21쪽 발췌(한/글 2024 재저장) 4쪽 0.48px 칸 괘선: 86.67 → 99.49. - 회귀: rhwp-studio/e2e/issue-8125-hairline-canvas2d.test.mjs (npm e2e:issue-8125-canvas2d) — 수정 전 calendar_year 가는 가로 괘선 182곳 미달, 수정 후 0곳.
쪽 끝에서 나뉘는 쪽 나눔 표의 첫 조각이 저장 첫 프레임(stored_complete_extent·첫 조각 빈 밴드) 경로로 확정되고 앞선 배치 계획이 없으면 emit 이 원점을 새로 만든다. 그 원점에 위 캡션 높이 (caption_extra)를 넣었다. 예산(프레임 = 하단 − 원점 − 캡션), 확정(commit_fragment 의 캡션 + 조각 높이)과 그리기(table_partial 표 = 원점 + 캡션 + 간격)는 모두 원점을 위 캡션을 포함한 개체 상자의 위끝으로 쓰므로 캡션이 두 번 들어가 표가 캡션 높이만큼 내려 그려졌다. - 표본 top_caption_rowbreak_p20.hwp(issue1937 보고서 50쪽의 문단 126–145 를 한/글 2024 로 다시 저장, 5쪽): 3쪽 끝 표 pi=18 위 괘선이 한/글 2024 Print 정본 834.1px 에 놓인다(수정 전 859.6). Visual Sweep 판정값(raw 실루엣) 3쪽 Native 73.84 → 99.90, fresh WASM 73.87 → 99.87, 나머지 쪽 불변, 5/5쪽 99 이상(edwardkim#8125 가는 괘선 장치 한 칸 위에서). - issue1937 원본 20쪽: Native 70.93 → 94.03, fresh WASM 71.30 → 94.92. - 회귀: issue_7732_source_frame_top_caption_origin (수정 전 실패: 표가 캡션 높이만큼 내려 첫 조각이 본문 아래를 넘는다).
…k_p20 3쪽 수정 전후 Native/fresh WASM review·overlay
planet6897
force-pushed
the
fix/source-frame-top-caption-origin
branch
from
October 24, 2026 00:21
a92ed55 to
6921684
Compare
Canvas2D 에 장치 한 칸 획 하한을 넣자 CI CanvasKit readiness 의 Canvas2D↔CanvasKit 시각 일치(table-core 0.0495 > 0.047, table-border-style 0.0075 > 0.006)가 깨졌다. CanvasKit 도 0.48px 표 괘선을 선언 굵기대로 anti-alias 해 옅게 그리던 같은 결함이다. - renderPage 의 배율(zoom × dpr)에서 장치 한 칸의 page 길이(1/scale)를 잡아, Canvas2D 가 하한을 둔 같은 자리(도형 외곽선·그림자 외곽선·직선/이중선 각 획)의 굵기 하한으로 쓴다. - 획 굵기가 배율을 따르므로 정적 picture 캐시 키에 배율을 넣는다. - 글자 장식·쪽 테두리·글리프 외곽 획은 Canvas2D 와 같이 바꾸지 않는다.
Contributor
Author
devel 에 이미 반영되어 닫습니다#8191 이 devel 에 들어간 뒤 이 PR 이 충돌 상태가 되어 다시 확인했습니다. 이 PR 의 코드 없이 최신
devel 의 저장 첫 프레임 경로가 위 캡션 표 원점에 캡션을 두 번 더하지 않게 되어, 이 PR 의
|
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.
요약
쪽 끝에서 나뉘는 쪽 나눔 표의 첫 조각이 저장 첫 프레임 경로(
stored_complete_extent·첫 조각 빈 밴드)로 확정되고 앞선 배치 계획이 없을 때, 위 캡션이 붙은 표가 캡션 높이(약 25px)만큼 내려 그려지던 문제를 고친다. 첫 조각 아래 괘선이 본문 아래를 넘던 넘침도 함께 사라진다.Refs #7732 (issue1937 20쪽의 원인 중 하나 — 이슈 전체를 닫지 않는다)
원인
src/renderer/typeset/table/continuation/fragment/emit.rs에서 이 경로가 원점을 새로 만들 때 위 캡션 높이caption_extra를 원점에 넣었다. 이후 소비 지점은 모두 원점을 위 캡션을 포함한 개체 상자의 위끝으로 보고 캡션을 한 번 더 더한다.budget.rscommit_fragmenttable_partial.rs그래서 캡션이 두 번 들어갔다. 이 이중 계상은
fd1a53fdc에서 들어왔고, 그 커밋의 사례에는 위 캡션이 없었다.변경
한 줄이다. 이 경로의 원점에서 캡션을 빼
current_height + host_before_overhead + vert_offset_overhead로 만든다. 다른 원점 생산자와 같은 정의다.caption_extra는 첫 조각의 위 캡션에서만 0이 아니다.검증 (head
692168436)이후 head
e89e55644는 #8133 의 CanvasKit 커밋(rhwp-studio/src/view/canvaskit-renderer.ts)만 더했다. Visual Sweep 의 Native·fresh WASM(Canvas2D) 출력과 회귀 검사에는 닿지 않는 경로라 아래 결과·이미지(692168436고정)를 그대로 쓴다.표본 교체
이전 표본
top_caption_rowbreak_p31.hwp는 그 사이 devel 의 다른 변경으로 이 경로를 타지 않게 되어 수정 전에도 통과했다(이전 본문의 ⚠ 항목). 그래서 결함이 실제로 남아 있는 issue1937 20쪽에서 새 표본을 만들었다.samples/issue1937/top_caption_rowbreak_p20.hwp—samples/issue1937_rowbreak_footnote_overpagination.hwp(50쪽)의 문단 126–145(18–21쪽)만 남겨 한/글 2024 로 다시 저장한 5쪽 문서. 저장 줄과 표 첫 프레임은 한/글이 다시 썼다.pdf/issue1937/top_caption_rowbreak_p20-2024.pdf— 같은 저장본의 한/글 2024 Print 출력(5쪽).전체 쪽 Visual Sweep
판정값 = raw 실루엣(TSV 4열),
--compat 2024. 수정 전 = 같은 branch 에서emit.rs만 되돌린 빌드.대표 이미지 (3쪽)
Native 수정 전 review / overlay
Native 수정 후 review / overlay
fresh WASM 수정 전 / 수정 후 review
회귀 테스트
tests/cases/issue_7732_source_frame_top_caption_origin.rs—stored_first_frame_top_caption_table_is_drawn_once_below_its_captionemit.rs만 되돌린 빌드): 표가 캡션 높이만큼 내려 첫 조각이 본문 아래를 넘는 assertion 에서 실패. 수정 후 통과.게이트 (head 코드)
--check통과.--features native-skia) 11,531건 중 11,528 통과. 실패 3건issue_7966_pdf_close_stroke::*는 이 host 의core.autocrlf=true가 fixturepdf/issue7966/close-stroke-controls.pdf를 CRLF 로 꺼내 바이트가 바뀐 탓이다(ImportResourceLimit). 저장소 blob 그대로의 바이트로 되돌리면 3건 모두 통과한다. 이 변경과 무관하다.원문 문서(보조 증거)
발췌 전 원문
samples/issue1937_rowbreak_footnote_overpagination.hwp20쪽: Native 70.93 → 94.03, fresh WASM 71.30 → 94.92. 원문에는 이 수정과 무관하게 수정 전후 값이 같은 90% 미만 쪽(21·33–43쪽, Native 는 49쪽 포함)이 남아 있어 검증 대상·fixture 로 쓰지 않고 보조 증거로만 적는다. 이 PR 은 #7732 전체를 닫지 않는다.미검증
emit.rs한 줄)에서 잰 값이며 새 base 에서 다시 재지 않았다.🤖 Generated with Claude Code