Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API: Support non-rounded outlines in TTF_SetFontOutline #422

Open
rubenlg opened this issue Oct 21, 2024 · 6 comments
Open

API: Support non-rounded outlines in TTF_SetFontOutline #422

rubenlg opened this issue Oct 21, 2024 · 6 comments
Milestone

Comments

@rubenlg
Copy link

rubenlg commented Oct 21, 2024

TTF_SetFontOutline always produces rounded outlines, which looks great for most fonts, but not for pixel art fonts. Here is an example:
image

It would be great to support non rounded outlines too, configurable with a flag, to get blocky outlines instead in those cases. This is how it should ideally look when the non-ronded flag is ON:
image

As a workaround, the same effect can be achieved by rendering the text 9 times, but SDL_ttf has an opportunity to do it more efficiently by controlling FT_Stroker_LineJoin and FT_Stroker_LineCap when calling FT_Stroker_Set.

An alternative could be to expose functions that allow controlling the line join and line cap of the outline, allowing all the variants supported by the freetype library.

@slouken
Copy link
Collaborator

slouken commented Oct 21, 2024

I think passing through the stroker parameters is reasonable. What are the set of parameters you would need here?

@rubenlg
Copy link
Author

rubenlg commented Oct 21, 2024

That's a good question. I'll try a few combinations with the freetype library directly to understand which combination works best for pixel fonts, and circle back with the results. My suspicion is that FT_STROKER_LINEJOIN_MITER should be enough, but I need to test it.

@rubenlg
Copy link
Author

rubenlg commented Oct 22, 2024

I tried all 12 combinations of linecap and linejoin and none of them render the pixel outline properly. I end up with either round corners or angle corners. I'll have to fall back to rendering the text 9 times instead. I'll close this bug since there isn't much SDL_ttf can do here. Sorry for the noise 😞

@rubenlg rubenlg closed this as completed Oct 22, 2024
@rubenlg
Copy link
Author

rubenlg commented Oct 22, 2024

I just realized I forgot to change the miter parameter when calling FT_Stroker_Set. If I set it correctly, to sqrt(2) (so that all the way up to right angles, you get sharp corners), then it works for all combinations that use either FT_STROKER_LINEJOIN_MITER_VARIABLE or FT_STROKER_LINEJOIN_MITER_FIXED . The linecap doesn't matter, all of them work correctly for pixel fonts.

So this would be the correct code to get pixel fonts rendering sharply:

#define RIGHT_ANGLE_MITER_LIMIT 92682  // sqrt(2) in 16.16 fixed-point format
[...]
FT_Stroker_Set(
    font->stroker, outline * 64,
    FT_STROKER_LINECAP_ROUND, // This one doesn't matter.
    FT_STROKER_LINEJOIN_MITER_FIXED,
    RIGHT_ANGLE_MITER_LIMIT);
[...]

@rubenlg rubenlg reopened this Oct 22, 2024
@slouken slouken added this to the 3.0 milestone Oct 22, 2024
@slouken
Copy link
Collaborator

slouken commented Oct 22, 2024

Interesting, I'll see if I can add something for SDL_ttf 3.0. Thanks!

@rubenlg
Copy link
Author

rubenlg commented Oct 22, 2024

Thanks!

One last thing: I tested these options with non-pixel fonts, and while I know it's mostly a matter of preference, I also prefer the straight corners on HD fonts:

FT_STROKER_LINEJOIN_MITER_FIXED:
image

FT_STROKER_LINEJOIN_ROUND:
image

The rounded version feels a bit less formal to me, which could work well in some contexts, but not for what I need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants