Skip to content

feat(form_fit): measure KS X 1001 symbols and common blocks at each face's width - #287

Open
airmang wants to merge 13 commits into
mainfrom
feat/formfit-glyph-table
Open

airmang wants to merge 13 commits into
mainfrom
feat/formfit-glyph-table

Conversation

@airmang

@airmang airmang commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

바뀐 점

  • FormFit이 글꼴 12종(바탕·바탕체·돋움·돋움체·굴림·굴림체·궁서·궁서체·한컴 고딕·함초롬바탕·함초롬돋움·맑은 고딕)에서 다음 글자를 글꼴의 설계 폭으로 잰다.
    • KS X 1001 특수 기호, 전각 문자
    • 라틴-1, 라틴 확장-A, 일반 문장 부호, 통화 기호, 수학 연산자, 도형, 기타 기호, 딩뱃, 반각/전각 형태 블록
  • 전에는 흔한 문장 부호와 기호 몇십 자 말고는 글자 종류의 평균 폭을 썼다.
  • 글꼴 넷을 더한다.
    • HY헤드라인M·휴먼명조: 위 글자와 _GLYPHS의 글자, 한글 음절, 공백을 글꼴의 설계 폭으로 잰다. 글꼴에 없는 글자는 함초롬바탕의 폭을 쓴다.
    • 기호 글꼴 Wingdings·Symbol: 문서가 글자를 두는 사용자 영역(U+F020–F0FF)의 설계 폭으로 잰다. 표에만 있는 글꼴(한글 음절·공백 줄이 없음)은 _design_units가 폭 표에서 읽는다.
  • 폭 표는 새 모듈 hwpx/form_fit/_glyph_table.py에 있다. 글꼴 파일의 hmtx·cmap에서 읽은 값이다.
  • 한글 음절·자모는 전처럼 한글 폭을 쓴다. 한자·가나는 표에 넣지 않는다(그 글자의 글꼴 종류는 FormFit이 보지 않는다).
  • 글꼴에 없는 글자는 한/글이 대신 그리는 글꼴의 폭을 쓴다. 대신 쓴 글꼴의 설계 폭은 원래 글꼴의 단위로 옮겨 반올림한다.
    • 바탕·궁서와 -체 글꼴, HY헤드라인M·휴먼명조는 함초롬바탕을 쓴다.
    • 굴림·돋움·맑은 고딕·한컴 고딕은 함초롬돋움을 쓴다.
    • 함초롬 글꼴은 Segoe UI Symbol을 쓴다.
  • 기존 표(_GLYPHS)에서 0이던 글자, 곧 글꼴에 없던 글자도 이제 이 규칙을 따른다. 글꼴에 있어도 한/글이 대신 그리는 글꼴로 놓는 글자(HY헤드라인M의 `)는 0으로 둔다.
  • 한/글이 규칙과 다르게 놓는 몇 글자는 그 폭을 표에 적었다(함초롬돋움의 그리스·키릴 문자, 한컴 고딕·HY헤드라인M의 я, HY헤드라인M의 ✀ 등).
  • 이런 글자가 든 칸은 채우기 결과(글자 크기, 줄 수)가 달라질 수 있다.
  • docs/architecture/module-ownership.json에 새 모듈을 올린다.

테스트

  • tests/test_form_fit_hancom_rules.py
    • 기호 다섯 글자의 폭이 한/글이 놓는 폭과 같다: 설계 폭 그대로인 글자, 맑은 고딕, 함초롬돋움의 그리스 문자, 한컴 고딕 я, 글꼴에 없어 대신 그리는 글자.
    • 실제 너비를 쓰는 Wingdings 글머리표(U+F09F) 아래 25줄이 한/글이 나눈 곳에서 나뉜다. 글머리표는 10 pt에서 456을 차지한다(한/글 저장본).
    • HY헤드라인M 22칸(글자 + 한글 다섯 자, 줄 수가 바뀌는 두 폭, 30 pt·10 pt)의 줄 수가 한/글과 같다(한/글 저장본).
    • 휴먼명조의 설계 폭 몇 개를 고정한다.
    • 휴먼명조 칸으로 "표에 없는 글꼴"을 재던 테스트는 휴먼명조 폭과 이름 없는 글꼴 두 가지로 잰다. 한/글의 줄 수는 둘 다 맞는다.
    • 대체 글꼴이 모두 표에 있다.
    • 기호 다섯 글자, Wingdings, HY헤드라인M, 휴먼명조 테스트는 고치기 전 코드에서 실패한다.
  • tests/test_product_boundary.py: 분류된 파일 수를 179로 바꾼다.

🤖 Generated with Claude Code

…ace's width

FormFit took the design advance of a few dozen punctuation marks and
symbols per face and class averages for everything else. It now reads
the KS X 1001 symbols and full-width forms, and the Latin-1, Latin
Extended-A, General Punctuation, Mathematical Operators, Geometric
Shapes, Miscellaneous Symbols, Dingbats and Halfwidth and Fullwidth
Forms blocks of twelve faces, from a table read from the font files
(form_fit/_glyph_table.py). A glyph a face lacks takes the advance of
the face Hancom lays it out from, moved into the face's own units.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@airmang

airmang commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

PR 처리 담당입니다. 폭 표를 글꼴 파일(hmtx·cmap)에서 읽은 것은 좋습니다. 다만 한/글 동작에 대한 주장에 한/글 쪽 근거가 없어 보류합니다.

참고: 바탕·굴림·돋움·궁서·맑은 고딕·Segoe UI Symbol에서 뽑은 설계 폭을 공개 저장소에 싣는 것은 오너께 한 번 확인받는 편이 좋겠습니다. 글꼴 파일이 아니라 폭 수치라서 위험은 낮다고 봅니다.

🤖 Generated with Claude Code

airmang and others added 2 commits September 29, 2026 21:52
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The symbol widths test compared the table with values taken from the
table. It is replaced by a fixture Hancom laid out and saved: each cell
holds a symbol and five Hangul syllables at one of the two widths where
its line breaks change, covering a face lacking the symbol (drawn from
its fallback face, in faces of 1000, 1024 and 2048 units per em), the
Greek of 함초롬돋움, 한컴 고딕's я and plain design advances. FormFit's
line count matches Hancom's line cache in every cell; before the table
11 of the 24 cells differed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@airmang

airmang commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

리뷰 고맙습니다. 요청대로 바꿨습니다(cf0c478).

  • 표에서 뽑은 값을 다시 확인하던 테스트를 지웠다. 대신 한/글이 배치해 저장한 fixture tests/fixtures/hancom_saved/formfit_glyph_cells.hwpx로 확인한다.
    • 칸마다 기호 하나와 한글 다섯 자를 넣고, 줄바꿈이 갈리는 두 폭(한 줄이 되는 폭과 그보다 2 좁은 폭)에 두었다.
    • 다루는 글자는 다음과 같다.
      • 글꼴에 없어 대신 그리는 글자: 바탕·굴림(단위 1024), 맑은 고딕(2048), 한컴 고딕(1000)의 〄, 함초롬바탕의 ✀(Segoe UI Symbol)
      • 예외: 함초롬돋움의 Ω, 한컴 고딕의 я
      • 설계 폭 그대로인 글자: 바탕 ∑, 맑은 고딕 ∮, 궁서 §, 돋움체 →, 함초롬돋움 é
  • test_cells_of_symbols_break_where_hancom_breaks_them은 칸마다 FormFit의 줄 수가 한/글의 줄 캐시(hp:lineseg) 수와 같은지 본다.
    • 24칸 모두 같다.
    • 이 PR 전의 measure.py로는 11칸이 다르다.
  • main을 합쳤다(테스트 파일 충돌).
  • 설계 폭 수치를 공개 저장소에 싣는 것은 오너께 확인을 받겠습니다.

🤖 Generated with Claude Code

@airmang

airmang commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

PR 처리 담당입니다. cf0c478을 확인했습니다.

  • formfit_glyph_cells.hwpx는 한/글이 배치하고 저장한 문서입니다. 문단 73개 모두에 linesegarray가 있고, 칸은 24개입니다.
  • 새 테스트는 칸마다 FormFit의 줄 수를 한/글의 줄 캐시(hp:lineseg) 수와 비교합니다. 한/글 쪽 근거에 대한 제 보류 사유는 해소되었습니다.

남은 것은 설계 폭 수치를 공개 저장소에 싣는 것에 대한 오너 확인뿐입니다. 확인이 오면 CI 녹색을 보고 머지하겠습니다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@airmang

airmang commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

오너 확인을 받았습니다. 이 PR의 글자별 설계 폭 수치(바탕·굴림·돋움·궁서·맑은 고딕·한컴 고딕·함초롬 계열과 대신 그리는 Segoe UI Symbol)를 공개 저장소에 싣습니다. 수치만 싣고 글꼴 파일이나 글자 윤곽은 싣지 않습니다.

main을 합쳤습니다(7bf49b8). 충돌은 tests/test_form_fit_hancom_rules.py 한 곳이었고, 양쪽이 같은 자리에 더한 테스트를 둘 다 남겼습니다. 합친 상태에서 전체 테스트와 게이트(hygiene, ruff, generics, census, mypy, pyright)가 통과했고, coverage ledger도 main과 같습니다.

🤖 Generated with Claude Code

# Conflicts:
#	docs/architecture/module-ownership.json
#	tests/test_form_fit_hancom_rules.py
#	tests/test_product_boundary.py
@airmang

airmang commented Sep 30, 2026

Copy link
Copy Markdown
Owner Author

main(edda201)을 합쳐 올렸습니다(7a87b83).

  • 충돌은 세 파일이었습니다.
    • docs/architecture/module-ownership.json: main의 oxml/curves.py 항목 뒤에 이 PR의 form_fit/_glyph_table.py 항목을 두었습니다.
    • tests/test_product_boundary.py: 두 모듈의 주석을 모두 두고, 분류된 모듈 수를 180으로 고쳤습니다.
    • tests/test_form_fit_hancom_rules.py: import 목록을 합쳤습니다.
  • 합친 상태에서 FormFit·layout·product boundary 테스트 633개가 통과하고, 게이트(hygiene, ruff 두 벌, generics, census, mypy, pyright)도 통과합니다.
  • 합친 뒤에도 이 PR의 폭 표가 쓰입니다. 예를 들어 함초롬돋움의 ′(U+2032)는 9 pt, 기호 장평 60 %에서 164로 잽니다(전에는 목록에 없어 226.8). 한/글이 줄을 나눈 자리와 같습니다.

airmang and others added 5 commits October 1, 2026 09:13
…dvances

The glyph table lists the symbol faces Wingdings and Symbol: their glyphs
at the private-use code points U+F020-F0FF documents store them at, each
at its design advance read from the font. A face only the glyph table
lists has no Hangul or space of its own; its other characters keep the
class averages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Hancom

25 rows under the bullet U+F09F in its own Wingdings shape with its own
width on, laid out and saved by Hancom: the label takes the glyph's design
advance (456 at 10 pt) and the half-em gap, and every row breaks where
Hancom broke it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…advances

HY헤드라인M joins the glyph table at its design advances. The glyphs it
lacks take 함초롬바탕's advance moved into its units, and so does the
grave accent; я and ✀ carry the advance Hancom lays them out at.

Every text face also gains the Currency Symbols block (₩ and the rest),
which the table left to the class averages.

The new test reads 22 cells Hancom laid out and saved: a glyph and five
Hangul syllables in HY헤드라인M at the two widths where the line count
changes, at 30 pt and 10 pt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
휴먼명조 joins the glyph table at its design advances, read from the
face's font file; the glyphs it lacks take 함초롬바탕's advance moved
into its units. A new test pins a few of them.

The test that measured ○ in a face the table does not list used
휴먼명조 cells; it now measures them with 휴먼명조's advances and with
the face left unnamed, and Hancom's line counts hold for both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@airmang

airmang commented Oct 1, 2026

Copy link
Copy Markdown
Owner Author

글꼴 넷을 더한 커밋을 올렸습니다. PR 본문도 함께 고쳤습니다.

  • 1275859: 기호 글꼴 Wingdings·Symbol을 사용자 영역(U+F020–F0FF)의 설계 폭으로 잽니다. 이 두 글꼴은 표에만 있어서(한글 음절·공백 줄 없음) _design_units가 폭 표에서 읽게 했습니다.
  • f5ae4e0: main(06cd822)을 합쳤습니다. 충돌은 없었습니다.
  • 48b853f: Wingdings 글머리표(U+F09F) 아래 25줄 테스트를 더했습니다(한/글 저장본).
  • cc9ab4c: HY헤드라인M과 통화 기호 블록을 더했습니다.
    • HY헤드라인M은 글꼴에 없는 글자와 `를 함초롬바탕의 폭으로 놓습니다. я·✀는 한/글이 놓는 폭을 표에 적었습니다.
    • 통화 기호 블록(₩ 등)은 모든 글꼴에 더했습니다.
    • HY헤드라인M 22칸 테스트(한/글 저장본)를 더했습니다.
  • 11f7fd1: 휴먼명조를 더했습니다. 글꼴에 없는 글자는 함초롬바탕의 폭을 씁니다.
    • "표에 없는 글꼴" 테스트는 휴먼명조 칸을 쓰고 있었습니다. 이제 휴먼명조 폭과 이름 없는 글꼴 두 가지로 재고, 두 경우 모두 한/글의 줄 수와 맞습니다.

글자별 설계 폭 수치만 싣고, 글꼴 파일이나 글자 윤곽은 싣지 않습니다. 전체 테스트와 게이트(hygiene, ruff, generics, census, mypy, pyright)가 통과했고, coverage ledger는 main과 같습니다.

🤖 Generated with Claude Code

@airmang

airmang commented Oct 1, 2026

Copy link
Copy Markdown
Owner Author

main(505bb2f)을 합쳤습니다. 충돌은 CHANGELOG뿐이었습니다. 6.7.0 릴리스로 이 PR 항목이 들어 있던 [Unreleased] 절이 [6.7.0]이 되어, 항목을 새 ## [Unreleased] / ### 바꿈 아래로 옮겼습니다. 코드는 바뀌지 않았고 FormFit·쪽 수 추정 테스트와 게이트를 다시 통과했습니다.

@airmang

airmang commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

main(ccd39a5)을 합쳤습니다(bfe03bc). 충돌은 CHANGELOG의 ### 바꿈 절뿐이었습니다. main의 import hwpx 두 항목과 이 PR의 FormFit 글꼴 폭 항목을 모두 두었고, main 항목을 먼저 놓았습니다. 코드는 바뀌지 않았습니다. FormFit·쪽 수 추정 시험, 전체 시험, 게이트를 다시 통과했습니다. 그 뒤 들어온 #389·#390과도 충돌하지 않습니다.

@airmang

airmang commented Oct 2, 2026

Copy link
Copy Markdown
Owner Author

main을 다시 합쳤습니다(31c9034). #395가 form_fit/measure.py의 table_sizes import 줄에 grid_widths_of를 더해서, 바로 아래 이 PR의 _glyph_table import와 맞닿아 충돌했습니다. 두 import를 모두 두었습니다. 그 밖의 코드는 바뀌지 않았습니다. FormFit·쪽 수 추정 시험(#395 시험 포함)과 게이트를 다시 통과했습니다.

This branch has not been deployed

No deployments
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