Wagner Barongello 3 days ago
committed by GitHub
parent
commit
41c8b96c8c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
3 changed files with 299 additions and 6 deletions
  1. +70
    -0
      examples/text/text_styled.c
  2. +10
    -6
      src/raylib.h
  3. +219
    -0
      src/rtext.c

+ 70
- 0
examples/text/text_styled.c View File

@ -0,0 +1,70 @@
/*******************************************************************************************
*
* raylib [text] example - Text styled
*
* Example complexity rating: [] 1/4
*
* 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 license that allows static linking with closed source software
*
* Copyright (c) 2025 Wagner Barongello (@SultansOfCode)
*
********************************************************************************************/
#include "raylib.h"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [text] example - text styled");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
Color colors[3] = { RED, GREEN, BLUE };
int colorCount = sizeof(colors) / sizeof(Color);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(SKYBLUE);
DrawTextStyled("This changes the \0032foreground color", 200, 80, 20, colors, colorCount);
DrawTextStyled("This changes the \0042background color", 200, 120, 20, colors, colorCount);
DrawTextStyled("This changes the \0031\0042foreground and background colors", 200, 160, 20, colors, colorCount);
DrawTextStyled("\0031\0042This \015restores the colors to the default ones", 200, 200, 20, colors, colorCount);
DrawTextStyled("\0031\0042This \022inverts\022 the colors", 200, 240, 20, colors, colorCount);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

+ 10
- 6
src/raylib.h View File

@ -1479,16 +1479,20 @@ 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)
// Text font info functions
RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found
RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
RLAPI void SetTextLineSpacing(int spacing); // Set vertical line spacing when drawing with line-breaks
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
RLAPI int MeasureTextStyled(const char *text, int fontSize); // Measure styled string width for default font
RLAPI Vector2 MeasureTextStyledEx(Font font, const char *text, float fontSize, float spacing); // Measure styled string size for Font
RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found
RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
// Text codepoints management functions (unicode characters)
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array

+ 219
- 0
src/rtext.c View File

@ -1202,6 +1202,131 @@ 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 == '\003' || codepoint == '\004')
{
bool isForeground = codepoint == '\003';
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);
}
if (colorBufferIndex > 0)
{
int colorIndex = atoi(&colorBuffer);
if (colorIndex >= 0)
{
if (isForeground)
{
foreground = colorIndex < colorCount ? colors[colorIndex] : defaultForeground;
}
else
{
background = colorIndex < colorCount ? colors[colorIndex] : defaultBackground;
}
}
}
continue;
}
else if (codepoint == '\015') {
foreground = defaultForeground;
background = defaultBackground;
i += codepointByteCount;
continue;
}
else if (codepoint == '\022') {
Color temp = foreground;
foreground = background;
background = temp;
i += codepointByteCount;
continue;
}
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)
{
@ -1338,6 +1463,100 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
return textSize;
}
// Measure styled string width for default font
int MeasureTextStyled(const char *text, int fontSize)
{
Vector2 textSize = { 0.0f, 0.0f };
// Check if default font has been loaded
if (GetFontDefault().texture.id != 0)
{
int defaultFontSize = 10; // Default Font chars height in pixel
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
int spacing = fontSize/defaultFontSize;
textSize = MeasureTextStyledEx(GetFontDefault(), text, (float)fontSize, (float)spacing);
}
return (int)textSize.x;
}
// Measure styled string size for Font
Vector2 MeasureTextStyledEx(Font font, const char *text, float fontSize, float spacing)
{
Vector2 textSize = { 0 };
if ((isGpuReady && (font.texture.id == 0)) ||
(text == NULL) || (text[0] == '\0')) return textSize; // Security check
int size = TextLength(text); // Get size in bytes of text
int tempByteCounter = 0; // Used to count longer text line num chars
int byteCounter = 0;
float textWidth = 0.0f;
float tempTextWidth = 0.0f; // Used to count longer text line width
float textHeight = fontSize;
float scaleFactor = fontSize/(float)font.baseSize;
int letter = 0; // Current character
int index = 0; // Index position in sprite font
for (int i = 0; i < size;)
{
int codepointByteCount = 0;
letter = GetCodepointNext(&text[i], &codepointByteCount);
i += codepointByteCount;
if (letter == '\015' || letter == '\022')
{
continue;
}
else if (letter == '\003' || letter == '\004')
{
letter = GetCodepointNext(&text[i], &codepointByteCount);
while (letter >= '0' && letter <= '9' && i < size)
{
i += codepointByteCount;
letter = GetCodepointNext(&text[i], &codepointByteCount);
}
continue;
}
byteCounter++;
if (letter != '\n')
{
index = GetGlyphIndex(font, letter);
if (font.glyphs[index].advanceX > 0) textWidth += font.glyphs[index].advanceX;
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);
}
else
{
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
byteCounter = 0;
textWidth = 0;
// NOTE: Line spacing is a global variable, use SetTextLineSpacing() to setup
textHeight += (fontSize + textLineSpacing);
}
if (tempByteCounter < byteCounter) tempByteCounter = byteCounter;
}
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
textSize.x = tempTextWidth*scaleFactor + (float)((tempByteCounter - 1)*spacing);
textSize.y = textHeight;
return textSize;
}
// Get index position for a unicode character on font
// NOTE: If codepoint is not found in the font it fallbacks to '?'
int GetGlyphIndex(Font font, int codepoint)

Loading…
Cancel
Save