Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


The GTL (or Generatore Tipografico di Libertà) is a Python library for the creation of generative fonts.

Foremost thing: huge credits to Daniele Capo. He's the designer of the original project - this repository is in some ways a branch and a departure from his idea.

And thanks also to all the XYZ2018 partecipants: Micol Salomone, Giovanni Abbatepaolo, Roberto Ciarambino, Alberto Guerra, Greta Capozzi, Enzo Di Gioia, Elsa Moro, Giulio Galli, Alessandra Del Nero, Vittorio Veronesi, Mattia Bressan, Marco Napoletano, Dania Menafra, Laura Laricchiuta, Roberto Lenza, Eleonora Cappuccio, Marco Balestra, Lucien Haba, Ass Diop Faty, Matija Grgič.

Some notes before starting:

  • Please read the full guide before going step-by-step.
  • # are used throughout this guide to indicate lines that are comments: it means they do not need to be typed at all.

0 - What does it do

The GTL takes as input

.........     ........
...O##...     ........
..O...#..     ........
..O...#..     .#O##O..
..#...O..     .#...#..
..O#O##..     .....O..
..#...#..     .#O#O#..
..#...O..     .#...#..
.#O...##.     .O#O#.#.
.........     ........
  • a syntax - a set of instructions
. -> draw a white space
# -> draw a rectangle
O -> draw a circle

and by combining the inputs generates an actual, usable font: The GTL is the perfect tool for the development of lazy-brutal-discrete typefaces, allowing for a fast and flexible drawing process: just by changing the syntax is it possible to generate endless variations for the same letter structure!

The GTL is meant to be used by everyone. If you're curious, let's dive in!

1 - Install guide

1.1 - Installing Python

The GTL requires Python: Download and install it.

If you're using Windows, remember to check Add Python 3.x to PATH.

1.2 - Setting up the workspace

Download the GTL and save it anywhere on your computer.

This is the folder architecture:

├── GTL			# CORE FOLDER, don't touch
│   └── ...
├──		# This is the file to run to generate the font
├──	# Here you'll set some minor (but important) parameters
├──	# Here you'll set the syntax
├── letters-liberta	# Here's a sample of some letters ready to use
│   └── ...
├── letters-nova	# Here's another sample of some letters ready to use
│   └── ...
├── LICENSE		# Ignore
├──		# Ignore
└── readme_images	# Ignore
    └── ...

2 - How it works

2.1 - Drawing the letters

First of all, you have to design the letter structure! Each letter should be drawn in a separate .TXT file. The file should look like this (check letters-nova or letters-liberta folders for some samples):

A               # LINE 1 ━ glyph name
                # LINE 2 ━ empty line
...##O...       # LINE 3 ┓
..#...#..	  .      ┃
..#...#..	  .      ┃
..#...#..	  .      ┃
..O####..	  .      ┣ glyph structure
..#...O..	  .      ┃   
..#...O..	  .      ┃
.O#...##.	  .      ┃
.........       # LINE N ┛

Important notes about the glyph name

  • The glyph name is not the glyph itself: for example, the name for à is agrave. You can search the glyph in this reference table and get its name from Glyph name column.
  • If a glyph is not in the provided table you can give it a random name. Only letters (A-Z, a-z) are accepted.

Important notes about the glyph structure

  • For each letter of the font - the number of the rows must be the same.
  • In the same letter - all the rows must have the same length.
  • It's important to have at least one empty column for each side, to give glyphs some margin.

Other things

  • Glyphs from the same font can have different widths (a different row length).
  • You can use all the symbols you want in the glyph structure. The more the symbols, the more will be possible to create complex designs.
  • Remember that the space is also a glyph.

Once you've drawn all the glyphs, store them in a folder.

2.2 - Syntax

Once you've designed the letters (or, if you're lazy, decided to use the sample letters in the master folder) it's time to define the syntax.


So open with a code editor and scroll all the way down: you'll find this

