Skip to content

수정: #7445 기존 완료 문서의 표·줄·글꼴·출력 경계 보존 - #8191

Merged
jangster77 merged 402 commits into
develfrom
fix/7445-completed-20261024
Oct 24, 2026
Merged

jangster77 merged 402 commits into
develfrom
fix/7445-completed-20261024

Conversation

@jangster77

@jangster77 jangster77 commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

범위와 현재 상태

Refs #7445

기존 완료 문서의 표 분할·저장 글줄·각주·글꼴·그림/출력 경계를 공통 로직에서 보정했습니다. #7445 전체 해결 PR은 아닙니다. 새 HWP 보정 대상을 늘리지 않고 동결한 제출 범위는 Native/fresh WASM 각각 49조건·1,772쪽입니다.

  • 측정과 실제 paint가 같은 내용 컷·저장 원점·물리 점유를 소비하도록 보정했습니다. 저장 줄 출처·중첩 표 점유·다단 독립 축과 전역 축 부재를 구분했습니다.
  • 쪽/줄/개체의 소속·순서·누락/중복·포함/비겹침을 정식 회귀로 보호했습니다. 원본115쪽과 분할 저장197쪽 검사는 유지했습니다.
  • sample11의 자간/탭·테두리·그림 연결, 원본 sample16 수식/dot 등 기존 보정 범위입니다. 별도 PR의 sample16 HWP5 2024 HWP/HWPX 및 바이트가 같은2010별칭은 제외하며, 서로 다른2022저장본과 HWP3원본은 유지했습니다.
  • ubuntu-ted2의 제거된 독립 그림 case는 기존 표 관계 검사에15assertion을 통합했습니다. 과거 PR 품질 래칫을 Visual Sweep에 자동 강제 연결하지 않습니다.
  • 새 Rust 회귀 함수 228개(integration224·unit4) 모두 현재 전체 nextest에서 실제 PASS입니다. 기존 교체/rename12·이동3은 제외했고, 순증가218개 및 Python/JS 계약과 구분합니다.

현재 검증 head와 출처

  • 고정 devel base: 3536e72819e165dbe959ee42cfd4e4cf8db33ce7
  • 검증 code head: 8ba0980feb5995dffbfdb84601e53085b49f810d
  • review·오늘할일·대표PNG만 추가한 trailing head: 8310b925b699277f355deeae58456db898117eef
  • 정식 셀프 리뷰 · 현재 검증/잔여 · 오늘할일

401개 패치의 range-diff와 자동 병합 tree 동일성을 확인한 뒤 리베이스를 반영했습니다. #8180/#8182는 exact3536 archive의 base와 현재 후보에서 실제 Studio 셀 편집6진입·잘못된 대상9건 거부, 직접WASM5계약 묶음·Studio getter4입력 및 Native7건으로 기능 보존을 확인했습니다. #8190 코덱 matrix는 source77의114 Native관측/68시각 출력과 관련 코드 동일성을 확인하여 재사용했으며8ba 재실행으로 쓰지 않습니다.

로컬 검증과 코드 CI 완료

검증 실제 완료 결과
release-test/native-skia 전체 nextest 11,766 PASS / 0 FAIL / 45 skip (검사1,035.984초)
필수22단계 prepare/manifest/unit tiers/fmt, Native·WASM·workspace·Skia all-target Clippy, workspace/release build·Skia lib·PDF·placeholder·doc·Studio unit/TS 모두 exit0
Native Skia root/다른 libs 3,859 PASS·12ignore / 182 PASS
직접 PDF / placeholder 14 PASS / 2 PASS
release root/다른 libs / doc 3,802 PASS·12ignore / 182 PASS / 8 PASS·3ignore
Studio/editor/shared PDF 2,421 PASS / 0 FAIL / 2 skip
현재 frontend 패키징6단계 Studio·Chrome·Firefox build, VSCode compile, binding/font11·실제 browser 글꼴10계약 PASS
실제 지원 소비 Native30·Canvas2D30·지원CanvasKit12 = 72관측, raw90% 미달0

검사 묶음에는 중복이 있어 고유 수로 합산하지 않습니다. Mac fresh WASM은 locked wrapper --target web --out-dir pkg --no-opt 로컬 대체 빌드이며 Docker 최적화 통과가 아닙니다.

정확한 code head8ba의 Full CI, CodeQL, Render Diff, Adapter, Proptest, Gym 계약이 모두 성공했습니다. Full Gym benchmark는 정책상 skip입니다. trailing head의 실제 CI/fast-pass는 별도로 확인하며 code head 결과로 대신하지 않습니다.

