[fonttools/fonttools] f608e4: [ot] Add 24-bit Layout converters

1 view
Skip to first unread message

Cosimo Lupo

unread,
Jun 18, 2026, 1:48:12 PM (7 days ago) Jun 18
to fontto...@googlegroups.com
Branch: refs/heads/beyond-64k
Home: https://github.com/fonttools/fonttools
Commit: f608e4adc1e1edbb2ef2f729d559c5f73368355d
https://github.com/fonttools/fonttools/commit/f608e4adc1e1edbb2ef2f729d559c5f73368355d
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otConverters.py

Log Message:
-----------
[ot] Add 24-bit Layout converters

Add signed and computed 24-bit integer converters, plus a glyph-name-aware 24-bit glyph ID converter for extended OpenType Layout formats.

Assisted-by: Codex


Commit: f05c998eebb53e8f652633b85dcff23c23cb3bef
https://github.com/fonttools/fonttools/commit/f05c998eebb53e8f652633b85dcff23c23cb3bef
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otData.py
A Tests/ttLib/tables/otData_test.py

Log Message:
-----------
[ot] Add beyond-64k Layout schemas

Add the extended OpenType Layout formats and versioned header fields
using specification names. Preserve the intentional 16-bit
chained-context and reverse-chain count exceptions documented by
HarfBuzz.

All pre-existing non-header schemas remain unchanged.

Assisted-by: Codex


Commit: 1bc0c48bc855cd89658caae36fa3204aedf91ad4
https://github.com/fonttools/fonttools/commit/1bc0c48bc855cd89658caae36fa3204aedf91ad4
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otBase.py

Log Message:
-----------
[ot] Support deferred uint24 counts

Teach CountReference to serialize three-byte count values used by the new beyond-64k table formats.

Assisted-by: Codex


Commit: c96c47b5a82bf11a4a6abcb2451ad303e5137a1b
https://github.com/fonttools/fonttools/commit/c96c47b5a82bf11a4a6abcb2451ad303e5137a1b
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otData.py
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/tables/otTables_test.py

Log Message:
-----------
[ot] Support extended Coverage and ClassDef formats

Read and write the beyond-64k Coverage and ClassDef formats, selecting
them only when glyph IDs or encoded counts exceed the legacy limits.

Keep shared field names consistent across duplicate formats while using
the extended record types internally.

Test semantic reads and writes as well as exact binary serialization and
decompilation.

Assisted-by: Codex


Commit: 8883f41b2d4e057d5a2e6bc2dfdab69d0d05c9fd
https://github.com/fonttools/fonttools/commit/8883f41b2d4e057d5a2e6bc2dfdab69d0d05c9fd
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/tables/otTables_test.py

Log Message:
-----------
[ot] Support extended SingleSubst formats

Read and write SingleSubst formats 3 and 4 when glyph IDs or counts
exceed the legacy limits.

Use 24-bit modular arithmetic for format 3 and preserve the legacy
formats whenever possible.

Assisted-by: Codex


Commit: 6a5cedaa8cc6cef6abf4db6da9cbdeb0b4591996
https://github.com/fonttools/fonttools/commit/6a5cedaa8cc6cef6abf4db6da9cbdeb0b4591996
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/tables/otTables_test.py

Log Message:
-----------
[ot] Support extended MultipleSubst format

Read and write MultipleSubst format 2 when input or substitute glyph
IDs, or the sequence count, exceed the legacy limits.

Preserve format 1 for representable mappings and use Sequence2 records
for the extended format.

Assisted-by: Codex


Commit: 457e7cc897eaa1509df8cff4428997efa5d549c2
https://github.com/fonttools/fonttools/commit/457e7cc897eaa1509df8cff4428997efa5d549c2
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/tables/otTables_test.py

Log Message:
-----------
[ot] Support extended AlternateSubst format

Read and write AlternateSubst format 2 when covered or alternate glyph
IDs, or the alternate-set count, exceed the legacy limits.

Preserve format 1 for representable mappings and use AlternateSet2
records for the extended format.

Assisted-by: Codex


Commit: 72863c33c89d855a84e6a35eb0b1e1a5e0faf5bb
https://github.com/fonttools/fonttools/commit/72863c33c89d855a84e6a35eb0b1e1a5e0faf5bb
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/tables/otTables_test.py

Log Message:
-----------
[ot] Support extended LigatureSubst format

Read and write LigatureSubst format 2 when component or ligature glyph
IDs, or the ligature-set count, exceed the legacy limits.

Preserve format 1 for representable mappings and emit matching
extended ligature-set and ligature records.

Assisted-by: Codex


Commit: 58c1a1a7fbb46fe09a828bf6a840a35a47dd19c0
https://github.com/fonttools/fonttools/commit/58c1a1a7fbb46fe09a828bf6a840a35a47dd19c0
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/misc/testTools.py
M Lib/fontTools/ttLib/tables/otTables.py
M Lib/fontTools/ttLib/ttFont.py
M Tests/ttLib/tables/otTables_test.py
M Tests/ttLib/ttFont_test.py

Log Message:
-----------
[ttFont] Add extended glyph ID capability

Add TTFont.hasExtendedGlyphIDs() to cheaply identify fonts whose glyph
ID namespace exceeds 16 bits.

Use it to skip extended-format selection scans for Coverage, ClassDef,
and handwritten GSUB subtables in normal fonts.

Assisted-by: Codex


Commit: 965f969e59d2b62d1659cb4a6583c032ea2287c9
https://github.com/fonttools/fonttools/commit/965f969e59d2b62d1659cb4a6583c032ea2287c9
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/otlLib/builder.py
M Tests/otlLib/builder_test.py

Log Message:
-----------
[otlLib] Build extended SinglePos formats

Select SinglePos formats 3 and 4 when the glyph map contains extended
glyph IDs.

Preserve the existing value-record grouping and format selection.

Assisted-by: Codex


Commit: b94e6fc4a3581b0c251943e2163f7756c0d6a41f
https://github.com/fonttools/fonttools/commit/b94e6fc4a3581b0c251943e2163f7756c0d6a41f
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/otlLib/builder.py
M Tests/otlLib/builder_test.py

Log Message:
-----------
[otlLib] Build extended PairPos formats

Select PairPos format 3 for glyph pairs and format 4 for class pairs
when the glyph map contains extended glyph IDs.

Emit PairSet2 and PairValue2 records for extended glyph-pair
subtables.

Assisted-by: Codex


Commit: fb04118378c13d592da6a21d4ea7ed7623941ed1
https://github.com/fonttools/fonttools/commit/fb04118378c13d592da6a21d4ea7ed7623941ed1
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/otlLib/builder.py
M Tests/otlLib/builder_test.py

Log Message:
-----------
[otlLib] Build extended attachment positioning

Select extended CursivePos, MarkBasePos, MarkLigPos, and MarkMarkPos
formats when the glyph map contains extended glyph IDs.

