From 7d2fa7eb8f62d0ecc0da8fcdabc901a6409a48df Mon Sep 17 00:00:00 2001 From: SultansOfCode Date: Thu, 6 Mar 2025 20:28:58 -0300 Subject: [PATCH] Adding DrawTextStyled and DrawTextStyledEx to draw styled texts --- src/raylib.h | 2 + src/rtext.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/src/raylib.h b/src/raylib.h index 7919db775..42b9b0fc3 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1479,6 +1479,8 @@ RLAPI void DrawFPS(int posX, int posY); RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation) +RLAPI void DrawTextStyled(const char *text, int posX, int posY, int fontSize, const Color *colors, int colorCount); // Draw styled text (using default font) +RLAPI void DrawTextStyledEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, const Color *colors, int colorCount); // Draw styled text using font and additional parameters RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) diff --git a/src/rtext.c b/src/rtext.c index 0d06caa9a..1979dc81b 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1202,6 +1202,143 @@ void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, rlPopMatrix(); } +// Draw styled text +void DrawTextStyled(const char *text, int posX, int posY, int fontSize, const Color *colors, int colorCount) +{ + if (GetFontDefault().texture.id != 0) + { + Vector2 position = { (float)posX, (float)posY }; + + int defaultFontSize = 10; + if (fontSize < defaultFontSize) fontSize = defaultFontSize; + int spacing = fontSize/defaultFontSize; + + DrawTextStyledEx(GetFontDefault(), text, position, (float)fontSize, (float)spacing, colors, colorCount); + } +} + +// Draw styled text using Font +void DrawTextStyledEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, const Color *colors, int colorCount) +{ + if (font.texture.id == 0) font = GetFontDefault(); + + int size = TextLength(text); + + Color defaultForeground = colorCount > 0 ? colors[0] : BLACK; + Color defaultBackground = { 0, 0, 0, 0 }; + + Color foreground = defaultForeground; + Color background = defaultBackground; + + float textOffsetY = 0.0f; + float textOffsetX = 0.0f; + + float scaleFactor = fontSize/font.baseSize; + + for (int i = 0; i < size;) + { + int codepointByteCount = 0; + int codepoint = GetCodepointNext(&text[i], &codepointByteCount); + + if (codepoint == '\n') + { + textOffsetY += (fontSize + textLineSpacing); + textOffsetX = 0.0f; + } + else + { + if (codepoint == '\3') { + char colorBuffer[16] = { 0 }; + int colorBufferIndex = 0; + + i += codepointByteCount; + + codepoint = GetCodepointNext(&text[i], &codepointByteCount); + + while (codepoint >= '0' && codepoint <= '9' && i < size && colorBufferIndex < sizeof(colorBuffer) - 1) { + colorBuffer[colorBufferIndex++] = codepoint; + + i += codepointByteCount; + + codepoint = GetCodepointNext(&text[i], &codepointByteCount); + } + + int colorIndex = atoi(&colorBuffer); + + foreground = colorIndex < colorCount ? colors[colorIndex] : defaultForeground; + + if (codepoint == ',' && i + codepointByteCount < size) { + int nextCodepointByteCount = 0; + int nextI = i + codepointByteCount; + int nextCodepoint = GetCodepointNext(&text[nextI], &nextCodepointByteCount); + + if (nextCodepoint >= '0' && nextCodepoint <= '9') { + memset(colorBuffer, 0, sizeof(colorBuffer)); + + colorBufferIndex = 0; + + i += codepointByteCount; + + codepoint = GetCodepointNext(&text[i], &codepointByteCount); + + while (codepoint >= '0' && codepoint <= '9' && i < size && colorBufferIndex < sizeof(colorBuffer) - 1) { + colorBuffer[colorBufferIndex++] = codepoint; + + i += codepointByteCount; + + codepoint = GetCodepointNext(&text[i], &codepointByteCount); + } + + colorIndex = atoi(&colorBuffer); + + background = colorIndex < colorCount ? colors[colorIndex] : defaultBackground; + } + } + } + else if (codepoint == '\15') { + foreground = defaultForeground; + background = defaultBackground; + + i += codepointByteCount; + + codepoint = GetCodepointNext(&text[i], &codepointByteCount); + } + else if (codepoint == '\22') { + Color temp = foreground; + + foreground = background; + background = temp; + + i += codepointByteCount; + + codepoint = GetCodepointNext(&text[i], &codepointByteCount); + } + + if (i >= size) break; + + int index = GetGlyphIndex(font, codepoint); + float increaseX = 0.0f; + + if (font.glyphs[index].advanceX == 0) increaseX = ((float)font.recs[index].width*scaleFactor + spacing); + else increaseX += ((float)font.glyphs[index].advanceX*scaleFactor + spacing); + + if (background.a > 0) + { + DrawRectangle(position.x + textOffsetX, position.y + textOffsetY, increaseX, fontSize + textLineSpacing, background); + } + + if ((codepoint != ' ') && (codepoint != '\t')) + { + DrawTextCodepoint(font, codepoint, (Vector2){ position.x + textOffsetX, position.y + textOffsetY }, fontSize, foreground); + } + + textOffsetX += increaseX; + } + + i += codepointByteCount; + } +} + // Draw one character (codepoint) void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint) {