전쪽 Visual Sweep

출력 조건 독립 전체 쪽수 최저 raw 90% 미달 후보 쪽수 차이 devel 대비2%p 이상 하락
Native Skia 49 1,772 93.06876% 0 0 0
fresh WASM Canvas 49 1,772 92.99291% 0 0 0
  • PDFium152.0.7947.0/pypdfium2 5.12.1 smooth RGB v1·96DPI·raw 2px·90%와 devel 하락 2%p 기준이며 이번 검증에서 문턱·마스크·예외를 추가하지 않았습니다.
  • 전쪽 raster의 실제 producer는 source77/base e7입니다. 새 API는 읽기 전용 getter이며 렌더/파서/글꼴/캡처 입력 동일성과196조건7,078 actual/reference쌍의hash를 확인한 뒤 196 TSV를 전쪽 재산출했습니다. 원 producer/build/font근거를 유지하며 8ba 전쪽 재캡처로 쓰지 않습니다.
  • 새8ba 실제72관측은 각각 새로 생산한 뒤 기존 판독 PNG쌍과 바이트가 같은 것을 확인했습니다. Native/Canvas2D/지원CK 최저93.13188%/93.13770%/99.87307%입니다. 준비 미달Canvas2D fallback10건은 CK통과가 아닙니다.
  • 실제 초기화52관측에서 root/pkg·public·frozen·응답 JS/WASM을 대조했습니다. 검증 뒤 publicJS의 자동JSDoc4줄만 복원했고, 주석 제외 바이트 동일성/원본을 보존했습니다. 정리 뒤 JS전체hash까지 같다고 하지 않습니다.
  • base의5조건×2backend 쪽수 차이는 그대로 공개했고 같은 수치 쪽을 같은 내용이라고 간주하지 않았습니다. 후보의 독립 쪽수·내용 관계 회귀와 확대 판독을 함께 확인했습니다.

입력·PDF 경로/hash와 보존 TSV 원문은 과거50조건의 이력입니다. 그중 sample16-hwpx를 제외한49조건만 현재 범위이며, 아래1개를 제외한195 TSV는 현재 재산출본과 바이트가 같습니다. 추가 Native/WASM10쌍 판독도 별도 보존했습니다.

현재 base/WASM/hwp3-alias 전16쪽 TSV 원문

과거 보존 사본과3·11쪽 base값이 달라 현재 재산출 원문을 아래에 제출합니다. 후보 TSV를 바꾸거나 과거 사본의 producer를 현재 base로 재표기하지 않았습니다.

page	tolerant_content_match_percent	below_90	silhouette_raw_match_percent	silhouette_boundary_reconciled_pixels
1	98.53984	0	98.53984	0
2	99.24403	0	99.24403	0
3	99.15465	0	99.15465	0
4	98.31808	0	98.31808	0
5	97.27361	0	97.27361	0
6	99.43209	0	99.43209	0
7	98.43261	0	98.43261	0
8	99.01800	0	99.01800	0
9	98.99386	0	98.99386	0
10	99.39507	0	99.39507	0
11	99.10484	0	99.10484	0
12	99.33919	0	99.33919	0
13	99.32731	0	99.32731	0
14	99.25026	0	99.25026	0
15	99.09871	0	99.09871	0
16	99.35341	0	99.35341	0

대표 Native/fresh WASM review와 standalone overlay

최저 rowbreak18의16쪽입니다. 그림의 실제 raster producer는 source77이며 현재 렌더 경로 동일성/byte감사로 재사용 자격을 확인했습니다. 현재 trailing SHA에 보존한 asset을 표시합니다.

Native

Native rowbreak18 p016 review

Native rowbreak18 p016 overlay

fresh WASM

fresh WASM rowbreak18 p016 review

fresh WASM rowbreak18 p016 overlay

남은 차이와 후속 처리

얇은 괘선·글리프 획·미세 간격, sample11 UI Print에 있는 면과 편집기 화면의 차이, 원본 sample16 수식/dot의 미세 경계를 RGB·원 글꼴·절대좌표 완전 동일로 확대하지 않습니다. KTX제목 획/그림자와 giant의 보존된 API검사4건 복구는 미해결이므로 #7780/#7813을 닫지 않습니다.

