60d8399ce8617bf31d27b7752576b66a9f29d9b2 braney Wed Jun 3 09:20:22 2026 -0700 hgTracks config: document how to add a new FreeType font Add a "HOW TO ADD A NEW FONT" comment block above the freeTypeFonts[] table explaining the two steps (place the file under freeTypeDir, add a {name, file} row), how freeTypeDir resolves relative to the CGI working directory (so it finds the shared htdocs/urw-fonts even from a per-user sandbox), the name/face/style convention used by the configure-page dropdown, and the gotchas -- notably that variable fonts like InterVariable.ttf render only their default master instance, so a static single-weight file should be used instead. refs #37698 Co-Authored-By: Claude Opus 4.8 (1M context) diff --git src/hg/hgTracks/config.c src/hg/hgTracks/config.c index 086369c4a7d..1a59b8fa9bb 100644 --- src/hg/hgTracks/config.c +++ src/hg/hgTracks/config.c @@ -46,30 +46,66 @@ char* name = el->name; name = chopPrefix(name); // chop off first three words name = chopPrefix(name); name = chopPrefix(name); replaceChar(name, '_', ' '); labels[i] = name; i++; } char* currentTheme = cartOptionalString(cart, "theme"); hDropList("theme", labels, i, currentTheme); slFreeList(themes); hPrintf(""); } +/* HOW TO ADD A NEW FONT + * + * The browser draws track text with either the old bitmap engine or, when + * freeType is on (hg.conf "freeType=on", the default in a FreeType build), the + * FreeType engine. The fonts the FreeType engine offers are the freeTypeFonts[] + * table below. To add one: + * + * 1. Put the font file where the engine can find it. At run time the file is + * looked up under freeTypeDir, which defaults to "../htdocs/urw-fonts". + * That path is relative to the CGI's working directory, so it resolves to + * the *shared* htdocs/urw-fonts even from a per-user sandbox -- you do not + * need a urw-fonts directory under your own htdocs-USER. (You can point + * somewhere else with "freeTypeDir" in hg.conf.) Both Type-1 (.pfb) and + * TrueType (.ttf) files work. + * + * 2. Add a row to freeTypeFonts[] giving the name and the file. The name is + * what shows up in the configure-page Font dropdown. The configure page + * splits the name on the first '-' into a face and a style: the part before + * the '-' is the face shown in the Font menu, the part after is an entry in + * the Style menu. So a plain weight is just the face name ("Lexend") and a + * variant is "Face-Style" ("Lexend-Bold"). Group a face's variants on + * consecutive rows so the Style menu lists them together. + * + * Gotchas: + * + * - Avoid variable fonts (e.g. InterVariable.ttf). FreeType is opened on face + * index 0 with no named instance selected, so a variable font renders only + * its default master -- usually not the weight you expected, which looks like + * "the option appeared but a different font was drawn". Use a static, + * single-weight file instead (e.g. Inter-Regular.ttf). + * + * - The name in the dropdown must match the name in this table exactly, + * including the face/style split above. A selected name that matches no row + * falls back to the bitmap engine (see maybeNewFonts). + */ + struct freeTypeFont /* A font offered to the FreeType text engine. The name and its file live on * one row so the two can never drift out of sync (this used to be two parallel * arrays indexed by position, which silently rendered the wrong font when they * disagreed). */ { char *name; /* Label shown in the configure-page dropdown. A normal-weight * font is just the face ("Lexend"); a variant is "Face-Style" * ("Lexend-Bold"). The dropdown splits this on the first '-'. */ char *file; /* Font file (.pfb Type-1 or .ttf TrueType) found under * freeTypeDir (hg.conf freeTypeDir, default ../htdocs/urw-fonts). */ }; struct freeTypeFont freeTypeFonts[] = { {"AvantGarde-Book", "a010013l.pfb"},