pax_global_header00006660000000000000000000000064141042550220014505gustar00rootroot0000000000000052 comment=47fb3f2187bc26477482fb9d121674feb74ee4a7 fontmake-2.4.1/000077500000000000000000000000001410425502200133155ustar00rootroot00000000000000fontmake-2.4.1/.codecov.yml000066400000000000000000000001151410425502200155350ustar00rootroot00000000000000comment: false coverage: status: project: off patch: off fontmake-2.4.1/.coveragerc000066400000000000000000000014301410425502200154340ustar00rootroot00000000000000[run] # measure 'branch' coverage in addition to 'statement' coverage # See: http://coverage.readthedocs.org/en/coverage-4.0.3/branch.html#branch branch = True omit = tests/* # list of directories or packages to measure source = fontmake # these are treated as equivalent when combining data [paths] source = Lib/fontmake */site-packages/fontmake [report] # Regexes for lines to exclude from consideration exclude_lines = # keywords to use in inline comments to skip coverage pragma: no cover # don't complain if tests don't hit defensive assertion code raise AssertionError raise NotImplementedError # don't complain if non-runnable code isn't run if 0: if __name__ == .__main__.: # ignore source code that can’t be found ignore_errors = True fontmake-2.4.1/.editorconfig000066400000000000000000000003431410425502200157720ustar00rootroot00000000000000# http://editorconfig.org root = true [*] indent_style = space indent_size = 4 trim_trailing_whitespace = true insert_final_newline = true charset = utf-8 end_of_line = lf [*.{yaml,yml}] indent_style = space indent_size = 2 fontmake-2.4.1/.gitattributes000066400000000000000000000005021410425502200162050ustar00rootroot00000000000000# Set the default behavior, in case people don't have core.autocrlf set. * text=auto # Explicitly declare text files you want to always be normalized and converted # to native line endings on checkout. *.cfg text *.in text *.ini text *.md text *.py text *.rst text *.sh text *.toml text *.txt text *.yaml text *.yml text fontmake-2.4.1/.github/000077500000000000000000000000001410425502200146555ustar00rootroot00000000000000fontmake-2.4.1/.github/workflows/000077500000000000000000000000001410425502200167125ustar00rootroot00000000000000fontmake-2.4.1/.github/workflows/ci.yml000066400000000000000000000101021410425502200200220ustar00rootroot00000000000000name: Test + Deploy on: push: branches: [main] tags: ["v*.*.*"] pull_request: branches: [main] jobs: lint: runs-on: ubuntu-latest # https://github.community/t/github-actions-does-not-respect-skip-ci/17325/8 if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')" steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.x" - name: Install dependencies run: pip install tox - name: Run style and static checks run: tox -e lint test: runs-on: ${{ matrix.platform }} if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')" strategy: matrix: python-version: [3.6, 3.7, 3.8, 3.9, "pypy-3.7"] platform: [ubuntu-latest, windows-latest] exclude: - platform: windows-latest python-version: "pypy-3.7" steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: pip install tox - name: Test with tox run: tox -e py - name: Produce coverage files run: tox -e coverage-report - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 with: file: coverage.xml flags: unittests name: codecov-umbrella fail_ci_if_error: true deploy: # only run if the commit is tagged... if: startsWith(github.ref, 'refs/tags/v') # ... and both the lint and test jobs completed successfully needs: - lint - test runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: # setuptools_scm requires the git clone to not be 'shallow' fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v2 with: python-version: "3.x" - name: Install dependencies run: | python -m pip install --upgrade pip pip install setuptools wheel twine - name: Extract release notes from annotated tag message id: release_notes env: # e.g. v0.1.0a1, v1.2.0b2 or v2.3.0rc3, but not v1.0.0 PRERELEASE_TAG_PATTERN: "v[[:digit:]]+\\.[[:digit:]]+\\.[[:digit:]]+([ab]|rc)[[:digit:]]+" run: | # GH checkout action doesn't preserve tag annotations, we must fetch them # https://github.com/actions/checkout/issues/290 git fetch --tags --force # strip leading 'refs/tags/' to get the tag name TAG_NAME="${GITHUB_REF##*/}" # Dump tag message to temporary .md file (excluding the PGP signature at the bottom) TAG_MESSAGE=$(git tag -l --format='%(contents)' $TAG_NAME | sed -n '/-----BEGIN PGP SIGNATURE-----/q;p') echo "$TAG_MESSAGE" > "${{ runner.temp }}/release_notes.md" # if the tag has a pre-release suffix mark the Github Release accordingly if egrep -q "$PRERELEASE_TAG_PATTERN" <<< "$TAG_NAME"; then echo "Tag contains a pre-release suffix" echo "IS_PRERELEASE=true" >> "$GITHUB_ENV" else echo "Tag does not contain pre-release suffix" echo "IS_PRERELEASE=false" >> "$GITHUB_ENV" fi - name: Create GitHub release id: create_release uses: actions/create-release@v1 env: # This token is provided by Actions, you do not need to create your own token GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: ${{ github.ref }} body_path: "${{ runner.temp }}/release_notes.md" draft: false prerelease: ${{ env.IS_PRERELEASE }} - name: Build and publish env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | if [ "$IS_PRERELEASE" == true ]; then echo "DEBUG: This is a pre-release" else echo "DEBUG: This is a final release" fi python setup.py sdist bdist_wheel twine upload dist/* fontmake-2.4.1/.gitignore000066400000000000000000000026311410425502200153070ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # Visual Studio Code .vscode # auto-generated version file Lib/fontmake/_version.py fontmake-2.4.1/.pyup.yml000066400000000000000000000002501410425502200151100ustar00rootroot00000000000000# controls the frequency of updates (undocumented beta feature) schedule: every week # do not pin dependencies unless they have explicit version specifiers pin: False fontmake-2.4.1/CONTRIBUTING.md000066400000000000000000000026521410425502200155530ustar00rootroot00000000000000Want to contribute? Great! First, read this page (including the small print at the end). ### Before you contribute Before we can use your code, you must sign the [Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) (CLA), which you can do online. The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code. We also need to be sure of various other things—for instance that you'll tell us if you know that your code infringes on other people's patents. You don't have to sign the CLA until after you've submitted your code for review and a member has approved it, but you must do it before we can put your code into our codebase. Before you start working on a larger contribution, you should get in touch with us first through the issue tracker with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on. ### Code reviews All submissions, including submissions by project members, require review. We use Github pull requests for this purpose. ### The small print Contributions made by corporations are covered by a different agreement than the one above, the [Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate). fontmake-2.4.1/LICENSE000066400000000000000000000261351410425502200143310ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. fontmake-2.4.1/Lib/000077500000000000000000000000001410425502200140235ustar00rootroot00000000000000fontmake-2.4.1/Lib/fontmake/000077500000000000000000000000001410425502200156275ustar00rootroot00000000000000fontmake-2.4.1/Lib/fontmake/__init__.py000066400000000000000000000001541410425502200177400ustar00rootroot00000000000000try: from ._version import version as __version__ except ImportError: __version__ = "0.0.0+unknown" fontmake-2.4.1/Lib/fontmake/__main__.py000066400000000000000000000436551410425502200177360ustar00rootroot00000000000000# Copyright 2015 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import logging import sys from argparse import ArgumentParser, FileType from contextlib import contextmanager from ufo2ft import CFFOptimization from ufo2ft.featureWriters import loadFeatureWriterFromString from ufo2ft.filters import loadFilterFromString from fontmake import __version__ from fontmake.errors import FontmakeError from fontmake.font_project import INTERPOLATABLE_OUTPUTS, FontProject def _loadPlugins(parser, specs, from_string_func, parser_error_message): plugins = [] for s in specs: if s == "None": # magic value that means "don't write any features or don't apply # any filters!" return [] try: plugins.append(from_string_func(s)) except Exception as e: parser.error(parser_error_message.format(type(e).__name__, e)) return plugins def _loadFeatureWriters(parser, specs): return _loadPlugins( parser, specs, loadFeatureWriterFromString, "Failed to load --feature-writer:\n {}: {}", ) def _loadFilters(parser, specs): return _loadPlugins( parser, specs, loadFilterFromString, "Failed to load --filter:\n {}: {}" ) def exclude_args(parser, args, excluded_args, target, positive=True): """Delete options that are not appropriate for a following code path; exit with an error if excluded options were passed in by the user. argparse generates a namespace with all options it knows, but not every attribute should be passed to all code paths (i.e. options about interpolation should not reach `run_from_ufos()`). This function can be run before entering a particular code path to clean up the kwargs passed to it. Exit with an error message if the user actually passed the options in. """ msg = '"%s" option invalid for %s' for argname in excluded_args: if argname not in args: continue if bool(args[argname]) is positive: optname = "--{}{}".format( "" if positive else "no-", argname.replace("_", "-") ) parser.error(msg % (optname, target)) del args[argname] @contextmanager def _make_tempdirs(parser, args): output = args["output"] tempdirs = [] for dirname in ("master_dir", "instance_dir"): if args.get(dirname) == "{tmp}": if "ufo" in output: parser.error( "Can't use temporary %s directory with 'ufo' output" % dirname.replace("_dir", "") ) import tempfile td = args[dirname] = tempfile.mkdtemp(prefix=dirname + "_") tempdirs.append(td) yield tempdirs if tempdirs: import shutil for td in tempdirs: shutil.rmtree(td) def main(args=None): parser = ArgumentParser() parser.add_argument("--version", action="version", version=__version__) inputGroup = parser.add_argument_group( title="Input arguments", description="The following arguments are mutually exclusive (pick only one):", ) xInputGroup = inputGroup.add_mutually_exclusive_group(required=True) xInputGroup.add_argument( "-g", "--glyphs-path", metavar="GLYPHS", help="Path to .glyphs source file" ) xInputGroup.add_argument( "-u", "--ufo-paths", nargs="+", metavar="UFO", help="One or more paths to UFO files", ) xInputGroup.add_argument( "-m", "--mm-designspace", metavar="DESIGNSPACE", help="Path to .designspace file", ) outputGroup = parser.add_argument_group(title="Output arguments") outputGroup.add_argument( "-o", "--output", nargs="+", default=("otf", "ttf"), metavar="FORMAT", help="Output font formats. Choose 1 or more from: %(choices)s. Default: otf, ttf. " "(No file paths).", choices=( "ufo", "otf", "otf-cff2", "ttf", "ttf-interpolatable", "otf-interpolatable", "variable", "variable-cff2", ), ) outputSubGroup = outputGroup.add_mutually_exclusive_group() outputSubGroup.add_argument( "--output-path", default=None, help="Output font file path. Only valid when the output is a single " "file (e.g. input is a single UFO or output is variable font)", ) outputSubGroup.add_argument( "--output-dir", default=None, help="Output folder. By default, output folders are created in the " "current working directory, grouping output fonts by format.", ) outputGroup.add_argument( "-i", "--interpolate", nargs="?", default=False, const=True, metavar="INSTANCE_NAME", help="Interpolate masters and generate all the instances defined. " "To only interpolate a specific instance (or instances) that " 'match a given "name" attribute, you can pass as argument ' "the full instance name or a regular expression. " 'E.g.: -i "Noto Sans Bold"; or -i ".* UI Condensed". ' "(for Glyphs or MutatorMath sources only). ", ) outputGroup.add_argument( "--use-mutatormath", action="store_true", help=( "Use MutatorMath to generate instances (supports extrapolation and " "anisotropic locations)." ), ) outputGroup.add_argument( "-M", "--masters-as-instances", action="store_true", help="Output masters as instances", ) outputGroup.add_argument( "--family-name", help="Family name to use for masters, and to filter output instances", ) outputGroup.add_argument( "--round-instances", dest="round_instances", action="store_true", help="Apply integer rounding to all geometry when interpolating", ) outputGroup.add_argument( "--designspace-path", default=None, help="Path to output designspace file (for Glyphs sources only).", ) outputGroup.add_argument( "--master-dir", default=None, help='Directory where to write master UFO. Default: "./master_ufo". ' 'If value is "{tmp}", a temporary directory is created and ' "removed at the end (for Glyphs sources only).", ) outputGroup.add_argument( "--instance-dir", default=None, help="Directory where to write instance UFOs. Default: " '"./instance_ufo". If value is "{tmp}", a temporary directory ' "is created and removed at the end (for Glyphs sources only).", ) outputGroup.add_argument( "--no-write-skipexportglyphs", action="store_false", dest="write_skipexportglyphs", help="Do not store the glyph export flags in the 'public.skipExportGlyphs' " "key of designspace/UFO lib, but use the old private glyph lib key " "'com.schriftgestaltung.Glyphs.Export' (for Glyphs sources only).", ) outputGroup.add_argument( "--validate-ufo", action="store_true", help="Enable ufoLib validation on reading/writing UFO files. It is " "disabled by default", ) outputGroup.add_argument( "--expand-features-to-instances", action="store_true", help="Resolves all include()s in the master feature file and writes " "the full feature file to all instance UFOs. Only valid when " "interpolating. Use if you share feature files of masters in " "external files, as instances can end up elsewhere.", ) outputGroup.add_argument( "--no-generate-GDEF", dest="generate_GDEF", action="store_false", help="Do not auto-generate a GDEF table, but keep an existing one intact.", ) contourGroup = parser.add_argument_group(title="Handling of contours") contourGroup.add_argument( "--keep-overlaps", dest="remove_overlaps", action="store_false", help="Do not remove any overlap.", ) contourGroup.add_argument( "--overlaps-backend", dest="overlaps_backend", metavar="BACKEND", choices=("booleanOperations", "pathops"), default="booleanOperations", help="Select library to remove overlaps. Choose between: %(choices)s " "(default: %(default)s)", ) contourGroup.add_argument( "--keep-direction", dest="reverse_direction", action="store_false", help="Do not reverse contour direction when output is ttf or " "ttf-interpolatable", ) contourGroup.add_argument( "-e", "--conversion-error", type=float, default=None, metavar="ERROR", help="Maximum approximation error for cubic to quadratic conversion " "measured in EM", ) contourGroup.add_argument( "-f", "--flatten-components", dest="flatten_components", action="store_true", help="Flatten nested components to single level.", ) contourGroup.add_argument( "-a", "--autohint", nargs="?", const="", help="Run ttfautohint. Can provide arguments, quoted", ) contourGroup.add_argument( "--cff-round-tolerance", type=float, default=None, metavar="FLOAT", help="Restrict rounding of point coordinates in CFF table to only " "those floats whose absolute difference from their integral part " "is less than or equal to the tolerance. By default, all floats " "are rounded to integer (tolerance 0.5); 0 disables rounding.", ) contourGroup.add_argument( "--optimize-cff", type=lambda s: CFFOptimization(int(s)), default=CFFOptimization.SUBROUTINIZE, help="0 disables all optimizations; 1 specializes the CFF charstring " "operators; 2 (default) also enables subroutinization", ) contourGroup.add_argument( "--subroutinizer", default=None, choices=["compreffor", "cffsubr"], help="name of the library to use for compressing CFF charstrings. " "Choose between: %(choices)s. By default compreffor is used for CFF 1, " "and cffsubr for CFF2. NOTE: compreffor doesn't support CFF2.", ) contourGroup.add_argument( "--no-optimize-gvar", dest="optimize_gvar", action="store_false", help="Do not perform IUP optimization on variable font's 'gvar' table. " "(only works with 'variable' TrueType-flavored output)", ) contourGroup.add_argument( "--filter", metavar="CLASS", action="append", dest="filter_specs", help="string specifying a filter class to load, either " "built-in or from an external module, optionally initialized with " "the given keyword arguments. The class and module names are " "separated by '::'. The option can be repeated multiple times " "for each filter class. The option overrides the filters specified " "in the UFO lib.", ) layoutGroup = parser.add_argument_group(title="Handling of OpenType Layout") layoutGroup.add_argument( "--interpolate-binary-layout", nargs="?", default=False, const=True, metavar="MASTER_DIR", help="Interpolate layout tables from compiled master binaries. " "Requires Glyphs or MutatorMath source.", ) layoutGroup.add_argument( "--feature-writer", metavar="CLASS", action="append", dest="feature_writer_specs", help="string specifying a feature writer class to load, either " "built-in or from an external module, optionally initialized with " "the given keyword arguments. The class and module names are " "separated by '::'. The option can be repeated multiple times " "for each writer class. A special value of 'None' will disable " "all automatic feature generation. The option overrides both the " "default ufo2ft writers and those specified in the UFO lib.", ) layoutGroup.add_argument( "--debug-feature-file", metavar="FILE", type=FileType("w", encoding="utf-8"), default=None, help=( "Path were to dump OpenType features text to debug auto-generated " "features (kern, mark, mkmk, etc.)." ), ) feaCompilerGroup = layoutGroup.add_mutually_exclusive_group(required=False) feaCompilerGroup.add_argument( "--mti-source", help="mtiLib feature definition .plist file path (use instead of FEA)", ) glyphnamesGroup = parser.add_mutually_exclusive_group(required=False) glyphnamesGroup.add_argument( "--production-names", dest="use_production_names", action="store_true", help="Rename glyphs with production names if available otherwise use " "uninames.", ) glyphnamesGroup.add_argument( "--no-production-names", dest="use_production_names", action="store_false" ) subsetGroup = parser.add_mutually_exclusive_group(required=False) subsetGroup.add_argument( "--subset", dest="subset", action="store_true", help="Subset font using export flags set by glyphsLib", ) subsetGroup.add_argument("--no-subset", dest="subset", action="store_false") subroutinizeGroup = parser.add_mutually_exclusive_group(required=False) subroutinizeGroup.add_argument( "-s", "--subroutinize", action="store_true", help="Optimize CFF table using compreffor (default) [DEPRECATED: use " "--optimize-cff option instead]", ) subroutinizeGroup.add_argument( "-S", "--no-subroutinize", dest="subroutinize", action="store_false" ) parser.set_defaults(use_production_names=None, subset=None, subroutinize=None) logGroup = parser.add_argument_group(title="Logging arguments") logGroup.add_argument( "--timing", action="store_true", help="Print the elapsed time for each steps" ) logGroup.add_argument( "--verbose", default="INFO", metavar="LEVEL", choices=("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"), help="Configure the logger verbosity level. Choose between: " "%(choices)s. Default: INFO", ) args = vars(parser.parse_args(args)) specs = args.pop("feature_writer_specs") if specs is not None: args["feature_writers"] = _loadFeatureWriters(parser, specs) specs = args.pop("filter_specs") if specs is not None: args["filters"] = _loadFilters(parser, specs) glyphs_path = args.pop("glyphs_path") ufo_paths = args.pop("ufo_paths") designspace_path = args.pop("mm_designspace") input_format = ( "Glyphs" if glyphs_path else "designspace" if designspace_path else "UFO" ) + " source" if INTERPOLATABLE_OUTPUTS.intersection(args["output"]): if not (glyphs_path or designspace_path): parser.error("Glyphs or designspace source required for variable font") exclude_args( parser, args, [ "interpolate", "masters_as_instances", "interpolate_binary_layout", "use_mutatormath", ], "variable output", ) else: exclude_args(parser, args, ["optimize_gvar"], "static output", positive=False) if args.get("use_mutatormath"): for module in ("defcon", "mutatorMath"): try: __import__(module) except ImportError: parser.error( f"{module} module not found; reinstall fontmake with the " "[mutatormath] extra" ) PRINT_TRACEBACK = args.get("verbose", "INFO") == "DEBUG" try: project = FontProject( timing=args.pop("timing"), verbose=args.pop("verbose"), validate_ufo=args.pop("validate_ufo"), ) if glyphs_path: with _make_tempdirs(parser, args): project.run_from_glyphs(glyphs_path, **args) return exclude_args( parser, args, [ "family_name", "mti_source", "designspace_path", "master_dir", "instance_dir", ], input_format, ) exclude_args( parser, args, ["write_skipexportglyphs"], input_format, positive=False ) if designspace_path: project.run_from_designspace(designspace_path, **args) return exclude_args( parser, args, [ "interpolate", "use_mutatormath", "interpolate_binary_layout", "round_instances", "expand_features_to_instances", ], input_format, ) project.run_from_ufos( ufo_paths, is_instance=args.pop("masters_as_instances"), **args ) except FontmakeError as e: if PRINT_TRACEBACK: logging.exception(e) sys.exit(1) sys.exit(f"fontmake: Error: {str(e)}") finally: debug_feature_file = args.get("debug_feature_file") if debug_feature_file is not None: debug_feature_file.close() if __name__ == "__main__": sys.exit(main()) fontmake-2.4.1/Lib/fontmake/errors.py000066400000000000000000000030111410425502200175100ustar00rootroot00000000000000import os def _try_relative_path(path): # Try to return 'path' relative to the current working directory, or # return input 'path' if we can't make a relative path. # E.g. on Windows, os.path.relpath fails when path and "." are on # different mount points, C: or D: etc. try: return os.path.relpath(path) except ValueError: return path class FontmakeError(Exception): """Base class for all fontmake exceptions. This exception is intended to be chained to the original exception. The main purpose is to provide a source file trail that points to where the explosion came from. """ def __init__(self, msg, source_file): self.msg = msg self.source_trail = [source_file] def __str__(self): trail = " -> ".join( f"'{str(_try_relative_path(s))}'" for s in reversed(self.source_trail) if s is not None ) cause = str(self.__cause__) if self.__cause__ is not None else None message = "" if trail: message = f"In {trail}: " message += f"{self.msg}" if cause: message += f": {cause}" return message class TTFAError(FontmakeError): def __init__(self, exitcode, source_file): self.exitcode = exitcode self.source_trail = source_file def __str__(self): return ( f"ttfautohint failed for '{str(_try_relative_path(self.source_trail))}': " f"error code {str(self.exitcode)}." ) fontmake-2.4.1/Lib/fontmake/font_project.py000066400000000000000000001404551410425502200207060ustar00rootroot00000000000000# Copyright 2015 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import glob import logging import math import os import shutil import tempfile from collections import OrderedDict from contextlib import contextmanager from functools import partial from re import fullmatch import attr import ufo2ft import ufo2ft.errors import ufoLib2 from fontTools import designspaceLib from fontTools.misc.loggingTools import Timer, configLogger from fontTools.misc.plistlib import load as readPlist from fontTools.ttLib import TTFont from fontTools.varLib.interpolate_layout import interpolate_layout from ufo2ft import CFFOptimization from ufo2ft.featureCompiler import parseLayoutFeatures from ufo2ft.featureWriters import FEATURE_WRITERS_KEY, loadFeatureWriters from ufo2ft.filters import FILTERS_KEY, loadFilters from ufo2ft.util import makeOfficialGlyphOrder from fontmake import instantiator from fontmake.errors import FontmakeError, TTFAError from fontmake.ttfautohint import ttfautohint logger = logging.getLogger(__name__) timer = Timer(logging.getLogger("fontmake.timer"), level=logging.DEBUG) PUBLIC_PREFIX = "public." GLYPHS_PREFIX = "com.schriftgestaltung." # for glyphsLib < 2.3.0 KEEP_GLYPHS_OLD_KEY = GLYPHS_PREFIX + "Keep Glyphs" # for glyphsLib >= 2.3.0 KEEP_GLYPHS_NEW_KEY = ( GLYPHS_PREFIX + "customParameter.InstanceDescriptorAsGSInstance.Keep Glyphs" ) GLYPH_EXPORT_KEY = GLYPHS_PREFIX + "Glyphs.Export" INTERPOLATABLE_OUTPUTS = frozenset( ["ttf-interpolatable", "otf-interpolatable", "variable", "variable-cff2"] ) @contextmanager def temporarily_disabling_axis_maps(designspace_path): """Context manager to prevent MutatorMath from warping designspace locations. MutatorMath assumes that the masters and instances' locations are in user-space coordinates -- whereas they actually are in internal design-space coordinates, and thus they do not need any 'bending'. To work around this we we create a temporary designspace document without the axis maps, and with the min/default/max triplet mapped "forward" from user-space coordinates (input) to internal designspace coordinates (output). Args: designspace_path: A path to a designspace document. Yields: A temporary path string to the thus modified designspace document. After the context is exited, it removes the temporary file. Related issues: https://github.com/LettError/designSpaceDocument/issues/16 https://github.com/fonttools/fonttools/pull/1395 """ try: designspace = designspaceLib.DesignSpaceDocument.fromfile(designspace_path) except Exception as e: raise FontmakeError("Reading Designspace failed", designspace_path) from e for axis in designspace.axes: axis.minimum = axis.map_forward(axis.minimum) axis.default = axis.map_forward(axis.default) axis.maximum = axis.map_forward(axis.maximum) del axis.map[:] fd, temp_designspace_path = tempfile.mkstemp() os.close(fd) try: designspace.write(temp_designspace_path) yield temp_designspace_path finally: os.remove(temp_designspace_path) class FontProject: """Provides methods for building fonts.""" def __init__(self, timing=False, verbose="INFO", validate_ufo=False): logging.basicConfig(level=getattr(logging, verbose.upper())) logging.getLogger("fontTools.subset").setLevel(logging.WARNING) if timing: configLogger(logger=timer.logger, level=logging.DEBUG) logger.debug( "ufoLib UFO validation is %s", "enabled" if validate_ufo else "disabled" ) self.validate_ufo = validate_ufo def open_ufo(self, path): try: return ufoLib2.Font.open(path, validate=self.validate_ufo) except Exception as e: raise FontmakeError("Reading UFO source failed", path) from e def save_ufo_as(self, font, path): try: font.save(path, overwrite=True, validate=self.validate_ufo) except Exception as e: raise FontmakeError("Writing UFO source failed", path) from e @timer() def build_master_ufos( self, glyphs_path, designspace_path=None, master_dir=None, instance_dir=None, family_name=None, mti_source=None, write_skipexportglyphs=True, generate_GDEF=True, ): """Build UFOs and MutatorMath designspace from Glyphs source.""" import glyphsLib if master_dir is None: master_dir = self._output_dir("ufo") if not os.path.isdir(master_dir): os.mkdir(master_dir) if instance_dir is None: instance_dir = self._output_dir("ufo", is_instance=True) if not os.path.isdir(instance_dir): os.mkdir(instance_dir) try: font = glyphsLib.GSFont(glyphs_path) except Exception as e: raise FontmakeError("Loading Glyphs file failed", glyphs_path) from e if designspace_path is not None: designspace_dir = os.path.dirname(designspace_path) else: designspace_dir = master_dir if os.path.isabs(instance_dir): # glyphsLib.to_designspace expects instance_dir to be relative instance_dir = os.path.relpath(instance_dir, designspace_dir) assert not os.path.isabs(instance_dir) designspace = glyphsLib.to_designspace( font, family_name=family_name, instance_dir=instance_dir, write_skipexportglyphs=write_skipexportglyphs, ufo_module=ufoLib2, generate_GDEF=generate_GDEF, ) masters = {} # multiple sources can have the same font/filename (but different layer), # we want to save a font only once for source in designspace.sources: if source.path in masters: assert source.font is masters[source.path] continue ufo_path = os.path.join(master_dir, source.filename) # no need to also set the relative 'filename' attribute as that # will be auto-updated on writing the designspace document source.path = ufo_path masters[ufo_path] = source.font if designspace_path is None: designspace_path = os.path.join(master_dir, designspace.filename) designspace.write(designspace_path) if mti_source: self.add_mti_features_to_master_ufos(mti_source, masters) for ufo_path, ufo in masters.items(): self.save_ufo_as(ufo, ufo_path) return designspace_path @timer() def add_mti_features_to_master_ufos(self, mti_source, masters): mti_dir = os.path.dirname(mti_source) with open(mti_source, "rb") as mti_file: mti_paths = readPlist(mti_file) for master_path, master in masters.items(): key = os.path.basename(master_path).rstrip(".ufo") for table, path in mti_paths[key].items(): with open(os.path.join(mti_dir, path), "rb") as mti_source: ufo_path = ( "com.github.googlei18n.ufo2ft.mtiFeatures/%s.mti" % table.strip() ) master.data[ufo_path] = mti_source.read() # If we have MTI sources, any Adobe feature files derived from # the Glyphs file should be ignored. We clear it here because # it only contains junk information anyway. master.features.text = "" def build_otfs(self, ufos, **kwargs): """Build OpenType binaries with CFF outlines.""" self.save_otfs(ufos, **kwargs) def build_ttfs(self, ufos, **kwargs): """Build OpenType binaries with TrueType outlines.""" self.save_otfs(ufos, ttf=True, **kwargs) def _load_designspace_sources(self, designspace): if isinstance(designspace, (str, os.PathLike)): ds_path = os.fspath(designspace) else: # reload designspace from its path so we have a new copy # that can be modified in-place. ds_path = designspace.path if ds_path is not None: try: designspace = designspaceLib.DesignSpaceDocument.fromfile(ds_path) except Exception as e: raise FontmakeError("Reading Designspace failed", ds_path) from e designspace.loadSourceFonts(opener=self.open_ufo) return designspace def _build_interpolatable_masters( self, designspace, ttf, use_production_names=None, reverse_direction=True, conversion_error=None, feature_writers=None, cff_round_tolerance=None, debug_feature_file=None, flatten_components=False, filters=None, **kwargs, ): designspace = self._load_designspace_sources(designspace) if ttf: return ufo2ft.compileInterpolatableTTFsFromDS( designspace, useProductionNames=use_production_names, reverseDirection=reverse_direction, cubicConversionError=conversion_error, featureWriters=feature_writers, debugFeatureFile=debug_feature_file, filters=filters, flattenComponents=flatten_components, inplace=True, ) else: return ufo2ft.compileInterpolatableOTFsFromDS( designspace, useProductionNames=use_production_names, roundTolerance=cff_round_tolerance, featureWriters=feature_writers, debugFeatureFile=debug_feature_file, filters=filters, inplace=True, ) def build_interpolatable_ttfs(self, designspace, **kwargs): """Build OpenType binaries with interpolatable TrueType outlines from DesignSpaceDocument object. """ return self._build_interpolatable_masters(designspace, ttf=True, **kwargs) def build_interpolatable_otfs(self, designspace, **kwargs): """Build OpenType binaries with interpolatable TrueType outlines from DesignSpaceDocument object. """ return self._build_interpolatable_masters(designspace, ttf=False, **kwargs) def build_variable_font( self, designspace, output_path=None, output_dir=None, ttf=True, optimize_gvar=True, optimize_cff=CFFOptimization.SPECIALIZE, use_production_names=None, reverse_direction=True, conversion_error=None, feature_writers=None, cff_round_tolerance=None, debug_feature_file=None, flatten_components=False, filters=None, **kwargs, ): """Build OpenType variable font from masters in a designspace.""" assert not (output_path and output_dir), "mutually exclusive args" designspace = self._load_designspace_sources(designspace) if output_path is None: output_path = ( os.path.splitext(os.path.basename(designspace.path))[0] + "-VF" ) ext = "ttf" if ttf else "otf" output_path = self._output_path( output_path, ext, is_variable=True, output_dir=output_dir ) logger.info("Building variable font " + output_path) if ttf: font = ufo2ft.compileVariableTTF( designspace, featureWriters=feature_writers, useProductionNames=use_production_names, cubicConversionError=conversion_error, reverseDirection=reverse_direction, optimizeGvar=optimize_gvar, flattenComponents=flatten_components, debugFeatureFile=debug_feature_file, filters=filters, inplace=True, ) else: font = ufo2ft.compileVariableCFF2( designspace, featureWriters=feature_writers, useProductionNames=use_production_names, roundTolerance=cff_round_tolerance, debugFeatureFile=debug_feature_file, optimizeCFF=optimize_cff, filters=filters, inplace=True, ) font.save(output_path) def _iter_compile(self, ufos, ttf=False, debugFeatureFile=None, **kwargs): # generator function that calls ufo2ft compiler for each ufo and # yields ttFont instances options = dict(kwargs) if ttf: for key in ("optimizeCFF", "roundTolerance", "subroutinizer", "cffVersion"): options.pop(key, None) compile_func, fmt = ufo2ft.compileTTF, "TTF" else: for key in ( "cubicConversionError", "reverseDirection", "flattenComponents", ): options.pop(key, None) compile_func, fmt = ufo2ft.compileOTF, "OTF" writeFontName = len(ufos) > 1 for ufo in ufos: name = self._font_name(ufo) logger.info(f"Building {fmt} for {name}") if debugFeatureFile and writeFontName: debugFeatureFile.write(f"\n### {name} ###\n") try: yield compile_func(ufo, debugFeatureFile=debugFeatureFile, **options) except Exception as e: raise FontmakeError("Compiling UFO failed", ufo.path) from e @timer() def save_otfs( self, ufos, ttf=False, is_instance=False, autohint=None, subset=None, use_production_names=None, subroutinize=None, # deprecated optimize_cff=CFFOptimization.NONE, cff_round_tolerance=None, remove_overlaps=True, overlaps_backend=None, reverse_direction=True, conversion_error=None, feature_writers=None, interpolate_layout_from=None, interpolate_layout_dir=None, output_path=None, output_dir=None, debug_feature_file=None, inplace=True, cff_version=1, subroutinizer=None, flatten_components=False, filters=None, generate_GDEF=True, ): """Build OpenType binaries from UFOs. Args: ufos: Font objects to compile. ttf: If True, build fonts with TrueType outlines and .ttf extension. is_instance: If output fonts are instances, for generating paths. autohint: Parameters to provide to ttfautohint. If not provided, the autohinting step is skipped. subset: Whether to subset the output according to data in the UFOs. If not provided, also determined by flags in the UFOs. use_production_names: Whether to use production glyph names in the output. If not provided, determined by flags in the UFOs. subroutinize: If True, subroutinize CFF outlines in output. cff_round_tolerance (float): controls the rounding of point coordinates in CFF table. It is defined as the maximum absolute difference between the original float and the rounded integer value. By default, all floats are rounded to integer (tolerance 0.5); a value of 0 completely disables rounding; values in between only round floats which are close to their integral part within the tolerated range. Ignored if ttf=True. remove_overlaps: If True, remove overlaps in glyph shapes. overlaps_backend: name of the library to remove overlaps. Can be either "booleanOperations" (default) or "pathops". reverse_direction: If True, reverse contour directions when compiling TrueType outlines. conversion_error: Error to allow when converting cubic CFF contours to quadratic TrueType contours. feature_writers: list of ufo2ft-compatible feature writer classes or pre-initialized objects that are passed on to ufo2ft feature compiler to generate automatic feature code. The default value (None) means that ufo2ft will use its built-in default feature writers (for kern, mark, mkmk, etc.). An empty list ([]) will skip any automatic feature generation. interpolate_layout_from: A DesignSpaceDocument object to give varLib for interpolating layout tables to use in output. interpolate_layout_dir: Directory containing the compiled master fonts to use for interpolating binary layout tables. output_path: output font file path. Only works when the input 'ufos' list contains a single font. output_dir: directory where to save output files. Mutually exclusive with 'output_path' argument. flatten_components: If True, flatten nested components to a single level. filters: list of ufo2ft-compatible filter classes or pre-initialized objects that are passed on to ufo2ft pre-processor to modify the glyph set. The filters are either pre-filters or post-filters, called before or after the default filters. The default filters are format specific and some can be disabled with other arguments. """ assert not (output_path and output_dir), "mutually exclusive args" if output_path is not None and len(ufos) > 1: raise ValueError("output_path requires a single input") if subroutinize is not None: import warnings warnings.warn( "the 'subroutinize' argument is deprecated, use 'optimize_cff'", UserWarning, ) if subroutinize: optimize_cff = CFFOptimization.SUBROUTINIZE else: # for b/w compatibility, we still run the charstring specializer # even when --no-subroutinize is used. Use the new --optimize-cff # option to disable both specilization and subroutinization optimize_cff = CFFOptimization.SPECIALIZE ext = "ttf" if ttf else "otf" if interpolate_layout_from is not None: if interpolate_layout_dir is None: interpolate_layout_dir = self._output_dir(ext, is_instance=False) finder = partial(_varLib_finder, directory=interpolate_layout_dir, ext=ext) # no need to generate automatic features in ufo2ft, since here we # are interpolating precompiled GPOS table with fontTools.varLib. # An empty 'featureWriters' list tells ufo2ft to not generate any # automatic features. # TODO: Add an argument to ufo2ft.compileOTF/compileTTF to # completely skip compiling features into OTL tables feature_writers = [] fonts = self._iter_compile( ufos, ttf, removeOverlaps=remove_overlaps, overlapsBackend=overlaps_backend, optimizeCFF=optimize_cff, roundTolerance=cff_round_tolerance, useProductionNames=use_production_names, reverseDirection=reverse_direction, cubicConversionError=conversion_error, featureWriters=feature_writers, debugFeatureFile=debug_feature_file, cffVersion=cff_version, subroutinizer=subroutinizer, flattenComponents=flatten_components, filters=filters, inplace=True, # avoid extra copy ) do_autohint = ttf and autohint is not None for font, ufo in zip(fonts, ufos): if interpolate_layout_from is not None: master_locations, instance_locations = self._designspace_locations( interpolate_layout_from ) loc = instance_locations[_normpath(ufo.path)] gpos_src = interpolate_layout( interpolate_layout_from, loc, finder, mapped=True ) font["GPOS"] = gpos_src["GPOS"] gsub_src = TTFont(finder(self._closest_location(master_locations, loc))) if "GDEF" in gsub_src: font["GDEF"] = gsub_src["GDEF"] if "GSUB" in gsub_src: font["GSUB"] = gsub_src["GSUB"] if do_autohint: # if we are autohinting, we save the unhinted font to a # temporary path, and the hinted one to the final destination fd, otf_path = tempfile.mkstemp("." + ext) os.close(fd) elif output_path is None: otf_path = self._output_path( ufo, ext, is_instance, output_dir=output_dir ) else: otf_path = output_path logger.info("Saving %s", otf_path) font.save(otf_path) # 'subset' is an Optional[bool], can be None, True or False. # When False, we never subset; when True, we always do; when # None (default), we check the presence of custom parameters if subset is False: pass elif subset is True or ( (KEEP_GLYPHS_OLD_KEY in ufo.lib or KEEP_GLYPHS_NEW_KEY in ufo.lib) or any(glyph.lib.get(GLYPH_EXPORT_KEY, True) is False for glyph in ufo) ): self.subset_otf_from_ufo(otf_path, ufo) if not do_autohint: continue if output_path is not None: hinted_otf_path = output_path else: hinted_otf_path = self._output_path( ufo, ext, is_instance, autohinted=True, output_dir=output_dir ) try: ttfautohint(otf_path, hinted_otf_path, args=autohint) except TTFAError: # copy unhinted font to destination before re-raising error shutil.copyfile(otf_path, hinted_otf_path) raise finally: # must clean up temp file os.remove(otf_path) def _save_interpolatable_fonts(self, designspace, output_dir, ttf): ext = "ttf" if ttf else "otf" for source in designspace.sources: assert isinstance(source.font, TTFont) otf_path = self._output_path( source, ext, is_instance=False, interpolatable=True, output_dir=output_dir, suffix=source.layerName, ) logger.info("Saving %s", otf_path) source.font.save(otf_path) source.path = otf_path source.layerName = None for instance in designspace.instances: instance.path = instance.filename = None if output_dir is None: output_dir = self._output_dir(ext, interpolatable=True) designspace_path = os.path.join(output_dir, os.path.basename(designspace.path)) logger.info("Saving %s", designspace_path) designspace.write(designspace_path) def subset_otf_from_ufo(self, otf_path, ufo): """Subset a font using "Keep Glyphs" custom parameter and export flags as set by glyphsLib. "Export Glyphs" and "Remove Glyphs" are currently not supported: https://github.com/googlei18n/glyphsLib/issues/295. """ from fontTools import subset # we must exclude from the final UFO glyphOrder all the glyphs that were not # exported to OTF because included in 'public.skipExportGlyphs' skip_export_glyphs = set(ufo.lib.get("public.skipExportGlyphs", ())) exported_glyphs = dict.fromkeys( g for g in ufo.keys() if g not in skip_export_glyphs ) ufo_order = makeOfficialGlyphOrder(exported_glyphs, glyphOrder=ufo.glyphOrder) # ufo2ft always inserts a ".notdef" glyph as the first glyph if ".notdef" not in exported_glyphs: ufo_order.insert(0, ".notdef") ot_order = TTFont(otf_path).getGlyphOrder() assert ot_order[0] == ".notdef" assert len(ufo_order) == len(ot_order) for key in (KEEP_GLYPHS_NEW_KEY, KEEP_GLYPHS_OLD_KEY): keep_glyphs_list = ufo.lib.get(key) if keep_glyphs_list is not None: keep_glyphs = set(keep_glyphs_list) break else: keep_glyphs = None include = [] for source_name, binary_name in zip(ufo_order, ot_order): if keep_glyphs and source_name not in keep_glyphs: continue if source_name in ufo: exported = ufo[source_name].lib.get(GLYPH_EXPORT_KEY, True) if not exported: continue include.append(binary_name) # copied from nototools.subset opt = subset.Options() opt.name_IDs = ["*"] opt.name_legacy = True opt.name_languages = ["*"] opt.layout_features = ["*"] opt.notdef_outline = True opt.recalc_bounds = True opt.recalc_timestamp = True opt.canonical_order = True opt.glyph_names = True font = subset.load_font(otf_path, opt, lazy=False) subsetter = subset.Subsetter(options=opt) subsetter.populate(glyphs=include) subsetter.subset(font) subset.save_font(font, otf_path, opt) def run_from_glyphs( self, glyphs_path, designspace_path=None, master_dir=None, instance_dir=None, family_name=None, mti_source=None, write_skipexportglyphs=True, generate_GDEF=True, **kwargs, ): """Run toolchain from Glyphs source. Args: glyphs_path: Path to source file. designspace_path: Output path of generated designspace document. By default it's "[-].designspace". master_dir: Directory where to save UFO masters (default: "master_ufo"). instance_dir: Directory where to save UFO instances (default: "instance_ufo"). family_name: If provided, uses this family name in the output. mti_source: Path to property list file containing a dictionary mapping UFO masters to dictionaries mapping layout table tags to MTI source paths which should be compiled into those tables. kwargs: Arguments passed along to run_from_designspace. """ logger.info("Building master UFOs and designspace from Glyphs source") designspace_path = self.build_master_ufos( glyphs_path, designspace_path=designspace_path, master_dir=master_dir, instance_dir=instance_dir, family_name=family_name, mti_source=mti_source, write_skipexportglyphs=write_skipexportglyphs, generate_GDEF=generate_GDEF, ) try: self.run_from_designspace(designspace_path, **kwargs) except FontmakeError as e: e.source_trail.append(glyphs_path) raise def interpolate_instance_ufos( self, designspace, include=None, round_instances=False, expand_features_to_instances=False, ): """Interpolate master UFOs with Instantiator and return instance UFOs. Args: designspace: a DesignSpaceDocument object containing sources and instances. include (str): optional regular expression pattern to match the DS instance 'name' attribute and only interpolate the matching instances. round_instances (bool): round instances' coordinates to integer. expand_features_to_instances: parses the master feature file, expands all include()s and writes the resulting full feature file to all instance UFOs. Use this if you share feature files among masters in external files. Otherwise, the relative include paths can break as instances may end up elsewhere. Only done on interpolation. Returns: generator of ufoLib2.Font objects corresponding to the UFO instances. Raises: FontmakeError: instances could not be prepared for interpolation or interpolation failed. ValueError: an instance descriptor did not have a filename attribute set. """ from glyphsLib.interpolation import apply_instance_data_to_ufo logger.info("Interpolating master UFOs from designspace") try: designspace = designspaceLib.DesignSpaceDocument.fromfile(designspace.path) except Exception as e: raise FontmakeError("Reading Designspace failed", designspace.path) from e try: generator = instantiator.Instantiator.from_designspace( designspace, round_geometry=round_instances ) except instantiator.InstantiatorError as e: raise FontmakeError( "Preparing the Designspace for interpolation failed", designspace.path ) from e if expand_features_to_instances: logger.debug("Expanding features to instance UFOs") fea_txt = parseLayoutFeatures(designspace.default.font).asFea() generator = attr.evolve(generator, copy_feature_text=fea_txt) for instance in designspace.instances: # Skip instances that have been set to non-export in Glyphs, stored as the # instance's `com.schriftgestaltung.export` lib key. if not instance.lib.get("com.schriftgestaltung.export", True): continue # Skip instances that do not match the user's inclusion regex if given. if include is not None and not fullmatch(include, instance.name): continue logger.info(f'Generating instance UFO for "{instance.name}"') try: instance.font = generator.generate_instance(instance) except instantiator.InstantiatorError as e: raise FontmakeError( f"Interpolating instance '{instance.styleName}' failed.", designspace.path, ) from e apply_instance_data_to_ufo(instance.font, instance, designspace) # TODO: Making filenames up on the spot is complicated, ideally don't save # anything if filename is not set, but make something up when "ufo" is in # output formats, but also consider output_path. if instance.filename is None: raise ValueError( "It is currently required that instances have filenames set." ) ufo_path = os.path.join( os.path.dirname(designspace.path), instance.filename ) os.makedirs(os.path.dirname(ufo_path), exist_ok=True) self.save_ufo_as(instance.font, ufo_path) yield instance.font def interpolate_instance_ufos_mutatormath( self, designspace, include=None, round_instances=False, expand_features_to_instances=False, ): """Interpolate master UFOs with MutatorMath and return instance UFOs. Args: designspace: a DesignSpaceDocument object containing sources and instances. include (str): optional regular expression pattern to match the DS instance 'name' attribute and only interpolate the matching instances. round_instances (bool): round instances' coordinates to integer. expand_features_to_instances: parses the master feature file, expands all include()s and writes the resulting full feature file to all instance UFOs. Use this if you share feature files among masters in external files. Otherwise, the relative include paths can break as instances may end up elsewhere. Only done on interpolation. Returns: list of defcon.Font objects corresponding to the UFO instances. Raises: FontmakeError: if any of the sources defines a custom 'layer', for this is not supported by MutatorMath. ValueError: "expand_features_to_instances" is True but no source in the designspace document is designated with ''. """ from glyphsLib.interpolation import apply_instance_data from mutatorMath.ufo.document import DesignSpaceDocumentReader if any(source.layerName is not None for source in designspace.sources): raise FontmakeError( "MutatorMath doesn't support DesignSpace sources with 'layer' " "attribute", None, ) with temporarily_disabling_axis_maps(designspace.path) as temp_designspace_path: builder = DesignSpaceDocumentReader( temp_designspace_path, ufoVersion=3, roundGeometry=round_instances, verbose=True, ) logger.info("Interpolating master UFOs from designspace") if include is not None: instances = self._search_instances(designspace, pattern=include) for instance_name in instances: builder.readInstance(("name", instance_name)) filenames = set(instances.values()) else: builder.readInstances() filenames = None # will include all instances logger.info("Applying instance data from designspace") instance_ufos = apply_instance_data(designspace, include_filenames=filenames) if expand_features_to_instances: logger.debug("Expanding features to instance UFOs") master_source = next( (s for s in designspace.sources if s.copyFeatures), None ) if not master_source: raise ValueError("No source is designated as the master for features.") else: master_source_font = builder.sources[master_source.name][0] master_source_features = parseLayoutFeatures(master_source_font).asFea() for instance_ufo in instance_ufos: instance_ufo.features.text = master_source_features instance_ufo.save() return instance_ufos def run_from_designspace( self, designspace_path, output=(), interpolate=False, masters_as_instances=False, interpolate_binary_layout=False, round_instances=False, feature_writers=None, filters=None, expand_features_to_instances=False, use_mutatormath=False, **kwargs, ): """Run toolchain from a DesignSpace document to produce either static instance fonts (ttf or otf), interpolatable or variable fonts. Args: designspace_path: Path to designspace document. interpolate: If True output all instance fonts, otherwise just masters. If the value is a string, only build instance(s) that match given name. The string is compiled into a regular expression and matched against the "name" attribute of designspace instances using `re.fullmatch`. masters_as_instances: If True, output master fonts as instances. interpolate_binary_layout: Interpolate layout tables from compiled master binaries. round_instances: apply integer rounding when interpolating with MutatorMath. kwargs: Arguments passed along to run_from_ufos. Raises: TypeError: "variable" or "interpolatable" outputs are incompatible with arguments "interpolate", "masters_as_instances", and "interpolate_binary_layout". """ interp_outputs = INTERPOLATABLE_OUTPUTS.intersection(output) static_outputs = set(output).difference(interp_outputs) if interp_outputs: for argname in ( "interpolate", "masters_as_instances", "interpolate_binary_layout", ): if locals()[argname]: raise TypeError( '"%s" argument incompatible with output %r' % (argname, ", ".join(sorted(interp_outputs))) ) try: designspace = designspaceLib.DesignSpaceDocument.fromfile(designspace_path) except Exception as e: raise FontmakeError("Reading Designspace failed", designspace_path) from e # if no --feature-writers option was passed, check in the designspace's # element if user supplied a custom featureWriters configuration; # if so, use that for all the UFOs built from this designspace if feature_writers is None and FEATURE_WRITERS_KEY in designspace.lib: feature_writers = loadFeatureWriters(designspace) if filters is None and FILTERS_KEY in designspace.lib: preFilters, postFilters = loadFilters(designspace) filters = preFilters + postFilters try: if static_outputs: self._run_from_designspace_static( designspace, outputs=static_outputs, interpolate=interpolate, masters_as_instances=masters_as_instances, interpolate_binary_layout=interpolate_binary_layout, round_instances=round_instances, feature_writers=feature_writers, expand_features_to_instances=expand_features_to_instances, use_mutatormath=use_mutatormath, filters=filters, **kwargs, ) if interp_outputs: self._run_from_designspace_interpolatable( designspace, outputs=interp_outputs, feature_writers=feature_writers, filters=filters, **kwargs, ) except FontmakeError as e: # Some called functions already added the Designspace file to the source # trail. if e.source_trail[-1] != designspace.path: e.source_trail.append(designspace.path) raise except Exception as e: raise FontmakeError( "Generating fonts from Designspace failed", designspace.path ) from e def _run_from_designspace_static( self, designspace, outputs, interpolate=False, masters_as_instances=False, interpolate_binary_layout=False, round_instances=False, feature_writers=None, expand_features_to_instances=False, use_mutatormath=False, **kwargs, ): ufos = [] if not interpolate or masters_as_instances: ufos.extend(s.path for s in designspace.sources if s.path) if interpolate: pattern = interpolate if isinstance(interpolate, str) else None if use_mutatormath: ufos.extend( self.interpolate_instance_ufos_mutatormath( designspace, include=pattern, round_instances=round_instances, expand_features_to_instances=expand_features_to_instances, ) ) else: ufos.extend( self.interpolate_instance_ufos( designspace, include=pattern, round_instances=round_instances, expand_features_to_instances=expand_features_to_instances, ) ) if interpolate_binary_layout is False: interpolate_layout_from = interpolate_layout_dir = None else: interpolate_layout_from = designspace if isinstance(interpolate_binary_layout, str): interpolate_layout_dir = interpolate_binary_layout else: interpolate_layout_dir = None self.run_from_ufos( ufos, output=outputs, is_instance=(interpolate or masters_as_instances), interpolate_layout_from=interpolate_layout_from, interpolate_layout_dir=interpolate_layout_dir, feature_writers=feature_writers, **kwargs, ) def _run_from_designspace_interpolatable( self, designspace, outputs, output_path=None, output_dir=None, **kwargs ): ttf_designspace = otf_designspace = None if "variable" in outputs: self.build_variable_font( designspace, output_path=output_path, output_dir=output_dir, **kwargs ) if "ttf-interpolatable" in outputs: ttf_designspace = self.build_interpolatable_ttfs(designspace, **kwargs) self._save_interpolatable_fonts(ttf_designspace, output_dir, ttf=True) if "variable-cff2" in outputs: self.build_variable_font( designspace, output_path=output_path, output_dir=output_dir, ttf=False, **kwargs, ) if "otf-interpolatable" in outputs: otf_designspace = self.build_interpolatable_otfs(designspace, **kwargs) self._save_interpolatable_fonts(otf_designspace, output_dir, ttf=False) def run_from_ufos(self, ufos, output=(), **kwargs): """Run toolchain from UFO sources. Args: ufos: List of UFO sources, as either paths or opened objects. output: List of output formats to generate. kwargs: Arguments passed along to save_otfs. """ if set(output) == {"ufo"}: return if "otf" in output and "otf-cff2" in output: raise ValueError("'otf' and 'otf-cff2' outputs are mutually exclusive") # the `ufos` parameter can be a list of UFO objects # or it can be a path (string) with a glob syntax ufo_paths = [] if isinstance(ufos, str): ufo_paths = glob.glob(ufos) ufos = [self.open_ufo(x) for x in ufo_paths] elif isinstance(ufos, list): # ufos can be either paths or open Font objects, so normalize them ufos = [self.open_ufo(x) if isinstance(x, str) else x for x in ufos] ufo_paths = [x.path for x in ufos] else: raise TypeError( "UFOs parameter is neither a defcon.Font object, a path or a glob, " f"nor a list of any of these: {ufos:r}." ) need_reload = False cff_version = 1 if "otf" in output else 2 if "otf-cff2" in output else None if cff_version is not None: self.build_otfs(ufos, cff_version=cff_version, **kwargs) need_reload = True if "ttf" in output: if need_reload: ufos = [self.open_ufo(path) for path in ufo_paths] self.build_ttfs(ufos, **kwargs) need_reload = True @staticmethod def _search_instances(designspace, pattern): instances = OrderedDict() for instance in designspace.instances: # is 'name' optional? 'filename' certainly must not be if fullmatch(pattern, instance.name): instances[instance.name] = instance.filename if not instances: raise FontmakeError("No instance found with %r" % pattern) return instances def _font_name(self, ufo): """Generate a postscript-style font name.""" family_name = ( ufo.info.familyName.replace(" ", "") if ufo.info.familyName is not None else "None" ) style_name = ( ufo.info.styleName.replace(" ", "") if ufo.info.styleName is not None else "None" ) return f"{family_name}-{style_name}" def _output_dir( self, ext, is_instance=False, interpolatable=False, autohinted=False, is_variable=False, ): """Generate an output directory. Args: ext: extension string. is_instance: The output is instance font or not. interpolatable: The output is interpolatable or not. autohinted: The output is autohinted or not. is_variable: The output is variable font or not. Return: output directory string. """ assert not (is_variable and any([is_instance, interpolatable])) # FIXME? Use user configurable destination folders. if is_variable: dir_prefix = "variable_" elif is_instance: dir_prefix = "instance_" else: dir_prefix = "master_" dir_suffix = "_interpolatable" if interpolatable else "" output_dir = dir_prefix + ext + dir_suffix if autohinted: output_dir = os.path.join("autohinted", output_dir) return output_dir def _output_path( self, ufo_or_font_name, ext, is_instance=False, interpolatable=False, autohinted=False, is_variable=False, output_dir=None, suffix=None, ): """Generate output path for a font file with given extension.""" if isinstance(ufo_or_font_name, str): font_name = ufo_or_font_name elif ufo_or_font_name.path: font_name = os.path.splitext( os.path.basename(os.path.normpath(ufo_or_font_name.path)) )[0] else: font_name = self._font_name(ufo_or_font_name) if output_dir is None: output_dir = self._output_dir( ext, is_instance, interpolatable, autohinted, is_variable ) if not os.path.exists(output_dir): os.makedirs(output_dir) if suffix: return os.path.join(output_dir, f"{font_name}-{suffix}.{ext}") else: return os.path.join(output_dir, f"{font_name}.{ext}") def _designspace_locations(self, designspace): """Map font filenames to their locations in a designspace.""" maps = [] for elements in (designspace.sources, designspace.instances): location_map = {} for element in elements: path = _normpath(element.path) location_map[path] = element.location maps.append(location_map) return maps def _closest_location(self, location_map, target): """Return path of font whose location is closest to target.""" def dist(a, b): return math.sqrt(sum((a[k] - b[k]) ** 2 for k in a.keys())) paths = iter(location_map.keys()) closest = next(paths) closest_dist = dist(target, location_map[closest]) for path in paths: cur_dist = dist(target, location_map[path]) if cur_dist < closest_dist: closest = path closest_dist = cur_dist return closest def _varLib_finder(source, directory="", ext="ttf"): """Finder function to be used with varLib.build to find master TTFs given the filename of the source UFO master as specified in the designspace. It replaces the UFO directory with the one specified in 'directory' argument, and replaces the file extension with 'ext'. """ fname = os.path.splitext(os.path.basename(source))[0] + "." + ext return os.path.join(directory, fname) def _normpath(fname): return os.path.normcase(os.path.normpath(fname)) fontmake-2.4.1/Lib/fontmake/instantiator.py000066400000000000000000000736341410425502200207350ustar00rootroot00000000000000# This code is based on ufoProcessor code, which is licensed as follows: # Copyright (c) 2017-2018 LettError and Erik van Blokland # All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """Module for generating static font instances. It is an alternative to mutatorMath (used internally by fontmake) and ufoProcessor. The aim is to be a minimal implementation that is focussed on using ufoLib2 for font data abstraction, varLib for instance computation and fontMath as a font data shell for instance computation directly and exclusively. At the time of this writing, varLib lacks support for anisotropic (x, y) locations and extrapolation. """ import copy import logging import typing from typing import Any, Dict, List, Mapping, Set, Tuple, Union import attr import fontMath import fontTools.designspaceLib as designspaceLib import fontTools.misc.fixedTools import fontTools.varLib as varLib import ufoLib2 logger = logging.getLogger(__name__) # Use the same rounding function used by varLib to round things for the variable font # to reduce differences between the variable and static instances. fontMath.mathFunctions.setRoundIntegerFunction(fontTools.misc.fixedTools.otRound) # Stand-in type for any of the fontMath classes we use. FontMathObject = Union[fontMath.MathGlyph, fontMath.MathInfo, fontMath.MathKerning] # MutatorMath-style location mapping type, i.e. # `{"wght": 1.0, "wdth": 0.0, "bleep": 0.5}`. # LocationKey is a Location turned into a tuple so we can use it as a dict key. Location = Mapping[str, float] LocationKey = Tuple[Tuple[str, float], ...] # Type of mapping of axes to their minimum, default and maximum values, i.e. # `{"wght": (100.0, 400.0, 900.0), "wdth": (75.0, 100.0, 100.0)}`. AxisBounds = Dict[str, Tuple[float, float, float]] # For mapping `wdth` axis user values to the OS2 table's width class field. WDTH_VALUE_TO_OS2_WIDTH_CLASS = { 50: 1, 62.5: 2, 75: 3, 87.5: 4, 100: 5, 112.5: 6, 125: 7, 150: 8, 200: 9, } # Font info fields that are not interpolated and should be copied from the # default font to the instance. # # fontMath at the time of this writing handles the following attributes: # https://github.com/robotools/fontMath/blob/0.5.0/Lib/fontMath/mathInfo.py#L360-L422 # # From the attributes that are left, we skip instance-specific ones on purpose: # - guidelines # - postscriptFontName # - styleMapFamilyName # - styleMapStyleName # - styleName # - openTypeNameCompatibleFullName # - openTypeNamePreferredFamilyName # - openTypeNamePreferredSubfamilyName # - openTypeNameUniqueID # - openTypeNameWWSFamilyName # - openTypeNameWWSSubfamilyName # - openTypeOS2Panose # - postscriptFullName # - postscriptUniqueID # - woffMetadataUniqueID # # Some, we skip because they are deprecated: # - macintoshFONDFamilyID # - macintoshFONDName # - year # # This means we implicitly require the `stylename` attribute in the Designspace # `` element. UFO_INFO_ATTRIBUTES_TO_COPY_TO_INSTANCES = { "copyright", "familyName", "note", "openTypeGaspRangeRecords", "openTypeHeadCreated", "openTypeHeadFlags", "openTypeNameDescription", "openTypeNameDesigner", "openTypeNameDesignerURL", "openTypeNameLicense", "openTypeNameLicenseURL", "openTypeNameManufacturer", "openTypeNameManufacturerURL", "openTypeNameRecords", "openTypeNameSampleText", "openTypeNameVersion", "openTypeOS2CodePageRanges", "openTypeOS2FamilyClass", "openTypeOS2Selection", "openTypeOS2Type", "openTypeOS2UnicodeRanges", "openTypeOS2VendorID", "postscriptDefaultCharacter", "postscriptForceBold", "postscriptIsFixedPitch", "postscriptWindowsCharacterSet", "trademark", "versionMajor", "versionMinor", "woffMajorVersion", "woffMetadataCopyright", "woffMetadataCredits", "woffMetadataDescription", "woffMetadataExtensions", "woffMetadataLicense", "woffMetadataLicensee", "woffMetadataTrademark", "woffMetadataVendor", "woffMinorVersion", } # Custom exception for this module class InstantiatorError(Exception): pass def process_rules_swaps(rules, location, glyphNames): """Apply these rules at this location to these glyphnames - rule order matters Return a list of (oldName, newName) in the same order as the rules. """ swaps = [] glyphNames = set(glyphNames) for rule in rules: if designspaceLib.evaluateRule(rule, location): for oldName, newName in rule.subs: # Here I don't check if the new name is also in glyphNames... # I guess it should be, so that we can swap, and if it isn't, # then it's better to error out later when we try to swap, # instead of silently ignoring the rule here. if oldName in glyphNames: swaps.append((oldName, newName)) return swaps @attr.s(auto_attribs=True, frozen=True, slots=True) class Instantiator: """Data class that holds all necessary information to generate a static font instance object at an arbitary location within the design space.""" axis_bounds: AxisBounds # Design space! copy_feature_text: str copy_nonkerning_groups: Mapping[str, List[str]] copy_info: ufoLib2.objects.Info copy_lib: Mapping[str, Any] default_design_location: Location designspace_rules: List[designspaceLib.RuleDescriptor] glyph_mutators: Mapping[str, "Variator"] glyph_name_to_unicodes: Dict[str, List[int]] info_mutator: "Variator" kerning_mutator: "Variator" round_geometry: bool skip_export_glyphs: List[str] special_axes: Mapping[str, designspaceLib.AxisDescriptor] @classmethod def from_designspace( cls, designspace: designspaceLib.DesignSpaceDocument, round_geometry: bool = True, ): """Instantiates a new data class from a Designspace object.""" if designspace.default is None: raise InstantiatorError(_error_msg_no_default(designspace)) if any(anisotropic(instance.location) for instance in designspace.instances): raise InstantiatorError( "The Designspace contains anisotropic instance locations, which are " "not supported by varLib. Look for and remove all 'yvalue=\"...\"' or " "use MutatorMath instead." ) designspace.loadSourceFonts(ufoLib2.Font.open) # The default font (default layer) determines which glyphs are interpolated, # because the math behind varLib and MutatorMath uses the default font as the # point of reference for all data. default_font = designspace.default.font glyph_names: Set[str] = set(default_font.keys()) for source in designspace.sources: other_names = set(source.font.keys()) diff_names = other_names - glyph_names if diff_names: logger.warning( "The source %s (%s) contains glyphs that are missing from the " "default source, which will be ignored: %s. If this is unintended, " "check that these glyphs have the exact same name as the " "corresponding glyphs in the default source.", source.name, source.filename, ", ".join(sorted(diff_names)), ) # Construct Variators axis_bounds: AxisBounds = {} # Design space! axis_order: List[str] = [] special_axes = {} for axis in designspace.axes: axis_order.append(axis.name) axis_bounds[axis.name] = ( axis.map_forward(axis.minimum), axis.map_forward(axis.default), axis.map_forward(axis.maximum), ) # Some axes relate to existing OpenType fields and get special attention. if axis.tag in {"wght", "wdth", "slnt"}: special_axes[axis.tag] = axis masters_info = collect_info_masters(designspace, axis_bounds) try: info_mutator = Variator.from_masters(masters_info, axis_order) except varLib.errors.VarLibError as e: raise InstantiatorError( f"Cannot set up fontinfo for interpolation: {e}'" ) from e masters_kerning = collect_kerning_masters(designspace, axis_bounds) try: kerning_mutator = Variator.from_masters(masters_kerning, axis_order) except varLib.errors.VarLibError as e: raise InstantiatorError( f"Cannot set up kerning for interpolation: {e}'" ) from e glyph_mutators: Dict[str, Variator] = {} glyph_name_to_unicodes: Dict[str, List[int]] = {} for glyph_name in glyph_names: items = collect_glyph_masters(designspace, glyph_name, axis_bounds) try: glyph_mutators[glyph_name] = Variator.from_masters(items, axis_order) except varLib.errors.VarLibError as e: raise InstantiatorError( f"Cannot set up glyph '{glyph_name}' for interpolation: {e}'" ) from e glyph_name_to_unicodes[glyph_name] = default_font[glyph_name].unicodes # Construct defaults to copy over copy_feature_text: str = default_font.features.text copy_nonkerning_groups: Mapping[str, List[str]] = { key: glyph_names for key, glyph_names in default_font.groups.items() if not key.startswith(("public.kern1.", "public.kern2.")) } # Kerning groups are taken care of by the kerning Variator. copy_info: ufoLib2.objects.Info = default_font.info copy_lib: Mapping[str, Any] = default_font.lib # The list of glyphs-not-to-export-and-decompose-where-used-as-a-component is # supposed to be taken from the Designspace when a Designspace is used as the # starting point of the compilation process. It should be exported to all # instance libs, where the ufo2ft compilation functions will pick it up. skip_export_glyphs = designspace.lib.get("public.skipExportGlyphs", []) return cls( axis_bounds, copy_feature_text, copy_nonkerning_groups, copy_info, copy_lib, designspace.default.location, designspace.rules, glyph_mutators, glyph_name_to_unicodes, info_mutator, kerning_mutator, round_geometry, skip_export_glyphs, special_axes, ) def generate_instance( self, instance: designspaceLib.InstanceDescriptor ) -> ufoLib2.Font: """Generate an interpolated instance font object for an InstanceDescriptor.""" if anisotropic(instance.location): raise InstantiatorError( f"Instance {instance.familyName}-" f"{instance.styleName}: Anisotropic location " f"{instance.location} not supported by varLib." ) font = ufoLib2.Font() # Instances may leave out locations that match the default source, so merge # default location with the instance's location. location = {**self.default_design_location, **instance.location} location_normalized = varLib.models.normalizeLocation( location, self.axis_bounds ) # Kerning kerning_instance = self.kerning_mutator.instance_at(location_normalized) if self.round_geometry: kerning_instance.round() kerning_instance.extractKerning(font) # Info self._generate_instance_info(instance, location_normalized, location, font) # Non-kerning groups. Kerning groups have been taken care of by the kerning # instance. for key, glyph_names in self.copy_nonkerning_groups.items(): font.groups[key] = [name for name in glyph_names] # Features font.features.text = self.copy_feature_text # Lib # 1. Copy the default lib to the instance. font.lib = typing.cast(dict, copy.deepcopy(self.copy_lib)) # 2. Copy the Designspace's skipExportGlyphs list over to the UFO to # make sure it wins over the default UFO one. font.lib["public.skipExportGlyphs"] = [name for name in self.skip_export_glyphs] # 3. Write _design_ location to instance's lib. font.lib["designspace.location"] = [loc for loc in location.items()] # Glyphs for glyph_name, glyph_mutator in self.glyph_mutators.items(): glyph = font.newGlyph(glyph_name) try: glyph_instance = glyph_mutator.instance_at(location_normalized) if self.round_geometry: glyph_instance = glyph_instance.round() # onlyGeometry=True does not set name and unicodes, in ufoLib2 we can't # modify a glyph's name. Copy unicodes from default font. glyph_instance.extractGlyph(glyph, onlyGeometry=True) except Exception as e: # TODO: Figure out what exceptions fontMath/varLib can throw. # By default, explode if we cannot generate a glyph instance for # whatever reason (usually outline incompatibility)... if glyph_name not in self.skip_export_glyphs: raise InstantiatorError( f"Failed to generate instance of glyph '{glyph_name}': " f"{str(e)}. (Note: the most common cause for an error here is " "that the glyph outlines are not point-for-point compatible or " "have the same starting point or are in the same order in all " "masters.)" ) from e # ...except if the glyph is in public.skipExportGlyphs and would # therefore be removed from the compiled font anyway. There's not much # we can do except leave it empty in the instance and tell the user. logger.warning( "Failed to generate instance of glyph '%s', which is marked as " "non-exportable. Glyph will be left empty. Failure reason: %s", glyph_name, e, ) glyph.unicodes = [uv for uv in self.glyph_name_to_unicodes[glyph_name]] # Process rules glyph_names_list = self.glyph_mutators.keys() # The order of the swaps below is independent of the order of glyph names. # It depends on the order of the s in the designspace rules. swaps = process_rules_swaps(self.designspace_rules, location, glyph_names_list) for name_old, name_new in swaps: if name_old != name_new: swap_glyph_names(font, name_old, name_new) return font def _generate_instance_info( self, instance: designspaceLib.InstanceDescriptor, location_normalized: Location, location: Location, font: ufoLib2.Font, ) -> None: """Generate fontinfo related attributes. Separate, as fontinfo treatment is more extensive than the rest. """ info_instance = self.info_mutator.instance_at(location_normalized) if self.round_geometry: info_instance = info_instance.round() info_instance.extractInfo(font.info) # Copy non-interpolating metadata from the default font. for attribute in UFO_INFO_ATTRIBUTES_TO_COPY_TO_INSTANCES: if hasattr(self.copy_info, attribute): setattr( font.info, attribute, copy.deepcopy(getattr(self.copy_info, attribute)), ) # TODO: multilingual names to replace possibly existing name records. if instance.familyName: font.info.familyName = instance.familyName if instance.styleName is None: logger.warning( "The given instance or instance at location %s is missing the " "stylename attribute, which is required. Copying over the styleName " "from the default font, which is probably wrong.", location, ) font.info.styleName = self.copy_info.styleName else: font.info.styleName = instance.styleName if instance.postScriptFontName: font.info.postscriptFontName = instance.postScriptFontName if instance.styleMapFamilyName: font.info.styleMapFamilyName = instance.styleMapFamilyName if instance.styleMapStyleName: font.info.styleMapStyleName = instance.styleMapStyleName # If the masters haven't set the OS/2 weight and width class, use the # user-space values ("input") of the axis mapping in the Designspace file for # weight and width axes, if they exist. The slnt axis' value maps 1:1 to # italicAngle. Clamp the values to the valid ranges. if info_instance.openTypeOS2WeightClass is None and "wght" in self.special_axes: weight_axis = self.special_axes["wght"] font.info.openTypeOS2WeightClass = weight_class_from_wght_value( weight_axis.map_backward(location[weight_axis.name]) ) if info_instance.openTypeOS2WidthClass is None and "wdth" in self.special_axes: width_axis = self.special_axes["wdth"] font.info.openTypeOS2WidthClass = width_class_from_wdth_value( width_axis.map_backward(location[width_axis.name]) ) if info_instance.italicAngle is None and "slnt" in self.special_axes: slant_axis = self.special_axes["slnt"] font.info.italicAngle = italic_angle_from_slnt_value( slant_axis.map_backward(location[slant_axis.name]) ) def _error_msg_no_default(designspace: designspaceLib.DesignSpaceDocument) -> str: if any(axis.map for axis in designspace.axes): bonus_msg = ( "For axes with a mapping, the 'default' values should have an " "'input=\"...\"' map value, where the corresponding 'output=\"...\"' " "value then points to the master source." ) else: bonus_msg = "" default_location = ", ".join( f"{k}: {v}" for k, v in designspace.newDefaultLocation().items() ) return ( "Can't generate UFOs from this Designspace because there is no default " f"master source at location '{default_location}'. Check that all 'default' " "values of all axes together point to a single actual master source. " f"{bonus_msg}" ) def location_to_key(location: Location) -> LocationKey: """Converts a Location into a sorted tuple so it can be used as a dict key.""" return tuple(sorted(location.items())) def anisotropic(location: Location) -> bool: """Tests if any single location value is a MutatorMath-style anisotropic value, i.e. is a tuple of (x, y).""" return any(isinstance(v, tuple) for v in location.values()) def collect_info_masters( designspace: designspaceLib.DesignSpaceDocument, axis_bounds: AxisBounds ) -> List[Tuple[Location, FontMathObject]]: """Return master Info objects wrapped by MathInfo.""" locations_and_masters = [] for source in designspace.sources: if source.layerName is not None: continue # No font info in source layers. normalized_location = varLib.models.normalizeLocation( source.location, axis_bounds ) locations_and_masters.append( (normalized_location, fontMath.MathInfo(source.font.info)) ) return locations_and_masters def collect_kerning_masters( designspace: designspaceLib.DesignSpaceDocument, axis_bounds: AxisBounds ) -> List[Tuple[Location, FontMathObject]]: """Return master kerning objects wrapped by MathKerning.""" # Always take the groups from the default source. This also avoids fontMath # making a union of all groups it is given. groups = designspace.default.font.groups locations_and_masters = [] for source in designspace.sources: if source.layerName is not None: continue # No kerning in source layers. # If a source has groups, they should match the default's. if source.font.groups and source.font.groups != groups: logger.warning( "The source %s (%s) contains different groups than the default source. " "The default source's groups will be used for the instances.", source.name, source.filename, ) # This assumes that groups of all sources are the same. normalized_location = varLib.models.normalizeLocation( source.location, axis_bounds ) locations_and_masters.append( (normalized_location, fontMath.MathKerning(source.font.kerning, groups)) ) return locations_and_masters def collect_glyph_masters( designspace: designspaceLib.DesignSpaceDocument, glyph_name: str, axis_bounds: AxisBounds, ) -> List[Tuple[Location, FontMathObject]]: """Return master glyph objects for glyph_name wrapped by MathGlyph. Note: skips empty source glyphs if the default glyph is not empty to almost match what ufoProcessor is doing. In e.g. Mutator Sans, the 'S.closed' glyph is left empty in one source layer. One could treat this as a source error, but ufoProcessor specifically has code to skip that empty glyph and carry on. """ locations_and_masters = [] default_glyph_empty = False other_glyph_empty = False for source in designspace.sources: if source.layerName is None: # Source font. source_layer = source.font.layers.defaultLayer else: # Source layer. source_layer = source.font.layers[source.layerName] # Sparse fonts do not and layers may not contain every glyph. if glyph_name not in source_layer: continue source_glyph = source_layer[glyph_name] if not (source_glyph.contours or source_glyph.components): if source is designspace.findDefault(): default_glyph_empty = True else: other_glyph_empty = True normalized_location = varLib.models.normalizeLocation( source.location, axis_bounds ) locations_and_masters.append( (normalized_location, fontMath.MathGlyph(source_glyph)) ) # Filter out empty glyphs if the default glyph is not empty. if not default_glyph_empty and other_glyph_empty: locations_and_masters = [ (loc, master) for loc, master in locations_and_masters if master.contours or master.components ] return locations_and_masters def width_class_from_wdth_value(wdth_user_value) -> int: """Return the OS/2 width class from the wdth axis user value. The OpenType 1.8.3 specification states: When mapping from 'wdth' values to usWidthClass, interpolate fractional values between the mapped values and then round, and clamp to the range 1 to 9. "Mapped values" probably means the in-percent numbers layed out for the OS/2 width class, so we are forcing these numerical semantics on the user values of the wdth axis. """ width_user_value = min(max(wdth_user_value, 50), 200) width_user_value_mapped = varLib.models.piecewiseLinearMap( width_user_value, WDTH_VALUE_TO_OS2_WIDTH_CLASS ) return fontTools.misc.fixedTools.otRound(width_user_value_mapped) def weight_class_from_wght_value(wght_user_value) -> int: """Return the OS/2 weight class from the wght axis user value.""" weight_user_value = min(max(wght_user_value, 1), 1000) return fontTools.misc.fixedTools.otRound(weight_user_value) def italic_angle_from_slnt_value(slnt_user_value) -> Union[int, float]: """Return the italic angle from the slnt axis user value.""" slant_user_value = min(max(slnt_user_value, -90), 90) return slant_user_value def swap_glyph_names(font: ufoLib2.Font, name_old: str, name_new: str): """Swap two existing glyphs in the default layer of a font (outlines, width, component references, kerning references, group membership). The idea behind swapping instead of overwriting is explained in https://github.com/fonttools/fonttools/tree/main/Doc/source/designspaceLib#ufo-instances. We need to keep the old glyph around in case any other glyph references it; glyphs that are not explicitly substituted by rules should not be affected by the rule application. The .unicodes are not swapped. The rules mechanism is supposed to swap glyphs, not characters. """ if name_old not in font or name_new not in font: raise InstantiatorError( f"Cannot swap glyphs '{name_old}' and '{name_new}', as either or both are " "missing." ) # 1. Swap outlines and glyph width. Ignore lib content and other properties. glyph_swap = ufoLib2.objects.Glyph(name="temporary_swap_glyph") glyph_old = font[name_old] glyph_new = font[name_new] p = glyph_swap.getPointPen() glyph_old.drawPoints(p) glyph_swap.width = glyph_old.width glyph_old.clearContours() glyph_old.clearComponents() p = glyph_old.getPointPen() glyph_new.drawPoints(p) glyph_old.width = glyph_new.width glyph_new.clearContours() glyph_new.clearComponents() p = glyph_new.getPointPen() glyph_swap.drawPoints(p) glyph_new.width = glyph_swap.width # 2. Swap anchors. glyph_swap.anchors = glyph_old.anchors glyph_old.anchors = glyph_new.anchors glyph_new.anchors = glyph_swap.anchors # 3. Remap components. for g in font: for c in g.components: if c.baseGlyph == name_old: c.baseGlyph = name_new elif c.baseGlyph == name_new: c.baseGlyph = name_old # 4. Swap literal names in kerning. kerning_new = {} for first, second in font.kerning.keys(): value = font.kerning[(first, second)] if first == name_old: first = name_new elif first == name_new: first = name_old if second == name_old: second = name_new elif second == name_new: second = name_old kerning_new[(first, second)] = value font.kerning = kerning_new # 5. Swap names in groups. for group_name, group_members in font.groups.items(): group_members_new = [] for name in group_members: if name == name_old: group_members_new.append(name_new) elif name == name_new: group_members_new.append(name_old) else: group_members_new.append(name) font.groups[group_name] = group_members_new @attr.s(auto_attribs=True, frozen=True, slots=True) class Variator: """A middle-man class that ingests a mapping of normalized locations to masters plus axis definitions and uses varLib to spit out interpolated instances at specified normalized locations. fontMath objects stand in for the actual master objects from the UFO. Upon generating an instance, these objects have to be extracted into an actual UFO object. """ masters: List[FontMathObject] location_to_master: Mapping[LocationKey, FontMathObject] model: varLib.models.VariationModel @classmethod def from_masters( cls, items: List[Tuple[Location, FontMathObject]], axis_order: List[str] ): masters = [] master_locations = [] location_to_master = {} for normalized_location, master in items: master_locations.append(normalized_location) masters.append(master) location_to_master[location_to_key(normalized_location)] = master model = varLib.models.VariationModel(master_locations, axis_order) return cls(masters, location_to_master, model) def instance_at(self, normalized_location: Location) -> FontMathObject: """Return a FontMathObject for the specified location ready to be inflated. If an instance location matches a master location, this method returns the master data instead of running through varLib. This is both an optimization _and_ it enables having a Designspace with instances matching their masters without requiring them to be compatible. Glyphs.app works this way; it will only generate a font from an instance, but compatibility is only required if there is actual interpolation to be done. This enables us to store incompatible bare masters in one Designspace and having arbitrary instance data applied to them. """ normalized_location_key = location_to_key(normalized_location) if normalized_location_key in self.location_to_master: return copy.deepcopy(self.location_to_master[normalized_location_key]) return self.model.interpolateFromMasters(normalized_location, self.masters) fontmake-2.4.1/Lib/fontmake/ttfautohint.py000066400000000000000000000050301410425502200205500ustar00rootroot00000000000000# Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import subprocess from fontmake.errors import FontmakeError, TTFAError def ttfautohint(in_file, out_file, args=None, **kwargs): """Thin wrapper around the ttfautohint command line tool. Can take in command line arguments directly as a string, or spelled out as Python keyword arguments. """ arg_list = ["ttfautohint"] file_args = [in_file, out_file] if args is not None: if kwargs: raise TypeError("Should not provide both cmd args and kwargs.") try: rv = subprocess.call(arg_list + args.split() + file_args) except OSError as e: raise FontmakeError( "Could not launch ttfautohint (is it installed?)", in_file ) from e if rv != 0: raise TTFAError(rv, in_file) return boolean_options = ( "debug", "composites", "dehint", "help", "ignore_restrictions", "detailed_info", "no_info", "adjust_subglyphs", "symbol", "ttfa_table", "verbose", "version", "windows_compatibility", ) other_options = ( "default_script", "fallback_script", "family_suffix", "hinting_limit", "fallback_stem_width", "hinting_range_min", "control_file", "hinting_range_max", "strong_stem_width", "increase_x_height", "x_height_snapping_exceptions", ) for option in boolean_options: if kwargs.pop(option, False): arg_list.append("--" + option.replace("_", "-")) for option in other_options: arg = kwargs.pop(option, None) if arg is not None: arg_list.append("--{}={}".format(option.replace("_", "-"), arg)) if kwargs: raise TypeError("Unexpected argument(s): " + ", ".join(kwargs.keys())) rv = subprocess.call(arg_list + file_args) if rv != 0: raise TTFAError(rv, in_file) fontmake-2.4.1/MANIFEST.in000066400000000000000000000002161410425502200150520ustar00rootroot00000000000000include README.rst include CONTRIBUTING.md include LICENSE include *requirements.txt recursive-include tests *.glyphs *.designspace *.plist fontmake-2.4.1/README.rst000066400000000000000000000044721410425502200150130ustar00rootroot00000000000000|GitHub Actions Build Status| |Python Versions| |PyPI Version| fontmake ======== This library provides a wrapper for several other Python libraries which together compile fonts from various sources (.glyphs, .ufo) into binaries (.otf, .ttf). Installation ~~~~~~~~~~~~ Fontmake requires Python 3.6 or later. Releases are available on `PyPI`_ and can be installed with `pip`_. .. code:: bash pip install fontmake Use the ``-U``, ``--upgrade`` option to update fontmake and its dependencies to the newest available release: .. code:: bash pip install -U fontmake Alternatively, you can download the git repository and install from source: .. code:: bash git clone https://github.com/googlefonts/fontmake cd fontmake pip install . Developers who want to quickly test changes to the source code without re-installing, can use the "--editable" option when installing from a local source checkout: .. code:: bash pip install -e . It is recommended to install fontmake inside a "virtual environment" to prevent conflicts between its dependencies and other modules installed globally. You could also use the `pipx`_ tool to automate the installation/upgrade of python apps like fontmake in isolated environments. Usage ~~~~~ After installation, you can use the ``fontmake`` console script. For example: .. code:: bash fontmake -g MyFont.glyphs # outputs binary font files for masters only Use ``fontmake -h`` to see options for specifying different types of input and output. You can also use fontmake as a module to run intermediate steps in the build process, via methods of the ``fontmake.font_project.FontProject`` class. .. _virtualenv: https://virtualenv.pypa.io .. _venv: https://docs.python.org/3/library/venv.html .. _pip: https://pip.pypa.io .. _pip documentation: https://pip.readthedocs.io/en/stable/user_guide/#requirements-files .. _PyPI: https://pypi.org/project/fontmake .. _Github releases: https://github.com/googlefonts/fontmake/releases .. _pipx: https://github.com/pipxproject/pipx .. |GitHub Actions Build Status| image:: https://github.com/googlefonts/fontmake/workflows/Test%20+%20Deploy/badge.svg .. |Python Versions| image:: https://img.shields.io/badge/python-3.6-blue.svg .. |PyPI Version| image:: https://img.shields.io/pypi/v/fontmake.svg :target: https://pypi.org/project/fontmake/ fontmake-2.4.1/build_pyz.sh000077500000000000000000000032111410425502200156520ustar00rootroot00000000000000#!/bin/bash set -e set -x HERE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" PLATFORMS=(manylinux1_x86_64 macosx_10_6_intel win32 win_amd64) PYTHON_VERSIONS=(3.6 3.7 3.8) FONTMAKE_VERSION="$(python setup.py --version)" FONTMAKE_WHEEL="${HERE}/dist/fontmake-${FONTMAKE_VERSION}-py3-none-any.whl" REQUIREMENTS="${HERE}/requirements.txt" LICENSE_FILE="${HERE}/LICENSE" OUTPUT_DIR="${HERE}/shivs" mkdir -p "${OUTPUT_DIR}" pushd "${OUTPUT_DIR}" for platform in ${PLATFORMS[*]}; do for version in ${PYTHON_VERSIONS[*]}; do if [ "${version}" == "3.8" ]; then if [ "$platform" == "macosx_10_6_intel" ]; then # for python 3.8 on macOS we only target >= 10.9 64-bit platform="macosx_10_9_x86_64" fi # python 3.8 removed the 'm' ABI flag m="" else m="m" fi v=${version//.} abi="cp${v}${m}" outdir="fontmake-${FONTMAKE_VERSION}-cp${v}-${abi}-${platform}" mkdir -p "${outdir}" if [[ $platform == win32 || $platform == win_amd64 ]]; then ext=".pyz" else ext="" fi shiv -c fontmake \ -o "${outdir}/fontmake${ext}" \ -p "/usr/bin/env python${version}" \ --python-version ${v} \ --platform ${platform} \ --abi ${abi} \ --implementation cp \ --only-binary=:all: \ -r "${REQUIREMENTS}" \ "${FONTMAKE_WHEEL}" cp "${HERE}/LICENSE" "${outdir}" zip -r "${outdir}.zip" "${outdir}" rm -rf "${outdir}" done done popd fontmake-2.4.1/pyproject.toml000066400000000000000000000002431410425502200162300ustar00rootroot00000000000000[build-system] requires = [ "setuptools", "wheel", "setuptools_scm", ] build-backend = "setuptools.build_meta" [tool.black] target-version = ["py36"] fontmake-2.4.1/requirements.txt000066400000000000000000000007231410425502200166030ustar00rootroot00000000000000fonttools[unicode,ufo,lxml]==4.22.0 ; platform_python_implementation == 'CPython' fonttools[unicode,ufo]==4.22.0 ; platform_python_implementation != 'CPython' cu2qu==1.6.7.post1 glyphsLib==5.3.2 ufo2ft[pathops]==2.21.0 MutatorMath==3.0.1 fontMath==0.6.0 defcon[lxml]==0.8.1 ; platform_python_implementation == 'CPython' defcon==0.8.1 ; platform_python_implementation != 'CPython' booleanOperations==0.9.0 ufoLib2==0.8.0 attrs==20.3.0 cffsubr==0.2.8 compreffor==0.5.1 fontmake-2.4.1/setup.cfg000066400000000000000000000003001410425502200151270ustar00rootroot00000000000000[wheel] universal = 0 [sdist] formats = zip [metadata] license_file = LICENSE [tool:pytest] filterwarnings = ignore:fromstring:DeprecationWarning ignore:tostring:DeprecationWarning fontmake-2.4.1/setup.py000066400000000000000000000052301410425502200150270ustar00rootroot00000000000000# Copyright 2015 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import site import sys from io import open from setuptools import find_packages, setup # See https://github.com/pypa/pip/issues/7953 site.ENABLE_USER_SITE = "--user" in sys.argv[1:] needs_wheel = {"bdist_wheel"}.intersection(sys.argv) wheel = ["wheel"] if needs_wheel else [] with open("README.rst", "r", encoding="utf-8") as f: long_description = f.read() setup( name="fontmake", use_scm_version={"write_to": "Lib/fontmake/_version.py"}, description=( "Compile fonts from sources (UFO, Glyphs) to binary (OpenType, TrueType)." ), long_description=long_description, url="https://github.com/googlei18n/fontmake", license="Apache Software License 2.0", packages=find_packages("Lib"), package_dir={"": "Lib"}, entry_points={"console_scripts": ["fontmake = fontmake.__main__:main"]}, setup_requires=wheel + ["setuptools_scm"], python_requires=">=3.6", install_requires=[ "fonttools[ufo,lxml,unicode]>=4.21.1 ; platform_python_implementation == 'CPython'", "fonttools[ufo,unicode]>=4.21.1 ; platform_python_implementation != 'CPython'", "glyphsLib>=5.3.2", "ufo2ft[compreffor]>=2.20.0", "fontMath>=0.6.0", "ufoLib2>=0.8.0", "attrs>=19", ], extras_require={ "pathops": ["skia-pathops>=0.3.0"], # this is now default; kept here for backward compatibility "lxml": [ # "lxml>=4.2.4", ], "mutatormath": ["MutatorMath>=2.1.2"], }, classifiers=[ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Multimedia :: Graphics", "Topic :: Multimedia :: Graphics :: Graphics Conversion", "Topic :: Multimedia :: Graphics :: Editors :: Vector-Based", "Topic :: Text Processing :: Fonts", ], ) fontmake-2.4.1/test_requirements.txt000066400000000000000000000002771410425502200176460ustar00rootroot00000000000000pytest>=4.5.0 coverage>=5 black ; platform_python_implementation == 'CPython' isort ; platform_python_implementation == 'CPython' flake8-bugbear ; platform_python_implementation == 'CPython' fontmake-2.4.1/tests/000077500000000000000000000000001410425502200144575ustar00rootroot00000000000000fontmake-2.4.1/tests/conftest.py000066400000000000000000000002051410425502200166530ustar00rootroot00000000000000from pathlib import Path import pytest @pytest.fixture(scope="session") def data_dir(): return Path(__file__).parent / "data" fontmake-2.4.1/tests/data/000077500000000000000000000000001410425502200153705ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceBrokenTest/000077500000000000000000000000001410425502200216165ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceBrokenTest/Designspace-MastersAsInstances.designspace000066400000000000000000000021571410425502200320270ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/DesignspaceTest.designspace000066400000000000000000000017271410425502200271210ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/000077500000000000000000000000001410425502200245005ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/fontinfo.plist000066400000000000000000000015661410425502200274070ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName MyFont guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV styleName Bold unitsPerEm 1000 xHeight 0 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/glyphs/000077500000000000000000000000001410425502200260065ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/glyphs/asas.glif000066400000000000000000000006511410425502200276020ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/glyphs/contents.plist000066400000000000000000000004401410425502200307160ustar00rootroot00000000000000 asas asas.glif l l.glif fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/glyphs/l.glif000066400000000000000000000005311410425502200271030ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/layercontents.plist000066400000000000000000000004371410425502200304530ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/lib.plist000066400000000000000000000004571410425502200263310ustar00rootroot00000000000000 public.glyphOrder l asas fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Bold.ufo/metainfo.plist000066400000000000000000000004761410425502200273660ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/000077500000000000000000000000001410425502200246675ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/fontinfo.plist000066400000000000000000000015671410425502200275770ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName MyFont guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV styleName Light unitsPerEm 1000 xHeight 0 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/glyphs/000077500000000000000000000000001410425502200261755ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/glyphs/asas.glif000066400000000000000000000007371410425502200277760ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/glyphs/contents.plist000066400000000000000000000004401410425502200311050ustar00rootroot00000000000000 asas asas.glif l l.glif fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/glyphs/l.glif000066400000000000000000000005271410425502200272770ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/layercontents.plist000066400000000000000000000004371410425502200306420ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/lib.plist000066400000000000000000000004571410425502200265200ustar00rootroot00000000000000 public.glyphOrder l asas fontmake-2.4.1/tests/data/DesignspaceBrokenTest/MyFont-Light.ufo/metainfo.plist000066400000000000000000000004761410425502200275550ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/000077500000000000000000000000001410425502200214415ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont.designspace000066400000000000000000000037631410425502200250750ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/000077500000000000000000000000001410425502200245415ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/fontinfo.plist000066400000000000000000000015671410425502200274510ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName MyFont guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV styleName Black unitsPerEm 1000 xHeight 0 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/glyphs/000077500000000000000000000000001410425502200260475ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/glyphs/Q_.alt.glif000066400000000000000000000026571410425502200300420ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/glyphs/Q_.glif000066400000000000000000000031731410425502200272550ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/glyphs/Q_.ss01.alt.glif000066400000000000000000000023611410425502200306170ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/glyphs/Q_.ss01.glif000066400000000000000000000023551410425502200300430ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/glyphs/contents.plist000066400000000000000000000006341410425502200307640ustar00rootroot00000000000000 Q Q_.glif Q.alt Q_.alt.glif Q.ss01 Q_.ss01.glif Q.ss01.alt Q_.ss01.alt.glif fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/layercontents.plist000066400000000000000000000004231410425502200305070ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/lib.plist000066400000000000000000000005501410425502200263640ustar00rootroot00000000000000 public.glyphOrder Q Q.alt Q.ss01 Q.ss01.alt fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Black.ufo/metainfo.plist000066400000000000000000000004641410425502200274240ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/000077500000000000000000000000001410425502200244105ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/fontinfo.plist000066400000000000000000000015721410425502200273140ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName MyFont guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV styleName Hairline unitsPerEm 1000 xHeight 0 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/glyphs/000077500000000000000000000000001410425502200257165ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/glyphs/Q_.alt.glif000066400000000000000000000026371410425502200277070ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/glyphs/Q_.glif000066400000000000000000000031521410425502200271210ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/glyphs/Q_.ss01.alt.glif000066400000000000000000000023571410425502200304730ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/glyphs/Q_.ss01.glif000066400000000000000000000023571410425502200277140ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/glyphs/contents.plist000066400000000000000000000006341410425502200306330ustar00rootroot00000000000000 Q Q_.glif Q.alt Q_.alt.glif Q.ss01 Q_.ss01.glif Q.ss01.alt Q_.ss01.alt.glif fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/layercontents.plist000066400000000000000000000004231410425502200303560ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/lib.plist000066400000000000000000000005501410425502200262330ustar00rootroot00000000000000 public.glyphOrder Q Q.alt Q.ss01 Q.ss01.alt fontmake-2.4.1/tests/data/DesignspaceRuleOrder/MyFont_Hair.ufo/metainfo.plist000066400000000000000000000004641410425502200272730ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceTest/000077500000000000000000000000001410425502200204555ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTest/DesignspaceTest-bare.designspace000066400000000000000000000013511410425502200266600ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/DesignspaceTest-instance-attrs.designspace000066400000000000000000000015241410425502200307100ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/DesignspaceTest-lib.designspace000066400000000000000000000024741410425502200265240ustar00rootroot00000000000000 blorb hurx public.skipExportGlyphs x y z public.skipExportGlyphs a b c fontmake-2.4.1/tests/data/DesignspaceTest/DesignspaceTest-opsz.designspace000066400000000000000000000011551410425502200267440ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/DesignspaceTest-slnt.designspace000066400000000000000000000011461410425502200267310ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/DesignspaceTest-wght-wdth.designspace000066400000000000000000000016241410425502200276670ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/DesignspaceTest.designspace000066400000000000000000000017271410425502200257600ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Bold.ufo/000077500000000000000000000000001410425502200233375ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Bold.ufo/fontinfo.plist000066400000000000000000000010441410425502200262350ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName MyFont styleName Bold unitsPerEm 1000 xHeight 0 fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Bold.ufo/glyphs/000077500000000000000000000000001410425502200246455ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Bold.ufo/glyphs/contents.plist000066400000000000000000000003551410425502200275620ustar00rootroot00000000000000 l l.glif fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Bold.ufo/glyphs/l.glif000066400000000000000000000005311410425502200257420ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Bold.ufo/layercontents.plist000066400000000000000000000004371410425502200273120ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Bold.ufo/metainfo.plist000066400000000000000000000004761410425502200262250ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/000077500000000000000000000000001410425502200235265ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/fontinfo.plist000066400000000000000000000015561410425502200264340ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName MyFont styleName Light unitsPerEm 1000 xHeight 0 openTypeOS2Panose 2 11 5 4 2 2 2 2 2 4 fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/glyphs/000077500000000000000000000000001410425502200250345ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/glyphs/contents.plist000066400000000000000000000003551410425502200277510ustar00rootroot00000000000000 l l.glif fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/glyphs/l.glif000066400000000000000000000005271410425502200261360ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/groups.plist000066400000000000000000000005451410425502200261260ustar00rootroot00000000000000 nonkerning_group A public.kern2.asdf A fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/layercontents.plist000066400000000000000000000004371410425502200275010ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/lib.plist000066400000000000000000000003601410425502200253500ustar00rootroot00000000000000 blorb asasa fontmake-2.4.1/tests/data/DesignspaceTest/MyFont-Light.ufo/metainfo.plist000066400000000000000000000004761410425502200264140ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/000077500000000000000000000000001410425502200233035ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Light.ufo/000077500000000000000000000000001410425502200302255ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Light.ufo/fontinfo.plist000066400000000000000000000016011410425502200331220ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName Designspace Test guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV styleName Light unitsPerEm 1000 xHeight 0 fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Light.ufo/glyphs/000077500000000000000000000000001410425502200315335ustar00rootroot00000000000000contents.plist000066400000000000000000000002671410425502200343730ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Light.ufo/glyphs layercontents.plist000066400000000000000000000004371410425502200341210ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Light.ufo public.default glyphs fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Light.ufo/metainfo.plist000066400000000000000000000004761410425502200331130ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Regular.ufo/000077500000000000000000000000001410425502200305575ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Regular.ufo/features.fea000066400000000000000000000000241410425502200330460ustar00rootroot00000000000000include(family.fea) fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Regular.ufo/fontinfo.plist000066400000000000000000000016031410425502200334560ustar00rootroot00000000000000 ascender 0 capHeight 0 descender 0 familyName Designspace Test guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV styleName Regular unitsPerEm 1000 xHeight 0 fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Regular.ufo/glyphs/000077500000000000000000000000001410425502200320655ustar00rootroot00000000000000contents.plist000066400000000000000000000002671410425502200347250ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Regular.ufo/glyphs layercontents.plist000066400000000000000000000004371410425502200344530ustar00rootroot00000000000000fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Regular.ufo public.default glyphs fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTest-Regular.ufo/metainfo.plist000066400000000000000000000004761410425502200334450ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/DesignspaceTestSharedFeatures.designspace000066400000000000000000000020431410425502200334240ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/DesignspaceTestSharedFeatures/family.fea000066400000000000000000000000071410425502200252360ustar00rootroot00000000000000# test fontmake-2.4.1/tests/data/GlyphsUnitTestSans.glyphs000066400000000000000000000735631410425502200224310ustar00rootroot00000000000000{ .appVersion = "1230"; DisplayStrings = ( A ); classes = ( { code = A; name = c2sc_source; }, { code = a.sc; name = c2sc_target; }, { code = ""; name = numbers; }, { code = a; name = smcp_source; }, { code = a.sc; name = smcp_target; } ); customParameters = ( { name = note; value = "Bla bla"; } ); date = "2015-06-08 08:53:00 +0000"; familyName = "Glyphs Unit Test Sans"; featurePrefixes = ( { code = "# Dancing Shoes 0.1.4 OpenType feature code generator by Yanone, Copyright 2009\012# Code generated for AFDKO version 2.5\012\012\012languagesystem DFLT dflt; # Default, Default\012languagesystem latn dflt; # Latin, Default\012\012\012\012\012"; name = Languagesystems; } ); features = ( { automatic = 1; code = "feature c2sc;\012feature smcp;\012"; name = aalt; }, { code = "# Small Capitals From Capitals\012\012 sub @c2sc_source by @c2sc_target; "; name = c2sc; }, { code = "# Small Capitals\012\012 sub @smcp_source by @smcp_target; "; name = smcp; } ); fontMaster = ( { alignmentZones = ( "{800, 10}", "{700, 10}", "{470, 10}", "{0, -10}", "{-200, -10}" ); ascender = 800; capHeight = 700; customParameters = ( { name = TTFStems; value = ( { horizontal = 1; name = Thin; width = 16; }, { horizontal = 1; name = Lowercase; width = 16; }, { horizontal = 1; name = Uppercase; width = 18; } ); } ); descender = -200; guideLines = ( { position = "{-113, 574}"; }, { position = "{524, 141}"; }, { position = "{-113, 765}"; }, { position = "{524, -122}"; } ); horizontalStems = ( 16, 16, 18 ); id = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; userData = { GSOffsetHorizontal = 9; GSOffsetMakeStroke = 1; GSOffsetVertical = 9; GSRoughenHorizontal = 15; GSRoughenSegmentLength = 15; GSRoughenVertical = 10; com.schriftgestaltung.Glyphs.ufoData = { customBinaryData = <746865206279746573>; }; noodleExtremesAndInflections = 1; noodleRemoveOverlap = 0; noodleThickness = "106.0"; }; verticalStems = ( 17, 19 ); weight = Light; weightValue = 17; xHeight = 470; }, { alignmentZones = ( "{800, 12}", "{700, 12}", "{480, 12}", "{0, -12}", "{-200, -12}" ); ascender = 800; capHeight = 700; customParameters = ( { name = TTFStems; value = ( { horizontal = 1; name = Thin; width = 80; }, { horizontal = 1; name = Lowercase; width = 88; }, { horizontal = 1; name = Uppercase; width = 91; } ); } ); descender = -200; guideLines = ( { position = "{-126, 593}"; }, { locked = 1; position = "{-126, 90}"; }, { position = "{-113, 773}"; }, { position = "{524, -133}"; }, { position = "{-126, 321}"; }, { position = "{-113, 959}"; } ); horizontalStems = ( 80, 88, 91 ); id = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; userData = { GSOffsetHorizontal = 45; GSOffsetMakeStroke = 1; GSOffsetVertical = 44; GSRoughenHorizontal = 15; GSRoughenSegmentLength = 15; GSRoughenVertical = 10; }; verticalStems = ( 90, 93 ); weightValue = 90; xHeight = 480; }, { alignmentZones = ( "{800, 15}", "{700, 15}", "{490, 15}", "{0, -15}", "{-200, -15}" ); ascender = 800; capHeight = 700; customParameters = ( { name = TTFStems; value = ( { horizontal = 1; name = Thin; width = 108; }, { horizontal = 1; name = Lowercase; width = 210; }, { horizontal = 1; name = Uppercase; width = 215; } ); } ); descender = -200; guideLines = ( { position = "{10, 660}"; }, { position = "{524, 44}"; }, { position = "{-113, 800}"; }, { position = "{524, -200}"; }, { position = "{998, -212}"; } ); horizontalStems = ( 108, 210, 215 ); id = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; userData = { GSOffsetHorizontal = 115; GSOffsetMakeStroke = 1; GSOffsetProportional = 1; GSOffsetVertical = 10; }; verticalStems = ( 220, 225 ); weight = Bold; weightValue = 220; xHeight = 490; } ); glyphs = ( { glyphname = A; lastChange = "2017-07-17 13:57:06 +0000"; layers = ( { anchors = ( { name = bottom; position = "{377, 0}"; }, { name = ogonek; position = "{678, 10}"; }, { name = top; position = "{377, 700}"; } ); background = { paths = ( { closed = 1; nodes = ( "566.99 700 LINE", "191 700 LINE", "24 0 LINE", "270 0 LINE", "364 470 LINE", "379 470 LINE", "477 0 LINE", "733 0 LINE" ); } ); }; layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; paths = ( { closed = 1; nodes = ( "555 700 LINE", "205 700 LINE", "20 0 LINE", "253 0 LINE", "356 470 LINE", "385 470 LINE", "491 0 LINE", "733 0 LINE" ); }, { closed = 1; nodes = ( "162 268 LINE", "154 103 LINE", "596 103 LINE", "600 268 LINE" ); } ); width = 753; }, { anchors = ( { name = bottom; position = "{329, 0}"; }, { name = ogonek; position = "{591, 10}"; }, { name = top; position = "{329, 700}"; } ); hints = ( { horizontal = 1; origin = "{1, 1}"; target = "{1, 0}"; type = Stem; }, { horizontal = 1; origin = "{0, 1}"; target = "{0, 4}"; type = Stem; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; paths = ( { closed = 1; nodes = ( "412 700 LINE", "248 700 LINE", "40 0 LINE", "134 0 LINE", "313 610 LINE", "342 610 LINE", "521 0 LINE", "617 0 LINE" ); }, { closed = 1; nodes = ( "150 269 LINE", "148 178 LINE", "510 178 LINE", "514 269 LINE" ); } ); width = 657; }, { anchors = ( { name = bottom; position = "{297, 0}"; }, { name = ogonek; position = "{548, 0}"; }, { name = top; position = "{297, 700}"; } ); background = { paths = ( { closed = 1; nodes = ( "133 253 LINE", "134 215 LINE", "451 215 LINE", "455 253 LINE" ); } ); }; backgroundImage = { crop = "{{0, 0}, {489, 637}}"; imagePath = A.jpg; }; guideLines = ( { angle = 71.7587; position = "{45, 0}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; paths = ( { closed = 1; nodes = ( "321 700 LINE {name = \"Hello World\";}", "275 700 LINE", "45 0 LINE", "65 0 LINE", "289 679 LINE", "307 679 LINE", "527 0 LINE", "548 0 LINE" ); }, { closed = 1; nodes = ( "128 225 LINE", "123 207 LINE", "472 207 LINE", "467 225 LINE" ); } ); width = 593; } ); leftKerningGroup = A; rightKerningGroup = A; unicode = 0041; script = ""; category = ""; subCategory = ""; }, { glyphname = Adieresis; layers = ( { components = ( { name = A; }, { name = dieresis; transform = "{1, 0, 0, 1, 110, 230}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; width = 593; }, { components = ( { name = A; }, { name = dieresis; transform = "{1, 0, 0, 1, 128, 220}"; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; width = 657; }, { components = ( { name = A; }, { name = dieresis; transform = "{1, 0, 0, 1, 110, 210}"; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; width = 753; } ); unicode = 00C4; }, { glyphname = a; lastChange = "2019-05-09 10:17:28 +0000"; layers = ( { anchors = ( { name = bottom; position = "{184, 0}"; }, { name = ogonek; position = "{488, 0}"; }, { name = top; position = "{258, 490}"; } ); background = { paths = ( { closed = 1; nodes = ( "268 153 LINE SMOOTH", "268 123 OFFCURVE", "254 113 OFFCURVE", "236 113 CURVE SMOOTH", "214 113 OFFCURVE", "205 127 OFFCURVE", "205 143 CURVE SMOOTH", "205 155 OFFCURVE", "210 164 OFFCURVE", "218 170 CURVE SMOOTH", "233 181 OFFCURVE", "254 182 OFFCURVE", "275 182 CURVE", "295 289 LINE", "203 289 OFFCURVE", "123 277 OFFCURVE", "72 240 CURVE SMOOTH", "40 216 OFFCURVE", "21 182 OFFCURVE", "21 133 CURVE SMOOTH", "21 49 OFFCURVE", "75 -8 OFFCURVE", "184 -8 CURVE SMOOTH", "260 -8 OFFCURVE", "301 16 OFFCURVE", "322 49 CURVE", "309 57 LINE", "336 0 LINE", "488 0 LINE", "488 454 LINE", "437 484 OFFCURVE", "354 505 OFFCURVE", "255 505 CURVE SMOOTH", "167 505 OFFCURVE", "86 489 OFFCURVE", "25 461 CURVE", "56 298 LINE", "90 311 OFFCURVE", "134 322 OFFCURVE", "194 322 CURVE SMOOTH", "225 322 OFFCURVE", "270 319 OFFCURVE", "308 305 CURVE", "268 392 LINE" ); } ); }; layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; paths = ( { closed = 1; nodes = ( "268 153 LINE SMOOTH", "268 123 OFFCURVE", "254 113 OFFCURVE", "236 113 CURVE SMOOTH", "214 113 OFFCURVE", "205 127 OFFCURVE", "205 143 CURVE SMOOTH", "205 155 OFFCURVE", "210 164 OFFCURVE", "218 170 CURVE SMOOTH", "233 181 OFFCURVE", "254 182 OFFCURVE", "275 182 CURVE", "295 289 LINE", "203 289 OFFCURVE", "123 277 OFFCURVE", "72 240 CURVE SMOOTH", "40 216 OFFCURVE", "21 182 OFFCURVE", "21 133 CURVE SMOOTH", "21 49 OFFCURVE", "75 -8 OFFCURVE", "184 -8 CURVE SMOOTH", "250 -8 OFFCURVE", "288 12 OFFCURVE", "310 44 CURVE", "320 44 LINE", "336 0 LINE", "488 0 LINE", "488 454 LINE", "437 484 OFFCURVE", "354 505 OFFCURVE", "255 505 CURVE SMOOTH", "167 505 OFFCURVE", "86 489 OFFCURVE", "25 461 CURVE", "56 298 LINE", "90 311 OFFCURVE", "134 322 OFFCURVE", "194 322 CURVE SMOOTH", "225 322 OFFCURVE", "270 319 OFFCURVE", "308 305 CURVE", "268 392 LINE" ); } ); width = 518; }, { anchors = ( { name = bottom; position = "{218, 0}"; }, { name = ogonek; position = "{423, 0}"; }, { name = top; position = "{248, 480}"; } ); annotations = ( { position = "{427, 535}"; text = "This is a text annotation"; type = Text; }, { angle = 41.22902; position = "{436, 446}"; type = Arrow; }, { position = "{334.937, 407.08}"; type = Circle; width = 65.05341; }, { position = "{301, 49}"; type = Plus; }, { position = "{372, 172}"; type = Minus; } ); background = { paths = ( { closed = 1; nodes = ( "333 176 LINE SMOOTH", "333 119 OFFCURVE", "309 69 OFFCURVE", "231 69 CURVE SMOOTH", "170 69 OFFCURVE", "153 99 OFFCURVE", "153 127 CURVE SMOOTH", "153 152 OFFCURVE", "166 169 OFFCURVE", "183 179 CURVE SMOOTH", "219 201 OFFCURVE", "284 204 OFFCURVE", "338 204 CURVE", "338 282 LINE", "249 282 OFFCURVE", "193 276 OFFCURVE", "142 251 CURVE SMOOTH", "94 227 OFFCURVE", "65 184 OFFCURVE", "65 124 CURVE SMOOTH", "65 41 OFFCURVE", "119 -11 OFFCURVE", "215 -11 CURVE SMOOTH", "283 -11 OFFCURVE", "325 14 OFFCURVE", "352 56 CURVE", "330 67 LINE", "346 0 LINE", "423 0 LINE", "423 435 LINE", "383 468 OFFCURVE", "317 492 OFFCURVE", "237 492 CURVE SMOOTH", "172 492 OFFCURVE", "117 476 OFFCURVE", "72 460 CURVE", "86 371 LINE", "122 387 OFFCURVE", "167 400 OFFCURVE", "226 400 CURVE SMOOTH", "263 400 OFFCURVE", "312 395 OFFCURVE", "353 361 CURVE", "333 454 LINE" ); } ); }; layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; paths = ( { closed = 1; nodes = ( "333 176 LINE SMOOTH", "333 119 OFFCURVE", "309 69 OFFCURVE", "231 69 CURVE SMOOTH", "170 69 OFFCURVE", "153 99 OFFCURVE", "153 127 CURVE SMOOTH", "153 152 OFFCURVE", "166 169 OFFCURVE", "183 179 CURVE SMOOTH", "219 200 OFFCURVE", "284 204 OFFCURVE", "338 204 CURVE", "338 282 LINE", "249 282 OFFCURVE", "193 276 OFFCURVE", "142 251 CURVE SMOOTH", "94 227 OFFCURVE", "65 185 OFFCURVE", "65 125 CURVE SMOOTH", "65 42 OFFCURVE", "119 -11 OFFCURVE", "215 -11 CURVE SMOOTH", "277 -11 OFFCURVE", "310 11 OFFCURVE", "330 41 CURVE", "338 41 LINE", "346 0 LINE", "423 0 LINE", "423 435 LINE", "383 468 OFFCURVE", "316 492 OFFCURVE", "232 492 CURVE SMOOTH", "171 492 OFFCURVE", "116 479 OFFCURVE", "72 460 CURVE", "86 371 LINE", "122 388 OFFCURVE", "166 400 OFFCURVE", "225 400 CURVE SMOOTH", "262 400 OFFCURVE", "312 395 OFFCURVE", "353 361 CURVE", "333 454 LINE" ); } ); width = 496; }, { anchors = ( { name = bottom; position = "{218, 0}"; }, { name = ogonek; position = "{369, 0}"; }, { name = top; position = "{226, 471}"; } ); background = { paths = ( { closed = 1; nodes = ( "352 147 LINE SMOOTH", "352 68 OFFCURVE", "314 7 OFFCURVE", "212 7 CURVE SMOOTH", "132 7 OFFCURVE", "97 47 OFFCURVE", "97 105 CURVE SMOOTH", "97 136 OFFCURVE", "107 160 OFFCURVE", "125 178 CURVE SMOOTH", "166 219 OFFCURVE", "249 224 OFFCURVE", "355 224 CURVE", "355 241 LINE", "245 241 OFFCURVE", "158 233 OFFCURVE", "113 190 CURVE SMOOTH", "92 169 OFFCURVE", "80 141 OFFCURVE", "80 105 CURVE SMOOTH", "80 39 OFFCURVE", "119 -10 OFFCURVE", "212 -10 CURVE SMOOTH", "281 -10 OFFCURVE", "336 15 OFFCURVE", "357 83 CURVE", "351 91 LINE", "354 0 LINE", "369 0 LINE", "369 428 LINE", "333 460 OFFCURVE", "291 480 OFFCURVE", "224 480 CURVE SMOOTH", "163 480 OFFCURVE", "116 462 OFFCURVE", "82 438 CURVE", "87 423 LINE", "123 448 OFFCURVE", "167 463 OFFCURVE", "224 463 CURVE SMOOTH", "284 463 OFFCURVE", "323 445 OFFCURVE", "355 417 CURVE", "352 429 LINE" ); } ); }; layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; paths = ( { closed = 1; nodes = ( "352 147 LINE SMOOTH {name = Hello;\nrememberToMakeCoffee = \"1\";}", "352 68 OFFCURVE", "314 7 OFFCURVE", "212 7 CURVE SMOOTH", "132 7 OFFCURVE", "97 47 OFFCURVE", "97 105 CURVE SMOOTH", "97 136 OFFCURVE", "107 160 OFFCURVE", "125 178 CURVE SMOOTH", "166 219 OFFCURVE", "249 224 OFFCURVE", "355 224 CURVE", "355 241 LINE", "245 241 OFFCURVE", "158 233 OFFCURVE", "113 190 CURVE SMOOTH", "92 169 OFFCURVE", "80 141 OFFCURVE", "80 105 CURVE SMOOTH", "80 39 OFFCURVE", "119 -10 OFFCURVE", "212 -10 CURVE SMOOTH", "283 -10 OFFCURVE", "334 18 OFFCURVE", "349 68 CURVE", "352 68 LINE", "354 0 LINE", "369 0 LINE", "369 428 LINE", "333 460 OFFCURVE", "291 480 OFFCURVE", "224 480 CURVE SMOOTH", "163 480 OFFCURVE", "116 462 OFFCURVE", "82 438 CURVE", "87 423 LINE", "123 448 OFFCURVE", "167 463 OFFCURVE", "224 463 CURVE SMOOTH", "284 463 OFFCURVE", "323 445 OFFCURVE", "355 417 CURVE", "352 429 LINE" ); } ); width = 456; } ); leftKerningGroup = a; rightKerningGroup = a; rightMetricsKey = m; unicode = 0061; }, { glyphname = adieresis; lastChange = "2016-03-18 09:51:27 +0000"; layers = ( { components = ( { name = a; }, { name = dieresis; transform = "{1, 0, 0, 1, 39, 1}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; width = 456; }, { components = ( { name = a; }, { name = dieresis; transform = "{1, 0, 0, 1, 47, 0}"; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; width = 496; }, { components = ( { name = a; }, { name = dieresis; transform = "{1, 0, 0, 1, -9, 0}"; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; width = 518; } ); unicode = 00E4; }, { glyphname = h; lastChange = "2017-10-09 14:18:19 +0000"; layers = ( { components = ( { name = _part.stem; piece = { height = 100; }; }, { name = _part.shoulder; piece = { crotchDepth = -80.20097; }; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; width = 511; }, { components = ( { name = _part.stem; piece = { height = 100; }; }, { name = _part.shoulder; piece = { crotchDepth = -80.20097; }; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; width = 532; }, { components = ( { name = _part.stem; piece = { height = 100; }; }, { name = _part.shoulder; piece = { crotchDepth = -80.20097; }; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; width = 560; } ); leftMetricsKey = m; rightMetricsKey = m; unicode = 0068; }, { glyphname = m; lastChange = "2017-10-09 14:03:19 +0000"; layers = ( { components = ( { name = _part.stem; }, { name = _part.shoulder; piece = { shoulderWidth = 0; }; }, { name = _part.shoulder; piece = { shoulderWidth = 0; }; transform = "{1, 0, 0, 1, 264, 0}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; width = 745; }, { components = ( { name = _part.stem; }, { name = _part.shoulder; piece = { shoulderWidth = 0; }; }, { name = _part.shoulder; piece = { shoulderWidth = 0; }; transform = "{1, 0, 0, 1, 270, 0}"; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; width = 820; }, { components = ( { name = _part.stem; }, { name = _part.shoulder; piece = { shoulderWidth = 0; }; }, { name = _part.shoulder; piece = { shoulderWidth = 0; }; transform = "{1, 0, 0, 1, 258, 0}"; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; width = 760; } ); unicode = 006D; }, { glyphname = n; lastChange = "2017-10-09 14:04:04 +0000"; layers = ( { background = { paths = ( { closed = 1; nodes = ( "250 0 LINE", "250 240 LINE SMOOTH", "250 272 OFFCURVE", "264 283 OFFCURVE", "284 283 CURVE SMOOTH", "295 283 OFFCURVE", "304 280 OFFCURVE", "310 276 CURVE", "310 0 LINE", "530 0 LINE", "530 448 LINE", "490 478 OFFCURVE", "430 501 OFFCURVE", "357 501 CURVE SMOOTH", "256 501 OFFCURVE", "199 459 OFFCURVE", "173 386 CURVE", "197 366 LINE", "162 490 LINE", "30 490 LINE", "30 0 LINE" ); } ); }; components = ( { name = _part.shoulder; }, { name = _part.stem; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; width = 560; }, { background = { paths = ( { closed = 1; nodes = ( "167 0 LINE", "167 270 LINE SMOOTH", "167 362 OFFCURVE", "209 402 OFFCURVE", "277 402 CURVE SMOOTH", "315 402 OFFCURVE", "345 390 OFFCURVE", "365 370 CURVE", "365 0 LINE", "455 0 LINE", "455 423 LINE", "423 454 OFFCURVE", "374 490 OFFCURVE", "288 490 CURVE SMOOTH", "199 490 OFFCURVE", "150 452 OFFCURVE", "139 382 CURVE", "159 356 LINE", "139 480 LINE", "77 480 LINE", "77 0 LINE" ); } ); }; components = ( { name = _part.shoulder; }, { name = _part.stem; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; width = 528; }, { background = { paths = ( { closed = 1; nodes = ( "117 0 LINE", "117 322 LINE SMOOTH", "117 435 OFFCURVE", "175 491 OFFCURVE", "270 491 CURVE SMOOTH", "324 491 OFFCURVE", "366 474 OFFCURVE", "394 445 CURVE", "394 -1 LINE", "411 -1 LINE", "411 435 LINE", "378 475 OFFCURVE", "340 509 OFFCURVE", "263 509 CURVE SMOOTH", "180 509 OFFCURVE", "133 468 OFFCURVE", "117 406 CURVE", "134 376 LINE", "123 500 LINE", "100 500 LINE", "100 0 LINE" ); } ); }; components = ( { name = _part.shoulder; }, { name = _part.stem; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; width = 501; } ); leftKerningGroup = n; leftMetricsKey = m; rightKerningGroup = n; rightMetricsKey = m; unicode = 006E; }, { color = 10; glyphname = a.sc; lastChange = "2016-12-19 17:35:01 +0000"; layers = ( { anchors = ( { name = bottom; position = "{307, 0}"; }, { name = ogonek; position = "{608, 0}"; }, { name = top; position = "{307, 552}"; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; paths = ( { closed = 1; nodes = ( "461 552 LINE", "158 552 LINE", "5 0 LINE", "208 0 LINE", "289 351 LINE", "312 351 LINE", "395 0 LINE", "608 0 LINE" ); }, { closed = 1; nodes = ( "122 234 LINE", "115 65 LINE", "495 65 LINE", "498 234 LINE" ); } ); width = 613; }, { anchors = ( { name = bottom; position = "{268, 0}"; }, { name = ogonek; position = "{511, 0}"; }, { name = top; position = "{268, 540}"; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; paths = ( { closed = 1; nodes = ( "357 540 LINE", "191 540 LINE", "24 0 LINE", "119 0 LINE", "255 448 LINE", "277 448 LINE", "414 0 LINE", "511 0 LINE" ); }, { closed = 1; nodes = ( "114 208 LINE", "111 125 LINE", "424 125 LINE", "427 208 LINE" ); } ); width = 535; }, { anchors = ( { name = bottom; position = "{240, 0}"; }, { name = ogonek; position = "{445, 0}"; }, { name = top; position = "{240, 528}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; paths = ( { closed = 1; nodes = ( "252 528 LINE", "228 528 LINE", "33 0 LINE", "41 0 LINE", "234 519 LINE", "247 519 LINE", "437 0 LINE", "445 0 LINE" ); }, { closed = 1; nodes = ( "99 167 LINE", "95 159 LINE", "384 159 LINE", "380 167 LINE" ); } ); width = 478; } ); leftKerningGroup = A.sc; rightKerningGroup = A.sc; rightMetricsKey = "=|"; }, { glyphname = dieresis; lastChange = "2015-12-31 14:44:23 +0000"; layers = ( { anchors = ( { name = _top; position = "{187, 470}"; }, { name = top; position = "{188, 650}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; paths = ( { closed = 1; nodes = ( "261 650 LINE", "261 621 LINE", "289 621 LINE", "289 650 LINE" ); }, { closed = 1; nodes = ( "88 650 LINE", "88 621 LINE", "116 621 LINE", "116 650 LINE" ); } ); width = 600; }, { anchors = ( { name = _top; position = "{201, 480}"; }, { name = top; position = "{201, 700}"; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; paths = ( { closed = 1; nodes = ( "252 700 LINE", "252 601 LINE", "349 601 LINE", "349 700 LINE" ); }, { closed = 1; nodes = ( "52 700 LINE", "52 601 LINE", "149 601 LINE", "149 700 LINE" ); } ); width = 600; }, { anchors = ( { name = _top; position = "{267, 490}"; }, { name = top; position = "{267, 740}"; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; paths = ( { closed = 1; nodes = ( "298 735 LINE", "298 547 LINE", "482 547 LINE", "482 735 LINE" ); }, { closed = 1; nodes = ( "48 735 LINE", "48 547 LINE", "232 547 LINE", "232 735 LINE" ); } ); width = 600; } ); unicode = 00A8; }, { export = 0; glyphname = _part.shoulder; lastChange = "2017-10-09 13:47:55 +0000"; layers = ( { anchors = ( { name = _connect; position = "{117, 0}"; }, { name = connect; position = "{411, 0}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; paths = ( { closed = 1; nodes = ( "117 266 LINE", "117 410 OFFCURVE", "173 463 OFFCURVE", "262 463 CURVE SMOOTH", "322 463 OFFCURVE", "365 437 OFFCURVE", "394 408 CURVE", "394 0 LINE", "411 0 LINE", "411 414 LINE", "377 450 OFFCURVE", "333 479 OFFCURVE", "262 479 CURVE SMOOTH", "169 479 OFFCURVE", "132 429 OFFCURVE", "121 384 CURVE", "102 384 LINE" ); } ); userData = { PartSelection = { crotchDepth = 2; shoulderWidth = 2; }; }; width = 501; }, { anchors = ( { name = _connect; position = "{167, 0}"; }, { name = connect; position = "{455, 0}"; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; paths = ( { closed = 1; nodes = ( "167 246 LINE", "167 355 OFFCURVE", "203 402 OFFCURVE", "277 402 CURVE SMOOTH", "315 402 OFFCURVE", "345 390 OFFCURVE", "365 370 CURVE", "365 0 LINE", "455 0 LINE", "455 423 LINE", "425 452 OFFCURVE", "380 490 OFFCURVE", "294 490 CURVE SMOOTH", "205 490 OFFCURVE", "170 452 OFFCURVE", "155 409 CURVE", "131 409 LINE" ); } ); userData = { PartSelection = { crotchDepth = 2; shoulderWidth = 2; }; }; width = 528; }, { anchors = ( { name = _connect; position = "{250, 0}"; }, { name = connect; position = "{530, 0}"; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; paths = ( { closed = 1; nodes = ( "250 229 LINE", "250 268 OFFCURVE", "259 283 OFFCURVE", "284 283 CURVE SMOOTH", "295 283 OFFCURVE", "304 280 OFFCURVE", "310 276 CURVE", "310 0 LINE", "530 0 LINE", "530 448 LINE", "490 478 OFFCURVE", "430 501 OFFCURVE", "357 501 CURVE SMOOTH", "259 501 OFFCURVE", "209 461 OFFCURVE", "188 401 CURVE", "162 401 LINE" ); } ); userData = { PartSelection = { crotchDepth = 2; shoulderWidth = 2; }; }; width = 560; }, { anchors = ( { name = _connect; position = "{117, 0}"; }, { name = connect; position = "{381, 0}"; } ); associatedMasterId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; layerId = "50EFFDD5-7E17-4ADC-BBC9-E16AAD6631DE"; name = NarrowShoulder; paths = ( { closed = 1; nodes = ( "117 266 LINE", "117 410 OFFCURVE", "173 463 OFFCURVE", "252 463 CURVE SMOOTH", "292 463 OFFCURVE", "335 437 OFFCURVE", "364 408 CURVE", "364 0 LINE", "381 0 LINE", "381 414 LINE", "347 450 OFFCURVE", "303 479 OFFCURVE", "252 479 CURVE SMOOTH", "169 479 OFFCURVE", "132 429 OFFCURVE", "121 384 CURVE", "102 384 LINE" ); } ); userData = { PartSelection = { crotchDepth = 2; shoulderWidth = 1; }; }; width = 501; }, { anchors = ( { name = _connect; position = "{117, 0}"; }, { name = connect; position = "{411, 0}"; } ); associatedMasterId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; layerId = "7C8F98EE-D140-44D5-86AE-E00A730464C0"; name = LowCrotch; paths = ( { closed = 1; nodes = ( "117 236 LINE", "117 410 OFFCURVE", "173 463 OFFCURVE", "262 463 CURVE SMOOTH", "322 463 OFFCURVE", "365 437 OFFCURVE", "394 408 CURVE", "394 0 LINE", "411 0 LINE", "411 414 LINE", "377 450 OFFCURVE", "333 479 OFFCURVE", "262 479 CURVE SMOOTH", "169 479 OFFCURVE", "132 429 OFFCURVE", "121 354 CURVE", "102 354 LINE" ); } ); userData = { PartSelection = { crotchDepth = 1; shoulderWidth = 2; }; }; width = 501; }, { anchors = ( { name = _connect; position = "{167, 0}"; }, { name = connect; position = "{425, 0}"; } ); associatedMasterId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; layerId = "595FDB8C-ED41-486A-B76A-0FEFEF8BCDD1"; name = NarrowShoulder; paths = ( { closed = 1; nodes = ( "167 246 LINE", "167 355 OFFCURVE", "203 402 OFFCURVE", "257 402 CURVE SMOOTH", "285 402 OFFCURVE", "315 390 OFFCURVE", "335 370 CURVE", "335 0 LINE", "425 0 LINE", "425 423 LINE", "395 452 OFFCURVE", "350 490 OFFCURVE", "274 490 CURVE SMOOTH", "205 490 OFFCURVE", "170 452 OFFCURVE", "155 409 CURVE", "131 409 LINE" ); } ); userData = { PartSelection = { crotchDepth = 2; shoulderWidth = 1; }; }; width = 528; }, { anchors = ( { name = _connect; position = "{167, 0}"; }, { name = connect; position = "{455, 0}"; } ); associatedMasterId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; layerId = "65575EEB-523C-4A39-985D-FB9ACFE951AF"; name = LowCrotch; paths = ( { closed = 1; nodes = ( "167 216 LINE", "167 325 OFFCURVE", "203 402 OFFCURVE", "277 402 CURVE SMOOTH", "315 402 OFFCURVE", "345 390 OFFCURVE", "365 370 CURVE", "365 0 LINE", "455 0 LINE", "455 423 LINE", "425 452 OFFCURVE", "380 490 OFFCURVE", "294 490 CURVE SMOOTH", "205 490 OFFCURVE", "170 452 OFFCURVE", "155 379 CURVE", "131 379 LINE" ); } ); userData = { PartSelection = { crotchDepth = 1; shoulderWidth = 2; }; }; width = 528; }, { anchors = ( { name = _connect; position = "{250, 0}"; }, { name = connect; position = "{520, 0}"; } ); associatedMasterId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; layerId = "D607B100-382C-478B-A297-2EF174C3A363"; name = NarrowShoulder; paths = ( { closed = 1; nodes = ( "250 229 LINE", "250 268 OFFCURVE", "259 283 OFFCURVE", "274 283 CURVE SMOOTH", "285 283 OFFCURVE", "294 280 OFFCURVE", "300 276 CURVE", "300 0 LINE", "520 0 LINE", "520 448 LINE", "480 478 OFFCURVE", "420 501 OFFCURVE", "347 501 CURVE SMOOTH", "259 501 OFFCURVE", "209 461 OFFCURVE", "188 401 CURVE", "162 401 LINE" ); } ); userData = { PartSelection = { crotchDepth = 2; shoulderWidth = 1; }; }; width = 560; }, { anchors = ( { name = _connect; position = "{250, 0}"; }, { name = connect; position = "{530, 0}"; } ); associatedMasterId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; layerId = "BA4F7DF9-9552-48BB-A5B8-E2D21D8D086E"; name = LowCrotch; paths = ( { closed = 1; nodes = ( "250 199 LINE", "250 251 OFFCURVE", "259 283 OFFCURVE", "284 283 CURVE SMOOTH", "295 283 OFFCURVE", "304 280 OFFCURVE", "310 276 CURVE", "310 0 LINE", "530 0 LINE", "530 448 LINE", "490 478 OFFCURVE", "430 501 OFFCURVE", "357 501 CURVE SMOOTH", "259 501 OFFCURVE", "209 461 OFFCURVE", "188 371 CURVE", "162 371 LINE" ); } ); userData = { PartSelection = { crotchDepth = 1; shoulderWidth = 2; }; }; width = 560; } ); partsSettings = ( { name = crotchDepth; bottomName = Low; bottomValue = -100; topName = High; topValue = 0; }, { name = shoulderWidth; bottomName = Low; bottomValue = 0; topName = High; topValue = 100; } ); }, { export = 0; glyphname = _part.stem; lastChange = "2017-10-09 14:18:06 +0000"; layers = ( { anchors = ( { name = connect; position = "{117, 0}"; } ); layerId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; paths = ( { closed = 1; nodes = ( "119 368 LINE", "115 470 LINE", "100 470 LINE", "100 0 LINE", "117 0 LINE", "117 306 LINE" ); } ); userData = { PartSelection = { height = 1; }; }; width = 600; }, { anchors = ( { name = connect; position = "{167, 0}"; } ); layerId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; paths = ( { closed = 1; nodes = ( "149 393 LINE", "139 480 LINE", "77 480 LINE", "77 0 LINE", "167 0 LINE", "167 286 LINE" ); } ); userData = { PartSelection = { height = 1; }; }; width = 600; }, { anchors = ( { name = connect; position = "{250, 0}"; } ); layerId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; paths = ( { closed = 1; nodes = ( "181 385 LINE", "162 490 LINE", "30 490 LINE", "30 0 LINE", "250 0 LINE", "250 256 LINE" ); } ); userData = { PartSelection = { height = 1; }; }; width = 600; }, { anchors = ( { name = connect; position = "{117, 0}"; } ); associatedMasterId = "C4872ECA-A3A9-40AB-960A-1DB2202F16DE"; layerId = "0D68D3E9-A0B2-4D78-A161-EB65D8511F0A"; name = TallStem; paths = ( { closed = 1; nodes = ( "117 368 LINE", "117 800 LINE", "100 800 LINE", "100 0 LINE", "117 0 LINE", "117 306 LINE" ); } ); userData = { PartSelection = { height = 2; }; }; width = 600; }, { anchors = ( { name = connect; position = "{167, 0}"; } ); associatedMasterId = "3E7589AA-8194-470F-8E2F-13C1C581BE24"; layerId = "3E1733D9-3B83-4E6A-B1E9-6381BBE1BD3A"; name = TallStem; paths = ( { closed = 1; nodes = ( "167 393 LINE", "167 800 LINE", "77 800 LINE", "77 0 LINE", "167 0 LINE", "167 286 LINE" ); } ); userData = { PartSelection = { height = 2; }; }; width = 600; }, { anchors = ( { name = connect; position = "{250, 0}"; } ); associatedMasterId = "BFFFD157-90D3-4B85-B99D-9A2F366F03CA"; layerId = "FD65D427-9013-43E2-9F74-398D99AA4763"; name = TallStem; paths = ( { closed = 1; nodes = ( "250 385 LINE", "250 800 LINE", "30 800 LINE", "30 0 LINE", "250 0 LINE", "250 256 LINE" ); } ); userData = { PartSelection = { height = 2; }; com.typemytype.robofont.layerData = { "Regular Nov 6 15, 18:44" = { anchors = ( ); components = ( { baseGlyph = tmA; transformation = ( 1, 0, 0, 1, 0, 0 ); } ); contours = ( { points = ( { smooth = 0; x = 2570; y = -907; } ); } ); lib = { }; name = tmAA; unicodes = ( ); width = 3047; }; }; }; width = 600; } ); partsSettings = ( { name = height; bottomName = Low; bottomValue = 0; topName = High; topValue = 100; } ); } ); instances = ( { interpolationWeight = 17; instanceInterpolations = { "C4872ECA-A3A9-40AB-960A-1DB2202F16DE" = 1; }; manualInterpolation = 1; name = Thin; weightClass = Thin; }, { interpolationWeight = 30; instanceInterpolations = { "3E7589AA-8194-470F-8E2F-13C1C581BE24" = 0.17808; "C4872ECA-A3A9-40AB-960A-1DB2202F16DE" = 0.82192; }; name = "Extra Light"; weightClass = ExtraLight; }, { interpolationWeight = 55; instanceInterpolations = { "3E7589AA-8194-470F-8E2F-13C1C581BE24" = 0.52055; "C4872ECA-A3A9-40AB-960A-1DB2202F16DE" = 0.47945; }; name = Light; weightClass = Light; }, { interpolationWeight = 90; instanceInterpolations = { "3E7589AA-8194-470F-8E2F-13C1C581BE24" = 1; }; name = Regular; }, { interpolationWeight = 133; instanceInterpolations = { "3E7589AA-8194-470F-8E2F-13C1C581BE24" = 0.66923; "BFFFD157-90D3-4B85-B99D-9A2F366F03CA" = 0.33077; }; name = Medium; weightClass = Medium; }, { interpolationWeight = 179; instanceInterpolations = { "3E7589AA-8194-470F-8E2F-13C1C581BE24" = 0.31538; "BFFFD157-90D3-4B85-B99D-9A2F366F03CA" = 0.68462; }; name = Bold; weightClass = Bold; }, { interpolationWeight = 220; instanceInterpolations = { "BFFFD157-90D3-4B85-B99D-9A2F366F03CA" = 1; }; name = Black; weightClass = Black; }, { customParameters = ( { name = weightClass; value = 357; } ); interpolationWeight = 75; instanceInterpolations = { "3E7589AA-8194-470F-8E2F-13C1C581BE24" = 0.79452; "C4872ECA-A3A9-40AB-960A-1DB2202F16DE" = 0.20548; }; name = Web; } ); unitsPerEm = 1000; userData = { AsteriskParameters = { "253E7231-480D-4F8E-8754-50FC8575C08E" = ( "754", "30", 7, 51, "80", "50" ); }; GSDimensionPlugin.Dimensions = { "3E7589AA-8194-470F-8E2F-13C1C581BE24" = { HH = 91; HV = 93; OH = 91; OV = 93; arAlef = 86; arBar = 92; nV = 90; oH = 88; }; "BFFFD157-90D3-4B85-B99D-9A2F366F03CA" = { HH = 215; HV = 225; nV = 220; oH = 210; }; "C4872ECA-A3A9-40AB-960A-1DB2202F16DE" = { HH = 18; HV = 19; nV = 17; oH = 16; }; }; uniTestValue = def; }; versionMajor = 1; versionMinor = 0; } fontmake-2.4.1/tests/data/InterpolateLayoutTest/000077500000000000000000000000001410425502200217145ustar00rootroot00000000000000fontmake-2.4.1/tests/data/InterpolateLayoutTest/InterpolateLayoutTest 0 GPOS.txt000066400000000000000000000003661410425502200276570ustar00rootroot00000000000000FontDame GPOS table % InterpolateLayoutTest - weight:0 EM 1000 script table begin DFLT default 0 latn default 0 script table end feature table begin 0 kern kern-latn feature table end lookup kern-latn pair left x advance V a -12 lookup end fontmake-2.4.1/tests/data/InterpolateLayoutTest/InterpolateLayoutTest 1000 GPOS.txt000066400000000000000000000003711410425502200300740ustar00rootroot00000000000000FontDame GPOS table % InterpolateLayoutTest - weight:1000 EM 1000 script table begin DFLT default 0 latn default 0 script table end feature table begin 0 kern kern-latn feature table end lookup kern-latn pair left x advance V a -40 lookup end fontmake-2.4.1/tests/data/InterpolateLayoutTest/InterpolateLayoutTest GDEF.txt000066400000000000000000000001111410425502200274600ustar00rootroot00000000000000FontDame GDEF table class definition begin V 1 a 1 class definition end fontmake-2.4.1/tests/data/InterpolateLayoutTest/InterpolateLayoutTest GSUB.txt000066400000000000000000000001341410425502200275200ustar00rootroot00000000000000FontDame GSUB table EM 1000 script table begin DFLT default latn default script table end fontmake-2.4.1/tests/data/InterpolateLayoutTest/InterpolateLayoutTest.glyphs000066400000000000000000000153701410425502200274760ustar00rootroot00000000000000{ .appVersion = "1008"; customParameters = ( { name = vendorID; value = ADBO; } ); date = "2017-04-11 12:06:06 +0000"; designer = "Paul D. Hunt"; disablesAutomaticAlignment = 1; disablesNiceNames = 1; familyName = InterpolateLayoutTest; featurePrefixes = ( { code = ""; name = Prefix; } ); fontMaster = ( { ascender = 722; capHeight = 660; customParameters = ( { name = typoAscender; value = 750; }, { name = typoDescender; value = -250; }, { name = typoLineGap; value = 0; }, { name = hheaAscender; value = 984; }, { name = hheaDescender; value = -273; }, { name = hheaLineGap; value = 0; }, { name = winAscent; value = 984; }, { name = winDescent; value = 273; }, { name = underlineThickness; value = 50; }, { name = underlinePosition; value = -75; } ); descender = -222; horizontalStems = ( 28, 40 ); id = "F391A38D-09EE-4697-93B1-BD76E14F8F30"; verticalStems = ( 32, 48 ); weight = Light; weightValue = 0; xHeight = 478; }, { ascender = 696; capHeight = 650; customParameters = ( { name = typoAscender; value = 750; }, { name = typoDescender; value = -250; }, { name = typoLineGap; value = 0; }, { name = hheaAscender; value = 984; }, { name = hheaDescender; value = -273; }, { name = hheaLineGap; value = 0; }, { name = winAscent; value = 984; }, { name = winDescent; value = 273; }, { name = underlineThickness; value = 50; }, { name = underlinePosition; value = -75; } ); descender = -176; horizontalStems = ( 134, 144 ); id = "AF818D18-A4CE-4FD4-8AD5-FA156C77929B"; verticalStems = ( 172, 176 ); weight = Bold; weightValue = 1000; xHeight = 500; } ); glyphs = ( { glyphname = V; lastChange = "2017-04-11 12:29:38 +0000"; layers = ( { anchors = ( { name = aboveUC; position = "{240, 682}"; }, { name = belowLC; position = "{244, -22}"; } ); layerId = "F391A38D-09EE-4697-93B1-BD76E14F8F30"; paths = ( { closed = 1; nodes = ( "226 0 LINE", "258 0 LINE", "476 660 LINE", "444 660 LINE", "316 264 LINE SMOOTH", "290 182 OFFCURVE", "272 122 OFFCURVE", "244 41 CURVE", "240 41 LINE", "212 122 OFFCURVE", "194 182 OFFCURVE", "168 264 CURVE SMOOTH", "40 660 LINE", "6 660 LINE" ); } ); width = 482; }, { anchors = ( { name = aboveUC; position = "{286, 672}"; }, { name = belowLC; position = "{282, -22}"; } ); layerId = "AF818D18-A4CE-4FD4-8AD5-FA156C77929B"; paths = ( { closed = 1; nodes = ( "182 0 LINE", "390 0 LINE", "582 650 LINE", "406 650 LINE", "340 366 LINE SMOOTH", "323 297 OFFCURVE", "310 230 OFFCURVE", "292 160 CURVE", "288 160 LINE", "270 230 OFFCURVE", "258 297 OFFCURVE", "240 366 CURVE SMOOTH", "172 650 LINE", "-10 650 LINE" ); } ); width = 572; } ); unicode = 0056; }, { glyphname = a; lastChange = "2017-04-11 12:07:34 +0000"; layers = ( { layerId = "F391A38D-09EE-4697-93B1-BD76E14F8F30"; paths = ( { closed = 1; nodes = ( "262 -12 OFFCURVE", "322 24 OFFCURVE", "372 64 CURVE", "374 64 LINE", "378 0 LINE", "404 0 LINE", "404 310 LINE SMOOTH", "404 406 OFFCURVE", "370 490 OFFCURVE", "258 490 CURVE SMOOTH", "180 490 OFFCURVE", "114 450 OFFCURVE", "84 428 CURVE", "100 404 LINE", "130 428 OFFCURVE", "188 462 OFFCURVE", "256 462 CURVE SMOOTH", "356 462 OFFCURVE", "376 376 OFFCURVE", "374 298 CURVE", "158 274 OFFCURVE", "60 224 OFFCURVE", "60 117 CURVE SMOOTH", "60 26 OFFCURVE", "124 -12 OFFCURVE", "198 -12 CURVE SMOOTH" ); }, { closed = 1; nodes = ( "142 16 OFFCURVE", "92 44 OFFCURVE", "92 118 CURVE SMOOTH", "92 200 OFFCURVE", "164 248 OFFCURVE", "374 272 CURVE", "374 98 LINE", "310 44 OFFCURVE", "258 16 OFFCURVE", "200 16 CURVE SMOOTH" ); } ); width = 486; }, { layerId = "AF818D18-A4CE-4FD4-8AD5-FA156C77929B"; paths = ( { closed = 1; nodes = ( "242 -12 OFFCURVE", "286 12 OFFCURVE", "326 48 CURVE", "330 48 LINE", "342 0 LINE", "482 0 LINE", "482 278 LINE SMOOTH", "482 442 OFFCURVE", "404 512 OFFCURVE", "274 512 CURVE SMOOTH", "196 512 OFFCURVE", "124 488 OFFCURVE", "54 446 CURVE", "114 334 LINE", "166 362 OFFCURVE", "204 376 OFFCURVE", "240 376 CURVE SMOOTH", "284 376 OFFCURVE", "306 360 OFFCURVE", "310 324 CURVE", "118 304 OFFCURVE", "38 246 OFFCURVE", "38 142 CURVE SMOOTH", "38 60 OFFCURVE", "94 -12 OFFCURVE", "188 -12 CURVE SMOOTH" ); }, { closed = 1; nodes = ( "218 120 OFFCURVE", "202 133 OFFCURVE", "202 156 CURVE SMOOTH", "202 184 OFFCURVE", "228 210 OFFCURVE", "310 222 CURVE", "310 154 LINE", "292 134 OFFCURVE", "276 120 OFFCURVE", "248 120 CURVE SMOOTH" ); } ); width = 536; } ); unicode = 0061; }, { glyphname = space; lastChange = "2017-04-11 12:07:34 +0000"; layers = ( { layerId = "F391A38D-09EE-4697-93B1-BD76E14F8F30"; width = 200; }, { layerId = "AF818D18-A4CE-4FD4-8AD5-FA156C77929B"; width = 200; } ); unicode = 0020; }, { glyphname = .notdef; lastChange = "2017-04-11 12:07:34 +0000"; layers = ( { layerId = "F391A38D-09EE-4697-93B1-BD76E14F8F30"; paths = ( { closed = 1; nodes = ( "96 0 LINE", "528 0 LINE", "528 660 LINE", "96 660 LINE" ); }, { closed = 1; nodes = ( "144 32 LINE", "246 208 LINE", "310 314 LINE", "314 314 LINE", "376 208 LINE", "476 32 LINE" ); }, { closed = 1; nodes = ( "310 366 LINE", "254 458 LINE", "160 626 LINE", "462 626 LINE", "368 458 LINE", "314 366 LINE" ); }, { closed = 1; nodes = ( "134 74 LINE", "134 610 LINE", "288 340 LINE" ); }, { closed = 1; nodes = ( "488 74 LINE", "336 340 LINE", "488 610 LINE" ); } ); width = 624; }, { layerId = "AF818D18-A4CE-4FD4-8AD5-FA156C77929B"; paths = ( { closed = 1; nodes = ( "76 0 LINE", "628 0 LINE", "628 660 LINE", "76 660 LINE" ); }, { closed = 1; nodes = ( "288 104 LINE", "314 160 LINE", "350 256 LINE", "354 256 LINE", "390 160 LINE", "416 104 LINE" ); }, { closed = 1; nodes = ( "350 424 LINE", "310 520 LINE", "292 556 LINE", "412 556 LINE", "394 520 LINE", "354 424 LINE" ); }, { closed = 1; nodes = ( "188 172 LINE", "188 508 LINE", "270 340 LINE" ); }, { closed = 1; nodes = ( "516 172 LINE", "434 340 LINE", "516 508 LINE" ); } ); width = 704; } ); } ); instances = ( { interpolationWeight = 0; instanceInterpolations = { "F391A38D-09EE-4697-93B1-BD76E14F8F30" = 1; }; name = ExtraLight; weightClass = ExtraLight; }, { instanceInterpolations = { "F391A38D-09EE-4697-93B1-BD76E14F8F30" = 0.9; "AF818D18-A4CE-4FD4-8AD5-FA156C77929B" = 0.1; }; name = Light; weightClass = Light; }, { interpolationWeight = 368; instanceInterpolations = { "F391A38D-09EE-4697-93B1-BD76E14F8F30" = 0.632; "AF818D18-A4CE-4FD4-8AD5-FA156C77929B" = 0.368; }; name = Regular; }, { interpolationWeight = 600; instanceInterpolations = { "F391A38D-09EE-4697-93B1-BD76E14F8F30" = 0.4; "AF818D18-A4CE-4FD4-8AD5-FA156C77929B" = 0.6; }; name = SemiBold; weightClass = SemiBold; }, { interpolationWeight = 824; instanceInterpolations = { "F391A38D-09EE-4697-93B1-BD76E14F8F30" = 0.176; "AF818D18-A4CE-4FD4-8AD5-FA156C77929B" = 0.824; }; isBold = 1; name = Bold; weightClass = Bold; }, { interpolationWeight = 1000; instanceInterpolations = { "AF818D18-A4CE-4FD4-8AD5-FA156C77929B" = 1; }; name = Black; weightClass = Black; } ); unitsPerEm = 1000; versionMajor = 2; versionMinor = 20; } fontmake-2.4.1/tests/data/InterpolateLayoutTest/InterpolateLayoutTest.plist000066400000000000000000000013141410425502200273140ustar00rootroot00000000000000 InterpolateLayoutTest-Light GDEF InterpolateLayoutTest GDEF.txt GPOS InterpolateLayoutTest 0 GPOS.txt GSUB InterpolateLayoutTest GSUB.txt InterpolateLayoutTest-Bold GDEF InterpolateLayoutTest GDEF.txt GPOS InterpolateLayoutTest 1000 GPOS.txt GSUB InterpolateLayoutTest GSUB.txt fontmake-2.4.1/tests/data/MutatorSans/000077500000000000000000000000001410425502200176505ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/LICENSE000066400000000000000000000020621410425502200206550ustar00rootroot00000000000000MIT License Copyright (c) 2017 Erik van Blokland Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. fontmake-2.4.1/tests/data/MutatorSans/MutatorSans-weight-only.designspace000066400000000000000000000026041410425502200266050ustar00rootroot00000000000000 com.letterror.skateboard.previewLocation weight 0.0 fontmake-2.4.1/tests/data/MutatorSans/MutatorSans-width-only.designspace000066400000000000000000000025621410425502200264400ustar00rootroot00000000000000 com.letterror.skateboard.previewLocation width 0.0 fontmake-2.4.1/tests/data/MutatorSans/MutatorSans-with-openNodes.designspace000066400000000000000000000050631410425502200272440ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSans.designspace000066400000000000000000000157071410425502200243510ustar00rootroot00000000000000 com.letterror.skateboard.interestingLocation weight 775.609 width 794.522 S1 weight 855.549 width 795.978 S2 com.letterror.skateboard.previewLocation weight 700.0 width 569.078 com.superpolator.data axiscolors weight 0.5 0.5 0.5 1.0 width 0.5 0.5 0.5 1.0 instancefolder instances lineInverted lineStacked sequence lineViewFilled previewtext Aaa snippets fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/000077500000000000000000000000001410425502200253445ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/features.fea000066400000000000000000000000521410425502200276340ustar00rootroot00000000000000# this is the feature from boldcondensed. fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/fontinfo.plist000066400000000000000000000035351410425502200302510ustar00rootroot00000000000000 ascender 800 capHeight 800 copyright License same as MutatorMath. BSD 3-clause. [test-token: A] descender -200 familyName MutatorMathTest guidelines italicAngle 0 openTypeNameLicense License same as MutatorMath. BSD 3-clause. [test-token: A] openTypeOS2VendorID LTTR postscriptBlueValues postscriptDefaultWidthX 500 postscriptFamilyBlues postscriptFamilyOtherBlues postscriptFontName MutatorMathTest-BoldCondensed postscriptFullName MutatorMathTest BoldCondensed postscriptOtherBlues postscriptSlantAngle 0 postscriptStemSnapH postscriptStemSnapV postscriptWindowsCharacterSet 1 styleMapFamilyName styleMapStyleName regular styleName BoldCondensed unitsPerEm 1000 versionMajor 1 versionMinor 2 xHeight 500 year 2004 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs.background/000077500000000000000000000000001410425502200307705ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs.background/S_.closed.glif000066400000000000000000000037041410425502200334500ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs.background/contents.plist000066400000000000000000000003741410425502200337060ustar00rootroot00000000000000 S.closed S_.closed.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs.background/layerinfo.plist000066400000000000000000000003661410425502200340420ustar00rootroot00000000000000 color 0.5,1,0,0.7 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/000077500000000000000000000000001410425502200266525ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/A_.glif000066400000000000000000000024471410425502200300430ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/A_acute.glif000066400000000000000000000005241410425502200310570ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/A_dieresis.glif000066400000000000000000000005321410425502200315640ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/B_.glif000066400000000000000000000034071410425502200300410ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/C_.glif000066400000000000000000000033711410425502200300420ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/D_.glif000066400000000000000000000021501410425502200300350ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/E_.glif000066400000000000000000000025461410425502200300470ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/F_.glif000066400000000000000000000013531410425502200300430ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/G_.glif000066400000000000000000000033561410425502200300510ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/H_.glif000066400000000000000000000013471410425502200300500ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/I_.glif000066400000000000000000000013451410425502200300470ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/I_.narrow.glif000066400000000000000000000012751410425502200313600ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/I_J_.glif000066400000000000000000000021611410425502200303150ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/J_.glif000066400000000000000000000016501410425502200300470ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/J_.narrow.glif000066400000000000000000000014711410425502200313570ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/K_.glif000066400000000000000000000015501410425502200300470ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/L_.glif000066400000000000000000000010361410425502200300470ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/M_.glif000066400000000000000000000016231410425502200300520ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/N_.glif000066400000000000000000000013451410425502200300540ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/O_.glif000066400000000000000000000025171410425502200300570ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/P_.glif000066400000000000000000000022641410425502200300570ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/Q_.glif000066400000000000000000000005731410425502200300610ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/R_.glif000066400000000000000000000034451410425502200300630ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/S_.closed.glif000066400000000000000000000043551410425502200313350ustar00rootroot00000000000000 com.letterror.skateboard.navigator location weight 1000.0 width 108.00694056919657 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/S_.glif000066400000000000000000000044771410425502200300720ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/T_.glif000066400000000000000000000010421410425502200300540ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/U_.glif000066400000000000000000000016501410425502200300620ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/V_.glif000066400000000000000000000013441410425502200300630ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/W_.glif000066400000000000000000000015321410425502200300630ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/X_.glif000066400000000000000000000014401410425502200300620ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/Y_.glif000066400000000000000000000013541410425502200300670ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/Z_.glif000066400000000000000000000013501410425502200300640ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/acute.glif000066400000000000000000000005411410425502200306160ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/arrowdown.glif000066400000000000000000000007531410425502200315440ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/arrowleft.glif000066400000000000000000000007521410425502200315260ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/arrowright.glif000066400000000000000000000007531410425502200317120ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/arrowup.glif000066400000000000000000000007521410425502200312200ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/colon.glif000066400000000000000000000003621410425502200306300ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/comma.glif000066400000000000000000000010111410425502200306020ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/contents.plist000066400000000000000000000051771410425502200315760ustar00rootroot00000000000000 A A_.glif Aacute A_acute.glif Adieresis A_dieresis.glif B B_.glif C C_.glif D D_.glif E E_.glif F F_.glif G G_.glif H H_.glif I I_.glif I.narrow I_.narrow.glif IJ I_J_.glif J J_.glif J.narrow J_.narrow.glif K K_.glif L L_.glif M M_.glif N N_.glif O O_.glif P P_.glif Q Q_.glif R R_.glif S S_.glif S.closed S_.closed.glif T T_.glif U U_.glif V V_.glif W W_.glif X X_.glif Y Y_.glif Z Z_.glif acute acute.glif arrowdown arrowdown.glif arrowleft arrowleft.glif arrowright arrowright.glif arrowup arrowup.glif colon colon.glif comma comma.glif dieresis dieresis.glif dot dot.glif period period.glif quotedblbase quotedblbase.glif quotedblleft quotedblleft.glif quotedblright quotedblright.glif quotesinglbase quotesinglbase.glif semicolon semicolon.glif space space.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/dieresis.glif000066400000000000000000000006001410425502200313200ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/dot.glif000066400000000000000000000005371410425502200303100ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/layerinfo.plist000066400000000000000000000005631410425502200317230ustar00rootroot00000000000000 color 1,0.75,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/period.glif000066400000000000000000000005361410425502200310030ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/quotedblbase.glif000066400000000000000000000011401410425502200321630ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/quotedblleft.glif000066400000000000000000000005051410425502200322070ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/quotedblright.glif000066400000000000000000000004101410425502200323650ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/quotesinglbase.glif000066400000000000000000000010661410425502200325450ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/semicolon.glif000066400000000000000000000003651410425502200315110ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/glyphs/space.glif000066400000000000000000000002321410425502200306050ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/groups.plist000066400000000000000000000005561410425502200277460ustar00rootroot00000000000000 public.kern1.@MMK_L_A A public.kern2.@MMK_R_A A fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/kerning.plist000066400000000000000000000107441410425502200300640ustar00rootroot00000000000000 A J -20 O -30 T -70 U -30 V -50 B A -20 J -50 O -20 S -10 T -10 U -20 V -30 C A -20 J -50 T -20 V -20 E J -20 T -10 V -10 F A -40 J -80 O -10 S -20 U -10 V -10 G J -20 S -10 T -40 U -10 V -30 H J -30 S -10 T -10 J J -70 L J -20 O -20 T -110 U -20 V -60 O A -30 J -60 S -10 T -30 V -30 P A -50 J -100 S -10 T -10 U -10 V -20 R H -10 J -20 O -30 S -20 T -30 U -30 V -40 S A -20 H -20 J -40 O -10 S -10 T -30 U -10 V -30 W -10 T A -65 H -10 J -130 O -20 U A -30 J -60 S -10 V -10 V J -100 O -30 S -20 U -10 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/layercontents.plist000066400000000000000000000005771410425502200313240ustar00rootroot00000000000000 foreground glyphs background glyphs.background fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/lib.plist000066400000000000000000000172401410425502200271730ustar00rootroot00000000000000 com.defcon.sortDescriptor allowPseudoUnicode ascending type alphabetical allowPseudoUnicode ascending type category allowPseudoUnicode ascending type unicode allowPseudoUnicode ascending type script allowPseudoUnicode ascending type suffix allowPseudoUnicode ascending type decompositionBase com.letterror.lightMeter.prefs chunkSize 5 diameter 200 drawTail invert toolDiameter 30 toolStyle fluid com.typemytype.robofont.background.layerStrokeColor 0.0 0.8 0.2 0.7 com.typemytype.robofont.compileSettings.autohint com.typemytype.robofont.compileSettings.checkOutlines com.typemytype.robofont.compileSettings.createDummyDSIG com.typemytype.robofont.compileSettings.decompose com.typemytype.robofont.compileSettings.generateFormat 0 com.typemytype.robofont.compileSettings.releaseMode com.typemytype.robofont.foreground.layerStrokeColor 0.5 0.0 0.5 0.7 com.typemytype.robofont.italicSlantOffset 0 com.typemytype.robofont.segmentType curve com.typemytype.robofont.shouldAddPointsInSplineConversion 1 com.typesupply.defcon.sortDescriptor ascending space A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n ntilde o p q r s t u v w x y z zcaron zero one two three four five six seven eight nine underscore hyphen endash emdash parenleft parenright bracketleft bracketright braceleft braceright numbersign percent period comma colon semicolon exclam question slash backslash bar at ampersand paragraph bullet dollar trademark fi fl .notdef a_b_c Atilde Adieresis Acircumflex Aring Ccedilla Agrave Aacute quotedblright quotedblleft type glyphList public.glyphOrder A Aacute Adieresis B C D E F G H I J K L M N O P Q R S T U V W X Y Z IJ S.closed I.narrow J.narrow quotesinglbase quotedblbase quotedblleft quotedblright comma period colon semicolon dot dieresis acute space arrowdown arrowleft arrowright arrowup fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldCondensed.ufo/metainfo.plist000066400000000000000000000004761410425502200302320ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/000077500000000000000000000000001410425502200243325ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/features.fea000066400000000000000000000000441410425502200266230ustar00rootroot00000000000000# this is the feature from BoldWide fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/fontinfo.plist000066400000000000000000000035161410425502200272360ustar00rootroot00000000000000 ascender 800 capHeight 800 copyright License same as MutatorMath. BSD 3-clause. [test-token: B] descender -200 familyName MutatorMathTest guidelines italicAngle 0 openTypeNameLicense License same as MutatorMath. BSD 3-clause. [test-token: B] openTypeOS2VendorID LTTR postscriptBlueValues postscriptDefaultWidthX 500 postscriptFamilyBlues postscriptFamilyOtherBlues postscriptFontName MutatorMathTest-BoldWide postscriptFullName MutatorMathTest BoldWide postscriptOtherBlues postscriptSlantAngle 0 postscriptStemSnapH postscriptStemSnapV postscriptWindowsCharacterSet 1 styleMapFamilyName styleMapStyleName regular styleName BoldWide unitsPerEm 1000 versionMajor 1 versionMinor 2 xHeight 500 year 2004 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs.background/000077500000000000000000000000001410425502200277565ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs.background/S_.closed.glif000066400000000000000000000037021410425502200324340ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs.background/S_.glif000066400000000000000000000037251410425502200311710ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs.background/contents.plist000066400000000000000000000004521410425502200326710ustar00rootroot00000000000000 S S_.glif S.closed S_.closed.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs.background/layerinfo.plist000066400000000000000000000003661410425502200330300ustar00rootroot00000000000000 color 0.5,1,0,0.7 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/000077500000000000000000000000001410425502200256405ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/A_.glif000066400000000000000000000016631410425502200270300ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/A_acute.glif000066400000000000000000000005421410425502200300450ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/A_dieresis.glif000066400000000000000000000005501410425502200305520ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/B_.glif000066400000000000000000000042331410425502200270250ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/C_.glif000066400000000000000000000026121410425502200270250ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/D_.glif000066400000000000000000000021761410425502200270330ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/E_.glif000066400000000000000000000017341410425502200270330ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/F_.glif000066400000000000000000000013561410425502200270340ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/G_.glif000066400000000000000000000033231410425502200270310ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/H_.glif000066400000000000000000000013541410425502200270340ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/I_.glif000066400000000000000000000013461410425502200270360ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/I_.narrow.glif000066400000000000000000000012751410425502200303460ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/I_J_.glif000066400000000000000000000022021410425502200272770ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/J_.glif000066400000000000000000000016541410425502200270410ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/J_.narrow.glif000066400000000000000000000014461410425502200303470ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/K_.glif000066400000000000000000000015531410425502200270400ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/L_.glif000066400000000000000000000010411410425502200270310ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/M_.glif000066400000000000000000000016271410425502200270440ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/N_.glif000066400000000000000000000013511410425502200270370ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/O_.glif000066400000000000000000000025531410425502200270450ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/P_.glif000066400000000000000000000021641410425502200270440ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/Q_.glif000066400000000000000000000005741410425502200270500ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/R_.glif000066400000000000000000000027271410425502200270530ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/S_.closed.glif000066400000000000000000000045011410425502200303140ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/S_.glif000066400000000000000000000045101410425502200270440ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/T_.glif000066400000000000000000000010451410425502200270450ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/U_.glif000066400000000000000000000020151410425502200270440ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/V_.glif000066400000000000000000000013461410425502200270530ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/W_.glif000066400000000000000000000015351410425502200270540ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/X_.glif000066400000000000000000000014431410425502200270530ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/Y_.glif000066400000000000000000000013561410425502200270570ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/Z_.glif000066400000000000000000000013561410425502200270600ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/acute.glif000066400000000000000000000005411410425502200276040ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/arrowdown.glif000066400000000000000000000007531410425502200305320ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/arrowleft.glif000066400000000000000000000007551410425502200305170ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/arrowright.glif000066400000000000000000000007571410425502200307040ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/arrowup.glif000066400000000000000000000007541410425502200302100ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/colon.glif000066400000000000000000000003621410425502200276160ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/comma.glif000066400000000000000000000010121410425502200275710ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/contents.plist000066400000000000000000000051771410425502200305640ustar00rootroot00000000000000 A A_.glif Aacute A_acute.glif Adieresis A_dieresis.glif B B_.glif C C_.glif D D_.glif E E_.glif F F_.glif G G_.glif H H_.glif I I_.glif I.narrow I_.narrow.glif IJ I_J_.glif J J_.glif J.narrow J_.narrow.glif K K_.glif L L_.glif M M_.glif N N_.glif O O_.glif P P_.glif Q Q_.glif R R_.glif S S_.glif S.closed S_.closed.glif T T_.glif U U_.glif V V_.glif W W_.glif X X_.glif Y Y_.glif Z Z_.glif acute acute.glif arrowdown arrowdown.glif arrowleft arrowleft.glif arrowright arrowright.glif arrowup arrowup.glif colon colon.glif comma comma.glif dieresis dieresis.glif dot dot.glif period period.glif quotedblbase quotedblbase.glif quotedblleft quotedblleft.glif quotedblright quotedblright.glif quotesinglbase quotesinglbase.glif semicolon semicolon.glif space space.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/dieresis.glif000066400000000000000000000005621410425502200303150ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/dot.glif000066400000000000000000000005371410425502200272760ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/layerinfo.plist000066400000000000000000000005631410425502200307110ustar00rootroot00000000000000 color 1,0.75,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/period.glif000066400000000000000000000005361410425502200277710ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/quotedblbase.glif000066400000000000000000000004031410425502200311520ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/quotedblleft.glif000066400000000000000000000005051410425502200311750ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/quotedblright.glif000066400000000000000000000004101410425502200313530ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/quotesinglbase.glif000066400000000000000000000003151410425502200315270ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/semicolon.glif000066400000000000000000000003651410425502200304770ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/glyphs/space.glif000066400000000000000000000002321410425502200275730ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/groups.plist000066400000000000000000000005561410425502200267340ustar00rootroot00000000000000 public.kern1.@MMK_L_A A public.kern2.@MMK_R_A A fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/kerning.plist000066400000000000000000000004551410425502200270500ustar00rootroot00000000000000 T public.kern2.@MMK_R_A -150 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/layercontents.plist000066400000000000000000000005771410425502200303120ustar00rootroot00000000000000 foreground glyphs background glyphs.background fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/lib.plist000066400000000000000000000300651410425502200261610ustar00rootroot00000000000000 com.defcon.sortDescriptor allowPseudoUnicode ascending type alphabetical allowPseudoUnicode ascending type category allowPseudoUnicode ascending type unicode allowPseudoUnicode ascending type script allowPseudoUnicode ascending type suffix allowPseudoUnicode ascending type decompositionBase com.letterror.lightMeter.prefs chunkSize 5 diameter 200 drawTail invert toolDiameter 30 toolStyle fluid com.typemytype.robofont.background.layerStrokeColor 0.0 0.8 0.2 0.7 com.typemytype.robofont.compileSettings.autohint com.typemytype.robofont.compileSettings.checkOutlines com.typemytype.robofont.compileSettings.createDummyDSIG com.typemytype.robofont.compileSettings.decompose com.typemytype.robofont.compileSettings.generateFormat 0 com.typemytype.robofont.compileSettings.releaseMode com.typemytype.robofont.foreground.layerStrokeColor 0.5 0.0 0.5 0.7 com.typemytype.robofont.italicSlantOffset 0 com.typemytype.robofont.segmentType curve com.typemytype.robofont.shouldAddPointsInSplineConversion 1 com.typesupply.defcon.sortDescriptor ascending space A Agrave Aacute Acircumflex Atilde Adieresis Aring B C Ccedilla D E Egrave Eacute Ecircumflex Edieresis F G H I Igrave Iacute Icircumflex Idieresis J K L M N Ntilde O Ograve Oacute Ocircumflex Otilde Odieresis P Q R S Scaron T U Ugrave Uacute Ucircumflex Udieresis V W X Y Yacute Ydieresis Z Zcaron AE Eth Oslash Thorn Lslash OE a agrave aacute acircumflex atilde adieresis aring b c ccedilla d e egrave eacute ecircumflex edieresis f g h i igrave iacute icircumflex idieresis j k l m n ntilde o ograve oacute ocircumflex otilde odieresis p q r s scaron t u ugrave uacute ucircumflex udieresis v w x y yacute ydieresis z zcaron ordfeminine ordmasculine germandbls ae eth oslash thorn dotlessi lslash oe zero one two three four five six seven eight nine onesuperior twosuperior threesuperior onequarter onehalf threequarters underscore hyphen endash emdash parenleft parenright bracketleft bracketright braceleft braceright numbersign percent perthousand quotesingle quotedbl quoteleft quoteright quotedblleft quotedblright quotesinglbase quotedblbase guilsinglleft guilsinglright guillemotleft guillemotright asterisk dagger daggerdbl period comma colon semicolon ellipsis exclam exclamdown question questiondown slash backslash fraction bar brokenbar at ampersand section paragraph periodcentered bullet plus minus plusminus divide multiply equal less greater logicalnot mu dollar cent sterling currency yen Euro florin asciicircum asciitilde acute grave hungarumlaut circumflex caron breve tilde macron dieresis dotaccent ring cedilla ogonek copyright registered trademark degree fi fl .notdef a_b_c type glyphList public.glyphOrder A Aacute Adieresis B C D E F G H I J K L M N O P Q R S T U V W X Y Z S.closed I.narrow J.narrow quotesinglbase quotedblbase quotedblleft quotedblright comma period colon semicolon dot dieresis acute space IJ arrowdown arrowleft arrowright arrowup fontmake-2.4.1/tests/data/MutatorSans/MutatorSansBoldWide.ufo/metainfo.plist000066400000000000000000000004761410425502200272200ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/000077500000000000000000000000001410425502200270765ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/features.fea000066400000000000000000000001041410425502200313640ustar00rootroot00000000000000# this is the feature from lightCondensed # Hi_this_is_the_feature. fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/fontinfo.plist000066400000000000000000000025521410425502200320010ustar00rootroot00000000000000 ascender 763.459275 capHeight 763.459275 copyright Copyright-token-string descender -200 familyName Intermediate guidelines italicAngle 0 openTypeOS2VendorID ADBE postscriptBlueValues postscriptDefaultWidthX 500 postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptSlantAngle 0 postscriptStemSnapH postscriptStemSnapV postscriptWindowsCharacterSet 1 styleName Narrow unitsPerEm 1000.0 versionMajor 1 versionMinor 2 xHeight 500 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.background/000077500000000000000000000000001410425502200325225ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.background/S_.glif000066400000000000000000000044611410425502200337330ustar00rootroot00000000000000 contents.plist000066400000000000000000000003441410425502200353560ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.background S S_.glif layerinfo.plist000066400000000000000000000005271410425502200355140ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.background color 0.5,1,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.interpolation/000077500000000000000000000000001410425502200332725ustar00rootroot00000000000000E_.glif000066400000000000000000000036221410425502200344040ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.interpolation contents.plist000066400000000000000000000003441410425502200361260ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.interpolation E E_.glif layerinfo.plist000066400000000000000000000005301410425502200362560ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.interpolation color 0,1,0.25,0.7 lib com.typemytype.robofont.segmentType curve glyphs.reference.interpolation/000077500000000000000000000000001410425502200351505ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufoE_.glif000066400000000000000000000016661410425502200363470ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.reference.interpolation S_.glif000066400000000000000000000061551410425502200363630ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.reference.interpolation contents.plist000066400000000000000000000004141410425502200400610ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.reference.interpolation E E_.glif S S_.glif layerinfo.plist000066400000000000000000000005251410425502200402170ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs.reference.interpolation color 0,1,1,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/000077500000000000000000000000001410425502200304045ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/B_.glif000066400000000000000000000034161410425502200315730ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/E_.glif000066400000000000000000000017271410425502200316010ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/F_.glif000066400000000000000000000016331410425502200315760ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/G_.glif000066400000000000000000000044031410425502200315750ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/S_.glif000066400000000000000000000051261410425502200316140ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/contents.plist000066400000000000000000000006461410425502200333240ustar00rootroot00000000000000 B B_.glif E E_.glif F F_.glif G G_.glif S S_.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/glyphs/layerinfo.plist000066400000000000000000000005631410425502200334550ustar00rootroot00000000000000 color 1,0.75,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/layercontents.plist000066400000000000000000000011471410425502200330500ustar00rootroot00000000000000 foreground glyphs background glyphs.background interpolation glyphs.interpolation reference.interpolation glyphs.reference.interpolation fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/lib.plist000066400000000000000000000403511410425502200307240ustar00rootroot00000000000000 com.letterror.lightMeter.prefs chunkSize 5 diameter 200 drawTail invert toolDiameter 30 toolStyle fluid com.typemytype.robofont.background.layerStrokeColor 0.0 0.8 0.2 0.7 com.typemytype.robofont.compileSettings.autohint com.typemytype.robofont.compileSettings.checkOutlines com.typemytype.robofont.compileSettings.createDummyDSIG com.typemytype.robofont.compileSettings.decompose com.typemytype.robofont.compileSettings.generateFormat 0 com.typemytype.robofont.compileSettings.releaseMode com.typemytype.robofont.foreground.layerStrokeColor 0.5 0.0 0.5 0.7 com.typemytype.robofont.italicSlantOffset 0 com.typemytype.robofont.segmentType curve com.typemytype.robofont.shouldAddPointsInSplineConversion 1 com.typesupply.MetricsMachine4.groupColors @MMK_L_A 1.0 0.0 0.0 0.25 @MMK_L_C 1.0 0.5 0.0 0.25 @MMK_L_E 1.0 1.0 0.0 0.25 @MMK_L_I 0.0 1.0 0.0 0.25 @MMK_L_N 0.0 1.0 1.0 0.25 @MMK_L_O 0.0 0.5 1.0 0.25 @MMK_L_S 0.0 0.0 1.0 0.25 @MMK_L_U 0.5 0.0 1.0 0.25 @MMK_L_Y 1.0 0.0 1.0 0.25 @MMK_L_Z 1.0 0.0 0.5 0.25 @MMK_L_a 1.0 0.0 0.0 0.25 @MMK_L_c 1.0 0.5 0.0 0.25 @MMK_L_e 1.0 1.0 0.0 0.25 @MMK_L_i 0.0 1.0 0.0 0.25 @MMK_L_n 0.0 1.0 1.0 0.25 @MMK_L_o 0.0 0.5 1.0 0.25 @MMK_L_s 0.0 0.0 1.0 0.25 @MMK_L_u 0.5 0.0 1.0 0.25 @MMK_L_y 1.0 0.0 1.0 0.25 @MMK_L_z 1.0 0.0 0.5 0.25 @MMK_R_A 1.0 0.0 0.0 0.25 @MMK_R_C 1.0 0.5 0.0 0.25 @MMK_R_E 1.0 1.0 0.0 0.25 @MMK_R_I 0.0 1.0 0.0 0.25 @MMK_R_N 0.0 1.0 1.0 0.25 @MMK_R_O 0.0 0.5 1.0 0.25 @MMK_R_S 0.0 0.0 1.0 0.25 @MMK_R_U 0.5 0.0 1.0 0.25 @MMK_R_Y 1.0 0.0 1.0 0.25 @MMK_R_Z 1.0 0.0 0.5 0.25 @MMK_R_a 1.0 0.0 0.0 0.25 @MMK_R_c 1.0 0.5 0.0 0.25 @MMK_R_e 1.0 1.0 0.0 0.25 @MMK_R_i 0.0 1.0 0.0 0.25 @MMK_R_n 0.0 1.0 1.0 0.25 @MMK_R_o 0.0 0.5 1.0 0.25 @MMK_R_s 0.0 0.0 1.0 0.25 @MMK_R_u 0.5 0.0 1.0 0.25 @MMK_R_y 1.0 0.0 1.0 0.25 @MMK_R_z 1.0 0.0 0.5 0.25 com.typesupply.defcon.sortDescriptor ascending space A Agrave Aacute Acircumflex Atilde Adieresis Aring B C Ccedilla D E Egrave Eacute Ecircumflex Edieresis F G H I Igrave Iacute Icircumflex Idieresis J K L M N Ntilde O Ograve Oacute Ocircumflex Otilde Odieresis P Q R S Scaron T U Ugrave Uacute Ucircumflex Udieresis V W X Y Yacute Ydieresis Z Zcaron AE Eth Oslash Thorn Lslash OE a agrave aacute acircumflex atilde adieresis aring b c ccedilla d e egrave eacute ecircumflex edieresis f g h i igrave iacute icircumflex idieresis j k l m n ntilde o ograve oacute ocircumflex otilde odieresis p q r s scaron t u ugrave uacute ucircumflex udieresis v w x y yacute ydieresis z zcaron ordfeminine ordmasculine germandbls ae eth oslash thorn dotlessi lslash oe mu zero one two three four five six seven eight nine onesuperior twosuperior threesuperior onequarter onehalf threequarters underscore hyphen endash emdash parenleft parenright bracketleft bracketright braceleft braceright numbersign percent perthousand quotesingle quotedbl quoteleft quoteright quotedblleft quotedblright quotesinglbase quotedblbase guilsinglleft guilsinglright asterisk dagger daggerdbl period comma colon semicolon ellipsis exclam exclamdown question questiondown slash backslash fraction bar brokenbar at ampersand section paragraph periodcentered bullet plus minus plusminus divide multiply equal less greater logicalnot dollar cent sterling currency yen Euro asciicircum asciitilde acute grave hungarumlaut circumflex caron breve tilde macron dieresis dotaccent ring cedilla ogonek copyright registered trademark degree florin guillemotleft guillemotright fi fl a_b_c .notdef type glyphList designspace width 0.0 weight 634.59275 public.glyphOrder B E F G S testLibItemKey a b c fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateCondensed.ufo/metainfo.plist000066400000000000000000000004761410425502200317640ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/000077500000000000000000000000001410425502200260645ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/features.fea000066400000000000000000000001041410425502200303520ustar00rootroot00000000000000# this is the feature from lightCondensed # Hi_this_is_the_feature. fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/fontinfo.plist000066400000000000000000000025501410425502200307650ustar00rootroot00000000000000 ascender 763.459275 capHeight 763.459275 copyright Copyright-token-string descender -200 familyName Intermediate guidelines italicAngle 0 openTypeOS2VendorID ADBE postscriptBlueValues postscriptDefaultWidthX 500 postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptSlantAngle 0 postscriptStemSnapH postscriptStemSnapV postscriptWindowsCharacterSet 1 styleName Wide unitsPerEm 1000.0 versionMajor 1 versionMinor 2 xHeight 500 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs.background/000077500000000000000000000000001410425502200315105ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs.background/S_.glif000066400000000000000000000045341410425502200327220ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 contents.plist000066400000000000000000000003441410425502200343440ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs.background S S_.glif layerinfo.plist000066400000000000000000000005271410425502200345020ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs.background color 0.5,1,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs/000077500000000000000000000000001410425502200273725ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs/B_.glif000066400000000000000000000034401410425502200305560ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs/E_.glif000066400000000000000000000022121410425502200305550ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs/F_.glif000066400000000000000000000016171410425502200305660ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs/G_.glif000066400000000000000000000041441410425502200305650ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs/contents.plist000066400000000000000000000005701410425502200323060ustar00rootroot00000000000000 B B_.glif E E_.glif F F_.glif G G_.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/glyphs/layerinfo.plist000066400000000000000000000005631410425502200324430ustar00rootroot00000000000000 color 1,0.75,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/kerning.plist000066400000000000000000000125261410425502200306040ustar00rootroot00000000000000 @MMK_L_A V -1.4210854715202004e-14 B H -14.61629 J -31.05961624999999 O -3.654072499999998 S -9.135181250000002 T -31.059616249999998 U -12.78925375 V -31.059616250000005 public.kern2.@MMK_R_A -9.135181249999999 C J -27.405543749999993 T -14.61629 V -23.75147125 public.kern2.@MMK_R_A -14.61629 E J -29.23258 T -3.6540725000000016 F H -12.78925375 J -89.52477625 O -18.270362499999997 S -25.5785075 U -3.6540725000000016 public.kern2.@MMK_R_A -45.67590625 G J -21.924435000000003 O -5.481108749999999 S -5.481108750000001 T -38.36776125 U -7.308145 V -25.5785075 public.kern2.@MMK_R_A -14.61629 H J -14.616290000000006 S -10.962217500000001 J J -49.32997874999998 O -3.6540725 public.kern2.@MMK_R_A -25.5785075 L J -9.135181250000002 O -34.71368875 T -111.44921125000002 U -31.059616250000005 V -67.60034125000001 O J -43.848870000000005 S -16.44332625 T -32.8866525 V -29.23258 public.kern2.@MMK_R_A -10.962217499999998 P J -73.08144999999999 T -7.308145 public.kern2.@MMK_R_A -34.713688749999996 R H -16.44332625 J -56.63812374999999 O -20.097398750000004 S -25.5785075 T -29.23258 U -21.924435000000003 V -34.71368875 public.kern2.@MMK_R_A -29.23258 S H -1.827036249999999 J -42.02183375 O -14.61629 S -16.44332625 T -18.270362500000005 U -3.6540725000000016 V -7.308145000000003 public.kern2.@MMK_R_A -16.44332625 T H -5.481108750000001 J -115.10328374999995 O -32.8866525 S -9.135181249999999 public.kern2.@MMK_R_A -78.56255875 U J -51.157015 public.kern2.@MMK_R_A -27.40554375 V @MMK_R_A -1.4210854715202004e-14 H -7.308145 J -96.83292124999997 O -20.097398750000004 S -18.270362500000005 public.kern2.@MMK_R_A -76.7355225 public.kern1.@MMK_L_A J -12.78925375 O -20.097398749999996 T -69.42737749999999 U -34.713688749999996 V -65.773305 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/layercontents.plist000066400000000000000000000005771410425502200320440ustar00rootroot00000000000000 foreground glyphs background glyphs.background fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/lib.plist000066400000000000000000000375371410425502200277260ustar00rootroot00000000000000 com.typemytype.robofont.background.layerStrokeColor 0.0 0.8 0.2 0.7 com.typemytype.robofont.compileSettings.autohint com.typemytype.robofont.compileSettings.checkOutlines com.typemytype.robofont.compileSettings.createDummyDSIG com.typemytype.robofont.compileSettings.decompose com.typemytype.robofont.compileSettings.generateFormat 0 com.typemytype.robofont.compileSettings.releaseMode com.typemytype.robofont.foreground.layerStrokeColor 0.5 0.0 0.5 0.7 com.typemytype.robofont.italicSlantOffset 0 com.typemytype.robofont.segmentType curve com.typemytype.robofont.shouldAddPointsInSplineConversion 1 com.typesupply.MetricsMachine4.groupColors @MMK_L_A 1.0 0.0 0.0 0.25 @MMK_L_C 1.0 0.5 0.0 0.25 @MMK_L_E 1.0 1.0 0.0 0.25 @MMK_L_I 0.0 1.0 0.0 0.25 @MMK_L_N 0.0 1.0 1.0 0.25 @MMK_L_O 0.0 0.5 1.0 0.25 @MMK_L_S 0.0 0.0 1.0 0.25 @MMK_L_U 0.5 0.0 1.0 0.25 @MMK_L_Y 1.0 0.0 1.0 0.25 @MMK_L_Z 1.0 0.0 0.5 0.25 @MMK_L_a 1.0 0.0 0.0 0.25 @MMK_L_c 1.0 0.5 0.0 0.25 @MMK_L_e 1.0 1.0 0.0 0.25 @MMK_L_i 0.0 1.0 0.0 0.25 @MMK_L_n 0.0 1.0 1.0 0.25 @MMK_L_o 0.0 0.5 1.0 0.25 @MMK_L_s 0.0 0.0 1.0 0.25 @MMK_L_u 0.5 0.0 1.0 0.25 @MMK_L_y 1.0 0.0 1.0 0.25 @MMK_L_z 1.0 0.0 0.5 0.25 @MMK_R_A 1.0 0.0 0.0 0.25 @MMK_R_C 1.0 0.5 0.0 0.25 @MMK_R_E 1.0 1.0 0.0 0.25 @MMK_R_I 0.0 1.0 0.0 0.25 @MMK_R_N 0.0 1.0 1.0 0.25 @MMK_R_O 0.0 0.5 1.0 0.25 @MMK_R_S 0.0 0.0 1.0 0.25 @MMK_R_U 0.5 0.0 1.0 0.25 @MMK_R_Y 1.0 0.0 1.0 0.25 @MMK_R_Z 1.0 0.0 0.5 0.25 @MMK_R_a 1.0 0.0 0.0 0.25 @MMK_R_c 1.0 0.5 0.0 0.25 @MMK_R_e 1.0 1.0 0.0 0.25 @MMK_R_i 0.0 1.0 0.0 0.25 @MMK_R_n 0.0 1.0 1.0 0.25 @MMK_R_o 0.0 0.5 1.0 0.25 @MMK_R_s 0.0 0.0 1.0 0.25 @MMK_R_u 0.5 0.0 1.0 0.25 @MMK_R_y 1.0 0.0 1.0 0.25 @MMK_R_z 1.0 0.0 0.5 0.25 com.typesupply.defcon.sortDescriptor ascending space A Agrave Aacute Acircumflex Atilde Adieresis Aring B C Ccedilla D E Egrave Eacute Ecircumflex Edieresis F G H I Igrave Iacute Icircumflex Idieresis J K L M N Ntilde O Ograve Oacute Ocircumflex Otilde Odieresis P Q R S Scaron T U Ugrave Uacute Ucircumflex Udieresis V W X Y Yacute Ydieresis Z Zcaron AE Eth Oslash Thorn Lslash OE a agrave aacute acircumflex atilde adieresis aring b c ccedilla d e egrave eacute ecircumflex edieresis f g h i igrave iacute icircumflex idieresis j k l m n ntilde o ograve oacute ocircumflex otilde odieresis p q r s scaron t u ugrave uacute ucircumflex udieresis v w x y yacute ydieresis z zcaron ordfeminine ordmasculine germandbls ae eth oslash thorn dotlessi lslash oe mu zero one two three four five six seven eight nine onesuperior twosuperior threesuperior onequarter onehalf threequarters underscore hyphen endash emdash parenleft parenright bracketleft bracketright braceleft braceright numbersign percent perthousand quotesingle quotedbl quoteleft quoteright quotedblleft quotedblright quotesinglbase quotedblbase guilsinglleft guilsinglright asterisk dagger daggerdbl period comma colon semicolon ellipsis exclam exclamdown question questiondown slash backslash fraction bar brokenbar at ampersand section paragraph periodcentered bullet plus minus plusminus divide multiply equal less greater logicalnot dollar cent sterling currency yen Euro asciicircum asciitilde acute grave hungarumlaut circumflex caron breve tilde macron dieresis dotaccent ring cedilla ogonek copyright registered trademark degree florin guillemotleft guillemotright fi fl a_b_c .notdef type glyphList designspace width 1000.0 weight 634.59275 public.glyphOrder B E F G testLibItemKey a b c fontmake-2.4.1/tests/data/MutatorSans/MutatorSansIntermediateWide.ufo/metainfo.plist000066400000000000000000000004761410425502200307520ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/000077500000000000000000000000001410425502200255335ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/features.fea000066400000000000000000000001041410425502200300210ustar00rootroot00000000000000# this is the feature from lightCondensed # Hi_this_is_the_feature. fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/fontinfo.plist000066400000000000000000000035401410425502200304340ustar00rootroot00000000000000 ascender 700 capHeight 700 copyright License same as MutatorMath. BSD 3-clause. [test-token: C] descender -200 familyName MutatorMathTest guidelines italicAngle 0 openTypeNameLicense License same as MutatorMath. BSD 3-clause. [test-token: C] openTypeOS2VendorID LTTR postscriptBlueValues postscriptDefaultWidthX 500 postscriptFamilyBlues postscriptFamilyOtherBlues postscriptFontName MutatorMathTest-LightCondensed postscriptFullName MutatorMathTest LightCondensed postscriptOtherBlues postscriptSlantAngle 0 postscriptStemSnapH postscriptStemSnapV postscriptWindowsCharacterSet 1 styleMapFamilyName styleMapStyleName regular styleName LightCondensed unitsPerEm 1000 versionMajor 1 versionMinor 2 xHeight 500 year 2004 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.background/000077500000000000000000000000001410425502200311575ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.background/S_.closed.glif000066400000000000000000000076361410425502200336470ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.background/S_.glif000066400000000000000000000064361410425502200323740ustar00rootroot00000000000000 com.letterror.skateboard.navigator location weight 820.0 width 1000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.background/contents.plist000066400000000000000000000004521410425502200340720ustar00rootroot00000000000000 S S_.glif S.closed S_.closed.glif layerinfo.plist000066400000000000000000000003641410425502200341500ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.background color 0,1,1,0.7 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.middle/000077500000000000000000000000001410425502200323515ustar00rootroot00000000000000S_.closed.glif000066400000000000000000000054111410425502200347470ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.middle com.letterror.skateboard.navigator location weight 700.0 width 569.078 contents.plist000066400000000000000000000003741410425502200352100ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.middle S.closed S_.closed.glif layerinfo.plist000066400000000000000000000003661410425502200353440ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.middle color 0.5,0,1,0.7 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.wide/000077500000000000000000000000001410425502200320435ustar00rootroot00000000000000S_.closed.glif000066400000000000000000000067271410425502200344540ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.wide com.letterror.skateboard.navigator location weight 673.7998527960526 width 1000.0 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.wide/S_.glif000066400000000000000000000067161410425502200332610ustar00rootroot00000000000000 com.letterror.skateboard.navigator location weight 759.5997715404774 width 1000.0 contents.plist000066400000000000000000000004521410425502200346770ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.wide S S_.glif S.closed S_.closed.glif layerinfo.plist000066400000000000000000000003671410425502200350370ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.S_.wide color 0,0.25,1,0.7 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar/000077500000000000000000000000001410425502200323715ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar/B_.glif000066400000000000000000000040771410425502200335640ustar00rootroot00000000000000 com.letterror.skateboard.navigator location weight 715.728 width -138.956 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar/E_.glif000066400000000000000000000026771410425502200335730ustar00rootroot00000000000000 com.letterror.skateboard.navigator location weight 715.728 width -138.956 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar/F_.glif000066400000000000000000000013571410425502200335660ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar/G_.glif000066400000000000000000000046241410425502200335670ustar00rootroot00000000000000 com.letterror.skateboard.navigator location weight 715.728 width -138.956 S_.closed.glif000066400000000000000000000006461410425502200347740ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar com.letterror.skateboard.navigator location weight 800.0 width 0.0 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar/S_.glif000066400000000000000000000066521410425502200336060ustar00rootroot00000000000000 com.letterror.skateboard.navigator location weight 889.1982375724028 width 0.0 contents.plist000066400000000000000000000007421410425502200352270ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar B B_.glif E E_.glif F F_.glif G G_.glif S S_.glif S.closed S_.closed.glif layerinfo.plist000066400000000000000000000003671410425502200353650ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbar color 0,1,0.25,0.7 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbars/000077500000000000000000000000001410425502200325545ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbars/E_.glif000066400000000000000000000022301410425502200337370ustar00rootroot00000000000000 contents.plist000066400000000000000000000003561410425502200354130ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbars E E_.glif layerinfo.plist000066400000000000000000000002671410425502200355470ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support.crossbars fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support/000077500000000000000000000000001410425502200305545ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support/A_.glif000066400000000000000000000014741410425502200317440ustar00rootroot00000000000000 com.letterror.skateboard.navigator location space 0.0 weight 600.0 width 500.0 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support/S_.glif000066400000000000000000000052221410425502200317610ustar00rootroot00000000000000 com.letterror.skateboard.navigator location space 25.0 weight 707.6485770089287 width 181.31051199776795 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support/W_.glif000066400000000000000000000015251410425502200317670ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support/contents.plist000066400000000000000000000005121410425502200334640ustar00rootroot00000000000000 A A_.glif S S_.glif W W_.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs.support/layerinfo.plist000066400000000000000000000005631410425502200336250ustar00rootroot00000000000000 color 0,1,0.25,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/000077500000000000000000000000001410425502200270415ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/A_.glif000066400000000000000000000016561410425502200302330ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/A_acute.glif000066400000000000000000000005401410425502200312440ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/A_dieresis.glif000066400000000000000000000005461410425502200317600ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/B_.glif000066400000000000000000000034071410425502200302300ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/C_.glif000066400000000000000000000025721410425502200302330ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/D_.glif000066400000000000000000000021601410425502200302250ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/E_.glif000066400000000000000000000017171410425502200302350ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/F_.glif000066400000000000000000000013471410425502200302350ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/G_.glif000066400000000000000000000033001410425502200302250ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/H_.glif000066400000000000000000000013451410425502200302350ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/I_.glif000066400000000000000000000013431410425502200302340ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/I_.narrow.glif000066400000000000000000000012751410425502200315470ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/I_J_.glif000066400000000000000000000021211410425502200305000ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/J_.glif000066400000000000000000000016411410425502200302360ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/J_.narrow.glif000066400000000000000000000014351410425502200315460ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/K_.glif000066400000000000000000000015461410425502200302430ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/L_.glif000066400000000000000000000010321410425502200302320ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/M_.glif000066400000000000000000000016221410425502200302400ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/N_.glif000066400000000000000000000013401410425502200302360ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/O_.glif000066400000000000000000000025341410425502200302450ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/P_.glif000066400000000000000000000021721410425502200302440ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/Q_.glif000066400000000000000000000005711410425502200302460ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/R_.glif000066400000000000000000000026661410425502200302560ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/S_.closed.glif000066400000000000000000000036561410425502200315270ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/S_.glif000066400000000000000000000046251410425502200302540ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/T_.glif000066400000000000000000000010421410425502200302430ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/U_.glif000066400000000000000000000016411410425502200302510ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/V_.glif000066400000000000000000000013411410425502200302470ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/W_.glif000066400000000000000000000015251410425502200302540ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/X_.glif000066400000000000000000000014361410425502200302560ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/Y_.glif000066400000000000000000000021401410425502200302500ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/Z_.glif000066400000000000000000000013431410425502200302550ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/acute.glif000066400000000000000000000005411410425502200310050ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/arrowdown.glif000066400000000000000000000011641410425502200317300ustar00rootroot00000000000000 public.markColor 0,0.95,0.95,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/arrowleft.glif000066400000000000000000000012621410425502200317120ustar00rootroot00000000000000 public.markColor 0,0.95,0.95,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/arrowright.glif000066400000000000000000000011631410425502200320750ustar00rootroot00000000000000 public.markColor 0,0.95,0.95,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/arrowup.glif000066400000000000000000000011621410425502200314030ustar00rootroot00000000000000 public.markColor 0,0.95,0.95,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/colon.glif000066400000000000000000000003461410425502200310210ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/comma.glif000066400000000000000000000010031410425502200307720ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/contents.plist000066400000000000000000000051771410425502200317650ustar00rootroot00000000000000 A A_.glif Aacute A_acute.glif Adieresis A_dieresis.glif B B_.glif C C_.glif D D_.glif E E_.glif F F_.glif G G_.glif H H_.glif I I_.glif I.narrow I_.narrow.glif IJ I_J_.glif J J_.glif J.narrow J_.narrow.glif K K_.glif L L_.glif M M_.glif N N_.glif O O_.glif P P_.glif Q Q_.glif R R_.glif S S_.glif S.closed S_.closed.glif T T_.glif U U_.glif V V_.glif W W_.glif X X_.glif Y Y_.glif Z Z_.glif acute acute.glif arrowdown arrowdown.glif arrowleft arrowleft.glif arrowright arrowright.glif arrowup arrowup.glif colon colon.glif comma comma.glif dieresis dieresis.glif dot dot.glif period period.glif quotedblbase quotedblbase.glif quotedblleft quotedblleft.glif quotedblright quotedblright.glif quotesinglbase quotesinglbase.glif semicolon semicolon.glif space space.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/dieresis.glif000066400000000000000000000005611410425502200315150ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/dot.glif000066400000000000000000000005351410425502200304750ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/layerinfo.plist000066400000000000000000000005631410425502200321120ustar00rootroot00000000000000 color 1,0.75,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/period.glif000066400000000000000000000005361410425502200311720ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/quotedblbase.glif000066400000000000000000000003531410425502200323570ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/quotedblleft.glif000066400000000000000000000005051410425502200323760ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/quotedblright.glif000066400000000000000000000004101410425502200325540ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/quotesinglbase.glif000066400000000000000000000003011410425502200327230ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/semicolon.glif000066400000000000000000000003511410425502200316730ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/glyphs/space.glif000066400000000000000000000002321410425502200307740ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/groups.plist000066400000000000000000000007531410425502200301340ustar00rootroot00000000000000 public.kern1.@MMK_L_A A public.kern2.@MMK_R_A A testGroup E F H fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/kerning.plist000066400000000000000000000010051410425502200302410ustar00rootroot00000000000000 T public.kern2.@MMK_R_A -75 V public.kern2.@MMK_R_A -100 public.kern1.@MMK_L_A V -15 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/layercontents.plist000066400000000000000000000014531410425502200315050ustar00rootroot00000000000000 foreground glyphs support glyphs.support support.crossbar glyphs.support.crossbar background glyphs.background support.S.wide glyphs.support.S_.wide support.S.middle glyphs.support.S_.middle fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/lib.plist000066400000000000000000000445501410425502200273660ustar00rootroot00000000000000 com.defcon.sortDescriptor allowPseudoUnicode ascending type alphabetical allowPseudoUnicode ascending type category allowPseudoUnicode ascending type unicode allowPseudoUnicode ascending type script allowPseudoUnicode ascending type suffix allowPseudoUnicode ascending type decompositionBase com.letterror.lightMeter.prefs chunkSize 5 diameter 200 drawTail invert toolDiameter 30 toolStyle fluid com.typemytype.robofont.background.layerStrokeColor 0.0 0.8 0.2 0.7 com.typemytype.robofont.compileSettings.autohint com.typemytype.robofont.compileSettings.checkOutlines com.typemytype.robofont.compileSettings.createDummyDSIG com.typemytype.robofont.compileSettings.decompose com.typemytype.robofont.compileSettings.generateFormat 0 com.typemytype.robofont.compileSettings.releaseMode com.typemytype.robofont.foreground.layerStrokeColor 0.5 0.0 0.5 0.7 com.typemytype.robofont.italicSlantOffset 0 com.typemytype.robofont.segmentType curve com.typemytype.robofont.shouldAddPointsInSplineConversion 1 com.typesupply.MetricsMachine4.groupColors @MMK_L_A 1.0 0.0 0.0 0.25 @MMK_L_C 1.0 0.5 0.0 0.25 @MMK_L_E 1.0 1.0 0.0 0.25 @MMK_L_I 0.0 1.0 0.0 0.25 @MMK_L_N 0.0 1.0 1.0 0.25 @MMK_L_O 0.0 0.5 1.0 0.25 @MMK_L_S 0.0 0.0 1.0 0.25 @MMK_L_U 0.5 0.0 1.0 0.25 @MMK_L_Y 1.0 0.0 1.0 0.25 @MMK_L_Z 1.0 0.0 0.5 0.25 @MMK_L_a 1.0 0.0 0.0 0.25 @MMK_L_c 1.0 0.5 0.0 0.25 @MMK_L_e 1.0 1.0 0.0 0.25 @MMK_L_i 0.0 1.0 0.0 0.25 @MMK_L_n 0.0 1.0 1.0 0.25 @MMK_L_o 0.0 0.5 1.0 0.25 @MMK_L_s 0.0 0.0 1.0 0.25 @MMK_L_u 0.5 0.0 1.0 0.25 @MMK_L_y 1.0 0.0 1.0 0.25 @MMK_L_z 1.0 0.0 0.5 0.25 @MMK_R_A 1.0 0.0 0.0 0.25 @MMK_R_C 1.0 0.5 0.0 0.25 @MMK_R_E 1.0 1.0 0.0 0.25 @MMK_R_I 0.0 1.0 0.0 0.25 @MMK_R_N 0.0 1.0 1.0 0.25 @MMK_R_O 0.0 0.5 1.0 0.25 @MMK_R_S 0.0 0.0 1.0 0.25 @MMK_R_U 0.5 0.0 1.0 0.25 @MMK_R_Y 1.0 0.0 1.0 0.25 @MMK_R_Z 1.0 0.0 0.5 0.25 @MMK_R_a 1.0 0.0 0.0 0.25 @MMK_R_c 1.0 0.5 0.0 0.25 @MMK_R_e 1.0 1.0 0.0 0.25 @MMK_R_i 0.0 1.0 0.0 0.25 @MMK_R_n 0.0 1.0 1.0 0.25 @MMK_R_o 0.0 0.5 1.0 0.25 @MMK_R_s 0.0 0.0 1.0 0.25 @MMK_R_u 0.5 0.0 1.0 0.25 @MMK_R_y 1.0 0.0 1.0 0.25 @MMK_R_z 1.0 0.0 0.5 0.25 com.typesupply.defcon.sortDescriptor ascending space A Agrave Aacute Acircumflex Atilde Adieresis Aring B C Ccedilla D E Egrave Eacute Ecircumflex Edieresis F G H I Igrave Iacute Icircumflex Idieresis J K L M N Ntilde O Ograve Oacute Ocircumflex Otilde Odieresis P Q R S Scaron T U Ugrave Uacute Ucircumflex Udieresis V W X Y Yacute Ydieresis Z Zcaron AE Eth Oslash Thorn Lslash OE a agrave aacute acircumflex atilde adieresis aring b c ccedilla d e egrave eacute ecircumflex edieresis f g h i igrave iacute icircumflex idieresis j k l m n ntilde o ograve oacute ocircumflex otilde odieresis p q r s scaron t u ugrave uacute ucircumflex udieresis v w x y yacute ydieresis z zcaron ordfeminine ordmasculine germandbls ae eth oslash thorn dotlessi lslash oe mu zero one two three four five six seven eight nine onesuperior twosuperior threesuperior onequarter onehalf threequarters underscore hyphen endash emdash parenleft parenright bracketleft bracketright braceleft braceright numbersign percent perthousand quotesingle quotedbl quoteleft quoteright quotedblleft quotedblright quotesinglbase quotedblbase guilsinglleft guilsinglright asterisk dagger daggerdbl period comma colon semicolon ellipsis exclam exclamdown question questiondown slash backslash fraction bar brokenbar at ampersand section paragraph periodcentered bullet plus minus plusminus divide multiply equal less greater logicalnot dollar cent sterling currency yen Euro asciicircum asciitilde acute grave hungarumlaut circumflex caron breve tilde macron dieresis dotaccent ring cedilla ogonek copyright registered trademark degree florin guillemotleft guillemotright fi fl a_b_c .notdef type glyphList public.glyphOrder A Aacute Adieresis B C D E F G H I J K L M N O P Q R S T U V W X Y Z S.closed I.narrow J.narrow quotesinglbase quotedblbase quotedblleft quotedblright comma period colon semicolon arrowleft arrowup arrowright arrowdown dot dieresis acute space IJ testLibItemKey a b c fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightCondensed.ufo/metainfo.plist000066400000000000000000000004761410425502200304210ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/000077500000000000000000000000001410425502200245215ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/features.fea000066400000000000000000000000451410425502200270130ustar00rootroot00000000000000# this is the feature from lightWide fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/fontinfo.plist000066400000000000000000000035211410425502200274210ustar00rootroot00000000000000 ascender 700 capHeight 700 copyright License same as MutatorMath. BSD 3-clause. [test-token: D] descender -200 familyName MutatorMathTest guidelines italicAngle 0 openTypeNameLicense License same as MutatorMath. BSD 3-clause. [test-token: D] openTypeOS2VendorID LTTR postscriptBlueValues postscriptDefaultWidthX 500 postscriptFamilyBlues postscriptFamilyOtherBlues postscriptFontName MutatorMathTest-LightWide postscriptFullName MutatorMathTest LightWide postscriptOtherBlues postscriptSlantAngle 0 postscriptStemSnapH postscriptStemSnapV postscriptWindowsCharacterSet 1 styleMapFamilyName styleMapStyleName regular styleName LightWide unitsPerEm 1000 versionMajor 1 versionMinor 2 xHeight 500 year 2004 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.background/000077500000000000000000000000001410425502200301455ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.background/S_.closed.glif000066400000000000000000000036551410425502200326320ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.background/contents.plist000066400000000000000000000003741410425502200330630ustar00rootroot00000000000000 S.closed S_.closed.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.background/layerinfo.plist000066400000000000000000000003661410425502200332170ustar00rootroot00000000000000 color 0.5,1,0,0.7 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_0.00_weight_0.00/000077500000000000000000000000001410425502200331615ustar00rootroot00000000000000contents.plist000066400000000000000000000002651410425502200360170ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_0.00_weight_0.00 layerinfo.plist000066400000000000000000000003551410425502200361520ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_0.00_weight_0.00 color 0,0.25,1,0.7 glyphs.master_width_500.00_weight_500.00/000077500000000000000000000000001410425502200334145ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufoS_.glif000066400000000000000000000046331410425502200346260ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_500.00_weight_500.00 contents.plist000066400000000000000000000003441410425502200363270ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_500.00_weight_500.00 S S_.glif layerinfo.plist000066400000000000000000000005301410425502200364570ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_500.00_weight_500.00 color 0,1,0.25,0.7 lib com.typemytype.robofont.segmentType curve glyphs.master_width_695.65_weight_166.38/000077500000000000000000000000001410425502200334715ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufocontents.plist000066400000000000000000000002651410425502200364060ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_695.65_weight_166.38 layerinfo.plist000066400000000000000000000003541410425502200365400ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_695.65_weight_166.38 color 0.5,0,1,0.7 glyphs.master_width_720.00_weight_645.00/000077500000000000000000000000001410425502200334325ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufoS_.glif000066400000000000000000000047511410425502200346450ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_720.00_weight_645.00 contents.plist000066400000000000000000000003441410425502200363450ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_720.00_weight_645.00 S S_.glif layerinfo.plist000066400000000000000000000005251410425502200365010ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs.master_width_720.00_weight_645.00 color 0,1,1,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/000077500000000000000000000000001410425502200260275ustar00rootroot00000000000000fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/A_.glif000066400000000000000000000024501410425502200272120ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/A_acute.glif000066400000000000000000000005421410425502200302340ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/A_dieresis.glif000066400000000000000000000005501410425502200307410ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/B_.glif000066400000000000000000000033711410425502200272160ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/C_.glif000066400000000000000000000026101410425502200272120ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/D_.glif000066400000000000000000000021561410425502200272200ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/E_.glif000066400000000000000000000025151410425502200272200ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/F_.glif000066400000000000000000000016721410425502200272240ustar00rootroot00000000000000 com.typemytype.robofont.guideline.magnetic.tCW6w1QdWl 5 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/G_.glif000066400000000000000000000033271410425502200272240ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/H_.glif000066400000000000000000000013561410425502200272250ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/I_.glif000066400000000000000000000013471410425502200272260ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/I_.narrow.glif000066400000000000000000000012771410425502200305370ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/I_J_.glif000066400000000000000000000022061410425502200274720ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/J_.glif000066400000000000000000000020401410425502200272160ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/J_.narrow.glif000066400000000000000000000014421410425502200305320ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/K_.glif000066400000000000000000000015531410425502200272270ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/L_.glif000066400000000000000000000010361410425502200272240ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/M_.glif000066400000000000000000000016341410425502200272310ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/N_.glif000066400000000000000000000013551410425502200272320ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/O_.glif000066400000000000000000000025541410425502200272350ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/P_.glif000066400000000000000000000021521410425502200272300ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/Q_.glif000066400000000000000000000005721410425502200272350ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/R_.glif000066400000000000000000000026631410425502200272410ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/S_.closed.glif000066400000000000000000000036621410425502200305120ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/S_.glif000066400000000000000000000044661410425502200272450ustar00rootroot00000000000000 com.typemytype.robofont.Image.Brightness 0 com.typemytype.robofont.Image.Contrast 1 com.typemytype.robofont.Image.Saturation 1 com.typemytype.robofont.Image.Sharpness 0.4 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/T_.glif000066400000000000000000000010451410425502200272340ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/U_.glif000066400000000000000000000016571410425502200272460ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/V_.glif000066400000000000000000000013441410425502200272400ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/W_.glif000066400000000000000000000015311410425502200272370ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/X_.glif000066400000000000000000000014411410425502200272400ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/Y_.glif000066400000000000000000000013531410425502200272430ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/Z_.glif000066400000000000000000000013601410425502200272420ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/acute.glif000066400000000000000000000005411410425502200277730ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/arrowdown.glif000066400000000000000000000010021410425502200307050ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/arrowleft.glif000066400000000000000000000010061410425502200306740ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/arrowright.glif000066400000000000000000000010061410425502200310570ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/arrowup.glif000066400000000000000000000010051410425502200303650ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/colon.glif000066400000000000000000000003461410425502200300070ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/comma.glif000066400000000000000000000010111410425502200277570ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/contents.plist000066400000000000000000000051771410425502200307530ustar00rootroot00000000000000 A A_.glif Aacute A_acute.glif Adieresis A_dieresis.glif B B_.glif C C_.glif D D_.glif E E_.glif F F_.glif G G_.glif H H_.glif I I_.glif I.narrow I_.narrow.glif IJ I_J_.glif J J_.glif J.narrow J_.narrow.glif K K_.glif L L_.glif M M_.glif N N_.glif O O_.glif P P_.glif Q Q_.glif R R_.glif S S_.glif S.closed S_.closed.glif T T_.glif U U_.glif V V_.glif W W_.glif X X_.glif Y Y_.glif Z Z_.glif acute acute.glif arrowdown arrowdown.glif arrowleft arrowleft.glif arrowright arrowright.glif arrowup arrowup.glif colon colon.glif comma comma.glif dieresis dieresis.glif dot dot.glif period period.glif quotedblbase quotedblbase.glif quotedblleft quotedblleft.glif quotedblright quotedblright.glif quotesinglbase quotesinglbase.glif semicolon semicolon.glif space space.glif fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/dieresis.glif000066400000000000000000000005621410425502200305040ustar00rootroot00000000000000 public.markColor 0.6567,0.6903,1,1 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/dot.glif000066400000000000000000000005351410425502200274630ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/layerinfo.plist000066400000000000000000000005631410425502200311000ustar00rootroot00000000000000 color 1,0.75,0,0.7 lib com.typemytype.robofont.segmentType curve fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/period.glif000066400000000000000000000005401410425502200301530ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/quotedblbase.glif000066400000000000000000000003531410425502200313450ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/quotedblleft.glif000066400000000000000000000005051410425502200313640ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/quotedblright.glif000066400000000000000000000004101410425502200315420ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/quotesinglbase.glif000066400000000000000000000003011410425502200317110ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/semicolon.glif000066400000000000000000000003511410425502200306610ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/glyphs/space.glif000066400000000000000000000002321410425502200277620ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/groups.plist000066400000000000000000000005561410425502200271230ustar00rootroot00000000000000 public.kern1.@MMK_L_A A public.kern2.@MMK_R_A A fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/kerning.plist000066400000000000000000000113641410425502200272400ustar00rootroot00000000000000 B H -40 J -85 O -10 S -25 T -85 U -35 V -85 public.kern2.@MMK_R_A -25 C J -75 T -40 V -65 public.kern2.@MMK_R_A -40 E J -80 T -10 F H -35 J -245 O -50 S -70 U -10 public.kern2.@MMK_R_A -125 G J -60 O -15 S -15 T -105 U -20 V -70 public.kern2.@MMK_R_A -40 H J -40 S -30 J J -135 O -10 public.kern2.@MMK_R_A -70 L J -25 O -95 T -305 U -85 V -185 O J -120 S -45 T -90 V -80 public.kern2.@MMK_R_A -30 P J -200 T -20 public.kern2.@MMK_R_A -95 R H -45 J -155 O -55 S -70 T -80 U -60 V -95 public.kern2.@MMK_R_A -80 S H -5 J -115 O -40 S -45 T -50 U -10 V -20 public.kern2.@MMK_R_A -45 T H -15 J -315 O -90 S -25 public.kern2.@MMK_R_A -215 U J -140 public.kern2.@MMK_R_A -75 V H -20 J -265 O -55 S -50 public.kern2.@MMK_R_A -210 public.kern1.@MMK_L_A J -35 O -55 T -190 U -95 V -180 fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/layercontents.plist000066400000000000000000000005771410425502200305010ustar00rootroot00000000000000 foreground glyphs background glyphs.background fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/lib.plist000066400000000000000000000435631410425502200263570ustar00rootroot00000000000000 com.defcon.sortDescriptor allowPseudoUnicode ascending type alphabetical allowPseudoUnicode ascending type category allowPseudoUnicode ascending type unicode allowPseudoUnicode ascending type script allowPseudoUnicode ascending type suffix allowPseudoUnicode ascending type decompositionBase com.typemytype.robofont.background.layerStrokeColor 1.0 0.75 0.0 0.7 com.typemytype.robofont.compileSettings.autohint com.typemytype.robofont.compileSettings.checkOutlines com.typemytype.robofont.compileSettings.createDummyDSIG com.typemytype.robofont.compileSettings.decompose com.typemytype.robofont.compileSettings.generateFormat 0 com.typemytype.robofont.compileSettings.releaseMode com.typemytype.robofont.foreground.layerStrokeColor 0.5 0.0 0.5 0.7 com.typemytype.robofont.italicSlantOffset 0 com.typemytype.robofont.segmentType curve com.typemytype.robofont.shouldAddPointsInSplineConversion 1 com.typesupply.MetricsMachine4.groupColors @MMK_L_A 1.0 0.0 0.0 0.25 @MMK_L_C 1.0 0.5 0.0 0.25 @MMK_L_E 1.0 1.0 0.0 0.25 @MMK_L_I 0.0 1.0 0.0 0.25 @MMK_L_N 0.0 1.0 1.0 0.25 @MMK_L_O 0.0 0.5 1.0 0.25 @MMK_L_S 0.0 0.0 1.0 0.25 @MMK_L_U 0.5 0.0 1.0 0.25 @MMK_L_Y 1.0 0.0 1.0 0.25 @MMK_L_Z 1.0 0.0 0.5 0.25 @MMK_L_a 1.0 0.0 0.0 0.25 @MMK_L_c 1.0 0.5 0.0 0.25 @MMK_L_e 1.0 1.0 0.0 0.25 @MMK_L_i 0.0 1.0 0.0 0.25 @MMK_L_n 0.0 1.0 1.0 0.25 @MMK_L_o 0.0 0.5 1.0 0.25 @MMK_L_s 0.0 0.0 1.0 0.25 @MMK_L_u 0.5 0.0 1.0 0.25 @MMK_L_y 1.0 0.0 1.0 0.25 @MMK_L_z 1.0 0.0 0.5 0.25 @MMK_R_A 1.0 0.0 0.0 0.25 @MMK_R_C 1.0 0.5 0.0 0.25 @MMK_R_E 1.0 1.0 0.0 0.25 @MMK_R_I 0.0 1.0 0.0 0.25 @MMK_R_N 0.0 1.0 1.0 0.25 @MMK_R_O 0.0 0.5 1.0 0.25 @MMK_R_S 0.0 0.0 1.0 0.25 @MMK_R_U 0.5 0.0 1.0 0.25 @MMK_R_Y 1.0 0.0 1.0 0.25 @MMK_R_Z 1.0 0.0 0.5 0.25 @MMK_R_a 1.0 0.0 0.0 0.25 @MMK_R_c 1.0 0.5 0.0 0.25 @MMK_R_e 1.0 1.0 0.0 0.25 @MMK_R_i 0.0 1.0 0.0 0.25 @MMK_R_n 0.0 1.0 1.0 0.25 @MMK_R_o 0.0 0.5 1.0 0.25 @MMK_R_s 0.0 0.0 1.0 0.25 @MMK_R_u 0.5 0.0 1.0 0.25 @MMK_R_y 1.0 0.0 1.0 0.25 @MMK_R_z 1.0 0.0 0.5 0.25 com.typesupply.defcon.sortDescriptor ascending space A Agrave Aacute Acircumflex Atilde Adieresis Aring B C Ccedilla D E Egrave Eacute Ecircumflex Edieresis F G H I Igrave Iacute Icircumflex Idieresis J K L M N Ntilde O Ograve Oacute Ocircumflex Otilde Odieresis P Q R S Scaron T U Ugrave Uacute Ucircumflex Udieresis V W X Y Yacute Ydieresis Z Zcaron AE Eth Oslash Thorn Lslash OE a agrave aacute acircumflex atilde adieresis aring b c ccedilla d e egrave eacute ecircumflex edieresis f g h i igrave iacute icircumflex idieresis j k l m n ntilde o ograve oacute ocircumflex otilde odieresis p q r s scaron t u ugrave uacute ucircumflex udieresis v w x y yacute ydieresis z zcaron ordfeminine ordmasculine germandbls ae eth oslash thorn dotlessi lslash oe zero one two three four five six seven eight nine onesuperior twosuperior threesuperior onequarter onehalf threequarters underscore hyphen endash emdash parenleft parenright bracketleft bracketright braceleft braceright numbersign percent perthousand quotesingle quotedbl quoteleft quoteright quotedblleft quotedblright quotesinglbase quotedblbase guilsinglleft guilsinglright guillemotleft guillemotright asterisk dagger daggerdbl period comma colon semicolon ellipsis exclam exclamdown question questiondown slash backslash fraction bar brokenbar at ampersand section paragraph periodcentered bullet plus minus plusminus divide multiply equal less greater logicalnot mu dollar cent sterling currency yen Euro florin asciicircum asciitilde acute grave hungarumlaut circumflex caron breve tilde macron dieresis dotaccent ring cedilla ogonek copyright registered trademark degree fi fl .notdef a_b_c type glyphList public.glyphOrder A Aacute Adieresis B C D E F G H I J K L M N O P Q R S T U V W X Y Z S.closed I.narrow J.narrow quotesinglbase quotedblbase quotedblleft quotedblright comma period colon semicolon arrowleft arrowup arrowright arrowdown dot dieresis acute space IJ fontmake-2.4.1/tests/data/MutatorSans/MutatorSansLightWide.ufo/metainfo.plist000066400000000000000000000004761410425502200274070ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/MutatorSans/MutatorSans_missing.designspace000066400000000000000000000204161410425502200260730ustar00rootroot00000000000000 com.superpolator.data expandRules horizontalPreviewAxis width includeLegacyRules keepWorkFiles outputFormatUFO 3 previewtext HOPA roundGeometry verticalPreviewAxis weight fontmake-2.4.1/tests/data/MutatorSans/MutatorSans_no_default.designspace000066400000000000000000000172321410425502200265440ustar00rootroot00000000000000 com.superpolator.data expandRules horizontalPreviewAxis width includeLegacyRules keepWorkFiles outputFormatUFO 3 previewtext HOPA roundGeometry verticalPreviewAxis weight fontmake-2.4.1/tests/data/SwapGlyphNames/000077500000000000000000000000001410425502200202725ustar00rootroot00000000000000fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/000077500000000000000000000000001410425502200212425ustar00rootroot00000000000000fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/fontinfo.plist000066400000000000000000000014261410425502200241440ustar00rootroot00000000000000 ascender 750 capHeight 700 descender -250 guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV unitsPerEm 1000 xHeight 500 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/000077500000000000000000000000001410425502200225505ustar00rootroot00000000000000fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/a.glif000066400000000000000000000006641410425502200236410ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/a.swap.glif000066400000000000000000000011051410425502200246010ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/aaa.glif000066400000000000000000000005761410425502200241450ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/aaa.swap.glif000066400000000000000000000006111410425502200251040ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/contents.plist000066400000000000000000000010371410425502200254630ustar00rootroot00000000000000 a a.glif a.swap a.swap.glif aaa aaa.glif aaa.swap aaa.swap.glif space space.glif x x.glif y y.glif fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/space.glif000066400000000000000000000002341410425502200245050ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/x.glif000066400000000000000000000012061410425502200236610ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/glyphs/y.glif000066400000000000000000000010121410425502200236550ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/groups.plist000066400000000000000000000007271410425502200236440ustar00rootroot00000000000000 public.kern1.a a public.kern1.aswap a.swap public.kern2.a a a.swap fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/kerning.plist000066400000000000000000000013121410425502200237510ustar00rootroot00000000000000 a y 30 a.swap y 40 public.kern1.a x 10 public.kern1.aswap x 20 y a 50 a.swap 60 fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/layercontents.plist000066400000000000000000000004371410425502200252150ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/lib.plist000066400000000000000000000006731410425502200230730ustar00rootroot00000000000000 public.glyphOrder space a a.swap aaa aaa.swap x y fontmake-2.4.1/tests/data/SwapGlyphNames/A.ufo/metainfo.plist000066400000000000000000000004761410425502200241300ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/000077500000000000000000000000001410425502200212435ustar00rootroot00000000000000fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/fontinfo.plist000066400000000000000000000014261410425502200241450ustar00rootroot00000000000000 ascender 750 capHeight 700 descender -250 guidelines postscriptBlueValues postscriptFamilyBlues postscriptFamilyOtherBlues postscriptOtherBlues postscriptStemSnapH postscriptStemSnapV unitsPerEm 1000 xHeight 500 fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/glyphs/000077500000000000000000000000001410425502200225515ustar00rootroot00000000000000fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/glyphs/a.alt.glif000066400000000000000000000014201410425502200244100ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/glyphs/a.glif000066400000000000000000000016021410425502200236330ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/glyphs/adieresis.alt.glif000066400000000000000000000003151410425502200261420ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/glyphs/adieresis.glif000066400000000000000000000003351410425502200253650ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/glyphs/contents.plist000066400000000000000000000007471410425502200254730ustar00rootroot00000000000000 a a.glif a.alt a.alt.glif adieresis adieresis.glif adieresis.alt adieresis.alt.glif dieresiscomb dieresiscomb.glif fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/glyphs/dieresiscomb.glif000066400000000000000000000010331410425502200260610ustar00rootroot00000000000000 fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/layercontents.plist000066400000000000000000000004371410425502200252160ustar00rootroot00000000000000 public.default glyphs fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/lib.plist000066400000000000000000000006321410425502200230670ustar00rootroot00000000000000 public.glyphOrder a a.alt adieresis dieresiscomb adieresis.alt fontmake-2.4.1/tests/data/SwapGlyphNames/B.ufo/metainfo.plist000066400000000000000000000004761410425502200241310ustar00rootroot00000000000000 creator com.github.fonttools.ufoLib formatVersion 3 fontmake-2.4.1/tests/data/TestSubset.glyphs000066400000000000000000000143621410425502200207330ustar00rootroot00000000000000{ .appVersion = "1150"; DisplayStrings = ( A, B, C, D, ABCD ); copyright = "Nobody 2019"; customParameters = ( { name = "Don't use Production Names"; value = 1; }, { name = glyphOrder; value = ( space, A, C, B, D ); } ); date = "2018-06-15 11:22:00 +0000"; designer = Nobody; familyName = Test; fontMaster = ( { ascender = 800; capHeight = 700; descender = -200; id = "6111F4CC-71E1-4957-80C0-165C5F37B12D"; weightValue = 400; xHeight = 500; }, { ascender = 800; capHeight = 700; descender = -200; id = "5C1BB0B4-E06E-4398-8A0A-FC3D2F3AAFA2"; weight = Bold; weightValue = 700; xHeight = 500; } ); glyphs = ( { glyphname = space; lastChange = "2018-06-15 11:32:24 +0000"; layers = ( { layerId = "6111F4CC-71E1-4957-80C0-165C5F37B12D"; width = 600; }, { layerId = "5C1BB0B4-E06E-4398-8A0A-FC3D2F3AAFA2"; width = 600; } ); unicode = 0020; }, { glyphname = A; lastChange = "2018-06-15 11:40:10 +0000"; layers = ( { layerId = "6111F4CC-71E1-4957-80C0-165C5F37B12D"; paths = ( { closed = 1; nodes = ( "-6 3 LINE", "104 -5 LINE", "201 298 LINE", "358 294 LINE", "477 -3 LINE", "574 9 LINE", "313 699 LINE", "250 704 LINE" ); }, { closed = 1; nodes = ( "298 573 LINE", "349 371 LINE", "215 368 LINE", "267 573 LINE" ); } ); width = 600; }, { layerId = "5C1BB0B4-E06E-4398-8A0A-FC3D2F3AAFA2"; paths = ( { closed = 1; nodes = ( "-36 3 LINE", "104 -5 LINE", "201 278 LINE", "358 274 LINE", "477 -3 LINE", "615 9 LINE", "354 699 LINE", "220 704 LINE" ); }, { closed = 1; nodes = ( "298 603 LINE", "349 371 LINE", "215 368 LINE", "267 603 LINE" ); } ); width = 600; } ); unicode = 0041; }, { glyphname = C; lastChange = "2018-06-15 11:33:54 +0000"; layers = ( { layerId = "6111F4CC-71E1-4957-80C0-165C5F37B12D"; paths = ( { closed = 1; nodes = ( "522 45 OFFCURVE", "414 -7 OFFCURVE", "310 -7 CURVE SMOOTH", "124 -7 OFFCURVE", "-26 157 OFFCURVE", "-26 359 CURVE SMOOTH", "-26 560 OFFCURVE", "124 724 OFFCURVE", "310 724 CURVE SMOOTH", "423 724 OFFCURVE", "512 685 OFFCURVE", "583 601 CURVE", "512 544 LINE", "466 612 OFFCURVE", "395 655 OFFCURVE", "315 655 CURVE SMOOTH", "176 655 OFFCURVE", "63 523 OFFCURVE", "63 360 CURVE SMOOTH", "63 197 OFFCURVE", "176 65 OFFCURVE", "315 65 CURVE SMOOTH", "393 65 OFFCURVE", "463 107 OFFCURVE", "509 172 CURVE", "583 127 LINE" ); } ); width = 600; }, { layerId = "5C1BB0B4-E06E-4398-8A0A-FC3D2F3AAFA2"; paths = ( { closed = 1; nodes = ( "522 45 OFFCURVE", "414 -7 OFFCURVE", "310 -7 CURVE SMOOTH", "124 -7 OFFCURVE", "-26 157 OFFCURVE", "-26 359 CURVE SMOOTH", "-26 560 OFFCURVE", "124 724 OFFCURVE", "310 724 CURVE SMOOTH", "423 724 OFFCURVE", "512 685 OFFCURVE", "583 601 CURVE", "479 512 LINE", "433 580 OFFCURVE", "382 618 OFFCURVE", "302 618 CURVE SMOOTH", "185 618 OFFCURVE", "103 523 OFFCURVE", "103 360 CURVE SMOOTH", "103 197 OFFCURVE", "186 113 OFFCURVE", "295 113 CURVE SMOOTH", "373 113 OFFCURVE", "423 147 OFFCURVE", "469 212 CURVE", "583 127 LINE" ); } ); width = 600; } ); unicode = 0043; }, { glyphname = B; export = 0; lastChange = "2018-06-15 11:34:17 +0000"; layers = ( { layerId = "6111F4CC-71E1-4957-80C0-165C5F37B12D"; paths = ( { closed = 1; nodes = ( "347 5 LINE", "456 5 OFFCURVE", "600 0 OFFCURVE", "600 209 CURVE SMOOTH", "600 387 OFFCURVE", "341 369 OFFCURVE", "261 371 CURVE", "261 392 LINE", "434 392 OFFCURVE", "548 377 OFFCURVE", "548 555 CURVE SMOOTH", "548 661 OFFCURVE", "484 702 OFFCURVE", "348 702 CURVE", "65 702 LINE", "62 3 LINE" ); }, { closed = 1; nodes = ( "159 325 LINE", "391 325 LINE SMOOTH", "471 325 OFFCURVE", "512 276 OFFCURVE", "505 185 CURVE SMOOTH", "499 110 OFFCURVE", "457 72 OFFCURVE", "404 74 CURVE SMOOTH", "178 73 LINE" ); }, { closed = 1; nodes = ( "166 653 LINE", "318 648 LINE", "378 643 OFFCURVE", "436 618 OFFCURVE", "436 561 CURVE SMOOTH", "436 500 OFFCURVE", "409 441 OFFCURVE", "319 433 CURVE", "155 426 LINE" ); } ); width = 600; }, { layerId = "5C1BB0B4-E06E-4398-8A0A-FC3D2F3AAFA2"; paths = ( { closed = 1; nodes = ( "347 5 LINE", "456 5 OFFCURVE", "600 0 OFFCURVE", "600 209 CURVE SMOOTH", "600 387 OFFCURVE", "341 369 OFFCURVE", "261 371 CURVE", "261 392 LINE", "434 392 OFFCURVE", "548 377 OFFCURVE", "548 555 CURVE SMOOTH", "548 661 OFFCURVE", "484 702 OFFCURVE", "348 702 CURVE", "65 702 LINE", "62 3 LINE" ); }, { closed = 1; nodes = ( "189 315 LINE", "361 315 LINE SMOOTH", "441 315 OFFCURVE", "468 262 OFFCURVE", "465 209 CURVE SMOOTH", "461 130 OFFCURVE", "417 94 OFFCURVE", "364 94 CURVE SMOOTH", "208 93 LINE" ); }, { closed = 1; nodes = ( "196 633 LINE", "308 628 LINE", "368 623 OFFCURVE", "416 598 OFFCURVE", "416 539 CURVE SMOOTH", "416 500 OFFCURVE", "399 451 OFFCURVE", "319 443 CURVE", "185 436 LINE" ); } ); width = 600; } ); unicode = 0042; }, { glyphname = D; lastChange = "2018-06-15 11:34:58 +0000"; layers = ( { layerId = "6111F4CC-71E1-4957-80C0-165C5F37B12D"; paths = ( { closed = 1; nodes = ( "501 0 OFFCURVE", "591 133 OFFCURVE", "598 356 CURVE SMOOTH", "606 599 OFFCURVE", "481 709 OFFCURVE", "277 709 CURVE", "30 708 LINE", "33 716 OFFCURVE", "27 239 OFFCURVE", "26 4 CURVE", "273 3 LINE" ); }, { closed = 1; nodes = ( "97 72 LINE", "98 248 OFFCURVE", "102 639 OFFCURVE", "100 633 CURVE", "286 634 LINE", "439 634 OFFCURVE", "513 539 OFFCURVE", "507 356 CURVE SMOOTH", "502 188 OFFCURVE", "454 69 OFFCURVE", "283 71 CURVE" ); } ); width = 600; }, { layerId = "5C1BB0B4-E06E-4398-8A0A-FC3D2F3AAFA2"; paths = ( { closed = 1; nodes = ( "501 0 OFFCURVE", "591 133 OFFCURVE", "598 356 CURVE SMOOTH", "606 599 OFFCURVE", "481 709 OFFCURVE", "277 709 CURVE", "30 708 LINE", "33 716 OFFCURVE", "27 239 OFFCURVE", "26 4 CURVE", "273 3 LINE" ); }, { closed = 1; nodes = ( "147 112 LINE", "148 288 OFFCURVE", "152 619 OFFCURVE", "150 613 CURVE", "262 614 LINE", "409 614 OFFCURVE", "473 499 OFFCURVE", "467 356 CURVE SMOOTH", "460 188 OFFCURVE", "400 111 OFFCURVE", "264 111 CURVE" ); } ); width = 600; } ); unicode = 0044; } ); instances = ( { interpolationWeight = 400; instanceInterpolations = { "6111F4CC-71E1-4957-80C0-165C5F37B12D" = 1; }; name = Regular; }, { customParameters = ( { name = "Keep Glyphs"; value = ( space, A, B, C ); } ); interpolationWeight = 400; instanceInterpolations = { "6111F4CC-71E1-4957-80C0-165C5F37B12D" = 1; }; name = "Subset Regular"; }, { interpolationWeight = 700; instanceInterpolations = { "5C1BB0B4-E06E-4398-8A0A-FC3D2F3AAFA2" = 1; }; name = Bold; weightClass = Bold; } ); unitsPerEm = 1000; versionMajor = 1; versionMinor = 0; } fontmake-2.4.1/tests/test_instantiator.py000066400000000000000000000571741410425502200206250ustar00rootroot00000000000000import logging import fontTools.designspaceLib as designspaceLib import pytest import ufoLib2 from fontTools.pens.recordingPen import RecordingPen from ufoLib2.objects.anchor import Anchor import fontmake.instantiator def test_interpolation_weight_width_class(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "MutatorSans" / "MutatorSans.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) for instance in designspace.instances: instance.font = generator.generate_instance(instance) # LightCondensed font = designspace.instances[0].font assert font.info.openTypeOS2WeightClass == 1 assert font.info.openTypeOS2WidthClass == 1 # BoldCondensed font = designspace.instances[1].font assert font.info.openTypeOS2WeightClass == 1000 assert font.info.openTypeOS2WidthClass == 1 # LightWide font = designspace.instances[2].font assert font.info.openTypeOS2WeightClass == 1 assert font.info.openTypeOS2WidthClass == 9 # BoldWide font = designspace.instances[3].font assert font.info.openTypeOS2WeightClass == 1000 assert font.info.openTypeOS2WidthClass == 9 # Medium_Narrow_I font = designspace.instances[4].font assert font.info.openTypeOS2WeightClass == 500 assert font.info.openTypeOS2WidthClass == 9 # Medium_Wide_I font = designspace.instances[5].font assert font.info.openTypeOS2WeightClass == 500 assert font.info.openTypeOS2WidthClass == 9 # Two font = designspace.instances[6].font assert font.info.openTypeOS2WeightClass == 1000 assert font.info.openTypeOS2WidthClass == 9 # One font = designspace.instances[7].font assert font.info.openTypeOS2WeightClass == 500 assert font.info.openTypeOS2WidthClass == 9 def test_default_groups_only(data_dir, caplog): """Test that only the default source's groups end up in instances.""" d = designspaceLib.DesignSpaceDocument() d.addAxisDescriptor( name="Weight", tag="wght", minimum=300, default=300, maximum=900 ) d.addSourceDescriptor(location={"Weight": 300}, font=ufoLib2.Font()) d.addSourceDescriptor(location={"Weight": 900}, font=ufoLib2.Font()) d.addInstanceDescriptor(styleName="2", location={"Weight": 400}) d.findDefault() d.sources[0].font.groups["public.kern1.GRK_alpha_alt_LC_1ST"] = [ "alpha.alt", "alphatonos.alt", ] d.sources[1].font.groups["public.kern1.GRK_alpha_LC_1ST"] = [ "alpha.alt", "alphatonos.alt", ] generator = fontmake.instantiator.Instantiator.from_designspace(d) assert "contains different groups than the default source" in caplog.text instance = generator.generate_instance(d.instances[0]) assert instance.groups == { "public.kern1.GRK_alpha_alt_LC_1ST": ["alpha.alt", "alphatonos.alt"] } def test_default_groups_only2(data_dir, caplog): """Test that the group difference warning is not triggered if non-default source groups are empty.""" d = designspaceLib.DesignSpaceDocument() d.addAxisDescriptor( name="Weight", tag="wght", minimum=300, default=300, maximum=900 ) d.addSourceDescriptor(location={"Weight": 300}, font=ufoLib2.Font()) d.addSourceDescriptor(location={"Weight": 900}, font=ufoLib2.Font()) d.addInstanceDescriptor(styleName="2", location={"Weight": 400}) d.findDefault() d.sources[0].font.groups["public.kern1.GRK_alpha_alt_LC_1ST"] = [ "alpha.alt", "alphatonos.alt", ] generator = fontmake.instantiator.Instantiator.from_designspace(d) assert "contains different groups than the default source" not in caplog.text instance = generator.generate_instance(d.instances[0]) assert instance.groups == { "public.kern1.GRK_alpha_alt_LC_1ST": ["alpha.alt", "alphatonos.alt"] } def test_interpolation_no_rounding(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "MutatorSans" / "MutatorSans.designspace" ) designspace.instances[4].location = {"weight": 123.456, "width": 789.123} generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=False ) instance_font = generator.generate_instance(designspace.instances[4]) assert isinstance(instance_font.info.ascender, float) assert isinstance(instance_font.kerning[("A", "J")], float) assert isinstance(instance_font["A"].contours[0][0].x, float) def test_interpolation_rounding(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "MutatorSans" / "MutatorSans.designspace" ) designspace.instances[4].location = {"weight": 123.456, "width": 789.123} generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[4]) assert isinstance(instance_font.info.ascender, int) assert isinstance(instance_font.kerning[("A", "J")], int) assert isinstance(instance_font["A"].contours[0][0].x, int) def test_weight_class_from_wght_axis(): assert fontmake.instantiator.weight_class_from_wght_value(-500) == 1 assert fontmake.instantiator.weight_class_from_wght_value(1.1) == 1 assert fontmake.instantiator.weight_class_from_wght_value(1) == 1 assert fontmake.instantiator.weight_class_from_wght_value(500.6) == 501 assert fontmake.instantiator.weight_class_from_wght_value(1000) == 1000 assert fontmake.instantiator.weight_class_from_wght_value(1000.0) == 1000 assert fontmake.instantiator.weight_class_from_wght_value(1000.1) == 1000 assert fontmake.instantiator.weight_class_from_wght_value(2000.1) == 1000 def test_width_class_from_wdth_axis(): assert fontmake.instantiator.width_class_from_wdth_value(-500) == 1 assert fontmake.instantiator.width_class_from_wdth_value(50) == 1 assert fontmake.instantiator.width_class_from_wdth_value(62.5) == 2 assert fontmake.instantiator.width_class_from_wdth_value(75) == 3 assert fontmake.instantiator.width_class_from_wdth_value(87.5) == 4 assert fontmake.instantiator.width_class_from_wdth_value(100) == 5 assert fontmake.instantiator.width_class_from_wdth_value(112) == 6 assert fontmake.instantiator.width_class_from_wdth_value(112.5) == 6 assert fontmake.instantiator.width_class_from_wdth_value(125) == 7 assert fontmake.instantiator.width_class_from_wdth_value(130) == 7 assert fontmake.instantiator.width_class_from_wdth_value(150) == 8 assert fontmake.instantiator.width_class_from_wdth_value(190) == 9 assert fontmake.instantiator.width_class_from_wdth_value(200) == 9 assert fontmake.instantiator.width_class_from_wdth_value(1000) == 9 def test_swap_glyph_names(data_dir): ufo = ufoLib2.Font.open(data_dir / "SwapGlyphNames" / "A.ufo") fontmake.instantiator.swap_glyph_names(ufo, "a", "a.swap") # Test swapped outlines. assert ufo["a"].unicode == 0x61 assert len(ufo["a"]) == 1 assert len(ufo["a"].contours[0]) == 8 assert ufo["a"].width == 666 assert ufo["a.swap"].unicode is None assert len(ufo["a.swap"]) == 1 assert len(ufo["a.swap"].contours[0]) == 4 assert ufo["a.swap"].width == 600 # Test swapped components. assert sorted(c.baseGlyph for c in ufo["aaa"].components) == [ "a.swap", "a.swap", "x", ] assert sorted(c.baseGlyph for c in ufo["aaa.swap"].components) == ["a", "a", "y"] # Test swapped anchors. assert ufo["a"].anchors == [ Anchor(x=153, y=0, name="bottom"), Anchor(x=153, y=316, name="top"), ] assert ufo["a.swap"].anchors == [ Anchor(x=351, y=0, name="bottom"), Anchor(x=351, y=613, name="top"), ] # Test swapped glyph kerning. assert ufo.kerning == { ("public.kern1.a", "x"): 10, ("public.kern1.aswap", "x"): 20, ("a", "y"): 40, ("a.swap", "y"): 30, ("y", "a"): 60, ("y", "a.swap"): 50, } # Test swapped group membership. assert ufo.groups == { "public.kern1.a": ["a.swap"], "public.kern1.aswap": ["a"], "public.kern2.a": ["a.swap", "a"], } # Swap a second time. fontmake.instantiator.swap_glyph_names(ufo, "aaa", "aaa.swap") # Test swapped glyphs. assert sorted(c.baseGlyph for c in ufo["aaa"].components) == ["a", "a", "y"] assert sorted(c.baseGlyph for c in ufo["aaa.swap"].components) == [ "a.swap", "a.swap", "x", ] # Test for no leftover temporary glyphs. assert {g.name for g in ufo} == { "space", "a", "a.swap", "aaa", "aaa.swap", "x", "y", } with pytest.raises(fontmake.instantiator.InstantiatorError, match="Cannot swap"): fontmake.instantiator.swap_glyph_names(ufo, "aaa", "aaa.swapa") def test_swap_glyph_names_spec(data_dir): """Test that the rule example in the designspaceLib spec works. `adieresis` should look the same as before the rule application. [1]: fonttools/Doc/source/designspaceLib#ufo-instances """ ufo = ufoLib2.Font.open(data_dir / "SwapGlyphNames" / "B.ufo") fontmake.instantiator.swap_glyph_names(ufo, "a", "a.alt") assert sorted(c.baseGlyph for c in ufo["adieresis"].components) == [ "a.alt", "dieresiscomb", ] assert sorted(c.baseGlyph for c in ufo["adieresis.alt"].components) == [ "a", "dieresiscomb", ] def test_rules_are_applied_deterministically(data_dir): """Test that a combination of designspace rules that end up mapping serveral input glyphs to the same destination glyph result in a correct and deterministic series of glyph swaps. The example is a font with 2 Q designs that depend on a style axis style < 0.5: Q style >= 0.5: Q.ss01 and each Q also has an alternative shape in bolder weights (like Skia) weight < 780: Q weight >= 780: Q.alt weight < 730: Q.ss01 weight >= 730: Q.ss01.alt Then we generate an instance at style = 1, weight = 900. From the rules, the default CMAP entry for Q should have the outlines of Q.ss01.alt from the black UFO. """ doc = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceRuleOrder" / "MyFont.designspace" ) instanciator = fontmake.instantiator.Instantiator.from_designspace(doc) instance = instanciator.generate_instance(doc.instances[0]) pen = RecordingPen() instance["Q"].draw(pen) instance_recording = pen.value black_ufo = ufoLib2.Font.open( data_dir / "DesignspaceRuleOrder" / "MyFont_Black.ufo" ) pen = RecordingPen() black_ufo["Q.ss01.alt"].draw(pen) black_ufo_recording = pen.value assert instance_recording == black_ufo_recording def test_raise_no_default_master(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "MutatorSans" / "MutatorSans_no_default.designspace" ) with pytest.raises(fontmake.instantiator.InstantiatorError, match="no default"): fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) def test_raise_failed_glyph_interpolation(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceBrokenTest" / "DesignspaceTest.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace(designspace) with pytest.raises( fontmake.instantiator.InstantiatorError, match="Failed to generate instance" ): for instance in designspace.instances: instance.font = generator.generate_instance(instance) def test_ignore_failed_glyph_interpolation(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceBrokenTest" / "DesignspaceTest.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace(designspace) generator.skip_export_glyphs.append("asas") for instance in designspace.instances: instance.font = generator.generate_instance(instance) assert ( not instance.font["asas"].contours and not instance.font["asas"].components ) def test_raise_anisotropic_location(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "MutatorSans" / "MutatorSans-width-only.designspace" ) designspace.instances[0].location["width"] = (100, 900) with pytest.raises( fontmake.instantiator.InstantiatorError, match="anisotropic instance locations" ): fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) def test_copy_nonkerning_group(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace(designspace) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.groups == { "nonkerning_group": ["A"], "public.kern2.asdf": ["A"], } def test_interpolation(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font["l"].width == 220 def test_interpolation_only_default(data_dir, caplog): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "MutatorSans" / "MutatorSans.designspace" ) designspace.loadSourceFonts(ufoLib2.Font.open) for name in designspace.default.font.glyphOrder: if name != "A": del designspace.default.font[name] with caplog.at_level(logging.WARNING): generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) assert "contains glyphs that are missing from the" in caplog.text instance_font = generator.generate_instance(designspace.instances[0]) assert {g.name for g in instance_font} == {"A"} def test_interpolation_masters_as_instances(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceBrokenTest" / "Designspace-MastersAsInstances.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.info.styleName == "Light ASDF" assert instance_font["l"].width == 160 instance_font = generator.generate_instance(designspace.instances[1]) assert instance_font.info.styleName == "Bold ASDF" assert instance_font["l"].width == 280 def test_instance_attributes(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-instance-attrs.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.info.familyName == "aaa" assert instance_font.info.styleName == "sss" assert instance_font.info.postscriptFontName == "ppp" assert instance_font.info.styleMapFamilyName == "yyy" assert instance_font.info.styleMapStyleName == "xxx" def test_instance_no_attributes(data_dir, caplog): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-bare.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) with caplog.at_level(logging.WARNING): instance_font = generator.generate_instance(designspace.instances[0]) assert "missing the stylename attribute" in caplog.text assert instance_font.info.familyName == "MyFont" assert instance_font.info.styleName == "Light" assert instance_font.info.postscriptFontName is None assert instance_font.info.styleMapFamilyName is None assert instance_font.info.styleMapStyleName is None def test_axis_mapping(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-wght-wdth.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.info.openTypeOS2WeightClass == 400 assert instance_font.info.openTypeOS2WidthClass == 5 assert instance_font.info.italicAngle is None assert instance_font.lib["designspace.location"] == [ ("weight", 100.0), ("width", 100.0), ] def test_axis_mapping_manual_os2_classes(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-wght-wdth.designspace" ) designspace.loadSourceFonts(ufoLib2.Font.open) designspace.sources[0].font.info.openTypeOS2WeightClass = 800 designspace.sources[0].font.info.openTypeOS2WidthClass = 7 designspace.sources[1].font.info.openTypeOS2WeightClass = 900 designspace.sources[1].font.info.openTypeOS2WidthClass = 9 generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.info.openTypeOS2WeightClass == 850 assert instance_font.info.openTypeOS2WidthClass == 8 assert instance_font.info.italicAngle is None assert instance_font.lib["designspace.location"] == [ ("weight", 100.0), ("width", 100.0), ] def test_axis_mapping_no_os2_width_class_inference(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-bare.designspace" ) designspace.loadSourceFonts(ufoLib2.Font.open) designspace.sources[0].font.info.openTypeOS2WeightClass = 800 designspace.sources[1].font.info.openTypeOS2WeightClass = 900 generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.info.openTypeOS2WeightClass == 850 assert instance_font.info.openTypeOS2WidthClass is None assert instance_font.info.italicAngle is None assert instance_font.lib["designspace.location"] == [("weight", 100.0)] def test_axis_mapping_no_os2_class_inference(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-opsz.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.info.openTypeOS2WeightClass is None assert instance_font.info.openTypeOS2WidthClass is None assert instance_font.info.italicAngle is None assert instance_font.lib["designspace.location"] == [("optical", 15.0)] def test_axis_mapping_italicAngle_inference(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-slnt.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.info.openTypeOS2WeightClass is None assert instance_font.info.openTypeOS2WidthClass is None assert instance_font.info.italicAngle == 40.123 assert instance_font.lib["designspace.location"] == [("slant", 40.123)] def test_lib_into_instance(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest-lib.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) assert designspace.default.font.lib["blorb"] == "asasa" assert "public.skipExportGlyphs" not in designspace.sources[0].font.lib instance_font = generator.generate_instance(designspace.instances[0]) assert instance_font.lib["blorb"] == "asasa" assert instance_font.lib["public.skipExportGlyphs"] == ["a", "b", "c"] instance_font2 = generator.generate_instance(designspace.instances[1]) assert instance_font2.lib["blorb"] == "asasa" assert instance_font2.lib["public.skipExportGlyphs"] == ["a", "b", "c"] def test_data_independence(data_dir): designspace = designspaceLib.DesignSpaceDocument.fromfile( data_dir / "DesignspaceTest" / "DesignspaceTest.designspace" ) generator = fontmake.instantiator.Instantiator.from_designspace( designspace, round_geometry=True ) instance_font1 = generator.generate_instance(designspace.instances[0]) designspace.instances[0].lib["aaaaaaaa"] = 1 instance_font2 = generator.generate_instance(designspace.instances[0]) instance_font1["l"].unicodes.append(2) assert instance_font1["l"].unicodes == [0x6C, 2] assert instance_font2["l"].unicodes == [0x6C] instance_font1["l"].lib["asdf"] = 1 assert instance_font1["l"].lib == {"asdf": 1} assert not instance_font2["l"].lib generator.copy_lib["sdjkhsjdhjdf"] = 1 instance_font1.lib["asdf"] = 1 assert instance_font1.lib == { "asdf": 1, "blorb": "asasa", "designspace.location": [("weight", 100.0)], "public.skipExportGlyphs": [], } assert instance_font2.lib == { "blorb": "asasa", "designspace.location": [("weight", 100.0)], "public.skipExportGlyphs": [], } assert generator.copy_info.openTypeOS2Panose == [2, 11, 5, 4, 2, 2, 2, 2, 2, 4] generator.copy_info.openTypeOS2Panose.append(1000) assert instance_font1.info.openTypeOS2Panose is None assert instance_font2.info.openTypeOS2Panose is None # copy_feature_text not tested because it is a(n immutable) string assert not generator.skip_export_glyphs generator.skip_export_glyphs.extend(["a", "b"]) assert not instance_font1.lib["public.skipExportGlyphs"] assert not instance_font2.lib["public.skipExportGlyphs"] instance_font1.lib["public.skipExportGlyphs"].append("z") assert not instance_font2.lib["public.skipExportGlyphs"] def test_skipped_fontinfo_attributes(): """Test that we consider all available font info attributes for copying.""" import fontMath.mathInfo import fontTools.ufoLib SKIPPED_ATTRS = { "guidelines", "macintoshFONDFamilyID", "macintoshFONDName", "openTypeNameCompatibleFullName", "openTypeNamePreferredFamilyName", "openTypeNamePreferredSubfamilyName", "openTypeNameUniqueID", "openTypeNameWWSFamilyName", "openTypeNameWWSSubfamilyName", "openTypeOS2Panose", "postscriptFontName", "postscriptFullName", "postscriptUniqueID", "styleMapFamilyName", "styleMapStyleName", "styleName", "woffMetadataUniqueID", "year", } assert ( fontTools.ufoLib.fontInfoAttributesVersion3 - set(fontMath.mathInfo._infoAttrs.keys()) - {"postscriptWeightName"} # Handled in fontMath specially. - fontmake.instantiator.UFO_INFO_ATTRIBUTES_TO_COPY_TO_INSTANCES == SKIPPED_ATTRS ) fontmake-2.4.1/tests/test_main.py000066400000000000000000000476401410425502200170270ustar00rootroot00000000000000import shutil import fontTools.designspaceLib as designspaceLib import fontTools.ttLib import pytest import ufoLib2 import fontmake.__main__ def test_interpolation(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "-i", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "MyFont-Regular.ttf", "MyFont-Regular.otf", } test_output_ttf = fontTools.ttLib.TTFont(tmp_path / "MyFont-Regular.ttf") assert test_output_ttf["OS/2"].usWeightClass == 400 glyph = test_output_ttf.getGlyphSet()["l"]._glyph assert glyph.xMin == 50 assert glyph.xMax == 170 test_output_otf = fontTools.ttLib.TTFont(tmp_path / "MyFont-Regular.otf") assert test_output_otf["OS/2"].usWeightClass == 400 glyph_set = test_output_otf.getGlyphSet() glyph = glyph_set["l"]._glyph x_min, _, x_max, _ = glyph.calcBounds(glyph_set) assert x_min == 50 assert x_max == 170 def test_interpolation_mutatormath(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "-i", "--use-mutatormath", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "MyFont-Regular.ttf", "MyFont-Regular.otf", } test_output_ttf = fontTools.ttLib.TTFont(tmp_path / "MyFont-Regular.ttf") assert test_output_ttf["OS/2"].usWeightClass == 400 glyph = test_output_ttf.getGlyphSet()["l"]._glyph assert glyph.xMin == 50 assert glyph.xMax == 170 test_output_otf = fontTools.ttLib.TTFont(tmp_path / "MyFont-Regular.otf") assert test_output_otf["OS/2"].usWeightClass == 400 glyph_set = test_output_otf.getGlyphSet() glyph = glyph_set["l"]._glyph x_min, _, x_max, _ = glyph.calcBounds(glyph_set) assert x_min == 50 assert x_max == 170 def test_interpolation_mutatormath_source_layer(data_dir, tmp_path): shutil.copyfile( data_dir / "MutatorSans" / "MutatorSans.designspace", tmp_path / "MutatorSans.designspace", ) with pytest.raises(SystemExit, match="sources with 'layer'"): fontmake.__main__.main( [ "-m", str(tmp_path / "MutatorSans.designspace"), "-i", "--use-mutatormath", "--output-dir", str(tmp_path), ] ) def test_interpolation_and_masters_as_instances(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "-i", "-M", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "MyFont-Bold.otf", "MyFont-Bold.ttf", "MyFont-Light.otf", "MyFont-Light.ttf", "MyFont-Regular.otf", "MyFont-Regular.ttf", } test_output_ttf = fontTools.ttLib.TTFont(tmp_path / "MyFont-Regular.ttf") assert test_output_ttf["OS/2"].usWeightClass == 400 glyph = test_output_ttf.getGlyphSet()["l"]._glyph assert glyph.xMin == 50 assert glyph.xMax == 170 test_output_otf = fontTools.ttLib.TTFont(tmp_path / "MyFont-Regular.otf") assert test_output_otf["OS/2"].usWeightClass == 400 glyph_set = test_output_otf.getGlyphSet() glyph = glyph_set["l"]._glyph x_min, _, x_max, _ = glyph.calcBounds(glyph_set) assert x_min == 50 assert x_max == 170 def test_masters_and_instances_ttf_interpolatable(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "-o", "ttf-interpolatable", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "MyFont-Bold.ttf", "MyFont-Light.ttf", "DesignspaceTest.designspace", } designspace = designspaceLib.DesignSpaceDocument.fromfile( tmp_path / "DesignspaceTest.designspace" ) assert {s.filename for s in designspace.sources} == { "MyFont-Bold.ttf", "MyFont-Light.ttf", } def test_masters_and_instances_otf_interpolatable(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "-o", "otf-interpolatable", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "MyFont-Bold.otf", "MyFont-Light.otf", "DesignspaceTest.designspace", } designspace = designspaceLib.DesignSpaceDocument.fromfile( tmp_path / "DesignspaceTest.designspace" ) assert {s.filename for s in designspace.sources} == { "MyFont-Bold.otf", "MyFont-Light.otf", } def test_variable_ttf(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "-o", "variable", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == {"DesignspaceTest-VF.ttf"} def test_variable_otf(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "-o", "variable-cff2", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == {"DesignspaceTest-VF.otf"} def test_no_interpolation(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTest", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTest.designspace"), "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "MyFont-Bold.otf", "MyFont-Bold.ttf", "MyFont-Light.otf", "MyFont-Light.ttf", } def test_ufo_interpolation(data_dir, tmp_path): shutil.copyfile( data_dir / "GlyphsUnitTestSans.glyphs", tmp_path / "GlyphsUnitTestSans.glyphs" ) instance_dir = tmp_path / "instance_ufos" fontmake.__main__.main( [ "-g", str(tmp_path / "GlyphsUnitTestSans.glyphs"), "--master-dir", str(tmp_path / "master_ufos"), "--instance-dir", str(instance_dir), "-i", "-o", "ufo", ] ) assert {p.name for p in instance_dir.glob("*.ufo")} == { "GlyphsUnitTestSans-Black.ufo", "GlyphsUnitTestSans-Bold.ufo", "GlyphsUnitTestSans-ExtraLight.ufo", "GlyphsUnitTestSans-Light.ufo", "GlyphsUnitTestSans-Medium.ufo", "GlyphsUnitTestSans-Regular.ufo", "GlyphsUnitTestSans-Thin.ufo", "GlyphsUnitTestSans-Web.ufo", } def test_ufo_interpolation_specific(data_dir, tmp_path): shutil.copyfile( data_dir / "GlyphsUnitTestSans.glyphs", tmp_path / "GlyphsUnitTestSans.glyphs" ) instance_dir = tmp_path / "instance_ufos" fontmake.__main__.main( [ "-g", str(tmp_path / "GlyphsUnitTestSans.glyphs"), "--master-dir", str(tmp_path / "master_ufos"), "--instance-dir", str(instance_dir), "-i", r".*Light.*", "-o", "ufo", ] ) assert {p.name for p in instance_dir.glob("*.ufo")} == { "GlyphsUnitTestSans-ExtraLight.ufo", "GlyphsUnitTestSans-Light.ufo", } @pytest.mark.parametrize( "write_skipexportglyphs", [ pytest.param(True, id="default"), pytest.param(False, id="no-write-skipexportglyphs"), ], ) def test_subsetting(data_dir, tmp_path, write_skipexportglyphs): shutil.copyfile(data_dir / "TestSubset.glyphs", tmp_path / "TestSubset.glyphs") args = [ "-g", str(tmp_path / "TestSubset.glyphs"), "--master-dir", str(tmp_path / "master_ufos"), "--instance-dir", str(tmp_path / "instance_ufos"), "-i", "Test Subset Regular", "-o", "ttf", "otf", "--output-dir", str(tmp_path), ] if not write_skipexportglyphs: args.append("--no-write-skipexportglyphs") fontmake.__main__.main(args) for output_format in ("ttf", "otf"): for font_path in tmp_path.glob("*." + output_format): font = fontTools.ttLib.TTFont(font_path) assert font.getGlyphOrder() == [".notdef", "space", "A", "C"] def test_shared_features_expansion(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTestSharedFeatures", tmp_path / "sources") fontmake.__main__.main( [ "-m", str(tmp_path / "sources" / "DesignspaceTestSharedFeatures.designspace"), "-i", "--expand-features-to-instances", "-o", "ttf", "--output-dir", str(tmp_path), ] ) test_feature_file = ( tmp_path / "sources/instance_ufo/DesignspaceTest-Light.ufo/features.fea" ) assert test_feature_file.read_text() == "# test" def test_shared_features_ufo(data_dir, tmp_path): shutil.copytree(data_dir / "DesignspaceTestSharedFeatures", tmp_path / "sources") fontmake.__main__.main( [ "-u", str(tmp_path / "sources" / "DesignspaceTest-Light.ufo"), str(tmp_path / "sources" / "DesignspaceTest-Regular.ufo"), "-o", "ttf", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "DesignspaceTest-Light.ttf", "DesignspaceTest-Regular.ttf", } def test_mti_sources(data_dir, tmp_path): shutil.copytree(data_dir / "InterpolateLayoutTest", tmp_path / "sources") fontmake.__main__.main( [ "-g", str(tmp_path / "sources" / "InterpolateLayoutTest.glyphs"), "--designspace-path", str(tmp_path / "InterpolateLayoutTest.designspace"), "--master-dir", str(tmp_path / "master_ufos"), "--instance-dir", str(tmp_path / "instance_ufos"), "--mti-source", str(tmp_path / "sources" / "InterpolateLayoutTest.plist"), "--no-production-names", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.*")} == { "InterpolateLayoutTest-Bold.otf", "InterpolateLayoutTest-Bold.ttf", "InterpolateLayoutTest-Light.otf", "InterpolateLayoutTest-Light.ttf", "InterpolateLayoutTest.designspace", } font_bold = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-Bold.ttf") assert font_bold["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font_bold["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -40 ) font_light = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-Light.ttf") assert font_light["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font_light["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -12 ) def test_interpolate_layout(data_dir, tmp_path): shutil.copytree(data_dir / "InterpolateLayoutTest", tmp_path / "sources") fontmake.__main__.main( [ "-g", str(tmp_path / "sources" / "InterpolateLayoutTest.glyphs"), "--designspace-path", str(tmp_path / "InterpolateLayoutTest.designspace"), "--master-dir", str(tmp_path / "master_ufos"), "--instance-dir", str(tmp_path / "instance_ufos"), "--mti-source", str(tmp_path / "sources" / "InterpolateLayoutTest.plist"), "--no-production-names", "-o", "ttf", "--output-dir", str(tmp_path / "master_ttf"), ] ) fontmake.__main__.main( [ "-g", str(tmp_path / "sources" / "InterpolateLayoutTest.glyphs"), "--designspace-path", str(tmp_path / "InterpolateLayoutTest.designspace"), "--master-dir", str(tmp_path / "master_ufos"), "--instance-dir", str(tmp_path / "instance_ufos"), "-i", "--interpolate-binary-layout", str(tmp_path / "master_ttf"), "--no-production-names", "-o", "ttf", "--output-dir", str(tmp_path), ] ) font = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-Black.ttf") assert font["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -40 ) font = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-Bold.ttf") assert font["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -35 ) font = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-SemiBold.ttf") assert font["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -29 ) font = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-Regular.ttf") assert font["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -22 ) font = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-Light.ttf") assert font["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -15 ) font = fontTools.ttLib.TTFont(tmp_path / "InterpolateLayoutTest-ExtraLight.ttf") assert font["GDEF"].table.GlyphClassDef.classDefs == {"V": 1, "a": 1} assert ( font["GPOS"] .table.LookupList.Lookup[0] .SubTable[0] .PairSet[0] .PairValueRecord[0] .Value1.XAdvance == -12 ) def test_write_skipexportglyphs(data_dir, tmp_path): shutil.copyfile( data_dir / "GlyphsUnitTestSans.glyphs", tmp_path / "GlyphsUnitTestSans.glyphs" ) args = [ "-g", str(tmp_path / "GlyphsUnitTestSans.glyphs"), "--master-dir", str(tmp_path / "master_ufos"), "-o", "ufo", ] fontmake.__main__.main(args) designspace = designspaceLib.DesignSpaceDocument.fromfile( tmp_path / "master_ufos" / "GlyphsUnitTestSans.designspace" ) assert "public.skipExportGlyphs" in designspace.lib assert designspace.lib["public.skipExportGlyphs"] == [ "_part.shoulder", "_part.stem", ] for path in (tmp_path / "master_ufos").glob("*.ufo"): with ufoLib2.Font.open(path) as ufo: assert "public.skipExportGlyphs" in ufo.lib shutil.rmtree(tmp_path / "master_ufos") fontmake.__main__.main(args + ["--no-write-skipexportglyphs"]) designspace = designspaceLib.DesignSpaceDocument.fromfile( tmp_path / "master_ufos" / "GlyphsUnitTestSans.designspace" ) assert "public.skipExportGlyphs" not in designspace.lib for path in (tmp_path / "master_ufos").glob("*.ufo"): with ufoLib2.Font.open(path) as ufo: assert "public.skipExportGlyphs" not in ufo.lib assert not ufo["_part.shoulder"].lib["com.schriftgestaltung.Glyphs.Export"] assert not ufo["_part.stem"].lib["com.schriftgestaltung.Glyphs.Export"] def test_debug_feature_file(data_dir, tmp_path): shutil.copyfile( data_dir / "GlyphsUnitTestSans.glyphs", tmp_path / "GlyphsUnitTestSans.glyphs" ) debug_feature_path = data_dir / "test.fea" fontmake.__main__.main( [ "-g", str(tmp_path / "GlyphsUnitTestSans.glyphs"), "--master-dir", "{tmp}", "--instance-dir", "{tmp}", "-i", "-o", "ttf", "--debug-feature-file", str(debug_feature_path), ] ) with open(debug_feature_path, "r") as debug_feature_file: features = debug_feature_file.read() assert "### GlyphsUnitTestSans-Regular" in features assert "### GlyphsUnitTestSans-Black" in features def test_ufo_to_static_otf_cff2(data_dir, tmp_path): fontmake.__main__.main( [ "-u", str(data_dir / "DesignspaceTest" / "MyFont-Light.ufo"), "-o", "otf-cff2", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.otf")} == {"MyFont-Light.otf"} def test_static_otf_cffsubr_subroutinizer(data_dir, tmp_path): fontmake.__main__.main( [ "-u", str(data_dir / "DesignspaceTest" / "MyFont-Light.ufo"), "-o", "otf", "--subroutinizer", "cffsubr", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.otf")} == {"MyFont-Light.otf"} def test_static_otf_compreffor_subroutinizer(data_dir, tmp_path): fontmake.__main__.main( [ "-u", str(data_dir / "DesignspaceTest" / "MyFont-Light.ufo"), "-o", "otf", "--subroutinizer", "compreffor", "--output-dir", str(tmp_path), ] ) assert {p.name for p in tmp_path.glob("*.otf")} == {"MyFont-Light.otf"} def test_main_with_feature_writer_none(data_dir, tmp_path): fontmake.__main__.main( [ "-u", str(data_dir / "MutatorSans" / "MutatorSansBoldCondensed.ufo"), "-o", "ttf", "--feature-writer", "None", "--output-dir", str(tmp_path), ] ) test_output_ttf = fontTools.ttLib.TTFont(tmp_path / "MutatorSansBoldCondensed.ttf") assert "GPOS" not in test_output_ttf def test_main_with_filter(data_dir, tmp_path): fontmake.__main__.main( [ "-u", str(data_dir / "DesignspaceTest" / "MyFont-Light.ufo"), "-o", "ttf", "--filter", "TransformationsFilter(OffsetX=100)", "--output-dir", str(tmp_path), ] ) test_output_ttf = fontTools.ttLib.TTFont(tmp_path / "MyFont-Light.ttf") hmtx = test_output_ttf["hmtx"] assert hmtx["l"] == (160, 170) fontmake-2.4.1/tox.ini000066400000000000000000000014361410425502200146340ustar00rootroot00000000000000[tox] envlist = lint, py3{6,7,8,9}, pypy3, coverage-report skip_missing_interpreters = true [testenv] deps = -r requirements.txt -r test_requirements.txt ; download the latest pip, setuptools and wheel when creating the venv download = true commands = coverage run --parallel-mode -m pytest {posargs} [testenv:lint] skip_install = true deps = -r test_requirements.txt commands = black --check --diff . isort --check-only --diff . flake8 [testenv:coverage-report] skip_install = true commands = coverage combine coverage xml coverage report coverage html [flake8] select = C, E, F, W, B, B9 ignore = E203, E266, E501, W503 max-line-length = 88 exclude = .git, __pycache__, build, dist, .eggs, .tox, venv, venv*, .venv, .venv* [isort] profile = black