Repository navigation
Adding fixed width font support to font groups #139
Description
Hi, I read the contributing guidelines and wondered if you would be open to a PR adding fixed-width font group support to the fontgenerator tool? I'm proposing a new argument that forces a specific width by centering the character (padding or cropping as needed). Example: -gfw 32 0 5 for a space character that's 5 pixels wide or updating the existing font group argument to accept an optional, fixed width. Example: -g 32 0 5.
I want to solve a spacing issue with the string "Cookies 325 12 mins". If I use the old font format to produce a fixed-width font, characters are expanded significantly further than necessary. I'm using canvas.getFont().setSpacing(0); for this example:
If I use the new font format to produce a variable-width font whose characters are not expanded in size, the "Cookies 325 12 mins" string is hard to read due to the space character being only 1 pixel wide. I'm using canvas.getFont().setSpacing(1); here:
So I made a change to the font generator to allow specifying a minimum character width and produced an easier to read, no wasted space result. I'm using the samecanvas.getFont().setSpacing(1); as above for this example:
After thinking about the minimum width argument I added, I thought it would be more useful to allow specifying an exact width for each font group since it would provide a lot more flexibility. Narrow characters like spaces, colons, and periods could be given more padding compared to other characters and also someone could use the feature to create a fixed-width font while using the font group support of the new font format. So ultimately something like this would be possible:
set "PYTHON=C:\Apps\WPy64-3.15.0.1\python\python.exe"
set "FONT_SCRIPT=C:\Google Drive\Projects\Common\Arduino\libraries\lcdgfx\tools\fontgenerator.py"
set "OUT_DIR=C:\Google Drive\Projects\NRFMan\Code\NRFMan\fonts"
rem Character groups with fixed width. The space and colon would be expanded (while remaining centered)
rem while the underscore would be trimmed (both left and right sides would be trimmed, keeping it centered).
set "SPACE=-gfw 32 0 5"
set "COLON=-gfw 58 0 3"
set "UNDERSCORE=-gfw 95 0 5"
rem Character groups with the default widths.
set "DIGITS=-g 48 9"
set "UPPERCASE_LETTERS=-g 65 25"
set "LOWERCASE_LETTERS=-g 97 25"
set "FONT_GROUPS=%SPACE% %COLON% %UNDERSCORE% %DIGITS% %UPPERCASE_LETTERS% %LOWERCASE_LETTERS%"
set FONT=consolas
set SIZE=10
"%PYTHON%" "%FONT_SCRIPT%" --ttf "%OUT_DIR%\%FONT%.ttf" -s %SIZE% %FONT_GROUPS% -f new > "%OUT_DIR%\%FONT%_%SIZE%.h"So that's the idea and I wondered if I should work on a PR. Or maybe I've totally missed something and you have an easier solution.
BTW you've probably heard this a zillion times but your driver is incredible: double-buffering support yet uses hundreds of bytes less program storage space compared to two other libraries I tried, absolutely amazing!
Activity
lexus2k commentedon Aug 2, 2026
Thanks for the detailed write-up (and the kind words!) — the before/after screenshots made the problem very clear.
I went ahead and implemented this. Rather than a minimum width (
-mw) or a separate-gfwflag, I took your second idea: an optional 3rd argument on the existing-g, since it's the most flexible and adds no new flag:It forces every char in that group to an exact pixel width, keeping the glyph centered — narrow chars are padded with blank columns on both sides, wider chars are cropped equally. The width lands in the new-format jump table (which already stores per-char width), so it's free at runtime and works together with
setSpacing().Your
Cookies 325 12 minscase becomes, for example:./fontgenerator.py --ttf consolas.ttf -s 10 \ -g 32 0 5 \ # space -> 5 px -g 58 0 3 \ # colon -> 3 px -g 48 9 -g 65 25 -g 97 25 \ # digits + upper + lower, natural width -f new > consolas_10.cppA couple of notes:
-fw, another-g, …) is never mistaken for a width.-fw, which forces one global width onto every char.It's up as PR #141 and will land in the next release. I also converted the old
tools/font_format.txtinto a friendlierdocs/font_format.mdthat documents this.If you get a chance to try it against your real strings, I'd love to hear whether the spacing comes out how you want — no need for a separate PR, but feedback very welcome.
Merge pull request #141 from lexus2k/feature/per-group-font-width
dparson55 commentedon Aug 3, 2026
Absolutely awesome, thanks for implementing this! I gave the new features a shot and the resulting text spacing for my project is perfect. The warning about cropping (and not failing) is also perfect for my use case as well, I'm purposefully wanting to make spaces and underscores the same width and want to crop the underscore rather than expand the space.
The new start and end ascii char support is really nice and helped clean up some of the variables in the font generation script of my project, I could even select single characters like the COLON and UNDERSCORE which was great. PERCENT didn't work and I'm not sure about SPACE but this is no big deal at all, these are just weird groups I have to help optimize program space.
The only little thing is when the name of the font gets changed due to the changed size. As I'm experimenting with different widths for the colon, I have to go check the generated font name and do a replace-all within the code. Not a big deal but it makes testing different widths slower. I imagine changing the generated name to be based on the -s argument would be a problem for other users.
So many thanks for this incredible library and all the font features you've added!