Skip to content

Commit

Permalink
[test-data] Add FEA-based test file generation
Browse files Browse the repository at this point in the history
This adds support in the font-test-data crate for compiling fonts using
FEA (instead of TTX) as the 'source of truth'. This is motivated by
wanting to test glyph closure, where FEA is a much more manageable and
intelligible source than TTX.
  • Loading branch information
cmyr committed Feb 8, 2024
1 parent 48c167c commit ca8eed3
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 4 deletions.
15 changes: 12 additions & 3 deletions font-test-data/test_data/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# test files

This directory contains files used for testing. The masters are the ttx files;
these are human readable/editable. From these, we generate the binary ttf
files that are the actual test inputs.
This directory contains files used for testing.

## ttx

The `ttx` directory contains ttx files describing test cases. These are compiled
and stored in the `ttf` directory; the `ttf` files are the actual test inputs.

## fea

The `fea` directory contains fea files describing test cases. Similarly to ttx,
these are compiled and stored in the `ttf` directory. Each test case is
comprised of a FEA file and a corresponding glyph list.

## extracted data
The extracted directory contains text files holding data computed by FreeType
Expand Down
43 changes: 43 additions & 0 deletions font-test-data/test_data/compile_fea.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import sys
import os

from fontTools.ttLib import TTFont

from fontTools.feaLib.builder import addOpenTypeFeatures

def makeTTFont(glyph_list_path):
glyphs = get_glyph_list(glyph_list_path)
font = TTFont()
font.setGlyphOrder(glyphs)
return font

def get_glyph_list(path):
with open(path) as f:
lines = f.read().splitlines()
return [l for l in lines if not l.startswith("#")]

def main():
try:
fea_path = sys.argv[1]
out_path = sys.argv[2]
except IndexError:
print("Usage: compile_fea.py <fea_file> <out_file>")
sys.exit(1)


if not os.path.exists(fea_path):
print("Feature file not found: " + fea_path)
sys.exit(1)
glyph_list_path = os.path.splitext(fea_path)[0] + "_glyphs.txt"
if not os.path.exists(glyph_list_path):
print("Glyph list file not found: " + glyph_list_path)
sys.exit(1)

font = makeTTFont((glyph_list_path))
addOpenTypeFeatures(font, fea_path)
# if you want to manually inspect you can dump as TTX:
# font.saveXML(out_path, tables=[ 'GDEF', 'GSUB', 'GPOS'])
font.save(out_path)

if __name__ == "__main__":
main()
23 changes: 23 additions & 0 deletions font-test-data/test_data/fea/simple_closure.fea
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
feature test {
lookup single_sub_f1 {
sub a by A;
} single_sub_f1;

lookup single_sub_f2 {
sub a by b;
# just to force format 2
sub X by Y;
} single_sub_f2;

lookup multiple_sub {
sub a by c d;
} multiple_sub;

lookup lig_sub {
sub a a by a_a;
} lig_sub;

lookup alt_sub {
sub a from [a.1 a.2];
} alt_sub;
} test;
10 changes: 10 additions & 0 deletions font-test-data/test_data/fea/simple_closure_glyphs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
a
b
c
d
A
a_a
a.1
a.2
X
Y
10 changes: 9 additions & 1 deletion font-test-data/test_data/rebuild.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
#!/usr/bin/env bash

# this script rebuilds the binary test fonts from their xml (ttx) sources
# this script rebuilds the binary test fonts from their xml (ttx) or FEA sources

set -o errexit
set -o nounset
set -o pipefail

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
SRC_DIR=$SCRIPT_DIR/ttx
FEA_DIR=$SCRIPT_DIR/fea
OUT_DIR=$SCRIPT_DIR/ttf
VENV_DIR=$SCRIPT_DIR/../../.venv
REQUIREMENTS=$SCRIPT_DIR/requirements.txt
PIP=$VENV_DIR/bin/pip
TTX=$VENV_DIR/bin/ttx
EXTRACT_GLYPHS=$SCRIPT_DIR/extract_glyphs.py
COMPILE_FEA=$SCRIPT_DIR/compile_fea.py

# check that we have python3 + virtualenv installed:
if ! python3 -m venv -h >/dev/null 2>&1; then
Expand All @@ -30,7 +32,13 @@ echo "Installing fonttools and freetype-py"
$PIP install --upgrade pip
$PIP install -r $REQUIREMENTS

# compile ttx sources
for f in $(ls $SRC_DIR/*.ttx); do
$TTX -o $OUT_DIR/$(basename "$f" .ttx).ttf --no-recalc-timestamp -b $f
$VENV_DIR/bin/python $EXTRACT_GLYPHS $OUT_DIR/$(basename "$f" .ttx).ttf
done

# compile FEA sources
for f in $(ls $FEA_DIR/*.fea); do
$VENV_DIR/bin/python $COMPILE_FEA $f $OUT_DIR/$(basename "$f" .fea).ttf
done
Binary file added font-test-data/test_data/ttf/simple_closure.ttf
Binary file not shown.

0 comments on commit ca8eed3

Please sign in to comment.