Skip to content

Instantly share code, notes, and snippets.

View typoman's full-sized avatar
:electron:
Never stop learning!

Bahman Eslami typoman

:electron:
Never stop learning!
View GitHub Profile
@typoman
typoman / arabic-kashida-in-lualatex-with-babel-with-control-over-the-stretching-using-the-word-spacing.tex
Created January 16, 2025 15:07
Arabic Scirpt kashida in lualatex with babel with control over the stretching using the word spacing
\documentclass{article}
\usepackage{multicol}
\usepackage[bidi = basic]{babel}
\babelprovide[
main,
import,
mapdigits,
justification=kashida,
transforms=kashida.base
@typoman
typoman / font-auto-weight-class.py
Last active November 13, 2024 13:07
Auto set the OpenType OS/2 Weight Class value for a UFO font based on its styleName.
import os
from fontParts.world import *
import argparse
"""
Command Line Python Script
- Type: Mastering
- Purpose: To determine the OpenType OS/2 Weight Class value for a font based on its styleName.
- Specifications:
- Parse the styleName of the font
- Use a predefined mapping of style names to weight classes
@typoman
typoman / Fix Contour Directions.py
Last active November 10, 2024 22:58
RoboFont script to fix contour direction for postscript curves (CFF/Cubic/OTF) on selected glyphs.
"""
RoboFont Script
based on:
https://gist.github.com/ryanbugden/a4ddf19cab034f837a51fb9d4f0db015
- Type: Mastering
- Purpose: To fix contour direction for postscript curves (CFF/Cubic/OTF) in selected glyphs.
- Specifications:
- Sorts contours by area and clusters them into contours that contain other contours
- Reverses the direction of contours in clusters where the largest contour is not clockwise
@typoman
typoman / Split groups by direction.py
Last active November 1, 2024 10:45
To fix the issue where fontmake skips kerning pairs: "Skipping kerning pair with mixed direction (LTR, RTL)" by splitting mixed RTL/Neutral kerning groups in a font and adding new kerning if necessary.
from fontgadgets.extensions.groups.kerning_groups import isKerningGroup
from ufo2ft.featureWriters import KernFeatureWriter
from ufo2ft.featureWriters.kernFeatureWriter import COMMON_SCRIPTS_SET, DFLT_SCRIPTS, script_direction
from ufo2ft.featureCompiler import parseLayoutFeatures
"""
RoboFont Script
- Type: Mastering
- Purpose: To fix the issue where fontmake skips kerning pairs: "Skipping kerning pair with mixed direction (LTR, RTL)" by splitting mixed RTL/Neutral kerning groups in a font and adding new kerning if necessary.
- Specifications:
- Parse the open type features of a font to determine the direction of each glyph
@typoman
typoman / cubic-curve-subdivide.py
Last active October 24, 2024 13:10
subdivide a 2d cubic curve into specific number of points in uniform (by arc length) and non uniform (curve speed) using pure python and no external libraries
import logging
import sys
import time
"""
based on:
https://pomax.github.io/bezierinfo/#tracing
Tracing a curve at fixed distance intervals from "A Primer on Bézier Curves" by Pomax
"""
logger = logging.getLogger('my_timer')
handler = logging.StreamHandler(sys.stdout)
@typoman
typoman / cubic_bezier_length.py
Created October 23, 2024 16:40
cubic bezier curve arc length approximation using gaussian quadrature in python
import math
"""
based on
https://pomax.github.io/bezierinfo/#arclength
we can determine the approximate length of a Bézier curve by computing the Legendre-Gauss sum.
"""
# Gaussian quadrature coefficients
T = [-0.9061798459, -0.5384693101, 0, 0.5384693101, 0.9061798459]
C = [0.2369268850, 0.4786286705, 0.5688888889, 0.4786286705, 0.2369268850]
@typoman
typoman / cubic-curve-type.py
Created October 23, 2024 15:40
determine cubic bezier curve type using the canonical form in python
import math
from typing import Tuple
EPSILON = .1
def forward_transform(points: Tuple[Tuple[float, float], ...], scale: float = 1) -> Tuple[float, float]:
p1, p2, p3, p4 = points
dy = p2[1] - p1[1]
if abs(dy) < EPSILON:
@typoman
typoman / cubic-bezier-inflection-point.py
Last active October 28, 2024 12:27
find inflection points on a cubic bezier curve using python
import logging
import sys
import time
logger = logging.getLogger('my_timer')
handler = logging.StreamHandler(sys.stdout)
logger.addHandler(handler)
def timeit(method):
"""
A decorator that makes it possible to time functions.
@typoman
typoman / bezier-path-find-closest-point.py
Last active October 28, 2024 19:11
Finds closest point on a bezier path using Newton–Raphson method and visualizes it in drawbot app
import math
def bezier_curve(p0, p1, p2, p3, t):
x = (1-t)**3 * p0[0] + 3*(1-t)**2 * t * p1[0] + 3*(1-t) * t**2 * p2[0] + t**3 * p3[0]
y = (1-t)**3 * p0[1] + 3*(1-t)**2 * t * p1[1] + 3*(1-t) * t**2 * p2[1] + t**3 * p3[1]
return (x, y)
def bezier_curve_derivative(p0, p1, p2, p3, t):
x = 3*(1-t)**2 * (p1[0] - p0[0]) + 6*(1-t) * t * (p2[0] - p1[0]) + 3*t**2 * (p3[0] - p2[0])
y = 3*(1-t)**2 * (p1[1] - p0[1]) + 6*(1-t) * t * (p2[1] - p1[1]) + 3*t**2 * (p3[1] - p2[1])
@typoman
typoman / drawbot-random-circles-on-a-line-grid.py
Created October 14, 2024 12:38
drawbot random circles on a line grid
import math
import cmath
import random
def distance(p1: tuple, p2: tuple):
"""
Calculate the Euclidean distance between two points.
Args:
p1 (tuple): The first point as a tuple of (x, y) coordinates.