Merge 0f5af53166
into 5f497d0687
This commit is contained in:
commit
f122fa9400
3 changed files with 299 additions and 6 deletions
70
examples/text/text_styled.c
Normal file
70
examples/text/text_styled.c
Normal 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;
|
||||
}
|
16
src/raylib.h
16
src/raylib.h
|
@ -1481,16 +1481,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
src/rtext.c
219
src/rtext.c
|
@ -1220,6 +1220,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)
|
||||
{
|
||||
|
@ -1356,6 +1481,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…
Add table
Add a link
Reference in a new issue