REVIEWED: ImageTextEx() to support line breaks #1131

NOTE: This functionality has an important issue, line space is fixed to 1.5 font.baseSize pixels, depending on the font and how it has been generated that spacing could be too wide or too narrow...
This commit is contained in:
raysan5 2020-03-15 16:18:48 +01:00
parent 427be604b9
commit 4611406c68

View file

@ -1932,9 +1932,8 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
{ {
int length = strlen(text); int length = strlen(text);
int index; // Index position in sprite font int textOffsetX = 0; // Image drawing position X
int letter = 0; // Current character int textOffsetY = 0; // Offset between lines (on line break '\n')
int positionX = 0; // Image drawing position
// NOTE: Text image is generated at font base size, later scaled to desired font size // NOTE: Text image is generated at font base size, later scaled to desired font size
Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing); Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing);
@ -1944,29 +1943,35 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
int next = 0; // Get next codepoint from byte string and glyph index in font
letter = GetNextCodepoint(&text[i], &next); int codepointByteCount = 0;
index = GetGlyphIndex(font, letter); int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
int index = GetGlyphIndex(font, codepoint);
if (letter == 0x3f) next = 1; // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
i += (next - 1); // but we need to draw all of the bad bytes using the '?' symbol moving one byte
if (codepoint == 0x3f) codepointByteCount = 1;
if (letter == '\n') if (codepoint == '\n')
{ {
// TODO: Support line break // NOTE: Fixed line spacing of 1.5 line-height
// TODO: Support custom line spacing defined by user
textOffsetY += font.baseSize + font.baseSize/2);
textOffsetX = 0.0f;
} }
else else
{ {
if (letter != ' ') if ((codepoint != ' ') && (codepoint != '\t'))
{ {
ImageDraw(&imText, font.chars[index].image, (Rectangle){ 0, 0, font.chars[index].image.width, font.chars[index].image.height }, Rectangle rec = { textOffsetX + font.chars[index].offsetX, textOffsetY + font.chars[index].offsetY, font.recs[index].width, font.recs[index].height };
(Rectangle){ (float)(positionX + font.chars[index].offsetX),(float)font.chars[index].offsetY, ImageDraw(&imText, font.chars[index].image, (Rectangle){ 0, 0, font.chars[index].image.width, font.chars[index].image.height }, rec, tint);
font.chars[index].image.width, font.chars[index].image.height }, tint);
} }
if (font.chars[index].advanceX == 0) positionX += (int)(font.recs[index].width + spacing); if (font.chars[index].advanceX == 0) textOffsetX += (int)(font.recs[index].width + spacing);
else positionX += font.chars[index].advanceX + (int)spacing; else textOffsetX += font.chars[index].advanceX + (int)spacing;
} }
i += (codepointByteCount - 1); // Move text bytes counter to next codepoint
} }
// Scale image depending on text size // Scale image depending on text size