bd85159b36db7ff8c02b32eb18d96ed6066feb8f
braney
  Wed Aug 5 13:59:46 2026 -0700
hgTracks: measure text with the same font engine that will draw it, refs #38027

Pack mode works out how many rows a track needs by measuring its item labels,
and mgFontStringWidth answers from whichever text engine is loaded at the time.
FreeType was only loaded when an image was created, so the measuring could
happen on the bitmap engine while the drawing happened on FreeType -- and which
one you got depended on whether the ideogram image had been built first.

Load the engine in initTl(), alongside the rest of the font setup, before
anything measures a string.  maybeNewFonts() and the new initFontEngine() share
chosenFreeTypeFont(), and mgLoadFontEngine() loads an engine without attaching
it to an image.  ftInitialize() now keeps the face it already has when asked for
the same font file, so the glyph cache hanging off that face survives the extra
call.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

diff --git src/hg/hgTracks/hgTracks.h src/hg/hgTracks/hgTracks.h
index 05eb0c1b3be..d7b9bfa00cd 100644
--- src/hg/hgTracks/hgTracks.h
+++ src/hg/hgTracks/hgTracks.h
@@ -1915,30 +1915,33 @@
 void printRecTrackSets();
 /* Create dialog with list of recommended track sets */
 
 boolean loadRecTrackSetFromFile(struct cart *cart, char *sessionName);
 /* If a contents file exists in htdocs for this recommended track set, merge its
  * settings into the current cart and return TRUE.  Return FALSE if no file, so the
  * caller can fall back to loading the session from hgcentral. */
 
 Color colorFromSoTerm(enum soTerm term);
 /* Assign a Color according to soTerm: red for non-synonymous, green for synonymous, blue for
  * UTR/noncoding, black otherwise. */
 
 void maybeNewFonts(struct hvGfx *hvg);
 /* Check to see if we want to use the alternate font engine (FreeType2). */
 
+void initFontEngine();
+/* Load the text engine the user has picked, before anything measures a string. */
+
 Color colorFromCart(struct track *tg, Color color);
 /* Return the RGB color from the cart setting 'colorOverride' or just return color */
 
 unsigned getParaLoadTimeout();
 // get the parallel load timeout in seconds (defaults to 90)
 
 void maybeDrawQuickLiftLines( struct track *tg, int seqStart, int seqEnd,
                       struct hvGfx *hvg, int xOff, int yOff, int width,
                       MgFont *font, Color color, enum trackVisibility vis);
 /* Draw the indel regions as a highlight. */
 
 unsigned findBiggest(unsigned num);
 /* find biggest font not bigger than num */
 #endif /* HGTRACKS_H */