Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/heddle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
if: always()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: heddle-0.1
name: heddle-0.2
path: |
fonts/heddle/
proofs/heddle/
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ Each family keeps its own changelog:

Release tags: `weft-vX.Y.Z`, `sans-vX.Y.Z`, `heddle-vX.Y.Z`, `warp-vX.Y.Z`, `site-vX.Y.Z`.

## 2026-10-28: Heddle 0.2

- machine-made Heddle 0.2.0 (font version 0.200): Latin Extended-A,
Ș ș Ț ț, new symbols and fractions, lighter marks, open counters at
Black, masters at wdth 85, hinted statics. See `heddle/CHANGELOG.md`.
- Site: the Heddle page and the download page link
`heddle-v0.2.0`.

## 2026-10-27: Warp 0.1

- machine-made Warp 0.1.0 (font version 0.100): machine-made Warp
Expand Down
2 changes: 1 addition & 1 deletion STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
| Visibility | public after the 0.1 release (founder approved) |
| Stage | released 0.1: machine-made Weft 0.1.0, machine-made Sans 0.1.0, specimen site 0.1.0, machine-made Heddle 0.1.0. machine-made Warp 0.1 built on branch `warp/v0.1` |
| Gate now | Warp: Jac reviews the PR from `warp/v0.1`; the founder reviews the proofs; then the tags `warp-v0.1.0` and a new `site-v*` |
| Next task | Warp 0.2: the OpenType MATH table; Warp 0.3: the variable font (see `warp/STATUS.md`). Heddle 0.2 (see `heddle/STATUS.md`). Weft: polish (look-alikes l/1, I/1, O/0; heavy accented capitals), width axis, Thread style. Sans 0.2: redraw in the style of Weft and match Weft's x-height (see `sans/STATUS.md`). npm packages for both families. |
| Next task | Warp 0.2: the OpenType MATH table; Warp 0.3: the variable font (see `warp/STATUS.md`). Heddle 0.2 built on branch `heddle/v0.2`, in review (see `heddle/STATUS.md`). Weft: polish (look-alikes l/1, I/1, O/0; heavy accented capitals), width axis, Thread style. Sans 0.2: redraw in the style of Weft and match Weft's x-height (see `sans/STATUS.md`). npm packages for both families. |
| Blocked by | none |
| Last green CI | none yet (first runs are on the release PR). Local end-to-end run of all steps on 2026-10-26: green |
| Owner model | to assign |
Expand Down
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-Black.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-Bold.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-CompressedBold.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-ExtendedBold.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-ExtraBold.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-ExtraLight.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-Light.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-Medium.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-Regular.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-SemiBold.ttf
Binary file not shown.
Binary file modified fonts/heddle/ttf/MachineMadeHeddle-Thin.ttf
Binary file not shown.
Binary file modified fonts/heddle/variable/MachineMadeHeddle[wdth,wght].ttf
Binary file not shown.
Binary file modified fonts/heddle/webfonts/MachineMadeHeddle-Bold.woff2
Binary file not shown.
Binary file modified fonts/heddle/webfonts/MachineMadeHeddle-Regular.woff2
Binary file not shown.
Binary file modified fonts/heddle/webfonts/MachineMadeHeddle[wdth,wght].woff2
Binary file not shown.
82 changes: 80 additions & 2 deletions heddle/BRIEF.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,36 @@ Heddle exist, none in the font market.
| Software named heddle: an AI-native version control CLI (MacPorts port `heddle`), and `heddle-mcp` on PyPI. | [ports.macports.org/port/heddle](https://ports.macports.org/port/heddle/), [socket.dev/pypi/package/heddle-mcp](https://socket.dev/pypi/package/heddle-mcp) | Low for a typeface. Not in the font market. |
| Trademarks (web): Steel Heddle Manufacturing Company holds marks for loom parts (textile machinery). No "HEDDLE" mark for fonts or typefaces found. | [trademark.justia.com/owners/steel-heddle-manufacturing-company-239051](https://trademark.justia.com/owners/steel-heddle-manufacturing-company-239051), [gleanmark.com/search?q=HEDDLE](https://gleanmark.com/search?q=HEDDLE) | Low. Weaving equipment, not type. The pages did not load in full; not a register search. |

## Register search: "HEDDLE" (2026-10-28, for 0.2)

Result: **no HEDDLE mark for fonts, typefaces or software found** in
what the web search reached. The two marks found are for loom parts and
for textile decor. The family name stays "machine-made Heddle"; this
search does not rename it.

| Register | Finding | Link | Risk |
| --- | --- | --- | --- |
| USPTO (via Justia, a mirror of USPTO data) | HEDDLE & CO., serial 98277502, filed 2023-11-20 by Linger in the Gap, for household decor and garden ornaments made of textiles. Status not shown on the page. | [trademarks.justia.com/owners/linger-in-the-gap-5709250](https://trademarks.justia.com/owners/linger-in-the-gap-5709250) | Low. Other goods (textiles, decor), not class 9, 16 or 42. |
| USPTO (via Justia) | STEEL HEDDLE (Steel Heddle Manufacturing Company), serials 76330022 and 75982481: loom parts. | [trademark.justia.com/763/30/steel-76330022.html](https://trademark.justia.com/763/30/steel-76330022.html), [trademarks.justia.com/759/82/steel-75982481.html](https://trademarks.justia.com/759/82/steel-75982481.html) | Low. Textile machinery. |
| USPTO (web search) | Other "heddle" hits are patents for loom heddles (US 7185679, 7017620, 5152325 and more), not marks. A near name, HEDDON (reg. 0507613, fishing tackle, class 16 in the old system), is a different word. | [trademarkregistration.app/Trademark/Details/71534141](https://trademarkregistration.app/Trademark/Details/71534141) | None. |
| EUIPO (web search) | No EU trade mark HEDDLE found. The hits are European patents for loom heddles (EP 1989346, EP 2422004 and others). | [data.epo.org/gpi/EP1989346B1](https://data.epo.org/gpi/EP1989346B1) | Low. |
| Swissreg (web search) | No Swiss mark HEDDLE found. Hits are Swiss patents for heddles ("Weblitze", CH 468489, CH 423661). | [patents.google.com/patent/CH468489A](https://patents.google.com/patent/CH468489A/en) | Low. |
| Font-name aggregator (GleanMark) | The search page for HEDDLE loaded without results in the text the tool could read. | [gleanmark.com/search?q=HEDDLE](https://gleanmark.com/search?q=HEDDLE) | Unknown; see limits. |

Limits of the register search:

* The register sites themselves (tmsearch.uspto.gov, euipo.europa.eu
eSearch, swissreg.ch, branddb.wipo.int) were not reachable from the
build machine (the network proxy refused the connection). The search
used WebSearch and pages that mirror register data (Justia). It is
not a clearance search.
* Web search finds marks with web pages; a pending or little-known
mark can be missing. Before a commercial use of "Heddle" alone, a
person should search the registers directly for HEDDLE in classes 9,
16 and 42.
* The shipped name is "machine-made Heddle", and the OFL Reserved Font
Name is "machine-made".

Limits of this check:

* A web search, not a trademark clearance. Before a public release, do
Expand Down Expand Up @@ -63,7 +93,7 @@ Limits of this check:
| Typo / hhea ascender | 950 |
| Typo / hhea descender | -250 |
| Line gap | 0 (line height 1200) |
| win ascent / descent | from the bounds of all masters (1051 / 295) |
| win ascent / descent | from the bounds of all masters (0.2: 950 / 296; 0.1: 1051 / 295) |
| Underline position / thickness | -120 / 71 |

Stroke rules (from the sketch engine):
Expand Down Expand Up @@ -119,6 +149,54 @@ so a cut always ends in a horizontal (or vertical) terminal. When a
counter closes (heavy weights, small hooks), the inner contour shrinks
to a point at the centre, as the sketch drew no counter there.

## 0.2 changes to the rules

* Masters: 16, at wght 100, 400, 700, 900 x wdth 70, 85, 100, 140. The
wdth 85 masters cut the drift from the width floor near wdth 85.
* Tabular figure width: the sketch value at every master width (0.8 at
70, 0.85 at 85, 1 at 100, 1.25 at 140), linear between them.
* Minimum counter rule (`geom.counter_min`): a ring keeps an inner
radius of at least 0.25 S, at most 38 units (clamped per weight). The
ring gets thinner to keep it, never below 45 % of its stroke. Bowls
with bars (`bowl_d`) give the bars the same strokes.
* Hooks (`glyphs.hook_span`: f, t, j, ſ, ŋ, Ŋ, £): the visible counter
between stem and terminal is at least two minimum radii. The hook
ring gets wider (j reaches left of its box at heavy weights), then the
terminal gets thinner. Nothing changes at Regular.
* Marks: stroke `0.62 S + 12`, height `140 + 0.2 S` (lowercase) and
0.72 of that (capitals), gap `40 + 0.22 S` and `30 + 0.16 S`.
Capital marks stay below the typo ascender (950). ".narrow" marks on
dotless i, I, l and dotless j are at most `S + 1.45 sidebearings`
wide, so ï Ï Ĩ ĺ keep the advance of their base.
* Static outlines: union with skia-pathops, round to integers, drop
degenerate segments, split self-touching contours into loops, wind
each loop by its nesting depth, then check against the nonzero fill
of the primitives and check that no overlap is left. No fallbacks.
* Hinting: static TTF with ttfautohint 1.8.4 (ttfautohint-py 0.6.1),
no version string, head dates kept, so the build stays
byte-reproducible. The variable font is not hinted.

## Glyph set (0.2)

398 glyphs, 338 code points (336 visible characters, space, no-break
space). 0.2 adds to the 0.1 set:

| Set | Characters |
| --- | --- |
| Latin Extended-A | all of U+0100 to U+017F, as components where Unicode decomposes (ogonek, caron, breve, macron, dot above, double acute, comma below, cedilla); drawn: Đ đ (Đ shares the glyph of Ð), Ħ ħ, Ŧ ŧ, Ł ł, ĸ, Ŋ ŋ, ſ; rows of glyphs: IJ ij ʼn; middle dot: Ŀ ŀ |
| Romanian | Ș ș Ț ț (comma below) |
| Base | ȷ (dotless j, for ĵ) |
| Symbols | `¢ £ ¥ § ¶ ± × ÷ −`, fraction slash `⁄`, `½ ¼ ¾` |
| Spacing marks | `¨ ¯ ´ ¸ ˆ ˇ ˘ ˙ ˚ ˛ ˜ ˝` |
| Unencoded | numerators and denominators (`zero.numr` ... `nine.dnom`), marks: macron, breve, dot above, caron, double acute, ogonek, comma below, turned comma above (ģ), vertical caron (ď ľ ť Ľ), and .narrow forms |

Features: `frac` (figures before a slash become numerators, after it
denominators; the slash becomes the fraction slash), `numr`, `dnom`,
`kern`.

Comma below, not cedilla, for Ģ Ķ ķ Ļ ļ Ņ ņ Ŗ ŗ (Latvian); ģ has a
turned comma above. Ş ş Ţ ţ keep the cedilla (Turkish; Unicode).

## Glyph set (0.1)

197 glyphs, 184 code points (182 visible characters, space, no-break
Expand Down Expand Up @@ -156,7 +234,7 @@ weight.
| Step | Scope | Gate |
| --- | --- | --- |
| 1 | Port the engine to `loom/` (Python). Analytic cut rings, fixed topology. | Same advances as the sketch engine at every master (test with node). |
| 2 | 12 masters: wght 100, 400, 700, 900 x wdth 70, 100, 140. Variable TTF with overlaps (overlap flags set). | `varLib.interpolatable` clean; drift report. |
| 2 | 12 masters (0.2: 16, with wdth 85): wght 100, 400, 700, 900 x wdth 70, 100, 140. Variable TTF with overlaps (overlap flags set). | `varLib.interpolatable` clean; drift report. |
| 3 | Statics from the masters (same interpolation), overlaps removed with skia-pathops, every union checked against a nonzero fill. | Fontspector universal: no FAIL. |
| 4 | Rest of ASCII, Latin-1 letters, marks, symbols, kerning. | Glyph and kerning tests. |
| 5 | Proofs, CI, release job, site page. | **Founder reviews the proofs by eye.** |
Expand Down
37 changes: 37 additions & 0 deletions heddle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
# Heddle changelog

## 0.200 (Heddle 0.2)

### Added

- Latin Extended-A (U+0100 to U+017F) and Ș ș Ț ț. Accented letters
are components; Đ đ Ħ ħ Ŧ ŧ Ł ł ĸ Ŋ ŋ ſ and the dotless j are drawn.
New marks: macron, breve, dot above, caron, double acute, ogonek,
comma below, turned comma above, vertical caron.
- `¢ £ ¥ § ¶ ± × ÷ −`, the fraction slash, `½ ¼ ¾`, numerators and
denominators, and the spacing marks `¨ ¯ ´ ¸ ˆ ˇ ˘ ˙ ˚ ˛ ˜ ˝`.
398 glyphs, 338 code points.
- Features `frac`, `numr` and `dnom`.
- Kerning for lowercase pairs and for figures against punctuation.
- Masters at wdth 85: 16 masters.
- Hinting: the static TTF are hinted with ttfautohint 1.8.4
(ttfautohint-py 0.6.1, pinned).
- `tools/readability.py`: an OCR check against 0.1 and DejaVu Sans.
- Proofs: `heddle-latin-ext.png`, `heddle-symbols.png` and before/after
sheets for the marks, the counters and the drift.

### Changed

- Marks are lighter and smaller. Narrow bases (ı I l ȷ) get narrow
marks, so ï Ï Ĩ ĺ keep the advance of their base. Capital marks stay
below the typo ascender; win ascent is now 950 (was 1051).
- Minimum counter rule: rings keep an open counter at Black (inner
radius at least 0.25 S, at most 38 units). The hooks of f, t, j (and
ſ ŋ Ŋ £) get wider at heavy weights so their counters stay open.
- ß, ð, @, ©, ®, % redrawn with the counter rule (© ® with lighter
inner letters; ð's ascender starts inside the bowl).
- Tabular figures at wdth 85 are 0.85 of their width (the sketch
value); 0.1 gave 0.9.
- Overlap removal for the statics: union, snap to integers, split
self-touching contours, wind by nesting depth, check. The fallbacks
of 0.1 (jitter, unsimplified rounded paths) are gone.
- The kerning test checks every member of every class.

## 0.100 (Heddle 0.1)

Sketched and first built as "Shuttle"; renamed to Heddle before the
Expand Down
34 changes: 34 additions & 0 deletions heddle/RELEASE-NOTES-0.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# machine-made Heddle 0.2

Heddle is a Swiss display grotesk built from four parts (rect, ring,
slant, vee) with a weight axis (100 to 900) and a width axis (70 to
140). Version 0.2 adds Central European languages and fixes the
heavy weights.

## New

- Latin Extended-A and Ș ș Ț ț: Polish, Czech, Slovak, Hungarian,
Romanian, Turkish, Croatian, Slovenian, Latvian, Lithuanian,
Estonian, Maltese and more.
- `¢ £ ¥ § ¶ ± × ÷ −`, `½ ¼ ¾`, and the `frac` feature for any
fraction (type 3/16 and turn on `frac`).
- Kerning for lowercase pairs and for figures before a period.
- Hinted static fonts (ttfautohint).

## Better

- Marks are lighter and smaller. ï and Ï no longer get wider at Black.
- Small rings and the hooks of a, f, j, s and t stay open at Black.
- ß, ð, @, ©, ® and % are redrawn.
- The variable font follows the generator more closely near width 85
(four more masters).

## Files

- `MachineMadeHeddle[wdth,wght].ttf`: the variable font.
- 11 static TTF: Thin to Black at Normal width, Compressed Bold,
Extended Bold.
- WOFF2: the variable font, Regular and Bold.

Free under the SIL Open Font License 1.1, Reserved Font Name
"machine-made".
Loading