Skip to main content

rotulo

npm PyPI license

Monoline typeface generated from skeletons: strokes of lines and arcs expanded with a round pen.

Rotulo Display and Rotulo Lectura specimen

Live demo

Every letter is a skeleton of straight lines and arcs drawn in code, never a hand-drawn outline. The generator expands each skeleton with a round pen and writes TrueType and WOFF2 fonts. Weight is the pen width, so the family is a variable font from 200 to 700. A reading cut, Lectura, adds weight, spacing and letters that are hard to mirror.

Install

npm install rotulo
pip install rotulo
Package What it is Needs
rotulo (npm) WOFF2 files and a stylesheet with the @font-face rules A bundler that resolves CSS imports, or a plain <link>
rotulo (PyPI) The generator: builds every font from the skeletons Python 3.12 or later

The TTF files are attached to each GitHub release.

Quick start

@import 'rotulo';

body {
    font-family: 'Rotulo', system-ui, sans-serif;
    font-weight: 200;
}

.reading {
    font-family: 'Rotulo Lectura', 'Rotulo', sans-serif;
}
python -m rotulo --out build --web build/web

Fonts

Family File Weight Use
Rotulo Rotulo-Variable.woff2, .ttf 200 to 700 Map labels, interface, titles
Rotulo Rotulo-Display.ttf 200, static and hinted Renderers without variable fonts, such as GeoServer or PDF libraries
Rotulo Lectura Rotulo-Lectura.woff2, .ttf 500, static and hinted Long reading

Color details

The fonts are one color. Built with color_details=True, dots, accents, the zero slash and punctuation move to a color layer (COLR/CPAL): the body takes the text color and the detail a palette color, #3d8a8f by default and #7fb7b5 on dark backgrounds (base-palette: 1).

Reading forms

ss01 switches four letters to the forms of Lectura: l with a tail, q with a crossed tail, a curved flag on 1 and a straight 9.

.labels {
    font-feature-settings: 'ss01';
}

Using the fonts outside the web

Where How
GeoServer Copy Rotulo-Display.ttf into the font directory and name Rotulo in the SLD font-family
PDF Embed Rotulo-Display.ttf or Rotulo-Lectura.ttf

Parameters

Params holds every design decision, in units of a 1000 em:

Field Default What it controls
weight 46 Pen width
x_height, cap_height 425, 700 Body and capital heights
ascender, descender 840, −415 Shared by every letter with a tail; the descender matches the ascender's reach above the x-height
sign_descender −180 Depth of brackets, braces, parentheses, |, / and _
corner 50 Radius used to round every skeleton vertex
gap 110 Space between a stroke and a floating detail
spacing, word_spacing 1.5, 1.0 Side bearings and space width
narrow_air 0.3 Extra room around narrow letters such as i, l, t
from dataclasses import replace
from pathlib import Path

from rotulo import DISPLAY, build_font

print(build_font(replace(DISPLAY, weight=70), "Medium", 400, Path("build")))

Known limitations

  • Latin script: Spanish, Portuguese, French and Catalan, figures and common symbols.
  • The variable font keeps overlapping strokes and is not hinted; use the static files at small sizes on Windows.

Development

python -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'
pytest
ruff check src tests && ruff format --check src tests
mypy

The demo in demo/ is a static specimen: build the fonts into it with python -m rotulo --out build --web demo/fonts && cp web/rotulo.css demo/ and serve the folder.

The tests build every font and check heights against the skeleton, kerning, the optional color layers, ss01, hinting and that the variable font interpolates every glyph.

Contributing

Issues are welcome. Please open one before sending a pull request.

License

OFL-1.1 © GHEgar

Metadata

Release files for rotulo 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rotulo 0.3.0
File Size Uploaded
rotulo-0.3.0.tar.gz 103.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rotulo 0.3.0
File Interpreter ABI Platform
rotulo-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 130.4 kB

Release files / rotulo-0.3.0.tar.gz

Download URL rotulo-0.3.0.tar.gz
Size 103.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f0f3d417312aa77ea7ea18537003ae6f4963342f14564257e279d3f9446180f2
BLAKE2b-256 checksum
How to use checksums
b4da14072f4b766dec71ead6e8436c27357504a6d52ba9ea0baf4df6b56a7333
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / rotulo-0.3.0-py3-none-any.whl

Download URL rotulo-0.3.0-py3-none-any.whl
Size 27.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
44a3188dc19894ec3ff9221dc8f868d8562ab4e99c8d85c4e1c60edafbaea3d5
BLAKE2b-256 checksum
How to use checksums
9980128a0af384668be975f485237f1d4e7633a0e6e4ed7db28b40c868e1be1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page