WARNING: REMOVED: DrawTextRec() and DrawTextRecEx()
- DrawTextRec() and DrawTextRecEx() have been moved to example, those functions could be very specific depending on user needs so it's better to give the user the full source in case of special requirements instead of allowing a function with +10 input parameters.
This commit is contained in:
parent
0ba49cce45
commit
5a259fa10f
4 changed files with 290 additions and 136 deletions
|
@ -13,6 +13,10 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
|
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
|
||||||
|
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
|
||||||
|
|
||||||
|
// Main entry point
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
|
@ -120,3 +124,143 @@ tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet ris
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Module functions definition
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw text using font inside rectangle limits
|
||||||
|
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint)
|
||||||
|
{
|
||||||
|
DrawTextRecEx(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw text using font inside rectangle limits with support for text selection
|
||||||
|
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
|
||||||
|
{
|
||||||
|
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
||||||
|
|
||||||
|
float textOffsetY = 0; // Offset between lines (on line break '\n')
|
||||||
|
float textOffsetX = 0.0f; // Offset X to next character to draw
|
||||||
|
|
||||||
|
float scaleFactor = fontSize/(float)font.baseSize; // Character rectangle scaling factor
|
||||||
|
|
||||||
|
// Word/character wrapping mechanism variables
|
||||||
|
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
|
||||||
|
int state = wordWrap? MEASURE_STATE : DRAW_STATE;
|
||||||
|
|
||||||
|
int startLine = -1; // Index where to begin drawing (where a line begins)
|
||||||
|
int endLine = -1; // Index where to stop drawing (where a line ends)
|
||||||
|
int lastk = -1; // Holds last value of the character position
|
||||||
|
|
||||||
|
for (int i = 0, k = 0; i < length; i++, k++)
|
||||||
|
{
|
||||||
|
// Get next codepoint from byte string and glyph index in font
|
||||||
|
int codepointByteCount = 0;
|
||||||
|
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||||
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
|
||||||
|
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
||||||
|
if (codepoint == 0x3f) codepointByteCount = 1;
|
||||||
|
i += (codepointByteCount - 1);
|
||||||
|
|
||||||
|
float glyphWidth = 0;
|
||||||
|
if (codepoint != '\n')
|
||||||
|
{
|
||||||
|
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
|
||||||
|
|
||||||
|
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
|
||||||
|
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
|
||||||
|
// and change states again and again recursively until the end of the text (or until we get outside of the container).
|
||||||
|
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
|
||||||
|
// and begin drawing on the next line before we can get outside the container.
|
||||||
|
if (state == MEASURE_STATE)
|
||||||
|
{
|
||||||
|
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
|
||||||
|
// Ref: http://jkorpela.fi/chars/spaces.html
|
||||||
|
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
|
||||||
|
|
||||||
|
if ((textOffsetX + glyphWidth) > rec.width)
|
||||||
|
{
|
||||||
|
endLine = (endLine < 1)? i : endLine;
|
||||||
|
if (i == endLine) endLine -= codepointByteCount;
|
||||||
|
if ((startLine + codepointByteCount) == endLine) endLine = (i - codepointByteCount);
|
||||||
|
|
||||||
|
state = !state;
|
||||||
|
}
|
||||||
|
else if ((i + 1) == length)
|
||||||
|
{
|
||||||
|
endLine = i;
|
||||||
|
state = !state;
|
||||||
|
}
|
||||||
|
else if (codepoint == '\n') state = !state;
|
||||||
|
|
||||||
|
if (state == DRAW_STATE)
|
||||||
|
{
|
||||||
|
textOffsetX = 0;
|
||||||
|
i = startLine;
|
||||||
|
glyphWidth = 0;
|
||||||
|
|
||||||
|
// Save character position when we switch states
|
||||||
|
int tmp = lastk;
|
||||||
|
lastk = k - 1;
|
||||||
|
k = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (codepoint == '\n')
|
||||||
|
{
|
||||||
|
if (!wordWrap)
|
||||||
|
{
|
||||||
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
|
textOffsetX = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
|
||||||
|
{
|
||||||
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
|
textOffsetX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When text overflows rectangle height limit, just stop drawing
|
||||||
|
if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break;
|
||||||
|
|
||||||
|
// Draw selection background
|
||||||
|
bool isGlyphSelected = false;
|
||||||
|
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
|
||||||
|
{
|
||||||
|
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
|
||||||
|
isGlyphSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw current character glyph
|
||||||
|
if ((codepoint != ' ') && (codepoint != '\t'))
|
||||||
|
{
|
||||||
|
DrawTextCodepoint(font, codepoint, (Vector2){ rec.x + textOffsetX, rec.y + textOffsetY }, fontSize, isGlyphSelected? selectTint : tint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wordWrap && (i == endLine))
|
||||||
|
{
|
||||||
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
|
textOffsetX = 0;
|
||||||
|
startLine = endLine;
|
||||||
|
endLine = -1;
|
||||||
|
glyphWidth = 0;
|
||||||
|
selectStart += lastk - k;
|
||||||
|
k = lastk;
|
||||||
|
|
||||||
|
state = !state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textOffsetX += glyphWidth;
|
||||||
|
}
|
||||||
|
}
|
|
@ -133,6 +133,9 @@ struct {
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
static void RandomizeEmoji(void); // Fills the emoji array with random emojis
|
static void RandomizeEmoji(void); // Fills the emoji array with random emojis
|
||||||
|
|
||||||
|
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
|
||||||
|
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
// Global variables
|
// Global variables
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
@ -145,6 +148,9 @@ struct {
|
||||||
|
|
||||||
static int hovered = -1, selected = -1;
|
static int hovered = -1, selected = -1;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Main entry point
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
|
@ -317,3 +323,143 @@ static void RandomizeEmoji(void)
|
||||||
emoji[i].message = GetRandomValue(0, SIZEOF(messages) - 1);
|
emoji[i].message = GetRandomValue(0, SIZEOF(messages) - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Module functions definition
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw text using font inside rectangle limits
|
||||||
|
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint)
|
||||||
|
{
|
||||||
|
DrawTextRecEx(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw text using font inside rectangle limits with support for text selection
|
||||||
|
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
|
||||||
|
{
|
||||||
|
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
||||||
|
|
||||||
|
float textOffsetY = 0; // Offset between lines (on line break '\n')
|
||||||
|
float textOffsetX = 0.0f; // Offset X to next character to draw
|
||||||
|
|
||||||
|
float scaleFactor = fontSize/(float)font.baseSize; // Character rectangle scaling factor
|
||||||
|
|
||||||
|
// Word/character wrapping mechanism variables
|
||||||
|
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
|
||||||
|
int state = wordWrap? MEASURE_STATE : DRAW_STATE;
|
||||||
|
|
||||||
|
int startLine = -1; // Index where to begin drawing (where a line begins)
|
||||||
|
int endLine = -1; // Index where to stop drawing (where a line ends)
|
||||||
|
int lastk = -1; // Holds last value of the character position
|
||||||
|
|
||||||
|
for (int i = 0, k = 0; i < length; i++, k++)
|
||||||
|
{
|
||||||
|
// Get next codepoint from byte string and glyph index in font
|
||||||
|
int codepointByteCount = 0;
|
||||||
|
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||||
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
|
||||||
|
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
||||||
|
if (codepoint == 0x3f) codepointByteCount = 1;
|
||||||
|
i += (codepointByteCount - 1);
|
||||||
|
|
||||||
|
float glyphWidth = 0;
|
||||||
|
if (codepoint != '\n')
|
||||||
|
{
|
||||||
|
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
|
||||||
|
|
||||||
|
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
|
||||||
|
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
|
||||||
|
// and change states again and again recursively until the end of the text (or until we get outside of the container).
|
||||||
|
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
|
||||||
|
// and begin drawing on the next line before we can get outside the container.
|
||||||
|
if (state == MEASURE_STATE)
|
||||||
|
{
|
||||||
|
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
|
||||||
|
// Ref: http://jkorpela.fi/chars/spaces.html
|
||||||
|
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
|
||||||
|
|
||||||
|
if ((textOffsetX + glyphWidth) > rec.width)
|
||||||
|
{
|
||||||
|
endLine = (endLine < 1)? i : endLine;
|
||||||
|
if (i == endLine) endLine -= codepointByteCount;
|
||||||
|
if ((startLine + codepointByteCount) == endLine) endLine = (i - codepointByteCount);
|
||||||
|
|
||||||
|
state = !state;
|
||||||
|
}
|
||||||
|
else if ((i + 1) == length)
|
||||||
|
{
|
||||||
|
endLine = i;
|
||||||
|
state = !state;
|
||||||
|
}
|
||||||
|
else if (codepoint == '\n') state = !state;
|
||||||
|
|
||||||
|
if (state == DRAW_STATE)
|
||||||
|
{
|
||||||
|
textOffsetX = 0;
|
||||||
|
i = startLine;
|
||||||
|
glyphWidth = 0;
|
||||||
|
|
||||||
|
// Save character position when we switch states
|
||||||
|
int tmp = lastk;
|
||||||
|
lastk = k - 1;
|
||||||
|
k = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (codepoint == '\n')
|
||||||
|
{
|
||||||
|
if (!wordWrap)
|
||||||
|
{
|
||||||
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
|
textOffsetX = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
|
||||||
|
{
|
||||||
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
|
textOffsetX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When text overflows rectangle height limit, just stop drawing
|
||||||
|
if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break;
|
||||||
|
|
||||||
|
// Draw selection background
|
||||||
|
bool isGlyphSelected = false;
|
||||||
|
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
|
||||||
|
{
|
||||||
|
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
|
||||||
|
isGlyphSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw current character glyph
|
||||||
|
if ((codepoint != ' ') && (codepoint != '\t'))
|
||||||
|
{
|
||||||
|
DrawTextCodepoint(font, codepoint, (Vector2){ rec.x + textOffsetX, rec.y + textOffsetY }, fontSize, isGlyphSelected? selectTint : tint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wordWrap && (i == endLine))
|
||||||
|
{
|
||||||
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
|
textOffsetX = 0;
|
||||||
|
startLine = endLine;
|
||||||
|
endLine = -1;
|
||||||
|
glyphWidth = 0;
|
||||||
|
selectStart += lastk - k;
|
||||||
|
k = lastk;
|
||||||
|
|
||||||
|
state = !state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textOffsetX += glyphWidth;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1329,9 +1329,6 @@ RLAPI void UnloadFont(Font font);
|
||||||
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);
|
|
||||||
RLAPI void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
|
|
||||||
RLAPI void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
|
|
||||||
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)
|
||||||
|
|
||||||
// Text misc. functions
|
// Text misc. functions
|
||||||
|
|
133
src/text.c
133
src/text.c
|
@ -890,140 +890,7 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw text using font inside rectangle limits
|
|
||||||
void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint)
|
|
||||||
{
|
{
|
||||||
DrawTextRecEx(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw text using font inside rectangle limits with support for text selection
|
|
||||||
void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
|
|
||||||
{
|
|
||||||
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
|
||||||
|
|
||||||
float textOffsetY = 0; // Offset between lines (on line break '\n')
|
|
||||||
float textOffsetX = 0.0f; // Offset X to next character to draw
|
|
||||||
|
|
||||||
float scaleFactor = fontSize/(float)font.baseSize; // Character quad scaling factor
|
|
||||||
|
|
||||||
// Word/character wrapping mechanism variables
|
|
||||||
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
|
|
||||||
int state = wordWrap? MEASURE_STATE : DRAW_STATE;
|
|
||||||
|
|
||||||
int startLine = -1; // Index where to begin drawing (where a line begins)
|
|
||||||
int endLine = -1; // Index where to stop drawing (where a line ends)
|
|
||||||
int lastk = -1; // Holds last value of the character position
|
|
||||||
|
|
||||||
for (int i = 0, k = 0; i < length; i++, k++)
|
|
||||||
{
|
|
||||||
// Get next codepoint from byte string and glyph index in font
|
|
||||||
int codepointByteCount = 0;
|
|
||||||
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
|
||||||
int index = GetGlyphIndex(font, codepoint);
|
|
||||||
|
|
||||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
|
||||||
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
|
||||||
if (codepoint == 0x3f) codepointByteCount = 1;
|
|
||||||
i += (codepointByteCount - 1);
|
|
||||||
|
|
||||||
float glyphWidth = 0;
|
|
||||||
if (codepoint != '\n')
|
|
||||||
{
|
|
||||||
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
|
|
||||||
|
|
||||||
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
|
|
||||||
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
|
|
||||||
// and change states again and again recursively until the end of the text (or until we get outside of the container).
|
|
||||||
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
|
|
||||||
// and begin drawing on the next line before we can get outside the container.
|
|
||||||
if (state == MEASURE_STATE)
|
|
||||||
{
|
|
||||||
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
|
|
||||||
// Ref: http://jkorpela.fi/chars/spaces.html
|
|
||||||
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
|
|
||||||
|
|
||||||
if ((textOffsetX + glyphWidth) > rec.width)
|
|
||||||
{
|
|
||||||
endLine = (endLine < 1)? i : endLine;
|
|
||||||
if (i == endLine) endLine -= codepointByteCount;
|
|
||||||
if ((startLine + codepointByteCount) == endLine) endLine = (i - codepointByteCount);
|
|
||||||
|
|
||||||
state = !state;
|
|
||||||
}
|
|
||||||
else if ((i + 1) == length)
|
|
||||||
{
|
|
||||||
endLine = i;
|
|
||||||
state = !state;
|
|
||||||
}
|
|
||||||
else if (codepoint == '\n') state = !state;
|
|
||||||
|
|
||||||
if (state == DRAW_STATE)
|
|
||||||
{
|
|
||||||
textOffsetX = 0;
|
|
||||||
i = startLine;
|
|
||||||
glyphWidth = 0;
|
|
||||||
|
|
||||||
// Save character position when we switch states
|
|
||||||
int tmp = lastk;
|
|
||||||
lastk = k - 1;
|
|
||||||
k = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (codepoint == '\n')
|
|
||||||
{
|
|
||||||
if (!wordWrap)
|
|
||||||
{
|
|
||||||
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
|
||||||
textOffsetX = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
|
|
||||||
{
|
|
||||||
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
|
||||||
textOffsetX = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When text overflows rectangle height limit, just stop drawing
|
|
||||||
if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break;
|
|
||||||
|
|
||||||
// Draw selection background
|
|
||||||
bool isGlyphSelected = false;
|
|
||||||
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
|
|
||||||
{
|
|
||||||
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
|
|
||||||
isGlyphSelected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw current character glyph
|
|
||||||
if ((codepoint != ' ') && (codepoint != '\t'))
|
|
||||||
{
|
|
||||||
DrawTextCodepoint(font, codepoint, (Vector2){ rec.x + textOffsetX, rec.y + textOffsetY }, fontSize, isGlyphSelected? selectTint : tint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wordWrap && (i == endLine))
|
|
||||||
{
|
|
||||||
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
|
||||||
textOffsetX = 0;
|
|
||||||
startLine = endLine;
|
|
||||||
endLine = -1;
|
|
||||||
glyphWidth = 0;
|
|
||||||
selectStart += lastk - k;
|
|
||||||
k = lastk;
|
|
||||||
|
|
||||||
state = !state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
textOffsetX += glyphWidth;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw one character (codepoint)
|
// Draw one character (codepoint)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue