Text & Typography
Draw, measure, and animate text in Processing using PFont and kinetic typography techniques.
Basic text
text() draws a string at a given position. By default text is drawn with its baseline at the y coordinate and its left edge at x.
void setup() {
size(600, 200);
background(20);
}
void draw() {
background(20);
fill(255);
textSize(48);
text("Hello, Processing!", 40, 120);
}
text() respects the current fill() colour. You can draw coloured, transparent, or even stroked text by setting fill and stroke before the call.
textSize and textAlign
textSize(24); // set font size in pixels
textAlign(CENTER, CENTER); // horizontal: LEFT / CENTER / RIGHT
// vertical: TOP / CENTER / BOTTOM / BASELINE
// Now coordinates are the centre of the text bounding box
text("Centred", width / 2, height / 2);
textAlign(CENTER, CENTER) is particularly useful when you want to position text relative to a shape’s centre rather than its baseline corner.
Loading fonts: loadFont and createFont
Processing can use any font installed on your system via createFont(), or use a pre-processed .vlw bitmap font created through the Tools → Create Font menu.
PFont mono;
PFont serif;
void setup() {
size(600, 300);
background(15);
// createFont loads a system font at a given size
mono = createFont("Courier New", 24);
serif = createFont("Georgia", 32);
}
void draw() {
background(15);
textFont(mono);
fill(120, 220, 120);
text("monospaced courier", 40, 100);
textFont(serif);
fill(220, 150, 80);
text("Georgia serif", 40, 180);
}
For maximum quality in exported PDFs or high-resolution output, generate .vlw fonts via Tools → Create Font and load them with loadFont("MyFont-32.vlw").
Measuring text
Three built-in functions let you measure text at the current font and size:
String msg = "Processing";
float w = textWidth(msg); // width in pixels
float asc = textAscent(); // height above baseline
float desc = textDescent(); // depth below baseline
float totalH = asc + desc;
// Draw a bounding box around the text
float tx = 50, ty = 150;
fill(255);
text(msg, tx, ty);
noFill();
stroke(255, 80, 80);
rect(tx, ty - asc, w, totalH);
These measurements are essential for text-based UI elements, speech bubbles, and any layout where text must be aligned with other objects.
Drawing text along a curve
By calculating a point on a circle for each character, you can arrange text in an arc:
String msg = "* CIRCULAR TEXT IN PROCESSING *";
float radius = 180;
void setup() {
size(500, 500);
}
void draw() {
background(15);
textAlign(CENTER, CENTER);
textSize(18);
fill(200, 220, 255);
noStroke();
float totalAngle = TWO_PI;
float step = totalAngle / msg.length();
for (int i = 0; i < msg.length(); i++) {
float angle = step * i - HALF_PI; // start at top
float x = width / 2 + cos(angle) * radius;
float y = height / 2 + sin(angle) * radius;
pushMatrix();
translate(x, y);
rotate(angle + HALF_PI); // rotate each letter to face outward
text(msg.charAt(i), 0, 0);
popMatrix();
}
}
Each character is extracted with msg.charAt(i) and drawn individually with a pushMatrix/rotate/popMatrix wrapper so it faces the correct direction.
Full example: animated kinetic typography
In kinetic typography, letters move independently. This sketch breaks a word into individual Letter objects, each drifting and returning to its home position.
import java.util.ArrayList;
ArrayList<Letter> letters = new ArrayList<Letter>();
String WORD = "PROCESS";
void setup() {
size(700, 400);
textAlign(CENTER, CENTER);
PFont f = createFont("Arial Bold", 80);
textFont(f);
// Calculate the total width so we can centre the word
float totalW = 0;
for (int i = 0; i < WORD.length(); i++) {
totalW += textWidth(WORD.charAt(i));
}
// Position each letter
float x = (width - totalW) / 2;
float y = height / 2;
for (int i = 0; i < WORD.length(); i++) {
char c = WORD.charAt(i);
float cw = textWidth(c);
letters.add(new Letter(c, x + cw / 2, y));
x += cw;
}
}
void draw() {
background(15);
for (Letter l : letters) {
l.update();
l.display();
}
}
// Click to scatter the letters
void mousePressed() {
for (Letter l : letters) {
l.scatter();
}
}
class Letter {
char c;
float homeX, homeY; // resting position
float x, y; // current position
float vx, vy; // velocity
Letter(char c, float hx, float hy) {
this.c = c;
homeX = hx; homeY = hy;
x = hx; y = hy;
vx = 0; vy = 0;
}
void scatter() {
vx = random(-8, 8);
vy = random(-12, -4);
}
void update() {
// Spring back toward home position
float ax = (homeX - x) * 0.06;
float ay = (homeY - y) * 0.06 + 0.3; // gravity
vx = (vx + ax) * 0.88;
vy = (vy + ay) * 0.88;
x += vx;
y += vy;
}
void display() {
float d = dist(x, y, homeX, homeY);
fill(map(d, 0, 200, 220, 80),
map(d, 0, 200, 220, 120),
255);
noStroke();
text(c, x, y);
}
}
Click to scatter the letters; they spring back with simulated gravity and damping. The colour shifts from near-white (at rest) toward blue-purple (displaced), giving instant visual feedback about each letter’s distance from home.
Key takeaways
text(str, x, y)draws at the baseline-left; usetextAlign(CENTER, CENTER)to centre on a point.createFont("FontName", size)loads any installed system font.textWidth(),textAscent(), andtextDescent()let you measure strings precisely.- Draw text along a curve by computing per-character positions and rotating with
pushMatrix/rotate/popMatrix. - Kinetic typography is achieved by treating each character as an independent animated object.