././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 011452 x ustar 00 0000000 0000000 28 mtime=1609371378.6076424
vfit-2.1.0/LICENSE.txt 0000644 0000000 0000000 00000002057 00000000000 012440 0 ustar 00 0000000 0000000 MIT 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. ././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 011452 x ustar 00 0000000 0000000 28 mtime=1609371378.6078413
vfit-2.1.0/README.md 0000644 0000000 0000000 00000003363 00000000000 012075 0 ustar 00 0000000 0000000
## 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.
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 011452 x ustar 00 0000000 0000000 28 mtime=1609373961.3084695
vfit-2.1.0/pyproject.toml 0000644 0000000 0000000 00000001167 00000000000 013532 0 ustar 00 0000000 0000000 [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"
././@PaxHeader 0000000 0000000 0000000 00000000031 00000000000 011447 x ustar 00 0000000 0000000 25 mtime=1609373944.8044
vfit-2.1.0/vfit/app.py 0000755 0000000 0000000 00000003426 00000000000 012723 0 ustar 00 0000000 0000000 #!/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)
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 011452 x ustar 00 0000000 0000000 28 mtime=1609373944.8046734
vfit-2.1.0/vfit/core.py 0000644 0000000 0000000 00000004041 00000000000 013062 0 ustar 00 0000000 0000000 import 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)
././@PaxHeader 0000000 0000000 0000000 00000000033 00000000000 011451 x ustar 00 0000000 0000000 27 mtime=1609373944.804939
vfit-2.1.0/vfit/util.py 0000644 0000000 0000000 00000007075 00000000000 013121 0 ustar 00 0000000 0000000 PLAT_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
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 011452 x ustar 00 0000000 0000000 28 mtime=1609374076.3757708
vfit-2.1.0/setup.py 0000644 0000000 0000000 00000005207 00000000000 012327 0 ustar 00 0000000 0000000 # -*- 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)
././@PaxHeader 0000000 0000000 0000000 00000000034 00000000000 011452 x ustar 00 0000000 0000000 28 mtime=1609374076.3761039
vfit-2.1.0/PKG-INFO 0000644 0000000 0000000 00000005056 00000000000 011714 0 ustar 00 0000000 0000000 Metadata-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.