File size: 6,516 Bytes
2a7ba35
 
 
 
 
 
 
483b03e
 
ba5f2cf
483b03e
 
 
 
2a7ba35
483b03e
 
 
2a7ba35
 
 
 
 
 
 
 
 
 
 
 
483b03e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
> **Published copy.** This file is the release copy of `data/FONTS.md` from
> [https://github.com/naeyn/de-htr-web](https://github.com/naeyn/de-htr-web). Paths to files that ship in this release have been rewritten to
> their locations here (`training-data/…`). Any other repository-relative path —
> `src/…`, `scripts/…`, `DECISIONS.md`, the raw corpora, the font `.ttf` files, and
> `data/german_wikipedia_lines.txt` — refers to the source repository, which is the
> only place those files exist.

# Handwriting fonts for synthetic training data

These fonts are used to render German text for **synthetic training data** (Tier 3). Every font listed below was **individually verified** for:

1. **License** — SIL Open Font License 1.1 only (sourced from the Google Fonts `ofl/` tree). Personal-use-only fonts are categorically rejected.
2. **German charset** — cmap coverage of Ä Ö Ü ä ö ü ß (`U+00C4 U+00D6 U+00DC U+00E4 U+00F6 U+00FC U+00DF`) via `fontTools.ttLib.TTFont.getBestCmap()`.

TTF files live in `data/fonts/`. Matching license texts live in `training-data/font-licenses/`.

| Font | File | Source URL | License | License file | German glyphs verified (method: fontTools cmap check) | Access date |
|------|------|------------|---------|--------------|------------------------------------------------------|-------------|
| Caveat | `Caveat[wght].ttf` | https://github.com/google/fonts/raw/main/ofl/caveat/Caveat%5Bwght%5D.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Caveat_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Kalam | `Kalam-Regular.ttf` | https://github.com/google/fonts/raw/main/ofl/kalam/Kalam-Regular.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Kalam_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Patrick Hand | `PatrickHand-Regular.ttf` | https://github.com/google/fonts/raw/main/ofl/patrickhand/PatrickHand-Regular.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Patrick_Hand_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Shadows Into Light | `ShadowsIntoLight.ttf` | https://github.com/google/fonts/raw/main/ofl/shadowsintolight/ShadowsIntoLight.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Shadows_Into_Light_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Shadows Into Light Two | `ShadowsIntoLightTwo-Regular.ttf` | https://github.com/google/fonts/raw/main/ofl/shadowsintolighttwo/ShadowsIntoLightTwo-Regular.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Shadows_Into_Light_Two_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Indie Flower | `IndieFlower-Regular.ttf` | https://github.com/google/fonts/raw/main/ofl/indieflower/IndieFlower-Regular.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Indie_Flower_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Architects Daughter | `ArchitectsDaughter-Regular.ttf` | https://github.com/google/fonts/raw/main/ofl/architectsdaughter/ArchitectsDaughter-Regular.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Architects_Daughter_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Reenie Beanie | `ReenieBeanie.ttf` | https://github.com/google/fonts/raw/main/ofl/reeniebeanie/ReenieBeanie.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Reenie_Beanie_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Gloria Hallelujah | `GloriaHallelujah.ttf` | https://github.com/google/fonts/raw/main/ofl/gloriahallelujah/GloriaHallelujah.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Gloria_Hallelujah_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| La Belle Aurore | `LaBelleAurore.ttf` | https://github.com/google/fonts/raw/main/ofl/labelleaurore/LaBelleAurore.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/La_Belle_Aurore_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Waiting for the Sunrise | `WaitingfortheSunrise.ttf` | https://github.com/google/fonts/raw/main/ofl/waitingforthesunrise/WaitingfortheSunrise.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Waiting_for_the_Sunrise_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |
| Covered By Your Grace | `CoveredByYourGrace.ttf` | https://github.com/google/fonts/raw/main/ofl/coveredbyyourgrace/CoveredByYourGrace.ttf | SIL Open Font License 1.1 | `training-data/font-licenses/Covered_By_Your_Grace_OFL.txt` | PASS (Ä Ö Ü ä ö ü ß) | 2026-07-28 |

## Verification

Command (run from repo root on 2026-07-28):

```bash
uv run --with fonttools python -c '
from fontTools.ttLib import TTFont
from pathlib import Path

REQUIRED = {
    0x00C4: "Ä",
    0x00D6: "Ö",
    0x00DC: "Ü",
    0x00E4: "ä",
    0x00F6: "ö",
    0x00FC: "ü",
    0x00DF: "ß",
}

order = [
    "Caveat[wght].ttf",
    "Kalam-Regular.ttf",
    "PatrickHand-Regular.ttf",
    "ShadowsIntoLight.ttf",
    "ShadowsIntoLightTwo-Regular.ttf",
    "IndieFlower-Regular.ttf",
    "ArchitectsDaughter-Regular.ttf",
    "ReenieBeanie.ttf",
    "GloriaHallelujah.ttf",
    "LaBelleAurore.ttf",
    "WaitingfortheSunrise.ttf",
    "CoveredByYourGrace.ttf",
]

for name in order:
    path = Path("data/fonts") / name
    font = TTFont(path)
    cmap = font.getBestCmap() or {}
    cps = set(cmap.keys())
    missing = [f"U+{cp:04X} ({ch})" for cp, ch in REQUIRED.items() if cp not in cps]
    status = "PASS" if not missing else "FAIL"
    miss = ", ".join(missing) if missing else "(none)"
    print(f"{status}\t{path.name}\tmissing={miss}")
'
```

Output:

```
PASS	Caveat[wght].ttf	missing=(none)
PASS	Kalam-Regular.ttf	missing=(none)
PASS	PatrickHand-Regular.ttf	missing=(none)
PASS	ShadowsIntoLight.ttf	missing=(none)
PASS	ShadowsIntoLightTwo-Regular.ttf	missing=(none)
PASS	IndieFlower-Regular.ttf	missing=(none)
PASS	ArchitectsDaughter-Regular.ttf	missing=(none)
PASS	ReenieBeanie.ttf	missing=(none)
PASS	GloriaHallelujah.ttf	missing=(none)
PASS	LaBelleAurore.ttf	missing=(none)
PASS	WaitingfortheSunrise.ttf	missing=(none)
PASS	CoveredByYourGrace.ttf	missing=(none)
```

## Rejected candidates

| Candidate | Reason |
|-----------|--------|
| Homemade Apple | Not SIL OFL 1.1 — lives under `apache/homemadeapple` in google/fonts (Apache 2.0) |
| Rock Salt | Not SIL OFL 1.1 — lives under `apache/rocksalt` in google/fonts (Apache 2.0) |

Additional OFL handwriting candidates that also PASSed the German cmap check but were not needed after the first 12 accepted fonts: Neucha, Bad Script, Marck Script, Sue Ellen Francisco.