trailing 검사가 성공하고 최종 head/MERGEABLE/CLEAN을 확인하면 승인된 머지를 진행합니다. 그 뒤 실제 해결 #7716·#7717·#7718·#7719·#7720·#7724·#7725·#7726·#7758·#7809만 근거를 남겨 종료하고 #7445 해당 행에 취소선을 반영합니다. 대표7445는 열어 두며 기존#8060의 좁은 높이 규칙과 #8100/#8095 전쪽 잔여를 구분합니다. 원본/PDF·글꼴·사용자초안/stash·공유target/output·사용자7729서버는 보존합니다.

중복 배치 필드와 누락된 호출 인자를 정리하고 원본 마지막 줄 컷의 인증 함수를 보존한다. 수용한 물리 행 계획과 저장 본문 프레임 근거를 공통 예약·배치에 전달하며 시작 컷 재스캔 뒤에도 바닥 예약을 적용한다. 빌드 잡 8개로 전체 테스트 대상 컴파일과 집중 회귀 50건 통과를 확인했다.
최신 devel로 리베이스한 뒤 Native와 fresh WASM 양쪽 98% 이상인 두 페이지에 좌표 검사 5개를 보완했습니다. 기존 소유·탭·정렬 관계를 유지하며 오래된 글꼴 이름 해독 실패의 provenance도 보정했습니다. #4138과 전체 PR 검증의 미완료 범위는 단계 기록에 명시했습니다.
쪽 배경과 사각형·타원·경로가 첫 색만 사용하던 소비 오류를 수정한다. 공통 축·반경과 띠 경계를 shader에 전달한다. 합성 PNG와 정상 출력 대조군 48건 통과, 선택 페이지 표지 97.75573% 및 KTX 95.75367%를 확인했다. 문서 전쪽 및 전체 PR 검증은 진행 중이다.
내장 래스터를 포함한 정상 변환 SVG가 조각용 상한에 막혀 회색 그림이 되던 소비 오류를 수정한다. 완결 그림은 기존 EPS 출력 범위 16MiB를 수용하고 조각 4MiB 및 픽셀 상한은 유지한다. 실제 PNG 검사 수정 전 FAIL, 관련 52건 PASS 및 sample16 35쪽 94.61992%를 확인했다. 전체 PR 검증과 잔여 차이는 진행 중이다.
FontFace에 JSON 인용부호를 포함해 다른 family로 등록하던 오류를 수정하고 등록 이름을 확인한다. 투명한 물리 캔버스 끝점은 흰 인쇄 용지에 합성해 실제 잉크와 구분한다. 원본 글꼴·비교 문턱·쪽수는 유지했다. Python 110건, Node 경계 4건 및 실제 Canvas 글꼴·배경 대조를 확인했으며 수정된 생산기의 전쪽 자격 검증은 진행 중이다.
@jangster77

Copy link
Copy Markdown
Collaborator Author

병합·검증·해결 이슈 후속 기록

최종 head 8310b925b699277f355deeae58456db898117eef의 적용 검사를 확인하고 squash 병합했습니다. merge는 60972534680a0c5e51e54ec189b92e252e81a867이며 devel 반영과 로컬 devel의 fast-forward를 확인했습니다. 셀프 리뷰·오늘할일·대표 증적은 이 PR에 포함됐습니다.

  • 최종 Full CI, CodeQL, Render Diff가 성공했습니다. 전체 check는 성공32·정책상 skip8·실패0입니다. Adapter/Proptest는 실제 trusted-mydocs-tail:8ba0980f... 판정을 확인해 이전 녹색 code CI를 재사용했습니다.
  • CI 파일 변경은 자동 수집되지 않던 기존 글꼴 trace 검사2개의 호출 연결과 ShellCheck SC2016 인용 보정입니다. 새 job·권한·trigger나 fast-pass 판정 규칙을 추가하지 않았습니다. main CI는 CI 실행 파일 변경과 PR 파일 목록3,000개 판정 경계 때문에 Full을 실행했으며 검증을 우회하지 않았습니다.
  • 현재 로컬 전체 nextest 11,766 PASS / 0 FAIL / 45 skip, 새 Rust 회귀228개 모두 실제 PASS입니다. 필수22게이트·frontend6단계, 새8ba 실제 지원 소비72관측·초기화52응답도 완료했습니다. Mac WASM은 locked wrapper --no-opt 로컬 대체 빌드입니다.
  • CI 대기 중 추가된 devel 7f1787708e의 #8178은 Chrome E2E 보고서 도구/기록입니다. 새 base의 feature 코드와 자동 병합 tree의 바이트가 같고 원 PR과 경로가 겹치지 않음을 확인했습니다. 병합 결과 archive에서 실제 브라우저 보안·레이아웃을 포함한35계약도 통과했습니다. 녹색 source head를 반복 리베이스하지 않았습니다.
  • Native/fresh WASM 각각 49조건·1,772쪽, 최저 93.06876%/92.99291%,90% 미달·후보 쪽수 차이·devel 대비2%p 이상 하락0입니다. source77/base e7의 기존 PNG 생산자/build/font와7,078쌍의 바이트를 감사하여196 TSV를 다시 산출했습니다. 이를8ba의 전쪽 재캡처로 쓰지 않습니다. 195개 제출 사본은 같고1개 최신 base/WASM 원문은 PR 본문에 구분해 제출했습니다.
  • duration 갱신은 실제로 ready=true / successful-pr-worker-measurements였습니다. source CI40067027187의 b/c/d attempt1·artifact [12550551692, 12550756162, 12550626410]를 확인하여46개 target을 metrics commit 14253f0ea4a5a148243995a0a697e9b421b573da로 게시했습니다. 병합 후 CI·CodeQL·Adapter·Proptest 검증을 새로 시작하지 않았습니다.

