Skip to content

Instantly share code, notes, and snippets.

@justvanrossum
justvanrossum / rename_fea_glyphs.py
Last active March 21, 2024 00:59
Rename glyph names in OpenType feature files
from functools import singledispatch
from io import StringIO
from fontTools.feaLib import ast
from fontTools.feaLib.error import FeatureLibError
from fontTools.feaLib.parser import Parser
def renameGlyphs(feaSource, renameFunc, glyphNames=()):
features = Parser(StringIO(feaSource), glyphNames=glyphNames).parse()
@justvanrossum
justvanrossum / make_named_instances_from_axis_labels.py
Created September 19, 2022 12:55
Rebuild the named instances in a designspace 5 file based on the axis labels. Use with caution!
import argparse
from itertools import product
import sys
from fontTools.designspaceLib import DesignSpaceDocument
def main():
parser = argparse.ArgumentParser(
description="Makes new named instances based on the axis labels"
)
@justvanrossum
justvanrossum / convert_ds_to_ds5.py
Created September 15, 2022 11:55
Likely incomplete script that converts 'statmake' axis labels to DesignSpace 5 axis labels
import argparse
import sys
from fontTools.designspaceLib import AxisLabelDescriptor, DesignSpaceDocument
def main():
parser = argparse.ArgumentParser(
description="Converts statmake axis labels to DesignSpace 5.0 axis labels"
)
parser.add_argument("input", help="The source .designspace file")
@justvanrossum
justvanrossum / SevenNutsPuzzle.py
Last active July 18, 2022 20:47
Visualization and solution to "seven nuts" puzzle. Requires DrawBot for the visualization.
# https://twitter.com/jenskutilek/status/1548996988892479488
def drawNuts(nuts, matches, nutPositions):
for (bi1, bs1), (bi2, bs2) in matches:
with savedState():
strokeWidth(0.3 * distX)
if nuts[bi1][bs1] == nuts[bi2][bs2]:
stroke(0, 1, 0)
else:
@justvanrossum
justvanrossum / bezier_xy.py
Created May 30, 2022 15:23
Cubic Bezier: find Y given X
# https://twitter.com/mttymtt/status/1531022994323251202
# DrawBot visualization
# FontTools for helper code
from fontTools.misc.bezierTools import calcCubicParameters, solveCubic
scaleFactor = 500
pt0 = (0, 0)
pt1 = (0.37, 0.05)
@justvanrossum
justvanrossum / bezier_drawbot.py
Last active April 10, 2023 11:09
Bezier demo for DrawBot
# See this Twitter thread:
# https://twitter.com/MauriceMeilleur/status/1488347208709718021
def lerp(v1, v2, t):
return v1 + t * (v2 - v1)
def lerpPoint(p1, p2, t):
return lerp(p1[0], p2[0], t), lerp(p1[1], p2[1], t)
@justvanrossum
justvanrossum / plotter_circle_spiral.py
Created December 8, 2021 21:12
[DrawBot] Given a circle radius and a pen thickness, create a spiral-ish path that fills a circle
# https://twitter.com/rosettatype/status/1468660017993854980
def plotter_circle_spiral(bez, center, radius, penWidth):
H = 0.5522847498 # Bezier circle magic constant
radius -= penWidth / 2
numRevolutions = ceil(radius / penWidth + 1)
xRadius = yRadius = radius
radiusDelta = radius / (numRevolutions - 1)
cx, cy = center
bez.moveTo((cx + radius, cy))
@justvanrossum
justvanrossum / RectangleGrid.py
Last active September 16, 2021 06:08
A grid of moving rectangles
# Inspired by:
# https://www.instagram.com/p/_hZD9hn9Xn/
def square(x, y, size, phase):
turns = phase // 2
q = (phase % 2) / 2
with savedState():
translate(x, y)
scale(size)
rotate(-90 * turns, center=(0.5, 0.5))
@justvanrossum
justvanrossum / Kapitzki.py
Last active August 29, 2021 12:18
Animated tribute to a work by Herbert W. Kapitzki (DrawBot script)
# Based on a work by Herbert W. Kapitzki
# https://twitter.com/Lett_Arc/status/1369712193063780352
# from fontTools.misc.vector import Vector
from fontTools.misc.arrayTools import Vector
def pairs(iterable):
it = iter(iterable)
first = next(it)
@justvanrossum
justvanrossum / filename_proposal.py
Last active January 30, 2021 14:08
Test implementation for new proposed reversible glyph name to file name scheme
# test implementation for https://github.com/unified-font-object/ufo-spec/issues/164
from urllib.parse import unquote
import string
separatorChar = "^"
# TODO: [insert references]