././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609371378.6076424 vfit-2.1.0/LICENSE.txt0000644000000000000000000000205700000000000012440 0ustar0000000000000000MIT License Copyright (c) 2020 Jon Palmisciano 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.././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609371378.6078413 vfit-2.1.0/README.md0000644000000000000000000000336300000000000012075 0ustar0000000000000000
## About VFIT (Variable Font Instancing Tool) allows you to generate custom, static instances of a variable font defined in a configuration file. ## Installation VFIT is now available on the Python Package Index. You can install VFIT with the following command: ```sh $ pip3 install vfit ``` Alternatively, you can install VFIT by downloading a pre-built wheel from the Releases section or by building it yourself. ``` sh # Skip this step if you're downloading a prebuilt wheel. $ git clone https://github.com/jonpalmisc/vfit.git && cd vfit $ poetry build && cd dist # Install VFIT from the wheel. $ pip install vfit-version-py3-none-any.whl ``` ## Usage To begin, you will need a variable font file to work with. Your first step will be creating a configuration file. See `sample.json` for an example. Next, run VFIT and pass your configuration and variable font file as arguments: ``` sh $ vfit config.json variable.ttf ``` If you would like to generate instances into a specific directory, you can use the `-o` option. For more options, see `vift --help`. ## Contributing All contributions are welcome. If you find a bug or have a request for a feature, feel free to create a new issue (or even better, a pull request). ## Credits Special thanks to [Viktor Rubenko](https://github.com/ViktorRubenko) for helping me get exported fonts to work on Windows! The VFIT logo uses [NewGlyph](https://beta.newglyph.com/)'s [Armada](https://beta.newglyph.com/discovery-collection/#font-armada) variable font. ## License Copyright © 2020 Jon Palmisciano VFIT is available under the MIT License. See [LICENSE.txt](LICENSE.txt) for more information. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609373961.3084695 vfit-2.1.0/pyproject.toml0000644000000000000000000000116700000000000013532 0ustar0000000000000000[tool.poetry] name = "vfit" version = "2.1.0" description = "Generate backwards-compatible, static instances of variable fonts" authors = ["Jon Palmisciano "] maintainers = ["Jon Palmisciano "] license = "MIT" readme = "README.md" repository = "https://github.com/jonpalmisc/vfit" keywords = ["fonts", "fonttools"] [tool.poetry.dependencies] python = "^3.6" tqdm = "^4.48.0" fonttools = "^4.13.0" brotli = "^1.0.7" [tool.poetry.dev-dependencies] yapf = "^0.30.0" [tool.poetry.scripts] vfit = "vfit.app:main" [build-system] requires = ["poetry>=0.12"] build-backend = "poetry.masonry.api" ././@PaxHeader0000000000000000000000000000003100000000000011447 xustar000000000000000025 mtime=1609373944.8044 vfit-2.1.0/vfit/app.py0000755000000000000000000000342600000000000012723 0ustar0000000000000000#!/usr/bin/env python3 # VFIT - Variable Font Instancing Tool # Copyright (c) 2020 Jon Palmisciano import argparse import json import sys from . import core # Loads and validates the config from the given path. def loadConfig(path): config = {} # Attempt to read and parse the config file. with open(path, "r") as cfg_file: config = json.load(cfg_file) # Regular subfamily should be the default if subfamily is not specified. for style in config: if style.get("subfamily") is None: style["subfamily"] = "Regular" return config def main(): from argparse import ArgumentParser parser = ArgumentParser( prog="vfit", description= "Generate backwards-compatible, static instances of variable fonts.") parser.add_argument("config", help="the metadata/style definition file") parser.add_argument("source", help="the font to generate instances of") parser.add_argument("-o", dest="outputPath", metavar="PATH", default=".", help="where to place output files") parser.add_argument("-f", dest="format", default=None, choices=["woff", "woff2"], help="which format to output as") parser.add_argument("-C", dest="fixContour", action="store_true", help="fix contours for macOS (side effects unknown)") args = parser.parse_args() try: cfg = loadConfig(args.config) except ValueError as error: print(f"error: failed to load config, check your JSON\n{error}") sys.exit(1) core.generateInstances(cfg, args) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609373944.8046734 vfit-2.1.0/vfit/core.py0000644000000000000000000000404100000000000013062 0ustar0000000000000000import os from fontTools.ttLib import TTFont from fontTools.varLib.instancer import instantiateVariableFont as instantiateFont from tqdm import tqdm from .util import updateNames, makeSelection, getPostscriptName, getMacStyle, sanitize, dropVariationTables, setOverlapFlags # Generates and writes each defined instance. def generateInstances(config, args): # Create the output path if it doesn't exist. if not os.path.exists(args.outputPath): os.makedirs(args.outputPath) for style in tqdm(config, ascii=True, leave=False): font = TTFont(args.source) # Instantiate the font and update the name table. instantiateFont(font, style["axes"], inplace=True, overlap=True) updateNames(font, style) family = style.get("prefFamily") if family == None: family = style.get("family") subfamily = style.get("subfamily") prefSubfamily = style.get("prefSubfamily") if prefSubfamily == None: prefSubfamily = subfamily prefSubfamily = prefSubfamily.replace(" ", "") # Perform additional table fixups. font["head"].macStyle = getMacStyle(subfamily) font["OS/2"].fsSelection = makeSelection(font["OS/2"].fsSelection, subfamily) # Override weight if requested. weightOverride = style.get("weightOverride") if weightOverride != None: font["OS/2"].usWeightClass = weightOverride # Override width if requested. widthOverride = style.get("widthOverride") if widthOverride != None: font["OS/2"].usWidthClass = widthOverride dropVariationTables(font) # Fix contour overlap issues on macOS. if args.fixContour == True: setOverlapFlags(font) ext = args.format if args.format is not None else "ttf" filename = getPostscriptName(style) + f".{ext}" outputPath = os.path.join(args.outputPath, filename) font.flavor = args.format font.save(outputPath) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1609373944.804939 vfit-2.1.0/vfit/util.py0000644000000000000000000000707500000000000013121 0ustar0000000000000000PLAT_MAC = 1 PLAT_WINDOWS = 3 ENC_ROMAN = 0 ENC_UNICODE_11 = 1 LANG_ENGLISH = 1033 MACSTYLE = {'Regular': 0, 'Bold': 1, 'Italic': 2, 'Bold Italic': 3} OVERLAP_SIMPLE = 0x40 OVERLAP_COMPOUND = 0x0400 # Removes spaces from a string. def sanitize(string): return string.replace(" ", "") # Produces a unique ID for a style. def getUniqueStyleID(style): id = style["name"] if "subfamily" in style: id = f"{style['subfamily']}-{id}" return sanitize(id) def getFullName(style): familyName = style.get("prefFamily") if familyName == None: familyName = style.get("family") subfamilyName = style.get("prefSubfamily") if subfamilyName == None: subfamilyName = style.get("subfamily") return f"{familyName} {subfamilyName}" def getPostscriptName(style): familyName = style.get("prefFamily") if familyName == None: familyName = style.get("family") subfamilyName = style.get("prefSubfamily") if subfamilyName == None: subfamilyName = style.get("subfamily") familyName = familyName.replace(" ", "") subfamilyName = subfamilyName.replace(" ", "") return f"{familyName}-{subfamilyName}" # Rewrites the name table with new metadata. def updateNames(font, style): nameTable = font["name"] nameTable.names = [] family = style.get("family") subfamily = style.get("subfamily") prefFamily = style.get("prefFamily") prefSubfamily = style.get("prefSubfamily") fullName = getFullName(style) postscriptName = getPostscriptName(style) nameTable.setName(family, 1, PLAT_MAC, ENC_ROMAN, 0) nameTable.setName(family, 1, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) nameTable.setName(subfamily, 2, PLAT_MAC, ENC_ROMAN, 0) nameTable.setName(subfamily, 2, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) nameTable.setName(fullName, 3, PLAT_MAC, ENC_ROMAN, 0) nameTable.setName(fullName, 3, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) nameTable.setName(fullName, 4, PLAT_MAC, ENC_ROMAN, 0) nameTable.setName(fullName, 4, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) nameTable.setName("Version 1.000", 5, PLAT_MAC, ENC_ROMAN, 0) nameTable.setName("Version 1.000", 5, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) nameTable.setName(postscriptName, 6, PLAT_MAC, ENC_ROMAN, 0) nameTable.setName(postscriptName, 6, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) if prefFamily is not None: nameTable.setName(prefFamily, 16, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) if prefSubfamily is not None: nameTable.setName(prefSubfamily, 17, PLAT_WINDOWS, ENC_UNICODE_11, LANG_ENGLISH) def makeSelection(bits, style): bits = bits ^ bits if style == 'Regular': bits |= 0b1000000 else: bits &= ~0b1000000 if style == 'Bold' or style == 'BoldItalic': bits |= 0b100000 else: bits &= ~0b100000 if style == 'Italic': bits |= 0b1 else: bits &= ~0b1 if not bits: bits = 0b1000000 return bits def getMacStyle(style): return MACSTYLE[style] def dropVariationTables(font): for tag in 'STAT cvar fvar gvar'.split(): if tag in font.keys(): del font[tag] def setOverlapFlags(font): glyf = font["glyf"] for glyph_name in glyf.keys(): glyph = glyf[glyph_name] if glyph.isComposite(): glyph.components[0].flags |= OVERLAP_COMPOUND elif glyph.numberOfContours > 0: glyph.flags[0] |= OVERLAP_SIMPLE ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609374076.3757708 vfit-2.1.0/setup.py0000644000000000000000000000520700000000000012327 0ustar0000000000000000# -*- coding: utf-8 -*- from setuptools import setup packages = \ ['vfit'] package_data = \ {'': ['*']} install_requires = \ ['brotli>=1.0.7,<2.0.0', 'fonttools>=4.13.0,<5.0.0', 'tqdm>=4.48.0,<5.0.0'] entry_points = \ {'console_scripts': ['vfit = vfit.app:main']} setup_kwargs = { 'name': 'vfit', 'version': '2.1.0', 'description': 'Generate backwards-compatible, static instances of variable fonts', 'long_description': '
\n \n
\n\n## About\n\nVFIT (Variable Font Instancing Tool) allows you to generate custom, static\ninstances of a variable font defined in a configuration file.\n\n## Installation\n\nVFIT is now available on the Python Package Index. You can install VFIT with\nthe following command:\n\n```sh\n$ pip3 install vfit\n```\n\nAlternatively, you can install VFIT by downloading a pre-built wheel from the\nReleases section or by building it yourself.\n\n``` sh\n# Skip this step if you\'re downloading a prebuilt wheel.\n$ git clone https://github.com/jonpalmisc/vfit.git && cd vfit\n$ poetry build && cd dist\n\n# Install VFIT from the wheel.\n$ pip install vfit-version-py3-none-any.whl\n```\n\n## Usage\n\nTo begin, you will need a variable font file to work with. Your first step will\nbe creating a configuration file. See `sample.json` for an example.\n\nNext, run VFIT and pass your configuration and variable font file as arguments:\n\n``` sh\n$ vfit config.json variable.ttf\n```\n\nIf you would like to generate instances into a specific directory, you can use\nthe `-o` option. For more options, see `vift --help`.\n\n## Contributing\n\nAll contributions are welcome. If you find a bug or have a request for a\nfeature, feel free to create a new issue (or even better, a pull request).\n\n## Credits\n\nSpecial thanks to [Viktor Rubenko](https://github.com/ViktorRubenko) for\nhelping me get exported fonts to work on Windows!\n\nThe VFIT logo uses [NewGlyph](https://beta.newglyph.com/)\'s\n[Armada](https://beta.newglyph.com/discovery-collection/#font-armada) variable\nfont.\n\n## License\n\nCopyright © 2020 Jon Palmisciano\n\nVFIT is available under the MIT License. See [LICENSE.txt](LICENSE.txt) for\nmore information.\n', 'author': 'Jon Palmisciano', 'author_email': 'jp@jonpalmisc.com', 'maintainer': 'Jon Palmisciano', 'maintainer_email': 'jp@jonpalmisc.com', 'url': 'https://github.com/jonpalmisc/vfit', 'packages': packages, 'package_data': package_data, 'install_requires': install_requires, 'entry_points': entry_points, 'python_requires': '>=3.6,<4.0', } setup(**setup_kwargs) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1609374076.3761039 vfit-2.1.0/PKG-INFO0000644000000000000000000000505600000000000011714 0ustar0000000000000000Metadata-Version: 2.1 Name: vfit Version: 2.1.0 Summary: Generate backwards-compatible, static instances of variable fonts Home-page: https://github.com/jonpalmisc/vfit License: MIT Keywords: fonts,fonttools Author: Jon Palmisciano Author-email: jp@jonpalmisc.com Maintainer: Jon Palmisciano Maintainer-email: jp@jonpalmisc.com Requires-Python: >=3.6,<4.0 Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Requires-Dist: brotli (>=1.0.7,<2.0.0) Requires-Dist: fonttools (>=4.13.0,<5.0.0) Requires-Dist: tqdm (>=4.48.0,<5.0.0) Project-URL: Repository, https://github.com/jonpalmisc/vfit Description-Content-Type: text/markdown
## About VFIT (Variable Font Instancing Tool) allows you to generate custom, static instances of a variable font defined in a configuration file. ## Installation VFIT is now available on the Python Package Index. You can install VFIT with the following command: ```sh $ pip3 install vfit ``` Alternatively, you can install VFIT by downloading a pre-built wheel from the Releases section or by building it yourself. ``` sh # Skip this step if you're downloading a prebuilt wheel. $ git clone https://github.com/jonpalmisc/vfit.git && cd vfit $ poetry build && cd dist # Install VFIT from the wheel. $ pip install vfit-version-py3-none-any.whl ``` ## Usage To begin, you will need a variable font file to work with. Your first step will be creating a configuration file. See `sample.json` for an example. Next, run VFIT and pass your configuration and variable font file as arguments: ``` sh $ vfit config.json variable.ttf ``` If you would like to generate instances into a specific directory, you can use the `-o` option. For more options, see `vift --help`. ## Contributing All contributions are welcome. If you find a bug or have a request for a feature, feel free to create a new issue (or even better, a pull request). ## Credits Special thanks to [Viktor Rubenko](https://github.com/ViktorRubenko) for helping me get exported fonts to work on Windows! The VFIT logo uses [NewGlyph](https://beta.newglyph.com/)'s [Armada](https://beta.newglyph.com/discovery-collection/#font-armada) variable font. ## License Copyright © 2020 Jon Palmisciano VFIT is available under the MIT License. See [LICENSE.txt](LICENSE.txt) for more information.