syntax = {
    # Add instructions here

Each symbol used in the glyph structure needs an instruction: the GTL needs to know what to do when it reads each symbol found in the glyph structure.

An instruction looks like this:

"character": (function, function_properties),		# the comma is important
  • character - here goes the symbol you used in the description
  • function - here you tell the GTL what to do when it reads that character
  • function_properties - here you set some parameters to modify the behaviour of the function


Before continuing, please check the section Functions and Properties to see the complete list of Functions and Functions Properties



Let's now say you decided that you want to draw a rectangle each time there's a # in the glyph structure. According to what we said before, we need a symbol, a function and function_properties. Symbol and function we have (respectively # and rectangle). But we do not have any function_properties! We'll have to write this one.

For the moment, the syntax looks like this

syntax = {
    "#": (rectangle, ?),


Writing a property

As you might have noticed, in the file, above the syntax, there's a section called Properties: there'll go our code.

We start by creating the "container" of the properties.

container = {

Since we will have different properties, it's good practice to give the container an appropriate name:

p_rectangle = {			# "p" is short for "properties"

Then, we add the corresponding properties for the function we chose. Since we chose the rectangle, we copy and paste its properties from the section below, enclosing them between quotes and adding a colon and a comma after it.

p_rectangle = {
    "scale_x": ,
    "scale_y": ,
    "rotation": ,

Then we have to add the values. Let's say we do not want to scale the rectangle, but we want to give it a random rotation each time it gets drawn. So the properties will look like this:

p_rectangle = {
    "scale_x": 1,		# Scaling by 1 means no change
    "scale_y": 1,		# Scaling by 1 means no change
    "rotation": (0, 360),	# A random angle between 0 and 360 will be chosen

And now that we have our property, we can write the instruction!

syntax = {
    "#": (rectangle, p_rectangle),

At this point, you just need to add an instruction for each symbol you used in the glyphs structures and you're good to go!


Extra tip

The property for the function do_nothing looks like this: p_do_nothing = {}. Since the function does nothing, the container for its properties is empty.

2.3 - How to generate the font (Where the magic happens!)

2.3.1 - Edit

Next (and almost final) step: you need to edit the file by adding all the requested variables.


# Path of folder containing glyphs txt
txt_path = "path/to/txt/files"

# Path of folder of output font
out_path = "path/to/chosen/folder"

# Font name (anything you like: Sator, Avocado, etc)
font_name = "Tenet"

# Style name (Regular, Bold, Rectangular, Dizzy, etc)
style_name = "Regular"
# For the font metrics section, you just have to count the rows as shown in this example:


# FLOAT - Set box width ratio (width_ratio=1 for square proportions)
width_ratio = 1

# (INT, INT) - Set box layout (e.g. box_layout = (1,1))
box_layout = 1,1


2.3.2 - Terminal instructions to make magic happen


python3 /path/to/

aaand… enjoy! :)

(The font will be saved both as UFO format: to make it fully usable you have to export it as OTF file from a font editor such as FontForge.)

Functions and properties

Here's a list of all the available functions and their properties.

function	    | function description
    - property	    | property description
do_nothing          | does nothing
    - [has no properties]

rectangle           | draws a rectangle
    - scale_x       | horizontal scale factor
    - scale_y       | vertical   scale factor
    - rotation      | rotation (in degrees)

ellipse             | draws an ellipse
    - scale_x       | "
    - scale_y       | "
    - rotation      | "
    - squaring      | squaring degree of the curve

ellipse_quarter | draws an ellipse quarter
    - scale_x       | "
    - scale_y       | "
    - rotation      | "
    - squaring      | "
    - orientation   | orientation of the quarter

random_function | executes a random function chosen between the ones provided
    - function_properties_list
                    | a list of function-properties couples

And this is a list of possible values for each property:

	- data type					data example
scale_x, scale_y, rotation, squaring
	- an integer number (int)			1
	- a floating point number (float)		3.14
	- a range of int and/or float			(-3.14, 9)
	- a list  of int and/or float			[0, 9.32, -12, 4.3]

	- an orientation (str)				"NW" or "NE" or "SW" or "SE"
	- a list of orientations			["NW", "NE", "SE"]

	- a list of function-properties couples		[(f1, f1_prop), (f2, f2_prop), …]

Important notes

  • In case of range values, will be chosen a random number between the extremes.
  • In case of list values, will be chosen a random value from the ones in the list.

Also remember:

  • Lists are always enclosed in squared brackets.
  • Ranges and couples are always enclosed in round brackets.


A Python set of libraries for the development of generative fonts







No releases published


No packages published