Emit matching long-offset nested arrays and records throughout each
subtable.

Assisted-by: Codex


Commit: 6d609712ebbf069964443c4c4dfbbb7b3ebeb2d1
https://github.com/fonttools/fonttools/commit/6d609712ebbf069964443c4c4dfbbb7b3ebeb2d1
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otData.py
M Lib/fontTools/ttLib/tables/otTables.py

Log Message:
-----------
[ot] Apply Black formatting

Apply Black 24.10 formatting to the beyond-64k Layout schemas and
handwritten table code.

Assisted-by: Codex


Commit: 4383692b5b60fcb825be502a1d519d351f51519f
https://github.com/fonttools/fonttools/commit/4383692b5b60fcb825be502a1d519d351f51519f
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/otlLib/builder.py
M Tests/otlLib/builder_test.py

Log Message:
-----------
[otlLib] Build extended contextual formats

Reuse the existing contextual lookup algorithms while selecting the
extended rule, class, coverage, and lookup-record structures for fonts
with extended glyph IDs.

The beyond-64k specification has no extended chained coverage format,
so exclude that candidate for extended chained-context lookups.

Assisted-by: Codex


Commit: b8e42c151df149554243ba0e845ea49e73ceb2ff
https://github.com/fonttools/fonttools/commit/b8e42c151df149554243ba0e845ea49e73ceb2ff
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/otlLib/builder.py
M Tests/otlLib/builder_test.py

Log Message:
-----------
[otlLib] Build extended reverse-chain substitutions

Select ReverseChainSingleSubst format 2 when the font has extended
glyph IDs. The existing coverage and substitution construction works
unchanged with the extended schema.

Assisted-by: Codex


Commit: fb856d8abd285fa1dbfc8b6fc7529c0f49ace41d
https://github.com/fonttools/fonttools/commit/fb856d8abd285fa1dbfc8b6fc7529c0f49ace41d
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/feaLib/builder.py
M Tests/feaLib/builder_test.py

Log Message:
-----------
[feaLib] Build extended GSUB and GPOS headers

Build layout lists normally, then move them to the extended top-level
fields after feature variations are complete for fonts with extended
glyph IDs.

Assisted-by: Codex


Commit: aa767809c7acec0275b3fc80da5bb3bd966ec30e
https://github.com/fonttools/fonttools/commit/aa767809c7acec0275b3fc80da5bb3bd966ec30e
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/feaLib/builder.py
M Lib/fontTools/otlLib/builder.py
M Tests/feaLib/builder_test.py
M Tests/otlLib/builder_test.py

Log Message:
-----------
[feaLib] Build extended GDEF headers

Move GDEF data to the version 1.4 top-level fields for fonts with
extended glyph IDs. Build LigCaretList2 in that case because its
internal coverage and ligature offsets are also extended.

Assisted-by: Codex


Commit: 51f285da7278875a345133618f13e3fb59df7b30
https://github.com/fonttools/fonttools/commit/51f285da7278875a345133618f13e3fb59df7b30
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/G_V_A_R_.py
A Lib/fontTools/ttLib/tables/M_A_X_P_.py
M Lib/fontTools/ttLib/tables/_g_v_a_r.py
M Lib/fontTools/ttLib/tables/_m_a_x_p.py
A Tests/ttLib/tables/M_A_X_P__test.py
M Tests/ttLib/tables/_g_v_a_r_test.py

Log Message:
-----------
[ttLib] Add MAXP and complete GVAR support

Add the MAXP table class with a 24-bit glyph count. Parameterize the
shared maxp and gvar implementations so uppercase tables pair with
GLYF while lowercase tables retain their existing behavior.

Assisted-by: Codex


Commit: c5d31a45d54ecf1d4a5aff43ec74bc6033c9637e
https://github.com/fonttools/fonttools/commit/c5d31a45d54ecf1d4a5aff43ec74bc6033c9637e
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
A Lib/fontTools/ttLib/tables/G_L_Y_F_.py
A Lib/fontTools/ttLib/tables/L_O_C_A_.py
M Lib/fontTools/ttLib/tables/_g_l_y_f.py
M Lib/fontTools/ttLib/tables/_l_o_c_a.py
A Tests/ttLib/tables/G_L_Y_F__test.py

Log Message:
-----------
[ttLib] Add GLYF and LOCA tables

Add locked uppercase GLYF and LOCA companions. Share the existing
glyph implementation while encoding composite component glyph IDs as
24-bit values when required.

Keep uppercase outline operations paired with MAXP and uppercase
metrics tables.

Assisted-by: Codex


Commit: c075b113d008e528576d41564258782eac4b1b8d
https://github.com/fonttools/fonttools/commit/c075b113d008e528576d41564258782eac4b1b8d
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
A Lib/fontTools/ttLib/tables/H_H_E_A_.py
A Lib/fontTools/ttLib/tables/H_M_T_X_.py
A Lib/fontTools/ttLib/tables/V_H_E_A_.py
A Lib/fontTools/ttLib/tables/V_M_T_X_.py
M Lib/fontTools/ttLib/tables/_h_h_e_a.py
M Lib/fontTools/ttLib/tables/_h_m_t_x.py
M Lib/fontTools/ttLib/tables/_v_h_e_a.py
A Tests/ttLib/tables/H_M_T_X__test.py

Log Message:
-----------
[ttLib] Add uppercase metrics tables

Add HHEA, HMTX, VHEA, and VMTX table classes with locked uppercase
pairing. Widen the metric counts in HHEA and VHEA to 32 bits while
sharing the existing metric-record implementation.

Assisted-by: Codex


Commit: 6b0cbf6bd1ca5a996245971b64de7bc5bffcc98d
https://github.com/fonttools/fonttools/commit/6b0cbf6bd1ca5a996245971b64de7bc5bffcc98d
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Doc/source/ttLib/tables.rst
A Doc/source/ttLib/tables/G_L_Y_F_.rst
M Doc/source/ttLib/tables/G_V_A_R_.rst
A Doc/source/ttLib/tables/H_H_E_A_.rst
A Doc/source/ttLib/tables/H_M_T_X_.rst
A Doc/source/ttLib/tables/L_O_C_A_.rst
A Doc/source/ttLib/tables/M_A_X_P_.rst
A Doc/source/ttLib/tables/V_H_E_A_.rst
A Doc/source/ttLib/tables/V_M_T_X_.rst
M Doc/source/ttx.rst
M Lib/fontTools/ttLib/tables/__init__.py
M Lib/fontTools/ttLib/ttFont.py

Log Message:
-----------
[ttLib] Register uppercase companion tables

Run the table metadata generator and document the new beyond-64k table
modules. Add TTFont type-checking overloads for their tags.

Assisted-by: Codex


