Add and optimize text rendering functions

New functions operate on two char*'s in the event strings are not null terminated
* MeasureTextViewEx
* MeasureTextView
* DrawTextViewEx
* DrawTextViewPro

Rewrote some conditional operations as math in DrawTexturePro to try to get compiler
to generate branchless code even in debug mode.
This commit is contained in:
Andersama 2023-04-10 15:49:30 -07:00
parent 796d96408b
commit da9c3b379e
3 changed files with 82 additions and 29 deletions

View File

@ -1362,16 +1362,22 @@ RLAPI void UnloadFont(Font font);
RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success
// Text drawing functions // Text drawing functions
RLAPI void DrawTextViewEx(Font font, const char* text, const char* textEnd, Vector2 position, float fontSize, float spacing, Color tint);
RLAPI void DrawFPS(int posX, int posY); // Draw current FPS RLAPI void DrawFPS(int posX, int posY); // Draw current FPS
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) 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 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 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 DrawTextViewPro(Font font, const char* text, const char* textEnd, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint);
RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) 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 count, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) RLAPI void DrawTextCodepoints(Font font, const int *codepoints, int count, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint)
// Text font info functions // Text font info functions
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font 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 Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
RLAPI int MeasureTextView(const char* text, const char* textEnd, int fontSize); // Measure string width for default font
RLAPI Vector2 MeasureTextViewEx(Font font, const char* text, const char* textEnd, 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 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 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 Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found

View File

@ -1015,8 +1015,7 @@ void DrawFPS(int posX, int posY)
Color color = LIME; // Good FPS Color color = LIME; // Good FPS
int fps = GetFPS(); int fps = GetFPS();
if ((fps < 30) && (fps >= 15)) color = ORANGE; // Warning FPS color = (fps >= 30) ? color : (fps >= 15) ? ORANGE : RED;
else if (fps < 15) color = RED; // Low FPS
DrawText(TextFormat("%2i FPS", GetFPS()), posX, posY, 20, color); DrawText(TextFormat("%2i FPS", GetFPS()), posX, posY, 20, color);
} }
@ -1039,20 +1038,18 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
} }
} }
// Draw text using Font void DrawTextViewEx(Font font, const char* text, const char* textEnd, Vector2 position, float fontSize, float spacing, Color tint)
// NOTE: chars spacing is NOT proportional to fontSize
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint)
{ {
if (font.texture.id == 0) font = GetFontDefault(); // Security check in case of not valid font if (font.texture.id == 0) font = GetFontDefault(); // Security check in case of not valid font
int size = TextLength(text); // Total size in bytes of the text, scanned by codepoints in loop int bytes = textEnd - text; // Total size in bytes of the text, scanned by codepoints in loop
int textOffsetY = 0; // Offset between lines (on linebreak '\n') int textOffsetY = 0; // Offset between lines (on linebreak '\n')
float textOffsetX = 0.0f; // Offset X to next character to draw float textOffsetX = 0.0f; // Offset X to next character to draw
float scaleFactor = fontSize / font.baseSize; // Character quad scaling factor float scaleFactor = fontSize / font.baseSize; // Character quad scaling factor
for (int i = 0; i < size;) for (int i = 0; i < bytes;)
{ {
// Get next codepoint from byte string and glyph index in font // Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0; int codepointByteCount = 0;
@ -1085,6 +1082,28 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
} }
} }
// Draw text using Font and pro parameters (rotation)
void DrawTextViewPro(Font font, const char* text, const char* textEnd, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint)
{
rlPushMatrix();
rlTranslatef(position.x, position.y, 0.0f);
rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
rlTranslatef(-origin.x, -origin.y, 0.0f);
DrawTextViewEx(font, text, textEnd, (Vector2) { 0.0f, 0.0f }, fontSize, spacing, tint);
rlPopMatrix();
}
// Draw text using Font
// NOTE: chars spacing is NOT proportional to fontSize
void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint)
{
int size = TextLength(text); // Total size in bytes of the text, scanned by codepoints in loop
DrawTextViewEx(font, text, text + size, position, fontSize, spacing, tint);
}
// Draw text using Font and pro parameters (rotation) // Draw text using Font and pro parameters (rotation)
void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint) void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint)
{ {
@ -1173,14 +1192,32 @@ int MeasureText(const char *text, int fontSize)
return (int)textSize.x; return (int)textSize.x;
} }
// Measure string width for default font
int MeasureTextView(const char* text, const char* textEnd, 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 = MeasureTextViewEx(GetFontDefault(), text, textEnd, (float)fontSize, (float)spacing);
}
return (int)textSize.x;
}
// Measure string size for Font // Measure string size for Font
Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing) Vector2 MeasureTextViewEx(Font font, const char* text, const char* textEnd, float fontSize, float spacing)
{ {
Vector2 textSize = { 0 }; Vector2 textSize = { 0 };
if ((font.texture.id == 0) || (text == NULL)) return textSize; if ((font.texture.id == 0) || (text == NULL)) return textSize;
int size = TextLength(text); // Get size in bytes of text //int size = TextLength(text);
int size = textEnd - text; // Get size in bytes of text
int tempByteCounter = 0; // Used to count longer text line num chars int tempByteCounter = 0; // Used to count longer text line num chars
int byteCounter = 0; int byteCounter = 0;
@ -1229,6 +1266,11 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
return textSize; return textSize;
} }
Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing)
{
int size = TextLength(text); // Get size in bytes of text
return MeasureTextViewEx(font, text, text + size, fontSize, spacing);
}
// Get index position for a unicode character on font // Get index position for a unicode character on font
// NOTE: If codepoint is not found in the font it fallbacks to '?' // NOTE: If codepoint is not found in the font it fallbacks to '?'

