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.
The GTL takes as input
- a structure - ASCII-like drawings of glyphs
......... ........
...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!
The GTL requires Python 3.6 or 3.7.
It is strongly recommended to create a Python Virtual Enviroment for the installation of all the needed libraries and the usage of the GTL.
-
Create a folder anywhere on your computer and give it appropriate name (e.g. venv_gtl
).
-
Open the terminal and input
python3 -m venv <DIR>
where <DIR>
is the full path of the created folder. For example:
python3 -m venv /Users/username/Desktop/venv_gtl
-
The virtual enviroment needs to be activated each time you want to use the GTL. To do it, run in the terminal
# On macOS
source <DIR>/bin/activate
# On Windows
<DIR>\Scripts\activate
e.g.
source /Users/username/Desktop/venv_gtl/bin/activate
(To exit from the environment anytime just enter deactivate
or close the terminal.)
FontParts is the core library over which the GTL has been built. FontParts is still in development, and newer version are already out. As of today, the GTL has been tested only on the 0.8.7 version.
To install fontparts - while the virtual environment is active - run in terminal
pip install fontParts==0.8.7
After you'll run this command probably you'll get two (probably yellow) lines saying
You are using pip version 19.0.3, however version 19.3.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Just ignore them.
Download the GTL and save it anywhere on your computer.
This is the folder architecture:
.
│
├── GTL # CORE FOLDER, don't touch
│ └── ...
│
├── GTL_main.py # This is the file to run to generate the font
├── GTL_params.py # Here you'll set some minor (but important) parameters
├── GTL_syntax.py # Here you'll set the syntax
│
├── test_letters # Here's a sample of some letters ready to use
│ └── ...
│
├── LICENSE # Ignore
├── README.md # Ignore
└── readme_images # Ignore
└── ...
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 the test_letters
folder 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
à
isagrave
. You can search the glyph in this reference table and get its name fromGlyph 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.
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 GTL_syntax.py
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, ?),
}
-
As you might have noticed, in the GTL_syntax.py
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!
-
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.
Next (and almost final) step: you need to edit the GTL_params.py
file by adding all the requested variables.
## PATHS
# 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 INFO
# Font name (anything you like: Sator, Avocado, etc)
font_name = "Tenet"
# Style name (Regular, Bold, Rectangular, Dizzy, etc)
style_name = "Regular"
## FONT METRICS
# For the font metrics section, you just have to count the rows as shown in this example:
## BOX PROPERTIES
# 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
-
Activate the Virtual Environment
# On macOS
source <DIR>/bin/activate
# On Windows
<DIR>\Scripts\activate
Run
python3 /path/to/GTL_main.py
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.)
Here's a list of all the available functions and their properties.
function | function description
- property | property description
p_do_nothing | does nothing
- [has no properties]
p_rectangle | draws a rectangle
- scale_x | horizontal scale factor
- scale_y | vertical scale factor
- rotation | rotation (in degrees)
p_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:
properties
- 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]
orientation
- an orientation (str) "NW" or "NE" or "SW" or "SE"
- a list of orientations ["NW", "NE", "SE"]
function_properties_list
- 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.