Commit: eeadd6722baaca111b19f7407bae15898c979318
https://github.com/fonttools/fonttools/commit/eeadd6722baaca111b19f7407bae15898c979318
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/misc/testTools.py
M Lib/fontTools/ttLib/tables/G_L_Y_F_.py
M Lib/fontTools/ttLib/tables/_g_l_y_f.py
M Lib/fontTools/ttLib/tables/_p_o_s_t.py
M Lib/fontTools/ttLib/ttFont.py
M Lib/fontTools/ttLib/ttGlyphSet.py
M Tests/ttLib/tables/G_L_Y_F__test.py
M Tests/ttLib/ttFont_test.py

Log Message:
-----------
[ttLib] Support uppercase outline families in TTFont

Prefer the locked uppercase outline, metrics, variation, and maximum
profile tables when they are present. Route post glyph-count access
through TTFont and support split-glyph TTX output for GLYF.

Assisted-by: Codex


Commit: ff49a961effdc074198e146f3f2dad82358f2423
https://github.com/fonttools/fonttools/commit/ff49a961effdc074198e146f3f2dad82358f2423
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
A Lib/fontTools/ttLib/beyond64k.py
A Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Add beyond-64k table conversion tool

Add directional APIs and a module CLI for converting the locked
companion-table family. Support selective conversion, overwrite and
missing-table controls, mixed-family validation, and binary round trips.

Assisted-by: Codex


Commit: e80872ba2a8b0b00e0b665a24a4f682fd740328f
https://github.com/fonttools/fonttools/commit/e80872ba2a8b0b00e0b665a24a4f682fd740328f
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Convert extended GSUB and GPOS headers

Generalize beyond-64k conversion entries to support same-tag in-place
transformations. Use them to move GSUB and GPOS top-level lists between
the compact and extended headers.

Assisted-by: Codex


Commit: e49bf52c00abcf6e56f1cca1a502527260f82fb1
https://github.com/fonttools/fonttools/commit/e49bf52c00abcf6e56f1cca1a502527260f82fb1
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Reject lossy GLYF lowering

Reject lowering GLYF when cubic outlines or composite glyph IDs cannot
be represented by the lowercase glyf table.

Assisted-by: Codex


Commit: b1508d6bfb15af9e03f2493c9af948432419931b
https://github.com/fonttools/fonttools/commit/b1508d6bfb15af9e03f2493c9af948432419931b
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Force automatic extended Layout formats

Make the beyond-64k conversion tool force the extended or compact
forms of automatic-format Layout structures. Propagate the selected
form to Coverage tables synthesized while compiling GSUB subtables.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/ttLib

Assisted-by: Codex


Commit: ba6c38d1d3738168daa1c498a9a11699c46cde39
https://github.com/fonttools/fonttools/commit/ba6c38d1d3738168daa1c498a9a11699c46cde39
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Convert explicit extended Layout formats

Convert non-contextual GSUB and GPOS subtables between their compact
and extended formats. Replace nested record objects where the extended
format uses wider glyph IDs, counts, or offsets.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/ttLib
Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/otlLib

Assisted-by: Codex


Commit: 0c33cc4cf9556c11f6f9d0b4ba1effca8908f4b7
https://github.com/fonttools/fonttools/commit/0c33cc4cf9556c11f6f9d0b4ba1effca8908f4b7
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Convert extended contextual Layout formats

Convert contextual GSUB and GPOS subtables between compact and
extended formats. Rename fields and replace rule, rule-set, and lookup
record objects where the formats differ.

Add end-to-end tests that upper and lower contextual Layout tables,
serialize them, and verify the formats after reloading.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/ttLib
Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/otlLib

Assisted-by: Codex


Commit: 9cdafe20b7db8797d51040b431849ae13834e675
https://github.com/fonttools/fonttools/commit/9cdafe20b7db8797d51040b431849ae13834e675
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Convert extended GDEF headers

Convert GDEF between its compact header fields and version 1.4
extended fields. Convert LigCaretList objects and force nested Coverage
and ClassDef formats in the selected direction.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/ttLib
Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/feaLib Tests/otlLib

Assisted-by: Codex


Commit: 49948a7f42d17756c696523fa90b6768e03fa85d
https://github.com/fonttools/fonttools/commit/49948a7f42d17756c696523fa90b6768e03fa85d
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otBase.py
M Lib/fontTools/ttLib/tables/otConverters.py
M Lib/fontTools/ttLib/tables/otData.py
M Lib/fontTools/ttLib/tables/otDataSchema.py
M Tests/ttLib/tables/otData_test.py

Log Message:
-----------
[ot] Support conditional repeated fields

Add a condition property to FieldSpec so a repeated field can be
version-gated independently from its repeat count adjustment. Use it
for the appended JSTF 1.1 script-record array.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/ttLib/tables/otData_test.py Tests/ttLib/tables/otTables_test.py

Assisted-by: Codex


Commit: 6ac405cd57034ea2579cee1087cbf5f03aff462c
https://github.com/fonttools/fonttools/commit/6ac405cd57034ea2579cee1087cbf5f03aff462c
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Convert extended BASE and JSTF structures

Convert BASE reference-glyph coordinates between formats 2 and 4.
Convert JSTF between its version 1.0 and 1.1 script records, including
extended script and extender-glyph structures.

Add serialized upper/lower round-trip tests for both tables.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/ttLib
Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q Tests/feaLib Tests/otlLib

Assisted-by: Codex


Commit: ae34a2e5744243bf87cb7a36ad5a84a5529d16aa
https://github.com/fonttools/fonttools/commit/ae34a2e5744243bf87cb7a36ad5a84a5529d16aa
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Test beyond-64k outline round trips

Compare SVGPathPen output before uppering, after uppering, and after
lowering companion outline tables.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 82d64b057dbd7b59d382d8bfe8f57f8125a1560d
https://github.com/fonttools/fonttools/commit/82d64b057dbd7b59d382d8bfe8f57f8125a1560d
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/__init__.py
M Lib/fontTools/merge/tables.py
M Tests/merge/merge_test.py

Log Message:
-----------
[merge] Use beyond-64k tables when needed

Keep the compact merge path unchanged unless the merged glyph order
exceeds 64k glyphs or an input already uses uppercase companion
tables. In those cases, convert input companion tables before merging
and convert the merged result after Layout merging has run.

Register the existing glyf, maxp, metrics, and loca merge behavior for
the uppercase companion table classes.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 3eba6d02e3c63d6abe7e212e726569bfa1058257
https://github.com/fonttools/fonttools/commit/3eba6d02e3c63d6abe7e212e726569bfa1058257
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/fontBuilder.py
M Lib/fontTools/ttLib/tables/O_S_2f_2.py
M Lib/fontTools/ttLib/tables/_p_o_s_t.py
M Tests/fontBuilder/fontBuilder_test.py

Log Message:
-----------
[fontBuilder] Add beyond-64k table family mode

