Centred text with setFontWithSpacing drifts left
-
I noticed my 'centred' knob labels were shifted 1-2px to the left and it turns out that letter spacing adds extra space after the last character, which shifts the whole text left.
Wider letter spacing = further shift to the left.
Claude says it expected JUCE behaviour. Expected, maybe, but not cool.

Notice how the first row (zero spacing) is centred, then the text shifts progressively further left as the spacing increases. The last 2 rows show 2 different fixes that Claude suggested. No idea how robust the fixes are. They're in the snippet at the bottom.
During this, Claude also found 2 HISE bugs. I'm still unpacking so I can submit bug fixes. Full explanation below the image.

1. Centred text with
setFontWithSpacingdrifts left (JUCE behaviour)setFontWithSpacingmaps toFont::setExtraKerningFactor, and JUCE addsspacing × heightafter every glyph, including the last one.drawAlignedText(..., "centred")centres the advance box, which therefore has an invisible trailing gap, so the visible glyphs end upspacing × height / 2px left of centre. Small at typical values (0.075 × 15 px ≈ 0.6 px) but visible on all-caps labels under a knob. Fine, that's how JUCE works, but the obvious fixes both fell over because of 2 and 3.2.
"Default"ignores the font sizeg.setFont("Default", 30)andg.setFontWithSpacing("Default", 30, x)do not draw at 30 px.MainController::getFontFromStringreturnsglobalFontunchanged for"Default"(hi_core/hi_core/MainController.cpp~line 2035), so the size argument is dropped and you get the global font at its own height (~14 px). No error, no warning. Every other font name goes throughFont(typeface).withHeight(fontSize). I'd expectglobalFont.withHeight(fontSize)here.3.
g.getStringWidthdoesn't measure the font that was setgetStringWidthdoesn't ask the currentFontfor its width; it looks up a per-character normalised width table (CustomTypeFace::getStringWidthFloat,MainController.h~line 2318) for the current font name, and if the name isn't aloadFontAsfont it falls back todefaultFont's table – then multiplies by the requested size. So with"Default"you get a different typeface's widths at a size that isn't being drawn. In my test the returned width was ~2.5× the rendered width. Combined with 2, both "shift by half the gap" and "measure and left-align" corrections came out wrong until I switched to aloadFontAsfont.Suggestion:
getStringWidthcould just usecurrentFont.getStringWidthFloat(text)(theFontobject is right there insetFontWithSpacing), which would honour size, kerning and the real typeface.Repro – snippet below. Six rows: a centred white bar with
MMMMM"centred" beneath it at increasing spacing, then the last two rows apply the two corrections. SwapFONTto"Default"to see 2 and 3 (text renders ~14 px regardless ofSIZE,+measurerow lands far off).HiseSnippet 2430.3ocsX8taaibDmJI5ZsZu16.5CvT8kRYSq+cxWbsqQtDG4F2KN1vxWR6EDDrhbo3VSsKA4RKqdHE8MnEnen.8S8wnnesuI2KP6av0Y1kThx1W9iAJMLf3ryL672e6v8jTkOOKSk5TqwYyS3N09w0GMWpi1OhIjNG9XmZ+j5Gwxz7TvR5QySXYY7.mZ0t6ulHTas64Xd9uO3QrXlzmujjiyyUBe9SESE5kTS9huTDGe.KfelXZEtG7EG5qj6qhU4n8b25ccRX9mylveFiX6N0cdBKKxo15060se.eK+A7PVP+9a6u01C3C5ELX6s51cPX+t9L1u79r6O1o1GMLPnUoizLMOCU5iTAyGEolIsavyEYhwwb5kdNivc1R1Y+HQbvIkAmLGmZ26jkgp6ZCU+r5GIBDKnuLj8IlEfkRTMnU6NuMSp2GfIUqhIcOqI8o0G4mJRzKWgrmeT8CkXFLjg4lplhkWm67u9o06zANkmjp1AlzNHkM6gwhIRdvY7K0tsa21CZ5yk5TdPyVPPpHTmAOc3AmAyh3RPGwgPkTCQrrFnlPgRYPLWia5lYXRTHm.tYb8AHSuPniFUPqCPT1YGbogjLeIOUhzOf4iAnVsQcQp6Dp9CDRsBTxCkBMnBAFDlxyhfmb3ng.Z3+dtu9WjQbYcTHy3b.SF.9poIhXNoO3XIGRXRdrGDJtfCopYYsggL+H5m6f5MSEKBfTTeL4jXNT33npMNZgvndI007H5oI5cymNkqSE9vj34IQdnZfLQ.eywbVJ4qrBNlChLXpPJlxhoXIalznnx3a49jgE8vLQfNBBDj0DOGFykblNpMbpZFzkB2PY3saoEkEoxiCfXA5n4I6ZzkIiASHeEUIpwRo91+zeEc67IQnxKnsdl3Ov6zGRtzDuNCEOFS.fdlxDrvHSBZDF8hlGGWpTaFUyvvcJYuBkDXIIwBL1spskIYIvXr2FxkAHxBopEw6cHFAL4bIzTlGLg2DLloFqpLbgZA8FToohIQZX70rbWTVbYUXHVW0ph5lxYY4onBI8Mo8DtdjlxMufhxtsnrRdlwZvZQQL4RSXId1jDVOGp2zpsq9vrcKPQXgp2xIK7RvkeIFA7wZVS9EUowf9ZkZpg0k0qt6qSi6r+z.XCXpJOiS8VbrDAK6KLbfMAgXxLaBokEwLrvOhkF.bLbksKPUqT9GqyXomW3P4kUxlVhwJLUYXuciF6iMg3RsmxNmePJ9xB3B2Ac65AeV2ts1sQCDbF26KXoPhLF1CJEiEDbB0T31DoaPQZ5AnXjPHk1XVvsooRFoOn6Jji3TRrY4drf93I1yAHMc4AGzuK8GYDna+s+8+w+4e9mgixQqYLmPBHrmXEdfR.bgfY9IAr7vLO3YGeFz7w3AE4w5lH5lEDB8xo1buMNpySk1L+jX0XVrUk4RphJ.eIcoNvVcjHfIbEFmM84jbmagtH0g0LTOdYWw+9uA+wdC7.oRWk1nC+5gsL3HWqTrLemALReIHJpOleQTQrYwBInY3YDVbv0CDgg7TLSrNDXMRi42FdDkjW1MZvliUpyQWZFllKZXW5YjexujYfZzQpLpqjkgB1tRHEX997DD+mYvsXiQ7RrXGwE0VTODAcNBXO0FCw.QHAEQ5tDyt.ttcigxI3ZsWpb2lcFYDtySEiSYoy6Pzy5LJGAR3SQejE24goBVbasNDKNZZp2HlZhUGKqPO33mclo0buprTkCJ9WvQ+t6Vdz.0gLmh31SCJyWHlL5PtHdq8zSpo75mm0ZwwByhD3AJknHaVTbTEYDU.ANNGba1DMAoRxwC7VZdmd7KFgzeYi09lRqXGnaarsx.lsCfhU77Fuqxz82x6cxT+2GMs0GHSk.1uUlV.C+lFupZF4oO7QCeZQNydrZ0UOc39m85WXVsWuAHRPAVwIHjn9TUtFqjbCyklvqKBy9MMVijaFJfNRjQ8XE.86ZWAyvOoxhOw.EgGCzwD7aGykSzQ3FsFU65JPV6tKHfe0JKChM1nE5qMVyny4HWBXcit2sfVYQzdFAeo3UsKnTx.c3zxEw2nEvpneyWs+P.QWyV4DNfER3.Ce9vS+ckCaHj9w4AzlnKNutDXxpoxYXFqtzL0.ShhbgcRyUNrifTptYsKLQZo8V3Iqa5dnPCo7QECLY.g7qbTt2Bzjh8mz1DJoYA2cInc6CkSvkBwOL3TTb2WNCSC8gMKS63KdXvcC3y8JH4Aa+pVkl.Mm50GgJLON1NulE0zqXjA6TGB8By4J8wtD5gmwG8J84BC7p1996aN2Zs0Dgl4Nf81aYANVWXJLHKb3UmC.TxhI.NeSABJZw0cYAWPeCUwqKmHAS.sH60jMzTQ80Ffwz+zBiYHujIs10Gk2vhGrH5pmsLxRmQMyy1UrI91qPzUZlmlF+6M3+73LdEWpnaeG6.Y1IeJpyLyosX9rHVbXoSzlPRvwryPmdg+XUvdKifVM2BdfovirUDC4c3SFk786JK99Eq2TT5VTPeAKNGKWI20z3XFzkgyJgC3J0hPAcb6JkKE0H85eiEFaadJV5pFbyx1nlnoV96MrN+OeOJ97.bIXCZYhFA9hGs7xAVmCSW8Fz06pYHxkLeEGNOQNZ1ES.5VoIvNrUqcpNMnGjDmmYRQapHaQO2nGqzQ4SlPVmYbwkeRTwfi2P+P2t19gapU1bH.Y3dWCy8UVYppss69101RfAJE+NT7UEeiUvUnmueweC9e44JXS6yTZ9wRWy4KMdSC3pKEFdiqQCKmphi4o23xzMgj91DzUlOcLO0yVptfQ7K+W85D9n2uqSv2N6dEFseZ8wI7h2OPEGPWS.86qe4CNEC+i+5qN7wLMitOhBZHe3.TZAYN0dL+BgO2d6DqU+w7ry0pDCuSSvYdPMT6GnMq9wk2cAUq5HvstQ8xOnv4RmZ0qQWRz7xeX.HQc9Q+kZ1qOxVcST7JnT9QDDMLE+cFhW+RS9j5GoBxiY5UuCG51sJV.yDqbwIz2Ggeafdd0a+5C3hc59VuXm2WS7SqehP6Gcy13ctAaDyQ++vFKtNrOt9P76P70KMv6U+fe6s8tudGaucfuIGwvy+nZimkOcDlo843tKw5mLpL4NTcp88tkkMi3x.yKeG9TrXO58ZEK1qbQmoL+T0q8s8ezEt8CMTPaRZtPx0peD8NzywzSVMNOUDHdsu+pp5ZB1+1J3mcaEbvsUvstsB942VAu+sUvse2BRWO6Cy0po11FGmiNYnADqVsgR5ndS0py+CyHjtwThis image shows the font set to "Default" which exposes the HISE bugs. The font size is ignored (point 2) and the width measurement is way off because it's measuring a different font size (bug 2).