해결된 하위 이슈와 잔여

실제 전쪽/회귀 근거를 각 이슈에 남겨 #7716·#7717·#7718·#7719·#7720·#7724·#7725·#7726·#7758·#7809를 종료하고 #7445 본문의 해당 행을 취소선 처리했습니다. 연결은 보존했으며 현재96개 중 OPEN85·CLOSED11입니다. 기존 #8060은 좁은 높이 규칙의 upstream 해결로 구분했습니다.

#7780의 KTX 제목 획/그림자, #7813의 giant API 회귀4건 복구와 다른 미해결 범위는 열린 상태로 유지합니다. 대표7445 전체 해결을 주장하지 않습니다. 제외한 sample16 HWP5 2024 HWP/HWPX·2010별칭은 별도 PR 범위입니다.

Visual Sweep와 대표 판독

Visual Sweep 비교 방법을 따랐습니다. PDFium152.0.7947.0/pypdfium2 5.12.1 smooth RGB v1·96DPI·raw2px90% 기준입니다. 아래 rowbreak18 16쪽의 Native/fresh WASM 수치는93.06876%/92.99291%입니다. 원 raster producer77을 보존했고 내용 소속/앞뒤 문단과 표 경계를 직접 판독한 근거를 재사용했습니다. raw는 사람의 판정 정확도가 아닌 내용 실루엣 자동 일치율 보조값이며, 얇은 선·획·미세 위치/안티앨리어싱 잔여와 RGB 완전 동일성을 구분합니다.

Native rowbreak18 p016 review

Native rowbreak18 p016 overlay

fresh WASM rowbreak18 p016 review

fresh WASM rowbreak18 p016 overlay

사용자 초안2개는 보존 stash에서 원래 SHA로 복원했고 PR에 섞지 않았습니다. 로컬 작업장/브랜치는 이 초안과 로컬 전용 PDF 보존을 위해 유지합니다. 공유 target·output·원본/PDF·설치 글꼴·backup/stash도 보존합니다. 이번 PR의 원격 임시 head 브랜치는 최종 SHA·다른 작업 사용 여부를 확인한 뒤 정리합니다.

@jangster77
jangster77 deleted the fix/7445-completed-20261024 branch October 24, 2026 06:17
planet6897 added a commit to planet6897/rhwp that referenced this pull request Oct 24, 2026
편집으로 넣은 글자처럼 취급 글상자·사각형이 줄 위(본문 위 여백)로 넘쳐 그려지고 줄의 글자는 줄
맨 위에 남았다. 한/글 2024 Print 는 줄을 도형 상자 높이만큼 키우고 앞뒤 글자를 그 줄의
기준선(도형 아래 변 쪽)에 놓는다. 원인은 네 겹이다.

1. `create_shape_control_native` 가 글자처럼 취급 도형을 넣고 host 문단의 줄을 다시 나누지
   않았다. 글자 입력과 같은 순서로 host 줄을 재조판하고 뒤 문단 세로 위치를 잇는다.
2. 본문 «도형 + 글자» 줄이 줄 높이·기준선을 글자 크기로 접었다. 접힘의 근거(hwp3-sample16
   pi=71 등)는 모두 글자 없는 도형 전용 줄이라 `max_fs <= 0` 인 줄로 좁힌다.
