| #!/usr/bin/env python3 | |
| import os | |
| import sys | |
| from hb_fuzzing_tools import ( | |
| fail, | |
| format_leading_comment, | |
| main_with_user_errors, | |
| parse_output_arg, | |
| print_recorded_seed_path, | |
| write_seed_file, | |
| ) | |
| COMMAND_NAMES = ("hb-shape", "hb-raster", "hb-vector") | |
| def usage(prog: str) -> str: | |
| return f"""Usage: {prog} [-o OUTPUT_OR_DIR] HB_{'{SHAPE|RASTER|VECTOR}'}_COMMAND FONT_FILE [HB_TOOL_ARGS...] | |
| Generate a shared text/render seed using the hb-shape-style payload format: | |
| an optional leading comment line containing the exact CLI invocation, | |
| followed by the raw font bytes. | |
| This recorder does not encode text, features, or variations into the payload. | |
| Those are preserved only in the leading comment line for human recovery. | |
| Options: | |
| -o OUTPUT_OR_DIR | |
| Write the seed to this file, or into this directory using | |
| <sha1(font)>.seed. | |
| Default: test/fuzzing/fonts/<sha1(font)>.seed | |
| -h, --help Show this help. | |
| """ | |
| def find_font_file(args: list[str]) -> str: | |
| if len(args) < 2: | |
| fail("Expected at least a HarfBuzz text/render command and FONT_FILE.") | |
| command = args[0] | |
| base = os.path.basename(command) | |
| if not any(name in base for name in COMMAND_NAMES): | |
| fail(f"First argument does not look like one of {', '.join(COMMAND_NAMES)}: '{command}'.") | |
| font_file = args[1] | |
| if font_file.startswith("-"): | |
| fail("Expected FONT_FILE as the second positional argument.") | |
| return font_file | |
| def record_test_main(argv: list[str]) -> int: | |
| usage_text = usage(argv[0]) | |
| out, args = parse_output_arg(argv, usage_text) | |
| if len(args) < 2: | |
| print(usage_text, end="", file=sys.stderr) | |
| return 1 | |
| font_file = find_font_file(args) | |
| seed_path = write_seed_file( | |
| font_file, | |
| out, | |
| bytearray(), | |
| default_suffix=".seed", | |
| leading_comment=format_leading_comment(args), | |
| ) | |
| print_recorded_seed_path(seed_path) | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main_with_user_errors(record_test_main, sys.argv)) |