Add an explicit FontBuilder mode that creates the uppercase companion
outline, metrics, maxp, loca, and gvar tables. Route setupGvar()
through the selected table family and remove setupGVAR().

Make post depend on both maxp and MAXP so saving an uppercase-family
font compiles the glyph-count table before post asks TTFont for the
glyph count.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 61184345cefe767c22aec28216577d8737bf9c06
https://github.com/fonttools/fonttools/commit/61184345cefe767c22aec28216577d8737bf9c06
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Document beyond-64k conversion helpers

Expand the beyond64k module documentation and command-line help to
cover upper/lower conversion, table selection, validation, overwriting,
and missing-table handling.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q \
Tests/ttLib/beyond64k_test.py

Assisted-by: Codex


Commit: dc076c9e0a8eb3bb6478630a9fee7ad14f4d8695
https://github.com/fonttools/fonttools/commit/dc076c9e0a8eb3bb6478630a9fee7ad14f4d8695
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Tests/fontBuilder/fontBuilder_test.py

Log Message:
-----------
[fontBuilder] Test beyond-64k XML round trips

Cover TTX export and import for FontBuilder-created uppercase-family
fonts, then save the imported font back to binary and verify the glyph
order, metrics, and outline bounds survive.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q \
Tests/fontBuilder/fontBuilder_test.py Tests/ttLib/beyond64k_test.py

Assisted-by: Codex


Commit: d45def863b380e190d01dc021b5e2d434304c7e1
https://github.com/fonttools/fonttools/commit/d45def863b380e190d01dc021b5e2d434304c7e1
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/scaleUpem.py
M Tests/ttLib/scaleUpem_test.py

Log Message:
-----------
[ttLib] Scale beyond-64k companion tables

Register scaleUpem visitors for uppercase hhea/vhea, metrics, glyf,
and gvar companion table classes. Use the gvar table's glyphTableTag so
GVAR variations are scaled against GLYF instead of assuming glyf.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 7546f78d508ada1aeb786a17e4895cb8f8b534a5
https://github.com/fonttools/fonttools/commit/7546f78d508ada1aeb786a17e4895cb8f8b534a5
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/removeOverlaps.py
M Tests/ttLib/removeOverlaps_test.py

Log Message:
-----------
[ttLib] Remove overlaps from beyond-64k glyf tables

Teach removeOverlaps to use GLYF and HMTX when a font uses the
uppercase beyond-64k companion table family. This keeps lowercase glyf
behavior unchanged while allowing uppercase-family TrueType outlines to
be simplified.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib \
/tmp/fonttools-pathops-venv/bin/python -m pytest -q \
Tests/ttLib/removeOverlaps_test.py
Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 7e5bcb5ced65b40a6b97c854d704717326f9ceb5
https://github.com/fonttools/fonttools/commit/7e5bcb5ced65b40a6b97c854d704717326f9ceb5
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/qu2cu/cli.py
M Tests/qu2cu/qu2cu_cli_test.py

Log Message:
-----------
[qu2cu] Convert beyond-64k glyf tables

Use GLYF when an input font has the uppercase beyond-64k companion
outline table, and reject both gvar and GVAR variable fonts before
converting quadratic outlines to cubic.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 16cc8632787973908da3e50e10c81ef2ca34d8e7
https://github.com/fonttools/fonttools/commit/16cc8632787973908da3e50e10c81ef2ca34d8e7
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/varLib/hvar.py
M Tests/varLib/hvar_test.py

Log Message:
-----------
[varLib] Build HVAR from beyond-64k gvar tables

Let varLib.hvar read GVAR when the font uses the uppercase beyond-64k
companion table family, and trigger VVAR generation for VMTX as well as
vmtx. Also fix add_VVAR so axisTags is initialized before use.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 3e79fbfdef92e8886269eb7b4a67f7002b5a67a1
https://github.com/fonttools/fonttools/commit/3e79fbfdef92e8886269eb7b4a67f7002b5a67a1
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/qu2cu/cli.py
M Tests/qu2cu/qu2cu_cli_test.py

Log Message:
-----------
[qu2cu] Write cubic outlines to GLYF

Convert fonts to the uppercase beyond-64k companion table family before
rewriting quadratic outlines as cubic outlines. Cubic TrueType outlines
belong in GLYF, so compact glyf inputs are uppered before conversion.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: f03339c6f9d9bfbac6203d2544d9c7547c815223
https://github.com/fonttools/fonttools/commit/f03339c6f9d9bfbac6203d2544d9c7547c815223
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/__main__.py
M Tests/ttLib/main_test.py

Log Message:
-----------
[ttLib] Optimize uppercase glyf table loading

Include GLYF and GVAR in the ttLib command-line table set that is
loaded when --optimize-font-speed is requested. This matches the
existing lowercase glyf/gvar behavior for beyond-64k companion fonts.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: ffdb84567130c97d4589585994f695c6e1c11255
https://github.com/fonttools/fonttools/commit/ffdb84567130c97d4589585994f695c6e1c11255
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/pens/svgPathPen.py
A Tests/pens/svgPathPen_test.py

Log Message:
-----------
[pens] Render SVG paths from HHEA fonts

Prefer HHEA over hhea in the svgPathPen command-line helper so
beyond-64k companion fonts can be rendered without lowering first.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 56847c7e980db0258494939a7e05789f49312582
https://github.com/fonttools/fonttools/commit/56847c7e980db0258494939a7e05789f49312582
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/varLib/interpolatable.py
M Tests/varLib/interpolatable_test.py

Log Message:
-----------
[varLib] Check interpolatability with GVAR

Use GVAR and GLYF when checking interpolatability of uppercase
beyond-64k companion variable TrueType fonts. This matches the existing
gvar/glyf path without requiring fonts to be lowered first.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib \
/tmp/fonttools-pathops-venv/bin/python -m pytest -q \
Tests/varLib/interpolatable_test.py
Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 6f2dc099c0a7425d28ab732c00656100f10a4ab8
https://github.com/fonttools/fonttools/commit/6f2dc099c0a7425d28ab732c00656100f10a4ab8
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/varLib/__init__.py
M Lib/fontTools/varLib/mvar.py
A Tests/varLib/mvar_test.py

Log Message:
-----------
[varLib] Prefer uppercase MVAR metric tables

Resolve MVAR hhea and vhea metric targets through the uppercase
beyond-64k companions when those tables are present. Keep the spec mapping
itself lowercase so compact fonts and callers that inspect MVAR_ENTRIES keep
seeing the existing defaults.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q \
Tests/varLib/mvar_test.py Tests/varLib/varLib_test.py

Assisted-by: Codex


Commit: 4d16dbc931637e1ab778a7ec87247d70cbfddfe3
https://github.com/fonttools/fonttools/commit/4d16dbc931637e1ab778a7ec87247d70cbfddfe3
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/TupleVariation.py
M Tests/ttLib/tables/TupleVariation_test.py

