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) <noreply@anthropic.com>
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("</TD>");
}
+/* 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"},