Skip to content

Example: typography poster

A practical use of letter, word, and line spacing: a text-only poster where Text::setLetterSpacing() gives headings a stylized, tracked-out look and TextWrap::setWordSpacing()/setLineSpacing() open up a body paragraph for readability.

Example output image

<?php
require 'vendor/autoload.php';
use Kehet\ImagickLayoutEngine\Containers\ColumnContainer;
use Kehet\ImagickLayoutEngine\Enums\Gravity;
use Kehet\ImagickLayoutEngine\Items\Text;
use Kehet\ImagickLayoutEngine\Items\TextWrap;
$width = 700;
$height = 620;
$imagick = new Imagick;
$imagick->newImage($width, $height, new ImagickPixel('#0f172a'));
$root = new ColumnContainer;
$root->setPadding(50);
// Eyebrow
$eyebrowDraw = draw(fill: '#38bdf8');
$eyebrowDraw->setFont('DejaVu-Sans');
$eyebrow = new Text($eyebrowDraw, 'FIELD NOTES', initialFontSize: 24, gravity: Gravity::TOP_LEFT);
$eyebrow->setLetterSpacing(8);
$root->addItem($eyebrow, forceSize: 36);
// Title
$titleDraw = draw(fill: 'white');
$titleDraw->setFont('DejaVu-Sans-Bold');
$title = new Text($titleDraw, 'STAY ON TRAIL', initialFontSize: 80, gravity: Gravity::TOP_LEFT);
$title->setLetterSpacing(4);
$root->addItem($title, forceSize: 110);
// Body copy
$bodyDraw = draw(fill: '#cbd5e1');
$bodyDraw->setFont('DejaVu-Sans');
$body = new TextWrap(
$bodyDraw,
'A short pause at the ridge line is worth more than a summit rushed. Carry water, watch the weather, and let someone know your route before you leave the car park.',
initialFontSize: 30,
gravity: Gravity::TOP_LEFT
);
$body->setWordSpacing(10);
$body->setLineSpacing(16);
$root->addItem($body, forceSize: 260);
// Footer signature
$footerDraw = draw(fill: '#64748b');
$footerDraw->setFont('DejaVu-Sans');
$footer = new Text($footerDraw, 'ISSUE NO. 12 — NORTHBOUND', initialFontSize: 20, gravity: Gravity::TOP_LEFT);
$footer->setLetterSpacing(3);
$root->addItem($footer);
$root->draw($imagick, 0, 0, $width, $height);
$imagick->setImageFormat('png');
$imagick->writeImage(__DIR__.'/typography-poster.png');

The same layout as a template. The dark #0f172a background comes from $imagick->newImage(...), not the layout tree itself, so it isn’t part of the template — the caller still creates the canvas before drawing the template’s root node onto it:

{
"type": "column",
"padding": 50,
"children": [
{"type":"text","text":"FIELD NOTES","fill":"#38bdf8","font":"DejaVu-Sans","fontSize":24,"letterSpacing":8,"size":36},
{"type":"text","text":"STAY ON TRAIL","fill":"white","font":"DejaVu-Sans-Bold","fontSize":80,"letterSpacing":4,"size":110},
{"type":"text-wrap","text":"A short pause at the ridge line is worth more than a summit rushed. Carry water, watch the weather, and let someone know your route before you leave the car park.","fill":"#cbd5e1","font":"DejaVu-Sans","fontSize":30,"wordSpacing":10,"lineSpacing":16,"size":260},
{"type":"text","text":"ISSUE NO. 12 — NORTHBOUND","fill":"#64748b","font":"DejaVu-Sans","fontSize":20,"letterSpacing":3}
]
}

The eyebrow, title, and footer all use setLetterSpacing() at different scales — 8px on the small caps eyebrow, 4px on the bold display title, 3px on the small-caps footer — to give each its own tracked-out, “designed” feel. The body paragraph uses TextWrap with a 10px word spacing and 16px line spacing on top of the font’s natural line height, opening up the block for easier reading against the dark background.

llms.txt