43f042236ce180b8e0712d43c8baabc4ad8df1cd max Sat Jul 25 18:21:54 2026 -0700 hgTracks: add compactPack mode and codon strand-direction arrows When zoomed to codon-coloring level, draw strand-direction chevrons across the exons (white over coding codons when too small to label, contrasting color over UTRs), and a per-codon arrow between amino-acid letters via drawScaledBoxWithText. Add a compactPack trackDb setting for shorter pack/squish rows and a small squish-mode codon font. Adds mgFontForCellHeight() to memgfx and enables compactPack on the JASPAR track. diff --git src/lib/memgfx.c src/lib/memgfx.c index 5adcec2b894..b5d159f649d 100644 --- src/lib/memgfx.c +++ src/lib/memgfx.c @@ -965,30 +965,46 @@ font = mgHelvetica34Font(); else errAbort("unknown textSize %s", textSize); } return font; } MgFont *mgFontForSize(char *textSize) /* Get a font of given size and style. Abort with error message if not found. * The textSize should be 6,8,10,12,14,18,24 or 34. For backwards compatibility * textSizes of "tiny" "small", "medium", "large" and "huge" are also ok. */ { return mgFontForSizeAndStyle(textSize, "medium"); } +MgFont *mgFontForCellHeight(int cellHeight) +/* Return a font whose reported cell height is cellHeight, cloned from the small + * font. Built-in fonts only come in fixed sizes, but the FreeType engine + * derives its render size from the font's cell height (see getFontCorrection in + * freeType.c), so this yields an in-between size that no fixed font offers (e.g. + * cellHeight 10 renders ~9px). VALID ONLY UNDER FREETYPE: the GEM bitmap engine + * indexes fixed bitmap rows by this height, so the glyphs would be misread. + * Callers must fall back to a real fixed-size font when FreeType is off. Not + * thread-safe; it hands back one static header re-stamped on each call. */ +{ +static struct font_hdr clone; +clone = *mgSmallFont(); // copy the header; FreeType ignores the glyph data +clone.frm_hgt = cellHeight; // this is what mgFontPixelHeight() returns +return &clone; +} + void mgSlowDot(struct memGfx *mg, int x, int y, int colorIx) /* Draw a dot when a macro won't do. */ { mixDot(mg, x, y, COLOR_32_ALPHA(colorIx)/255.0, colorIx); } int mgSlowGetDot(struct memGfx *mg, int x, int y) /* Fetch a dot when a macro won't do. */ { return mgGetDot(mg, x, y); } struct memGfx *mgRotate90(struct memGfx *in) /* Create a copy of input that is rotated 90 degrees clockwise. */