diff --git a/src/Drawer2D.c b/src/Drawer2D.c index ced0a8356..87e34dfe9 100644 --- a/src/Drawer2D.c +++ b/src/Drawer2D.c @@ -323,29 +323,53 @@ cc_bool Drawer2D_ValidColorCodeAt(const cc_string* text, int i) { return BitmapCol_A(Drawer2D_GetColor(text->buffer[i])) != 0; } -cc_bool Drawer2D_IsEmptyText(const cc_string* text) { +cc_bool Drawer2D_NextPart(cc_string* left, cc_string* part, BitmapCol* color) { + BitmapCol c; int i; - if (!text->length) return true; - - for (i = 0; i < text->length; i++) { - if (text->buffer[i] != '&') return false; - if (!Drawer2D_ValidColorCodeAt(text, i + 1)) return false; - i++; /* skip color code */ + + /* check if current part starts with a colour code */ + if (left->length >= 2 && left->buffer[0] == '&') { + c = Drawer2D_GetColor(left->buffer[1]); + + if (BitmapCol_A(c)) { + *color = c; + left->buffer += 2; + left->length -= 2; + } + } + + for (i = 0; i < left->length; i++) + { + if (left->buffer[i] == '&' && Drawer2D_ValidColorCodeAt(left, i + 1)) break; + } + + /* advance string starts and lengths */ + part->buffer = left->buffer; + part->length = i; + left->buffer += i; + left->length -= i; + + return part->length > 0 || left->length > 0; +} + +cc_bool Drawer2D_IsEmptyText(const cc_string* text) { + cc_string left = *text, part; + BitmapCol color; + + while (Drawer2D_NextPart(&left, &part, &color)) + { + if (part.length) return false; } return true; } void Drawer2D_WithoutColors(cc_string* str, const cc_string* src) { - char c; - int i; - for (i = 0; i < src->length; i++) { - c = src->buffer[i]; + cc_string left = *src, part; + BitmapCol color; - if (c == '&' && Drawer2D_ValidColorCodeAt(src, i + 1)) { - i++; /* skip color code */ - } else { - String_Append(str, c); - } + while (Drawer2D_NextPart(&left, &part, &color)) + { + String_AppendString(str, &part); } } @@ -699,7 +723,7 @@ cc_result Font_Make(struct FontDesc* desc, const cc_string* fontName, int size, desc->height = Drawer2D_AdjHeight(size); desc->handle = Mem_TryAlloc(fontName->length + 1, 1); - if (!desc->handle) return 0; + if (!desc->handle) return ERR_OUT_OF_MEMORY; String_CopyToRaw(desc->handle, fontName->length + 1, fontName); return 0; @@ -720,29 +744,53 @@ void Font_Free(struct FontDesc* desc) { } void SysFonts_Register(const cc_string* path) { } -extern void interop_SetFont(const char* font, int size, int flags); -extern int interop_TextWidth(const char* text, const int len); -extern void interop_TextDraw(const char* text, const int len, struct Bitmap* bmp, int x, int y, cc_bool shadow); +extern void interop_SetFont(const char* font, int size, int flags); +extern double interop_TextWidth(const char* text, const int len); +extern double interop_TextDraw(const char* text, const int len, struct Bitmap* bmp, int x, int y, cc_bool shadow, const char* hex); static int Font_SysTextWidth(struct DrawTextArgs* args) { struct FontDesc* font = args->font; - char buffer[NATIVE_STR_LEN]; - int len = Platform_EncodeUtf8(buffer, &args->text); + cc_string left = args->text, part; + double width = 0; + BitmapCol color; interop_SetFont(font->handle, font->size, font->flags); - return interop_TextWidth(buffer, len); + while (Drawer2D_NextPart(&left, &part, &color)) + { + char buffer[NATIVE_STR_LEN]; + int len = Platform_EncodeUtf8(buffer, &part); + width += interop_TextWidth(buffer, len); + } + return Math_Ceil(width); } static void Font_SysTextDraw(struct DrawTextArgs* args, struct Bitmap* bmp, int x, int y, cc_bool shadow) { struct FontDesc* font = args->font; - char buffer[NATIVE_STR_LEN]; - int len = Platform_EncodeUtf8(buffer, &args->text); + cc_string left = args->text, part; + BitmapCol color = Drawer2D.Colors['f']; + double xOffset = 0; + char hexBuffer[7]; + cc_string hex; /* adjust y position to more closely match FreeType drawn text */ y += (args->font->height - args->font->size) / 2; - interop_SetFont(font->handle, font->size, font->flags); - interop_TextDraw(buffer, len, bmp, x, y, shadow); + + while (Drawer2D_NextPart(&left, &part, &color)) + { + char buffer[NATIVE_STR_LEN]; + int len = Platform_EncodeUtf8(buffer, &part); + if (shadow) color = GetShadowColor(color); + + String_InitArray(hex, hexBuffer); + String_Append(&hex, '#'); + String_AppendHex(&hex, BitmapCol_R(color)); + String_AppendHex(&hex, BitmapCol_G(color)); + String_AppendHex(&hex, BitmapCol_B(color)); + + /* TODO pass as double directly instead of (int) ?*/ + xOffset += interop_TextDraw(buffer, len, bmp, x + (int)xOffset, y, shadow, hexBuffer); + } } #else #include "freetype/ft2build.h" diff --git a/src/Drawer2D.h b/src/Drawer2D.h index fa81c22a4..ff1a2fbb2 100644 --- a/src/Drawer2D.h +++ b/src/Drawer2D.h @@ -95,6 +95,7 @@ void Drawer2D_WithoutColors(cc_string* str, const cc_string* src); char Drawer2D_LastColor(const cc_string* text, int start); /* Returns whether the color code is f, F or \0 */ cc_bool Drawer2D_IsWhiteColor(char c); +cc_bool Drawer2D_NextPart(cc_string* left, cc_string* part, BitmapCol* color); void Drawer2D_ReducePadding_Tex(struct Texture* tex, int point, int scale); void Drawer2D_ReducePadding_Height(int* height, int point, int scale); diff --git a/src/interop_web.js b/src/interop_web.js index d021e93ef..e04a17374 100644 --- a/src/interop_web.js +++ b/src/interop_web.js @@ -1013,24 +1013,22 @@ mergeInto(LibraryManager.library, { var text = UTF8ArrayToString(HEAPU8, textStr, textLen); var ctx = window.FONT_CONTEXT; var data = ctx.measureText(text); - return Math.ceil(data.width)|0; + return data.width; }, - interop_TextDraw: function(textStr, textLen, bmp, dstX, dstY, shadow) { + interop_TextDraw: function(textStr, textLen, bmp, dstX, dstY, shadow, hexStr) { var text = UTF8ArrayToString(HEAPU8, textStr, textLen); + var hex = UTF8ArrayToString(HEAPU8, hexStr, 7); var ctx = window.FONT_CONTEXT; - // resize canvas if necessary so test fits + // resize canvas if necessary so text fits var data = ctx.measureText(text); var text_width = Math.ceil(data.width)|0; if (text_width > ctx.canvas.width) ctx.canvas.width = text_width; var text_offset = 0.0; - ctx.fillStyle = "#ffffff"; - if (shadow) { - text_offset = 1.3; - ctx.fillStyle = "#7f7f7f"; - } + ctx.fillStyle = hex; + if (shadow) { text_offset = 1.3; } ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fillText(text, text_offset, text_offset); @@ -1072,5 +1070,6 @@ mergeInto(LibraryManager.library, { HEAPU8[dst_row + (x<<2)+3] = I + ((HEAPU8[dst_row + (x<<2)+3] * invI) >> 8); } } + return data.width; }, }); \ No newline at end of file