OptionalCreativeVersion 0.1.0

Draw Your Font: Turn Handwriting Photos into a TTF Font with Hermes Agent

Turn a handwriting photo into an installable TTF font.

Written by Neura Market from the official Hermes Agent documentation for Draw Your Font. Commands, paths, and version numbers are reproduced from the source unchanged.

Read the official documentation

This skill turns a photo of handwritten letters into an installable TTF font. You do the seeing: find and label letters, judge quality. The CLI does all geometry: tracing, metrics, and font assembly. You never edit SVG paths or coordinates yourself. Reach for this when you want a personal font from your own handwriting, or when a user asks for a custom typeface based on their script.

What it does

The draw-your-font skill is a wrapper around a pinned npm package that runs entirely on your machine. You feed it one or more photos of handwritten characters, and it produces a font file you can install on macOS or Windows. The workflow is split into clear stages: segment the image into individual letter blobs, label each blob with the correct character, build the font, judge the result visually, and deliver the file. The skill is designed for iterative refinement: you can rebuild the font with different weights or smoothing levels without re-photographing, as long as the source ink is good.

Before you start

  • The skill is optional and installed on demand. Its path is optional-skills/creative/draw-your-font, version 0.1.0, authored by Danilo Znamerovszkij and ported by Hermes Agent. It is MIT licensed and works on Linux, macOS, and Windows.
  • You need Node.js version 18 or higher. There is no global install; you run the CLI via npx.
  • The CLI is pinned to version 0.1.0. Wherever the examples show $DYF, use the full command npx -y draw-your-font@0.1.0. Shell variables do not persist between tool calls, so paste the full command each time.
  • Everything runs locally. The user's handwriting never leaves the machine.
  • Photos must be real files. If a photo arrives in the conversation without a file path, ask the user for the file. Do not proceed from memory of the image.
  • For visual steps like contact sheets, previews, and glyph sheets, load the PNGs with vision_analyze.

Decide the flow

Before starting, determine which path fits the user's situation:

  • User has no photo yet → offer the template: print, write, photograph.
  • User shares photo(s) of handwriting → main flow below.
  • User pasted an image but there is no file path → you can see it, but the CLI needs a file. Ask them to drag the image file into the terminal (that inserts its path) or give the path directly. Do not proceed from memory.
  • User wants changes to a font built this session → Refine section.

Template flow (best quality)

For the best results, start with a template. Generate a PDF with the minimal or Spanish character set:

$DYF template -o template.pdf --charset minimal   # or: spanish

Tell the user: print it, write one character per box with a dark pen (0.5 mm+), keep the letter sitting on the solid line, then photograph each page from above in good light and share the file paths. The grid prints in light grey and vanishes during processing, only their ink survives.

Main flow: photo(s) → font

1. Segment

Works for template pages and freeform photos alike. Run the segment command with all your photos and a working directory:

$DYF segment photo1.jpg photo2.jpg -d work

This creates a work directory with contact sheets and crops. You will inspect these next.

2. Look, then label

Load work/contact-1.png with vision_analyze (one per photo). Every detected blob is numbered. This is the step where your eyes matter. Check:

  • Did every written character get exactly one box? A letter drawn with separate strokes may appear as two boxes (relabel handles it: give the main box the character and mark the fragment ""), and two touching letters may share one box (ask the user to re-shoot just those, or accept the gap).
  • Junk boxes (shadows, ruled lines, smudges, page edges) → label them "".

Then write work/labels.json mapping blob id to character, e.g. {"0": "A", "1": "B", "7": "", "8": "a"}.

  • Template page: order is the charset order printed on the template. Verify against the sheet instead of trusting it blindly. Minimal order: A, Z, a, z, 0, 9, then .,;:!?'"-()@#&+/$; spanish appends ÑñÁÉÍÓÚáéíóúü¿¡.
  • Freeform: identify each letter from the contact sheet. Uppercase vs lowercase for shape-twins (S/s, O/o, C/c, X/x…) is decided by relative size and position. Compare against neighbors you're sure of.
  • The user told you what they wrote (e.g. "ABC then abc")? Trust it, map in reading order (top row first, left to right), and verify visually.
  • Same letter appears twice → label the better-drawn one, "" the other.