Log Message:
-----------
[ttLib] Accept GVAR tuple variation stores

Treat uppercase GVAR like gvar when decompiling tuple variation point
numbers and glyph deltas. GVAR uses the same tuple variation data shape as
compact gvar.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q \
Tests/ttLib/tables/TupleVariation_test.py

Assisted-by: Codex


Commit: 4e2419e536ae124367fd13a96647bc45b2a8d836
https://github.com/fonttools/fonttools/commit/4e2419e536ae124367fd13a96647bc45b2a8d836
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/cffLib/CFF2ToCFF.py
M Lib/fontTools/cffLib/width.py
A Tests/cffLib/width_test.py

Log Message:
-----------
[cffLib] Prefer HMTX for CFF widths

Use the uppercase HMTX companion table when choosing widths for CFF2 to
CFF conversion and the width optimizer CLI. Fall back to hmtx for compact
fonts.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q \
Tests/cffLib/width_test.py Tests/cffLib

Assisted-by: Codex


Commit: cc03b4074c68836475359b5b26729ca90260543e
https://github.com/fonttools/fonttools/commit/cc03b4074c68836475359b5b26729ca90260543e
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Tests/ttLib/woff2_test.py

Log Message:
-----------
[woff2] Test beyond-64k companion round trips

Cover saving uppercase beyond-64k companion tables in WOFF2. The uppercase
tables are not WOFF2 transformed tables, so they should round-trip as generic
tables without reintroducing compact lowercase companions.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib \
/tmp/fonttools-pathops-venv/bin/python -m pytest -q Tests/ttLib/woff2_test.py

Assisted-by: Codex


Commit: 4a248245d5c6b6de4f18fe8fffec02ba1366277c
https://github.com/fonttools/fonttools/commit/4a248245d5c6b6de4f18fe8fffec02ba1366277c
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/varLib/__init__.py
M Tests/varLib/varLib_test.py

Log Message:
-----------
[varLib] Build GVAR from uppercase masters

Infer the TrueType companion table family from the masters when building a
variable font. If the masters use uppercase GLYF, build GVAR and read the
matching uppercase metrics and maxp companions; if they use compact glyf,
keep the existing compact behavior.

Reject mixed glyf/GLYF master families so varLib does not silently combine
incompatible companion table sets.

Tests: PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: Codex


Commit: 64898f49ebfc096981e4be430c2d95c7a0f776ab
https://github.com/fonttools/fonttools/commit/64898f49ebfc096981e4be430c2d95c7a0f776ab
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/__init__.py

Log Message:
-----------
[merge] Ignore absent tables when merging objects

The DefaultTable merge path passed NotImplemented placeholders through
to field-level merge logic. Tables present in only some inputs could then
compare or merge those placeholders as real values.

Mirror the shared mergeObjects helper by filtering absent and None tables
before collecting keys and merging fields.

Tested by merging the Noto Serif Regular set with vertical metrics
dropped.

Assisted-by: OpenAI Codex


Commit: bf24693664e780feb1c0faf39e67b2ba229c4536
https://github.com/fonttools/fonttools/commit/bf24693664e780feb1c0faf39e67b2ba229c4536
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/__init__.py

Log Message:
-----------
Revert "[merge] Ignore absent tables when merging objects"

The Noto merge test now drops partial vertical metrics tables instead of
changing generic merge-object behavior. Restore the previous logic so this
branch stays focused on beyond-64k changes.

Assisted-by: OpenAI Codex


Commit: 04ea8b89092714d2701b27d00675f635687164dc
https://github.com/fonttools/fonttools/commit/04ea8b89092714d2701b27d00675f635687164dc
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/__init__.py

Log Message:
-----------
[merge] Drop post glyph names for large merged fonts

Merged fonts with more than 65535 glyphs cannot encode a post format 2
glyph-name index array. Switch format 2 merged post tables to format 3
when the output glyph order exceeds the compact glyph count limit.

This lets beyond-64k merged fonts serialize instead of overflowing the
post table's uint16 glyph-name indices.

Assisted-by: OpenAI Codex


Commit: d4114dddc895bb9d0533deec57c02c1bd82e5f1f
https://github.com/fonttools/fonttools/commit/d4114dddc895bb9d0533deec57c02c1bd82e5f1f
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/tables.py

Log Message:
-----------
[merge] Use cmap format 12 for large glyph IDs

A merged cmap can map BMP codepoints to glyph IDs above 65535. Those
mappings still fit the Unicode range for format 4, but the glyph IDs do
not fit format 4's uint16 glyph index array.

Build the format 4 subtable only from BMP mappings whose final glyph ID
fits in 16 bits, and emit format 12 whenever any mapping is omitted from
format 4.

Assisted-by: OpenAI Codex


Commit: debb17ac915b1eea1e942665e7cc989996910763
https://github.com/fonttools/fonttools/commit/debb17ac915b1eea1e942665e7cc989996910763
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otBase.py
M Lib/fontTools/ttLib/tables/otTables.py

Log Message:
-----------
[ttLib] Handle LookupList2 in overflow resolution

Beyond-64k GSUB/GPOS tables use LookupList2. Offset overflow records and
recovery still assumed the compact LookupList field, so uppered Layout
tables could fail overflow resolution before a lookup index was found.

Recognize LookupList2 when building overflow records, and use either
LookupList or LookupList2 when resolving lookup and subtable overflows.

Assisted-by: OpenAI Codex


Commit: 1bb57e245d4fac941a2b28c0b82f5e3edcbe1f4a
https://github.com/fonttools/fonttools/commit/1bb57e245d4fac941a2b28c0b82f5e3edcbe1f4a
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/layout.py
M Lib/fontTools/ttLib/beyond64k.py
M Lib/fontTools/ttLib/tables/otData.py

Log Message:
-----------
[ttLib] Use long lookup offsets in LookupList2

Beyond-64k GSUB/GPOS top-level LookupList2 uses long offsets to its
Lookup records. Model it as a distinct table class instead of reusing
LookupList, whose lookup-offset array is still 16-bit.

Convert LookupList to LookupList2 when uppering Layout headers, convert
it back when lowering, and let merge layout helpers operate on both list
classes.

Tested by merging all downloaded Noto Sans Regular fonts with vertical
metrics tables dropped:

fonttools merge --drop-tables=vhea,vmtx,VHEA,VMTX \
--output-file=noto/NotoSans-merged.ttf \
--input-file=noto/sans-merge-inputs.txt

Assisted-by: OpenAI Codex


Commit: 2d3ac77336820b32877de725b07da3984297b7d0
https://github.com/fonttools/fonttools/commit/2d3ac77336820b32877de725b07da3984297b7d0
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/feaLib/builder.py
M Lib/fontTools/merge/tables.py
M Tests/ttLib/tables/otData_test.py

