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 / 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 / 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 / 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 / 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 / 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 / StackOfSquares.py
Last active October 25, 2021 02:30
Create a simple animation with Python in DrawBot
# This script is part of a tutorial screencast: https://vimeo.com/149247423
CANVAS = 500
SQUARESIZE = 158
NSQUARES = 50
SQUAREDIST = 6
width = NSQUARES * SQUAREDIST
NFRAMES = 50
@justvanrossum
justvanrossum / VasarelyCircles.py
Last active September 24, 2021 09:39
DrawBot: Generate a moving interpretation of works by Victor Vasarely.
# http://dailydrawbot.tumblr.com/post/136811506080/circles-after-victor-vasarely-source-code
#
# Based on works by Victor Vasarely
# https://s-media-cache-ak0.pinimg.com/originals/a6/df/1f/a6df1fc5d2dd07d79a44c3aea5172b59.jpg
# https://s-media-cache-ak0.pinimg.com/736x/1e/38/82/1e38820f1304c8750de216a31a5f5abe.jpg
# http://interiorator.com/wp-content/uploads/2013/07/Vasarely-01.jpg
def circle(pt, radius):
diameter = 2 * radius
x, y = pt
@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))