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"},