Log Message:
-----------
[ttLib] Fix LookupList2 promotion fallout

feaLib promoted Layout headers by renaming LookupList to LookupList2,
but after LookupList2 became a distinct long-offset table shape the object
also needs to be converted before compile/decompile round-trips.

Keep direct cmap merge unit tests working when they bypass Merger.merge()
and do not provide a final glyph order, and update the otData expectation
for the explicit LookupList2 target type.

Tested with:

PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q

Assisted-by: OpenAI Codex


Commit: be05397c0871f2e14236357871d3985fefd3de5b
https://github.com/fonttools/fonttools/commit/be05397c0871f2e14236357871d3985fefd3de5b
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/feaLib/builder.py
M Lib/fontTools/merge/layout.py
M Lib/fontTools/ttLib/beyond64k.py
M Lib/fontTools/ttLib/tables/otBase.py
M Lib/fontTools/ttLib/tables/otData.py
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/tables/otData_test.py

Log Message:
-----------
[ttLib] Correct GSUB/GPOS 1.2 LookupList handling

GSUB/GPOS version 1.2 has a long top-level LookupList2 offset,
but it still points to the normal LookupList table. Do not model a
separate LookupList2 object with 32-bit internal lookup offsets.

Update feaLib and merge code to move and operate on the active layout
lists, and make overflow recovery pick LookupList2 for version 1.2
layout tables. When overflow recovery finds that a lookup was already
promoted, report no progress instead of retrying indefinitely.

Skip hb.repack by default for version 1.2 GSUB/GPOS tables, while still
honoring an explicit request to use it.

Tested with:
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q \
Tests/ttLib/beyond64k_test.py::test_layout_header_round_trip \
Tests/merge/merge_test.py::test_merge_uses_upper_layout_above_glyph_limit \
Tests/ttLib/tables/otData_test.py::test_extended_layout_header_fields \
Tests/feaLib/builder_test.py::BuilderTest::test_extended_layout_table_headers \
Tests/ttLib/tables/otTables_test.py

Assisted-by: OpenAI Codex


Commit: a2c26279e6948ce90fb0def0d51ff93150dc48f7
https://github.com/fonttools/fonttools/commit/a2c26279e6948ce90fb0def0d51ff93150dc48f7
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/layout.py

Log Message:
-----------
[merge] Format layout merge maps with Black 24.10

Apply the Black version pinned by CI to the layout merge helper.
The Snippets/fontTools path is a symlink to Lib/fontTools locally,
so this tracked file update covers both paths reported by CI.

Tested with:
/tmp/fonttools-lint-venv/bin/black --check --diff \
Lib/fontTools/merge/layout.py Snippets/fontTools/merge/layout.py
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=Lib pytest -q \
Tests/merge/merge_test.py::test_merge_uses_upper_layout_above_glyph_limit

Assisted-by: OpenAI Codex


Commit: 2cecf0c9ff69a022af4ee42b9a650e67311276df
https://github.com/fonttools/fonttools/commit/2cecf0c9ff69a022af4ee42b9a650e67311276df
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otData.py

Log Message:
-----------
[otlLib] Use 24-bit nested offsets in extended Layout

The beyond-64k Layout formats use 32-bit offsets for selected top-level
subtable links, but many nested arrays remain 24-bit offsets. Update the
extended GSUB/GPOS otData entries so generated fonts match the spec and
HarfBuzz's parser.

ChainedSeqRuleSet2 keeps 16-bit offsets to each ChainedSeqRule2, matching
the existing SeqRuleSet2 rule-set model. The rule payloads still carry the
extended glyph IDs.

Tested with:
- PYTHONPATH=Lib python3 -m pytest Tests/ttLib/beyond64k_test.py \
Tests/merge/merge_test.py::test_merge_uses_upper_tables_above_glyph_limit
- PYTHONPATH=Lib python3 -m black --check Lib/fontTools/ttLib/tables/otData.py
(fails: black is not installed)
- hb-shape source and uppered NotoSerifSinhala match for "සිංහල"

Assisted-by: OpenAI Codex <co...@openai.com>


Commit: 8b833f4817b607c399f4c3db70ae483b6a7f36b8
https://github.com/fonttools/fonttools/commit/8b833f4817b607c399f4c3db70ae483b6a7f36b8
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otConverters.py
M Lib/fontTools/ttLib/tables/otData.py

Log Message:
-----------
[otlLib] Rename Offset24To converter

The converter template points to a table through a 24-bit offset, so name it
Offset24To instead of LOffset24To. This keeps the schema naming aligned with
OffsetTo and LOffsetTo without implying a long offset.

Tested with:
- PYTHONPATH=Lib python3 -m pytest Tests/ttLib/beyond64k_test.py \
Tests/merge/merge_test.py::test_merge_uses_upper_tables_above_glyph_limit

Assisted-by: OpenAI Codex <co...@openai.com>


Commit: 2a31783169731434bafcbf5a59e5bba4af20a024
https://github.com/fonttools/fonttools/commit/2a31783169731434bafcbf5a59e5bba4af20a024
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Tests/ttLib/tables/otTables_test.py

Log Message:
-----------
[ttLib] Update extended GSUB test vectors

The format-2 GSUB subtables now use spec-correct 24-bit nested
offsets. Update the binary test fixtures that still expected the
older 32-bit nested-offset encoding.

Tests:
PYTHONPATH=Lib python3 -m pytest Tests/ttLib/tables/otTables_test.py -q
PYTHONPATH=Lib python3 -m pytest Tests/ttLib/beyond64k_test.py \
Tests/merge/merge_test.py::test_merge_uses_upper_tables_above_glyph_limit -q

Assisted-by: OpenAI Codex <co...@openai.com>


Commit: 1dec6c4940755251f005c0bfc47a81b55ad628fc
https://github.com/fonttools/fonttools/commit/1dec6c4940755251f005c0bfc47a81b55ad628fc
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otData.py

Log Message:
-----------
[otlLib] Use 24-bit PairSet offsets in PairPosFormat3

The beyond-64k PairPosFormat3 PairSet array uses Offset24
entries, not 32-bit offsets. Writing 32-bit offsets misaligned
the PairSet array and made extended GPOS tables fail sanitization
or shape incorrectly.

Tested with:
`PYTHONPATH=Lib python3 -m pytest Tests/ttLib/tables/otTables_test.py Tests/ttLib/beyond64k_test.py Tests/merge/merge_test.py::test_merge_uses_upper_tables_above_glyph_limit -q`

Also verified a Noto Sans/Serif shaping sweep against HarfBuzz.

Assisted-by: OpenAI Codex <co...@openai.com>


Commit: 3f42fbc55ada5c83d7af6b91dbe3953fba30aac2
https://github.com/fonttools/fonttools/commit/3f42fbc55ada5c83d7af6b91dbe3953fba30aac2
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otData.py

Log Message:
-----------
[otlLib] Use 24-bit CursivePosFormat2 anchor offsets

The beyond-64k EntryExit2 record uses Offset24 entries for
entry and exit anchors. Writing these as 32-bit offsets misaligned
the EntryExit array and broke CursivePosFormat2 shaping.

Tested with:
`PYTHONPATH=Lib python3 -m pytest Tests/ttLib/tables/otTables_test.py Tests/ttLib/beyond64k_test.py Tests/merge/merge_test.py::test_merge_uses_upper_tables_above_glyph_limit -q`

Also verified the previously failing Indic Siyaq and Nastaliq
uppered-font shaping samples against HarfBuzz.

Assisted-by: OpenAI Codex <co...@openai.com>


Commit: 8cfe5b34109307d4b7b1a64b6eff70e1a21be4ef
https://github.com/fonttools/fonttools/commit/8cfe5b34109307d4b7b1a64b6eff70e1a21be4ef
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/feaLib/builder.py
M Lib/fontTools/merge/layout.py
M Lib/fontTools/ttLib/beyond64k.py
M Lib/fontTools/ttLib/tables/otData.py
M Tests/ttLib/tables/otData_test.py

Log Message:
-----------
[ttLib] Use 32-bit lookup offsets in LookupList2

Add a separate LookupList2 table class whose lookup array uses long
offsets, and point GSUB/GPOS v1.2 headers at it. Convert promoted
layout headers in both beyond64k and feaLib so existing LookupList
objects compile using the widened offsets.

As of June 2026, the proposed GSUB/GPOS v1.2 spec still points
LookupList2 at LookupList, which would keep per-lookup offsets at
16 bits. Record that fontTools intentionally widens those offsets to
32 bits with feedback, because the proposed shape is not suitable for
beyond-64k fonts.

Also share the LookupList merge behavior with LookupList2.

Testing: PYTHONPATH=Lib python3 -m pytest -q

Assisted-by: OpenAI Codex


Commit: 957e5ca759c52e5759fafabf73e390d83b88294f
https://github.com/fonttools/fonttools/commit/957e5ca759c52e5759fafabf73e390d83b88294f
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py

Log Message:
-----------
[ttLib] Blacken beyond64k helper

Apply Black 24.10.0 formatting to the LookupList2 conversion added in
the beyond64k helper.

Testing: git ls-files '*.py' | xargs /tmp/fonttools-black-24.10.0/bin/black --check --diff
Testing: PYTHONPATH=Lib python3 -m pytest Tests/ttLib/beyond64k_test.py Tests/feaLib/builder_test.py::BuilderTest::test_extended_layout_table_headers Tests/ttLib/tables/otData_test.py::test_extended_layout_header_fields -q

Assisted-by: OpenAI Codex


Commit: b38985ef99d4de7ea925123a95b779148eb77eab
https://github.com/fonttools/fonttools/commit/b38985ef99d4de7ea925123a95b779148eb77eab
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Drop compact cmap/post data for beyond-64k fonts

When uppering a font with more than 64k glyphs, cmap format 4 and post
format 2.0 can still fail to serialize because both carry 16-bit fields.
Drop cmap format 4 subtables after preserving their Unicode mappings in a
format 12 subtable when needed, and switch post format 2.0 to format 3.0.

This matches the existing merger behavior for post glyph names and lets
BMP-only fonts with high glyph IDs keep Unicode coverage through format 12.

Tested with:
- /Users/behdad/ft/venv/bin/python -m pytest -q Tests/ttLib/beyond64k_test.py
- black Lib/fontTools/ttLib/beyond64k.py Tests/ttLib/beyond64k_test.py
- /Users/behdad/ft/venv/bin/python -m fontmake /Users/behdad/ft/NotoSans.ufo -o otf-cff2 --keep-overlaps --no-subroutinize

Assisted-by: OpenAI Codex


Commit: 1bb290c5df6e2f625d9daa5164ee5b909d22a7cd
https://github.com/fonttools/fonttools/commit/1bb290c5df6e2f625d9daa5164ee5b909d22a7cd
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Lib/fontTools/ttLib/tables/_c_m_a_p.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Convert UVS cmap for beyond-64k fonts

Add cmap format 15 support as the 24-bit non-default UVS variant of
format 14. Uppering now converts format 14 UVS subtables only when a
non-default mapping references a glyph ID above 65535.

Lowering converts format 15 back to format 14 when all referenced glyph
IDs fit, and rejects the conversion otherwise.

Tested with:
- /Users/behdad/ft/venv/bin/python -m pytest -q Tests/ttLib/beyond64k_test.py
- /Users/behdad/ft/venv/bin/python -m pytest -q Tests/ttLib/tables/_c_m_a_p_test.py

Assisted-by: OpenAI Codex


Commit: 336680e2132e90b9436c5a38ae0cd16535bf41d9
https://github.com/fonttools/fonttools/commit/336680e2132e90b9436c5a38ae0cd16535bf41d9
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Do not force compact layout subtables to extended

Keep upper_tables focused on table-family and structurally required layout
conversions. Coverage, ClassDef, and other auto-selected layout subtables now
remain compact unless their own compiler logic needs an extended format for the
data being serialized.

Tested with:
- /Users/behdad/ft/venv/bin/python -m pytest -q Tests/ttLib/beyond64k_test.py
- /opt/homebrew/bin/black Lib/fontTools/ttLib/beyond64k.py Tests/ttLib/beyond64k_test.py

Assisted-by: OpenAI Codex


Commit: 6ac58d592ce44ae6b90c883fab3df5ad9339fac3
https://github.com/fonttools/fonttools/commit/6ac58d592ce44ae6b90c883fab3df5ad9339fac3
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otTables.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[ttLib] Remove forced extended layout format hook

Drop the private _forceExtended override for auto-selected layout formats.
Coverage, ClassDef, and substitution subtables now choose compact or extended
formats only from their data and the font's glyph ID range.

Tested with:
- /Users/behdad/ft/venv/bin/python -m pytest -q Tests/ttLib/beyond64k_test.py Tests/ttLib/tables/_c_m_a_p_test.py
- /opt/homebrew/bin/black Lib/fontTools/ttLib/tables/otTables.py Tests/ttLib/beyond64k_test.py

Assisted-by: OpenAI Codex


Commit: 1ac902fd0d5a73bb34b6946dd7b74599c7abd874
https://github.com/fonttools/fonttools/commit/1ac902fd0d5a73bb34b6946dd7b74599c7abd874
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/_h_e_a_d.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[head] Add MAXP/LOCA to head dependencies

The uppercase MAXP/LOCA companions sort last in the save order, so a beyond-64k
font with long loca would write head before LOCA and freeze a stale
indexToLocFormat, corrupting the saved loca offsets. List the companions as head
dependencies so head is written after them, matching post which already depends
on both maxp and MAXP.