View File

@ -3546,10 +3546,10 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
float width = (float)texture.width; float width = (float)texture.width;
float height = (float)texture.height; float height = (float)texture.height;
bool flipX = false; bool flipX = source.width < 0;
if (source.width < 0) { flipX = true; source.width *= -1; } source.width = flipX ? source.width * -1 : source.width;
if (source.height < 0) source.y -= source.height; source.y -= (source.height < 0) ? source.height : 0.0f;
Vector2 topLeft = { 0 }; Vector2 topLeft = { 0 };
Vector2 topRight = { 0 }; Vector2 topRight = { 0 };
@ -3594,24 +3594,29 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
rlColor4ub(tint.r, tint.g, tint.b, tint.a); rlColor4ub(tint.r, tint.g, tint.b, tint.a);
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
float right_edge_x = (source.x + source.width) / width;
float left_edge_x = source.x / width;
float bottom_edge_y = (source.y + source.height) / height;
float top_edge_y = source.y / height;
// Should communicate the non-branchy version of this expression to the compiler
float l_edge = (flipX * right_edge_x) + (!flipX * left_edge_x);//flipX ? right_edge_x : left_edge_x;
float r_edge = (flipX * left_edge_x) + (!flipX * right_edge_x);//flipX ? left_edge_x : right_edge_x;
// Top-left corner for texture and quad // Top-left corner for texture and quad
if (flipX) rlTexCoord2f((source.x + source.width)/width, source.y/height); rlTexCoord2f(l_edge, top_edge_y);
else rlTexCoord2f(source.x/width, source.y/height);
rlVertex2f(topLeft.x, topLeft.y); rlVertex2f(topLeft.x, topLeft.y);
// Bottom-left corner for texture and quad // Bottom-left corner for texture and quad
if (flipX) rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height); rlTexCoord2f(l_edge, bottom_edge_y);
else rlTexCoord2f(source.x/width, (source.y + source.height)/height);
rlVertex2f(bottomLeft.x, bottomLeft.y); rlVertex2f(bottomLeft.x, bottomLeft.y);
// Bottom-right corner for texture and quad // Bottom-right corner for texture and quad
if (flipX) rlTexCoord2f(source.x/width, (source.y + source.height)/height); rlTexCoord2f(r_edge, bottom_edge_y);
else rlTexCoord2f((source.x + source.width)/width, (source.y + source.height)/height);
rlVertex2f(bottomRight.x, bottomRight.y); rlVertex2f(bottomRight.x, bottomRight.y);
// Top-right corner for texture and quad // Top-right corner for texture and quad
if (flipX) rlTexCoord2f(source.x/width, source.y/height); rlTexCoord2f(r_edge, top_edge_y);
else rlTexCoord2f((source.x + source.width)/width, source.y/height);
rlVertex2f(topRight.x, topRight.y); rlVertex2f(topRight.x, topRight.y);
rlEnd(); rlEnd();