1#!/usr/bin/env python3
2
3# Pre-generates the expected output subset files (via fonttools) for
4# specified subset test suite(s).
5
6import os
7import sys
8import shutil
9import io
10import re
11import tempfile
12
13from difflib import unified_diff
14from fontTools.ttLib import TTFont
15
16from subprocess import check_call
17from subset_test_suite import SubsetTestSuite
18
19
20def usage():
21	print("Usage: generate-expected-outputs.py hb-subset <test suite file> ...")
22
23
24def strip_check_sum (ttx_string):
25	return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
26		       'checkSumAdjustment value="0x00000000"',
27		       ttx_string, count=1)
28
29
30def generate_expected_output(input_file, unicodes, profile_flags, output_directory, font_name):
31	fonttools_path = os.path.join(tempfile.mkdtemp (), font_name)
32	args = ["fonttools", "subset", input_file]
33	args.extend(["--drop-tables+=DSIG",
34		     "--drop-tables-=sbix",
35		     "--unicodes=%s" % unicodes,
36		     "--output-file=%s" % fonttools_path])
37	args.extend(profile_flags)
38	check_call(args)
39	with io.StringIO () as fp:
40		with TTFont (fonttools_path) as font:
41			font.saveXML (fp)
42		fonttools_ttx = strip_check_sum (fp.getvalue ())
43
44	harfbuzz_path = os.path.join(tempfile.mkdtemp (), font_name)
45	args = [
46		hb_subset,
47		"--font-file=" + input_file,
48		"--output-file=" + harfbuzz_path,
49		"--unicodes=%s" % unicodes,
50		"--drop-tables+=DSIG",
51		"--drop-tables-=sbix"]
52	args.extend(profile_flags)
53	check_call(args)
54	with io.StringIO () as fp:
55		with TTFont (harfbuzz_path) as font:
56			font.saveXML (fp)
57		harfbuzz_ttx = strip_check_sum (fp.getvalue ())
58
59	if harfbuzz_ttx != fonttools_ttx:
60		for line in unified_diff (fonttools_ttx.splitlines (1), harfbuzz_ttx.splitlines (1), fonttools_path, harfbuzz_path):
61			sys.stdout.write (line)
62		sys.stdout.flush ()
63		raise Exception ('ttx for fonttools and harfbuzz does not match.')
64
65	output_path = os.path.join(output_directory, font_name)
66	shutil.copy(harfbuzz_path, output_path)
67
68
69args = sys.argv[1:]
70if not args:
71	usage()
72hb_subset, args = args[0], args[1:]
73if not args:
74	usage()
75
76for path in args:
77	with open(path, mode="r", encoding="utf-8") as f:
78		test_suite = SubsetTestSuite(path, f.read())
79		output_directory = test_suite.get_output_directory()
80
81		print("Generating output files for %s" % output_directory)
82		for test in test_suite.tests():
83			unicodes = test.unicodes()
84			font_name = test.get_font_name()
85			print("Creating subset %s/%s" % (output_directory, font_name))
86			generate_expected_output(test.font_path, unicodes, test.get_profile_flags(),
87						 output_directory, font_name)
88