3. Build

Once labels are ready, build the font:

$DYF build -d work --labels work/labels.json --name "Dan's Hand"

Name the font after the user. Ask if unclear, but keep it to one short question max.

4. Judge before delivering

Load work/preview.png and work/glyphs.png with vision_analyze and critique like an art director:

  • Broken or blotchy letters (bad trace) → often a faint pen stroke; try --weight 1, or ask for a re-shoot of just that letter.
  • Everything too thin/thick → rebuild with --weight 1 / --weight -1.
  • Jagged edges → rebuild with --smooth 1.5 (up to 2).
  • A letter placed wrong (e.g. a g not descending) → usually a mislabel; fix labels.json and rebuild.
  • Filled-in bowls (b, o, g look solid): should never happen. If it does, the crop is smudged; ask for a re-shoot.

Rebuilds are cheap and safe to iterate. Fix what you can yourself first; only bother the user for re-shoots when the source ink is the problem.

5. Deliver

The font lands at /.ttf (the build output prints the exact path). Give that path and how to install: macOS: double-click → "Install Font"; Windows: right-click → "Install". Mention what's missing (the build prints uncovered letters) and offer, without pushing:

  • Web formats + CSS: rebuild with --formats ttf,woff,woff2,css.
  • A legibility read (below).
  • Their next photo to fill missing characters: re-run segment with ALL photos (old and new) into a fresh workdir: $DYF segment p1.jpg p2.jpg -d work2, then relabel from the new contact sheets (blob ids renumber; the old labels.json does not carry over) and build from the new workdir.

Refine (conversational iteration)

After the first build, the user may ask for tweaks. The table below maps common requests to rebuild commands. All refine commands rebuild from the stored crops, so no re-photographing is needed unless the ink itself is the problem.

User saysDo
"smoother / rounder"build … --smooth 1.5 (max 2)
"thicker / bolder"build … --weight 1 (max 2)
"thinner / lighter"build … --weight=-1 (negative needs the = form)
"the g looks bad"show them work/crops/.png for that letter; offer re-shoot or smooth
"wrong letter" / swapedit labels.json, rebuild
"give me woff2 / web"build … --formats ttf,woff,woff2,css
custom preview text$DYF preview -d work --text "…" (after a build)

Legibility report (offer after delivering)

After delivering the font, offer a legibility read. Generate a preview with a test string that stresses common confusions:

$DYF preview -d work --text "minimum mill rn m cl d I l 1 O 0 quick brown fox" -o work/legibility.png

Read it and give an honest, kind read: a score out of 10 for body-text use, the 2, 3 letter pairs most likely to confuse (rn→m, cl→d, I/l/1, O/0), and one or two concrete fixes (rewrite those letters larger, more spacing). Note that display use (headings, notes) is more forgiving than paragraphs. Never gate delivery on this. It's advice, not a blocker.

Troubleshooting

Segmentation found far too many or too few blobs, grey guide lines surviving, shadow blobs, faint ballpoint strokes: see references/troubleshooting.md.

When not to use it

This skill is for turning handwriting into a font. If the user wants a font that looks machine-made or perfectly geometric, this is not the right tool. It also requires real photos; you cannot work from memory or from an image pasted without a file path. If the user cannot provide a clear photo of each character, the output will be poor. For pixel art or other creative tasks, consider the related pixel-art skill instead.

Limits and gotchas

  • The CLI must be run with the full npx command each time; $DYF is just a placeholder. To see the full command in action, run:
npx -y draw-your-font@0.1.0 --help
  • Blob ids renumber when you re-segment with new photos, so old labels.json files do not carry over.
  • Negative weight values require the = form (--weight=-1), not a space.
  • Smoothing and weight are capped at 2. Going beyond that is not supported.
  • The font file lands at /.ttf; the exact path is printed by the build output.
  • Filled-in bowls should never happen; if they do, the crop is smudged and you need a re-shoot.
  • The legibility report is advice, not a blocker. Never withhold delivery based on it.

Related skills

This skill pairs well with pixel-art, another creative skill in the same category. If you enjoy turning visual input into digital artifacts, explore that next.

Skills the docs pair this with

More Creative skills