diff --git a/examples/text/text_font_size_metric.c b/examples/text/text_font_size_metric.c new file mode 100644 index 000000000..6059dbf42 --- /dev/null +++ b/examples/text/text_font_size_metric.c @@ -0,0 +1,98 @@ +/******************************************************************************************* +* +* raylib [text] example - font scaling metrics +* +* Example originally created with raylib 5.5, last time updated with raylib 5.5 +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like open-source license that allows free use in commercial applications. +* +********************************************************************************************/ + +#include "raylib.h" +#include + +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 960; + const int screenHeight = 540; + + InitWindow(screenWidth, screenHeight, "raylib [text] example - font scaling metrics"); + + // Some fonts need to be loaded using the Em Box scaling metric. + // Loading pixel fonts with default metric can cause blurry rendering when drawn to render texture. + SetFontSizeMetric(FONT_SIZE_METRIC_EM_BOX); + + Font fontM5x7 = LoadFontEx("resources/m5x7.ttf", 16, NULL, 0); + Font fontM6x11 = LoadFontEx("resources/m6x11.ttf", 16, NULL, 0); + Font fontMonogram = LoadFontEx("resources/monogram.ttf", 16, NULL, 0); + + // Other fonts can use the default Ascent scaling metric. + SetFontSizeMetric(FONT_SIZE_METRIC_ASCENT); + Font fontAutography = LoadFontEx("resources/autography.ttf", 64, NULL, 0); + Font fontCreatorGenius = LoadFontEx("resources/creator_genius.ttf", 32, NULL, 0); + Font fontPixelSimpel = LoadFontEx("resources/pixel_simpel.ttf", 32, NULL, 0); + + // Set up Render Texture + RenderTexture2D target = LoadRenderTexture(480, 270); + SetTextureFilter(target.texture, TEXTURE_FILTER_POINT); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update your variables here + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginTextureMode(target); + ClearBackground(BLACK); + + // Render fonts with Em Box scaling metric + DrawTextEx(fontM5x7, "m5x7", (Vector2){ 50, 50 }, 32.0f, 2, WHITE); + DrawTextEx(fontM6x11, "m6x11", (Vector2){ 50, 100 }, 32.0f, 2, WHITE); + DrawTextEx(fontMonogram, "monogram", (Vector2){ 50, 150 }, 32.0f, 2, WHITE); + + // Render fonts with Ascent scaling metric + DrawTextEx(fontAutography, "Autography", (Vector2){ 200, 50 }, 64.0f, 2, WHITE); + DrawTextEx(fontCreatorGenius, "Creator Genius", (Vector2){ 200, 100 }, 32.0f, 2, WHITE); + DrawTextEx(fontPixelSimpel, "Pixel Simpel", (Vector2){ 200, 150 }, 32.0f, 2, WHITE); + EndTextureMode(); + + BeginDrawing(); + ClearBackground(BLACK); + DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE); + + DrawLine(180, 0, 180, 250, WHITE); + DrawLine(50, 30, 450, 30, WHITE); + + DrawText("Em Box", 50, 0, 32, WHITE); + DrawText("Ascent", 200, 0, 32, WHITE); + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadFont(fontM5x7); + UnloadFont(fontM6x11); + UnloadFont(fontMonogram); + + UnloadFont(fontAutography); + UnloadFont(fontCreatorGenius); + UnloadFont(fontPixelSimpel); + + UnloadRenderTexture(target); + + CloseWindow(); + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/src/raylib.h b/src/raylib.h index 154158131..1d38a49d9 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1756,3 +1756,4 @@ RLAPI void DetachAudioMixedProcessor(AudioCallback processor); // Detach audio s #endif #endif // RAYLIB_H +RLAPI void SetFontSizeMetric(int metric); diff --git a/src/rtext.c b/src/rtext.c index 0431a6f57..7982305b7 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -130,6 +130,9 @@ static Font defaultFont = { 0 }; // Text vertical line spacing in pixels (between lines) static int textLineSpacing = 2; +// The desired font scaling metric to use for calculating the font's ascent height +static int fontSizeMetric = FONT_SIZE_METRIC_ASCENT; + //---------------------------------------------------------------------------------- // Other Modules Functions Declaration (required by text) //---------------------------------------------------------------------------------- @@ -639,8 +642,21 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz if (stbtt_InitFont(&fontInfo, (unsigned char *)fileData, 0)) // Initialize font for data reading { - // Calculate font scale factor - float scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize); + // Calculate font scale factor using desired font size metric + float scaleFactor = 0.0f; + if (fontSizeMetric == FONT_SIZE_METRIC_ASCENT) + { + scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize); + } + else if (fontSizeMetric == FONT_SIZE_METRIC_EM_BOX) + { + scaleFactor = stbtt_ScaleForMappingEmToPixels(&fontInfo, (float)fontSize); + } + else + { + TRACELOG(LOG_WARNING, "FONT: Invalid font size metric [%d], assuming FONT_METRIC_ASCENT", fontSizeMetric); + scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize); + } // Calculate font basic metrics // NOTE: ascent is equivalent to font baseline @@ -2409,6 +2425,18 @@ const char *CodepointToUTF8(int codepoint, int *utf8Size) return utf8; } +// Allows the user to choose which font size metric they want (either FONT_SIZE_METRIC_ASCENT or FONT_SIZE_METRIC_EM_BOX) +void SetFontSizeMetric(int metric) +{ + if ((metric != FONT_SIZE_METRIC_ASCENT) && (metric != FONT_SIZE_METRIC_EM_BOX)) + { + TRACELOG(LOG_WARNING, "TEXT: Attempting to set font size metric to invalid enum [%d]", metric); + return; + } + + fontSizeMetric = metric; +} + // Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found // When an invalid UTF-8 byte is encountered, exit as soon as possible and a '?'(0x3f) codepoint is returned // Total number of bytes processed are returned as a parameter