@overpunch/vf-clamp 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,7 +38,7 @@ A variable font is usually all-or-nothing: customers buy the whole family to get
38
38
  Why it matters:
39
39
 
40
40
  - **A new revenue tier** — two adjacent styles become a variable purchase, not just two statics. Price a ladder: two-style VF → subfamily → full family.
41
- - **Licence scope you can see** — a full VF exposes every weight, including ones the customer never paid for. A clamped VF's axes, named instances and STAT entries stop at the purchased range, so the file matches the invoice. (A determined user could still extrapolate simple two-master designs past the range; the licence's terms do the enforcing.)
41
+ - **Licence scope you can see** — a full VF exposes every weight, including ones the customer never paid for. A clamped VF's axes, named instances and STAT entries stop at the purchased range, so the file shows what was bought. It isn't protection: the remaining data can be extrapolated past the range (in our test, Inter clamped to 400–700 reproduced Black to within about 2 font units), so the licence's terms and a per-order watermark do the enforcing.
42
42
  - **Named for the purchase** — the name table (family, full name, PostScript name) is rewritten to the purchased range, so the file is identifiable as that range. It does not identify the order: the unique ID (name ID 3) is rewritten to `version;PostScriptName;family`, which depends only on the output name and is the same for every buyer of that range, so add a watermark or per-order ID at fulfilment if you need tracing.
43
43
  - **Lighter files for the web** — a site that uses only Medium–Black shouldn't ship Thin–Light deadweight. Clamping drops the variation data outside the licensed range: variation across what they bought, at a smaller download — from two styles up, smaller than the statics themselves (see below).
44
44
  - **Sell bespoke cuts** — pin an axis to a coordinate that was never a named instance (a custom optical size or width) and sell that exact cut, without shipping it in the retail family.
@@ -46,22 +46,23 @@ Why it matters:
46
46
 
47
47
  The npm package, CLI, and editor plugins all share the same axis-constraint model, so the same delivery logic runs in your build pipeline, your storefront, or a designer's font editor.
48
48
 
49
- **Real numbers** — Inter (wght 100–900) clamped to a Text weight range (400–700), same WOFF2 format so the delta is pure clamping:
49
+ **Real numbers** — Inter (wght 100–900) clamped to a Text weight range (400–700), optical size kept, same WOFF2 format so the delta is pure clamping (vf-clamp 2.3.0, 1 KB = 1,000 bytes):
50
50
 
51
51
  | Font | Source TTF | Full WOFF2 | Text-clamped WOFF2 |
52
52
  |---|---|---|---|
53
- | Inter | 843 KB | 337 KB | **243 KB** — −28% vs full WOFF2 |
53
+ | Inter | 863 KB | 346 KB | **248 KB** — −28% vs full WOFF2 |
54
54
 
55
55
  Pinning an axis outright (e.g. a fixed width or optical size) removes that axis and its variation data entirely and saves more.
56
56
 
57
- Against the static files a two-style buyer would otherwise get (Inter 4, fontTools instancer, WOFF2, October 2026 — [method](https://vfclamp.com/paper#method)):
57
+ Against the static files the customer would otherwise get, for adjacent purchases (Inter 4, opsz pinned like the statics, WOFF2, October 2026 — [method](https://vfclamp.com/paper#method)):
58
58
 
59
- | Inter, Regular + Bold | Two statics | Clamped VF (wght 400–700, opsz pinned) |
59
+ | Inter purchase | Statics | Clamped VF |
60
60
  |---|---|---|
61
- | Full character set | 226 KB | **173 KB** |
62
- | Latin subset | 64,104 B | **50,168 B** (−22%) |
61
+ | Regular + Medium | 226 KB | **163 KB** (−28%) |
62
+ | Regular to Bold (4 styles) | 456 KB | **173 KB** (−62%) |
63
+ | Latin subset, Regular + Medium | 64.0 KB | **46.9 KB** (−27%) |
63
64
 
64
- At seven styles the clamped VF is 72% smaller than the statics. Keeping a free axis such as `opsz` variable costs size: worth it from about three styles up.
65
+ At seven styles the clamped VF is 72% smaller than the statics. A non-adjacent purchase such as Regular + Bold comes back as two files from `planOutputs`, the same size as the statics, unless you choose to deliver (and price) the weights in between. Keeping a free axis such as `opsz` variable costs size.
65
66
 
66
67
  ### For type designers
67
68
 
@@ -485,7 +486,7 @@ For font engineers — the pipeline, in order, per output:
485
486
  2. **STAT** — left to the fontTools instancer, which drops axis values outside the range. STAT design axes that aren't in `fvar` (such as Inter's `ital`) are kept, because upright/italic linking needs them. (Before 2.3.0, vf-clamp also pruned those axes; that broke the linking.)
486
487
  3. **Weight normalisation** (only with `normalizeWeightAxis`) — the wght user-space range is remapped to start at 100; avar is unchanged because normalised values are preserved. This changes registered-axis semantics, so use it only when CSS `font-weight` must reach the lightest weight.
487
488
  4. **OS/2 and head** — `usWeightClass`, `fsSelection` and `macStyle` follow the new default (or the pinned weight). REGULAR is set only when the file is neither bold nor italic, and the italic bit is kept.
488
- 5. **Names** — see the name table note under [Notes](#notes).
489
+ 5. **Names, style bits and STAT links** — one shared implementation, specified in [docs/NAMING.md](docs/NAMING.md). Unnamed outputs get one range per axis in the font's own style words, e.g. `Encode Sans SemiCondensed-Normal Thin-Light`.
489
490
  6. **Encode** — WOFF or WOFF2 when requested.
490
491
 
491
492
  The engine is fontTools **4.56.0** (via [`@web-alchemy/fonttools`](https://www.npmjs.com/package/@web-alchemy/fonttools)) on **Pyodide 0.29.3** — about 15 MB on disk, none of it shipped to browsers. Fonts with avar version 2 or a VARC table are refused, because this fontTools version can't restrict them correctly. Hinting is whatever the instancer keeps; most VFs ship unhinted.