Commit: 989679ed0a094859d589a25077fded8c3a321647
https://github.com/fonttools/fonttools/commit/989679ed0a094859d589a25077fded8c3a321647
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/tables/otData.py
M Lib/fontTools/ttLib/tables/otTables.py
M Lib/fontTools/varLib/__init__.py
M Tests/ttLib/tables/otTables_test.py
M Tests/varLib/builder_test.py

Log Message:
-----------
[varLib] Support beyond-64k glyphs in HVAR/VVAR

varLib.build raised struct.error building HVAR/VVAR for fonts with more than
0xFFFF glyphs, from two uint16 ceilings:

- _add_VHVAR builds a direct (no-map) advance store with one VarData item per
glyph to compare its size against the indirect store, but VarData.ItemCount is
uint16. The direct/no-map form indexes a single VarData by glyph id and so
cannot represent more than 0xFFFF glyphs; skip it past the boundary and use the
indirect store.
- the advance index map (VarIdxMap) had a fixed uint16 MappingCount. Make
VarIdxMap a subclass of the format-switching DeltaSetIndexMap so it escalates to
Format 1 (uint32 MappingCount) past 0xFFFF entries, while keeping its
glyph-name-keyed mapping. The Format is derived from the mapping size at write
time and is not stored, so Format 0 output (and its TTX) is unchanged for
existing fonts.


Commit: e2786d26a3c22bdfda1715eeb51ed4ef0ebea3bd
https://github.com/fonttools/fonttools/commit/e2786d26a3c22bdfda1715eeb51ed4ef0ebea3bd
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/varLib/__init__.py
M Lib/fontTools/varLib/merger.py

Log Message:
-----------
[varLib] Support beyond-64k extended formats in OTL merger

The OTL mergers dispatch on the format 1/2 GPOS subtable layouts, so
merging masters whose GPOS uses the beyond-64k extended layouts (PairPos/
SinglePos format 3/4, mark/cursive format 2) raised UnsupportedFormat. feaLib
promotes a master's layout to these by glyph count, so every master of a font
with more than 65535 glyphs is already extended.

Demote the extended GPOS subtables to format 1/2 before merging and promote
the merged output back afterwards, reusing the converter in ttLib.beyond64k;
only the records that embed glyph ids/counts/offsets are reclassed (Coverage and
ClassDef pick their wire format at compile time). This lives in the shared Lookup
merger, so it covers both varLib.build and the instancer's per-master OTL merge.
Contextual positioning, mark-to-ligature and GSUB go through the generic object
walker and are left as-is.

Also let _merge_OTL attach the VarStore to a beyond-64k v1.4 GDEF without
asserting v1.2 or dropping its extended fields.


Commit: da28212aafb7dfc2aee47ae6625610513f7a4c47
https://github.com/fonttools/fonttools/commit/da28212aafb7dfc2aee47ae6625610513f7a4c47
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Tests/varLib/varLib_test.py

Log Message:
-----------
[varLib] Test beyond-64k GPOS/GDEF merging

Build a beyond-64k VF through the per-master OTL fallback path: one test
round-trips the whole font and checks all five GPOS lookup types come out in the
extended formats with the high glyph id intact and the GDEF VarStore at v1.4; the
other checks PairPos coverage alignment and backfill across disjoint masters.
Interpolated values are resolved against the VarStore.


Commit: 485df1b0798ef1418952e02c0c578a83473a645e
https://github.com/fonttools/fonttools/commit/485df1b0798ef1418952e02c0c578a83473a645e
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/varLib/merger.py
M Tests/varLib/varLib_test.py

Log Message:
-----------
[varLib.merger] Merge beyond-64k v1.4 GDEF GlyphClassDef2 leniently

The lenient GDEF merger that unions per-master glyph class assignments was
keyed on the GlyphClassDef attribute only, so a beyond-64k v1.4 GDEF stores
its class def in GlyphClassDef2 and fell through to the strict generic merge,
raising ShouldBeConstant whenever masters diverged (even on non-conflicting
glyphs). Register the merger for both names so v1.4 fonts get the same union
semantics v1.2 always had.


Commit: 33738aae0fb85eb5822025ddf246084b664fef66
https://github.com/fonttools/fonttools/commit/33738aae0fb85eb5822025ddf246084b664fef66
Author: Behdad Esfahbod <beh...@behdad.org>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Tests/varLib/varLib_test.py

Log Message:
-----------
black


Commit: 5652830478ad9f1bca63323ddd74ec8c2bef48d4
https://github.com/fonttools/fonttools/commit/5652830478ad9f1bca63323ddd74ec8c2bef48d4
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/varLib/instancer/__init__.py
M Tests/varLib/instancer/instancer_test.py

Log Message:
-----------
[varLib] Support beyond-64k companion tables in instancer

The instancer addressed variation/metric tables by their lowercase tags (gvar, glyf, hmtx, hhea), so on a beyond-64k font that uses the uppercase companion tables nothing matched: GVAR was never instanced or dropped, and saving a full instance then raised KeyError('fvar') from gvar's compile reaching the deleted fvar. Resolve each tag to whichever spelling is present.

Also keep the GDEF at v1.4 when instancing fully consumes the VarStore: NULL the VarStore (it stays part of the v1.4 layout) instead of downgrading the table and dropping its extended *2 fields like GlyphClassDef2.


Commit: 4b6ebfb59eb35d844dd7ab163c2806fd8de56273
https://github.com/fonttools/fonttools/commit/4b6ebfb59eb35d844dd7ab163c2806fd8de56273
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/ttLib/beyond64k.py
M Tests/ttLib/beyond64k_test.py

Log Message:
-----------
[beyond64k] Drop post 2.0 names at 65536 glyphs, not 65537

post 2.0 numberOfGlyphs is uint16, so a glyph count of exactly 65536 already overflows it even though every glyph id still fits. _drop_beyond64k_post_glyph_names gated on > 0x10000 (i.e. >= 65537) instead of > 0xFFFF (>= 65536), leaving such a font with an unencodable post 2.0 table.


Commit: 1b728758274a0cca56e41e899fe0e197ccd9f2fc
https://github.com/fonttools/fonttools/commit/1b728758274a0cca56e41e899fe0e197ccd9f2fc
Author: Cosimo Lupo <cos...@anthrotype.com>
Date: 2026-06-18 (Thu, 18 Jun 2026)

Changed paths:
M Lib/fontTools/merge/__init__.py

Log Message:
-----------
[merge] Use upper tables at exactly 65536 glyphs

numGlyphs is uint16, so the threshold is count > 0xFFFF, not > 0x10000.


Compare: https://github.com/fonttools/fonttools/compare/fc858f5809f3...1b728758274a

To unsubscribe from these emails, change your notification settings at https://github.com/fonttools/fonttools/settings/notifications
Reply all
Reply to author
Forward
0 new messages