3. 줄 나눔이 도형 상자에서 바깥 여백을 뺐다. 한/글 저장 줄은 바깥 여백 있는 글자처럼 사각형
   78줄(samples HWPX) 모두 `vertsize = 높이 + 위 + 아래 여백` 이고, 배치도 같은 상자로
   기준선 자리를 센다. `tac_shape_box_hu` 가 크기에 바깥 여백을 더한다.
4. `flow_height_hu` 가 HWPX `curSz=0` 을 파서가 `orgSz` 로 채운 값(renderingInfo 배율 전)
   을 실제 높이로 썼다. `current_*_was_zero` 면 저장 프레임만 쓴다(HWP5-nopassword hwpx 의
   `sz` 1284·`orgSz` 6768 URL 글상자 줄). 2의 접힘이 이 과대 높이를 가리고 있었다.

- 회귀: `issue_8167_tac_shape_insert_line` — 편집 API 로 만든 문서에서 host 줄 높이 ≥ 도형
  높이, 도형이 본문 위·host 줄 상자 안, 글자 기준선이 도형 아래쪽 절반, 다음 문단이 도형 아래
  (글상자·사각형). 수정 전 2건 실패, 대조군(글자만) 전후 통과.
- 표본: `samples/issue8167/` 편집 결과 HWPX 와 한/글 2024(13.0.0.564) Print
  `pdf/issue8167/*-2024.pdf`. 저장본을 여는 경로는 devel 9418ed0 에서 이미 100.00 이고
  (edwardkim#8191) 이 수정 뒤에도 100.00 이다. 남은 결함은 편집 경로(1)와 materialize 높이(4)다.
- `HWP5-nopassword-123456.hwpx` 전 24쪽 Visual Sweep raw: 최저 38.22(18쪽, 90% 미만 2쪽)
  → 97.06(90% 미만 0쪽), fresh WASM 37.19 → 97.30. samples 1,317건 A/B 에서 바뀐 문서는
  이 문서와 `hwp3-sample16-hwp5.hwpx`(8·41쪽, 점수 동일) 둘이다.
planet6897 added a commit to planet6897/rhwp that referenced this pull request Oct 24, 2026
RowBreak 표에서 앞 행의 병합 칸 안쪽에 있는 행이 쪽 끝에 걸릴 때, 그 행의 글줄과
안 여백이 남은 높이에 다 들어가면 한/글은 그 행을 이 쪽에 남은 높이로 끝내고
다음 쪽은 다음 행에서 선언 높이로 시작한다. 종전에는 남는 빈 띠가 25px 이상일
때만 그렇게 했고(그 미만이면 행을 통째로 넘김), 내용 소진 밴드 컷은 선언 높이의
나머지를 다음 쪽 첫머리로 이월했다. 한/글 2020 합성(줄간격·안 여백·글자 크기를
바꾼 네 계열)에서 문턱은 늘 «내용 + 안 여백 ≤ 남은 높이» 였고 픽셀 미만 허용치는
없다(table_scattered_header_rowbreak 2쪽: 0.04px 넘치는 행은 넘김). 병합 칸이
그 행에서 시작하거나 끝나면 남은 내용을 같은 행의 컷으로 이어야 해 종전 규칙을
유지한다.

위 캡션 흐름 표의 저장 프레임 원점은 devel edwardkim#8191 이 같은 규칙으로 이미 고쳤다.
이 커밋은 그 코드를 넣지 않고, 회귀 검사 captioned_float_table_stored_frame 과
입력·PDF 만 남긴다(devel 에서도 통과, Native/WASM 97.70/97.68).

1342000-202300055: p37 52.85→98.47, p38 53.48→98.90, p40 65.37→99.27,
p41 60.20→99.66 (Native raw). 10k: 1690000-201300011 295→294
(한/글 쪽수와 일치). — rebase 전 head 측정값.

[rebase 재유도 2026-10-23] devel def947c 의 SOURCE_BAND_CLOSE·BAND_CLOSE·RSPAN_CLOSE 판정은 그대로 두고,
그 밴드 컷이 받지 않은 병합 칸 안쪽 행에만 «내용 + 안 여백 ≤ 남은 높이» 종료 갈래
(COVERED_ROW_CLOSE)를 더한다. 글줄을 다 소비한 행(fully_consumed)만 대상이다.
종전 PR 의 저장 사다리 RSPAN_BAND 갈래 교체는 devel 의 SOURCE_BAND_CLOSE 가 같은 사례를
이미 닫으므로 넣지 않는다.
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