Skip to content

Commit

Permalink
New source assembly line, with build script (#85)
Browse files Browse the repository at this point in the history
* New script to break out the layers into final UFO sources

New script to break out the layers into final UFO sources.

* Ignore 'build' folder

* fiddle with file and folder names; set familyName and styleName

* BungeeLayers-Shade should not add tracking

* Add initial build script

* Print what's happening

* whitespace

* copy kerning, groups and features; reroute feature includes to the right place

* fiddle with name and value of tracking offset: make it independent of the tracking value itself

* don't convert to production glyph names

* Add script to build the layered + rotated UFO sources

* Add rotation script and its output to fontmake input

* removed unused function

* finish exception mapping; map to None if this glyph will be mapped to, but also exists 'normally'

* Assemble Tools

Assemble tools for assembleSources.py and assembleRotatedSources.py

* remove venv map

* ignore all the things

* Layer-Shade does not need full decomposition

* create script for COLv0 fonts

* Add color sources to build

* minor cleanup

* fix color name

* rename var

* some shuffling of lines

* More shuffling/renaming

* Add gradients and build source for Bungee Spice

* Add Regular to Bungee Basic

* attempt to make tracking logic match the existing fonts

* formatting

* Also look into (nested) components for shade layers

* special-case /space: it should be tracked for Basic Shade

* special-case a whole bunch of glyph names for shade tracking/offsetting

* Add comment about these exceptions

* update color palettes bungee-spice

* Add initial requirements file

* Update requirements

* Clear OS/2 fsType flags, this fixes #87

---------

Co-authored-by: marte verhaegen <marte.verhaegen@gmail.com>
  • Loading branch information
justvanrossum and martelahaie authored Sep 18, 2023
1 parent fc39128 commit 965d5d9
Show file tree
Hide file tree
Showing 9 changed files with 832 additions and 7 deletions.
134 changes: 133 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,133 @@
.DS_Store
# 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
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# 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

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# 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/

# Misc
.DS_Store
/vault/
22 changes: 22 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh

set -e # make sure to abort on error
set -x # echo commands


python scripts/assembleSources.py
python scripts/assembleRotatedSources.py
python scripts/assembleColorSources.py


for folder in Bungee_Basic Bungee_Layers Bungee_Rotated Bungee_Color
do
for ufo in build/$folder/*.ufo
do
fontmake -o ttf \
--overlaps-backend pathops \
--output-dir build/fonts/$folder \
--no-production-names \
-u $ufo
done
done
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fontmake==3.6.1
skia-pathops==0.8.0
130 changes: 130 additions & 0 deletions scripts/assembleColorSources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import pathlib
from fontTools.ttLib.tables import otTables as ot
import ufoLib2
from ufo2ft.constants import COLOR_LAYERS_KEY, COLOR_PALETTES_KEY


def parseColorTable(colorTable):
colorNames = []
colors = []
for line in colorTable.splitlines():
line = line.strip()
if not line:
continue
colorName, *hexColors = line.split()
colorNames.append(colorName)
colors.append([colorFromHex(hexColor) for hexColor in hexColors])

palettes = [list(palette) for palette in zip(*colors)]
colorIndices = {colorName: i for i, colorName in enumerate(colorNames)}
return palettes, colorIndices


def colorFromHex(hexString):
assert len(hexString) in [6, 8]
channels = []
for i in range(0, len(hexString), 2):
channels.append(int(hexString[i : i + 2], 16) / 255)
if len(channels) == 3:
channels.append(1)
return channels


inlineSuffix = ".inline"

colorTableRegular = """
regular C90900 FFFFFF 23849F 666666 0B5BA8 EFBB43 FFDA99 FFE10B
inline FF9580 E8E8E7 F6EECD DCF676 55A5FE EAE2B1 FF5140 FF0035
"""

colorTableSpice = """
color1 C90900 132A66 038F60
color2 FFD700 60A0EF ABFE37
"""


palettesRegular, colorIndexRegular = parseColorTable(colorTableRegular)
palettesSpice, colorIndexSpice = parseColorTable(colorTableSpice)

gradient_color1 = colorIndexSpice["color1"]
gradient_color2 = colorIndexSpice["color2"]


gradient_color1_color2 = {
"Format": ot.PaintFormat.PaintLinearGradient,
"ColorLine": {
"ColorStop": [(0.0, gradient_color1), (1.0, gradient_color2)],
"Extend": "reflect",
},
"x0": 0,
"y0": 0,
"x1": 0,
"y1": 900,
"x2": 100,
"y2": 0,
}

gradient_color2_color1 = {
"Format": ot.PaintFormat.PaintLinearGradient,
"ColorLine": {
"ColorStop": [(0.0, gradient_color2), (1.0, gradient_color1)],
"Extend": "reflect",
},
"x0": 0,
"y0": 0,
"x1": 0,
"y1": 900,
"x2": 100,
"y2": 0,
}

repoDir = pathlib.Path(__file__).resolve().parent.parent
layersDir = repoDir / "build" / "Bungee_Layers"
outputDir = repoDir / "build" / "Bungee_Color"
outputDir.mkdir(exist_ok=True)

sourceFont = ufoLib2.Font.open(layersDir / "BungeeLayers-Regular.ufo")
inlineFont = ufoLib2.Font.open(layersDir / "BungeeLayers-Inline.ufo")

colorGlyphsRegular = {}
colorGlyphsSpice = {}

for glyph in inlineFont:
inlineGlyphName = glyph.name + inlineSuffix
sourceFont[inlineGlyphName] = inlineFont[glyph.name].copy()
inlineGlyph = sourceFont[inlineGlyphName]
inlineGlyph.unicode = None

for compo in inlineGlyph.components:
inlineBaseGlyph = compo.baseGlyph + inlineSuffix
compo.baseGlyph = inlineBaseGlyph

colorGlyphsRegular[glyph.name] = [
(glyph.name, colorIndexRegular["regular"]),
(inlineGlyphName, colorIndexRegular["inline"]),
]

gradientLayers = [
{
"Format": ot.PaintFormat.PaintGlyph,
"Paint": gradient_color2_color1 if suffix else gradient_color1_color2,
"Glyph": glyph.name + suffix,
}
for suffix in ["", inlineSuffix]
]
colorGlyphsSpice[glyph.name] = (ot.PaintFormat.PaintColrLayers, gradientLayers)


sourceFont.lib[COLOR_PALETTES_KEY] = palettesRegular
sourceFont.lib[COLOR_LAYERS_KEY] = colorGlyphsRegular
sourceFont.info.familyName = "Bungee Color"
sourceFont.info.styleName = "Regular"

sourceFont.save(outputDir / "BungeeColor-Regular-COLRv0.ufo", overwrite=True)

sourceFont.lib[COLOR_PALETTES_KEY] = palettesSpice
sourceFont.lib[COLOR_LAYERS_KEY] = colorGlyphsSpice
sourceFont.info.familyName = "Bungee Spice"
sourceFont.info.styleName = "Regular"

sourceFont.save(outputDir / "BungeeSpice-Regular-COLRv1.ufo", overwrite=True)
Loading

0 comments on commit 965d5d9

Please sign in to comment.