3x5 Font for those with good eyesight

That’s useful info, but I think my question was a bit vague… Let me restate it:
When passing the ‘Space’ character (ASCII #32), where is the width of that determined? (Sorry if it’s obvious!)

Ah, clearly I misread the first time because I was only skim reading.


All characters that aren’t explicitly handled advance the cursor without drawing anything,
so space is the same as any other unrecognised character.
(Or rather, all unrecognised characters are treated as spaces.)

One man’s ‘obvious’ is another man’s ‘subtle’.

Thanks. That makes complete sense. The 5px ‘space’ is made up of 1px from the past character plus the 3 + 1px of the absent character.

In many of my games, I have modified the library to you a ~ (tilda) to do a half space as the normal space is too much.

1 Like

Would you be open to a PR that adds _spaceWidth as a signed int8, that can contract or expand word spacing?

Word spacing? Do you mean space width … in which case, sure why not.

1 Like

Neat. Should I roll in @Pharap’s hint and make the _x variables into constants with a #define? (Currently the compiler defined constants are directly in Font3x5.cpp and the variables in Font3x5.cpp).

Edit: Trawling GitHub repos, it seems _lineHeight is genuinely adjusted via setHeight. But _letterSpacing (or tracking width) is fixed at 1px.

Don’t use macros for constants. Use constexpr variables instead.

If another library (probably another font library) defines the same macro they’ll conflict with each other.

Also if you were thinking “someone can use #define to change the value before including the library”, that’s not how it works.

If you want someone to be able to change the value without editing the source, you’re better off using templates.

I’m not sure why you’d want a negative value.

Surely that means you’d end up moving backwards and overwriting previously written characters?

That’s what I said earlier:

1 Like

Thanks for the insightful feedback, gratefully received.
I guess I always strive to match the style of the source that I’m contributing to… so will leave it to @filmote whether to change over to constexpr or not.

It was by design, to make text more compact or expanded. After testing I changed the approach to use just a positive integer.

I credited you at the start of the post, you want credit every paragraph !? :wink:

Now that I’m not rushing…

To clarify what I meant by this…

.cpp files are compiled separately, so even if someone tried to redefine some macros before including the library header, the .cpp file won’t see the redefined macros, they’ll only see what the header normally declares.

I think making a header-only library might change this, but Arduino still precompiles libraries where possible, so there’s a chance that that might not make a difference either.

Conversely, I know for definite that templates can’t be precompiled (and can’t be split into .h and .cpp files because the whole definition is needed in the header), so templates are one easy, portable way to inject settings dynamically.

Ideally macros should be reserved for changing behaviour based on the platform, and even then only when that can’t be done reliably with templates or other features.

To demonstrate using templates for settings:
struct DefaultFontSettings
{
	static constexpr uint8_t spaceWidth = 3;
	static constexpr uint8_t characterSpacing = 1;
};

template<typename Settings = DefaultFontSettings>
class Font
{
public:
	static constexpr uint8_t spaceWidth = Settings::spaceWidth;
	static constexpr uint8_t characterSpacing = Settings::characterSpacing;

	// ...
};

using DefaultFont = Font<>;

And then should someone want to use the default settings but with one setting changed:

// Use inheritance to 'inherit' the default settings
struct CustomSettings : DefaultFontSettings
{
	// And override individual settings as you please
	static constexpr uint8_t characterSpacing = 0;
};

(Not that I’m necessarily suggesting that’s what should be done here. I’m merely illustrating what’s possible. Though it might save memory if the ‘settings’ don’t need to be changed at runtime.)

Bowing to other people’s brace and layout styles is one thing, but choice of implementation is another.

If people are aware of the flaws in their chosen method then fair enough, but I’ve worked with enough people who aren’t aware of alternative options to have no qualms about proposing (and justifying) other options.

Because the font overwriting itself looked odd?

Your wording had implied that you’d had to ‘trawl repos’ to find out _letterSpacing wasn’t being modified, I was just pointing out that if that were the case then you needn’t have bothered trawling. :P

The plan was to have a relative adjustment. E.g. space is 4px, the adjustment might be -4px to +8px typically. In reality, it was simpler and more compact to just modify the absolute space width (in this example, 0-12px).

I just checked through how (/if) people were using _lineHeight and the Font resource in general.

1 Like

Ah, that makes more sense. I thought you were talking about the space between characters.

In both cases making the value an unsigned absolute width is certainly the better option.

Does anyone actually set the line height?

I’d be surprised if anyone is actually modifying it,
and even more surprised if they’re doing so more than once in a program.

1 Like

Yes, surprisingly line height is being adjusted.