diff --git a/src/graphics/font.c b/src/graphics/font.c index 7299ba3e..186f2db5 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -14,6 +14,8 @@ Font* lovrFontCreate(FontData* fontData) { if (!font) return NULL; font->fontData = fontData; + font->texture = NULL; + font->lineHeight = 1.f; vec_init(&font->vertices); map_init(&font->kerning); @@ -21,13 +23,14 @@ Font* lovrFontCreate(FontData* fontData) { int padding = 1; font->atlas.x = padding; font->atlas.y = padding; - font->atlas.width = 256; - font->atlas.height = 256; + font->atlas.width = 128; + font->atlas.height = 128; font->atlas.padding = padding; map_init(&font->atlas.glyphs); - while (font->atlas.width < 4 * fontData->size) { - font->atlas.width <<= 1; + // Set initial atlas size + while (font->atlas.height < 4 * fontData->size) { + lovrFontExpandTexture(font); } // Texture @@ -59,6 +62,7 @@ void lovrFontPrint(Font* font, const char* str) { float v = atlas->height; int length = strlen(str); + const char* start = str; const char* end = str + length; size_t bytes; unsigned int previous = '\0'; @@ -72,7 +76,7 @@ void lovrFontPrint(Font* font, const char* str) { // Newlines if (codepoint == '\n') { x = 0; - y -= font->fontData->size; + y -= font->fontData->size * font->lineHeight; previous = '\0'; str += bytes; continue; @@ -82,8 +86,21 @@ void lovrFontPrint(Font* font, const char* str) { x += lovrFontGetKerning(font, previous, codepoint); previous = codepoint; - // Glyph geometry + // Get glyph Glyph* glyph = lovrFontGetGlyph(font, codepoint); + + // Start over if texture was repacked + if (u != atlas->width || v != atlas->height) { + x = 0; + y = -lovrFontGetHeight(font); + u = atlas->width; + v = atlas->height; + str = start; + previous = '\0'; + continue; + } + + // Glyph geometry int gx = glyph->x; int gy = glyph->y; int gw = glyph->w; @@ -173,6 +190,14 @@ int lovrFontGetBaseline(Font* font) { return font->fontData->height / 1.25f; } +float lovrFontGetLineHeight(Font* font) { + return font->lineHeight; +} + +void lovrFontSetLineHeight(Font* font, float lineHeight) { + font->lineHeight = lineHeight; +} + int lovrFontGetKerning(Font* font, unsigned int left, unsigned int right) { char key[12]; snprintf(key, 12, "%d,%d", left, right); @@ -224,11 +249,6 @@ void lovrFontAddGlyph(Font* font, Glyph* glyph) { // Expand the texture if needed. Expanding the texture re-adds all the glyphs, so we can return. if (atlas->y + glyph->h > atlas->height - 2 * atlas->padding) { - if (atlas->width == atlas->height) { - atlas->width <<= 1; - } else { - atlas->height <<= 1; - } lovrFontExpandTexture(font); return; } @@ -249,9 +269,23 @@ void lovrFontAddGlyph(Font* font, Glyph* glyph) { void lovrFontExpandTexture(Font* font) { FontAtlas* atlas = &font->atlas; + if (atlas->width == atlas->height) { + atlas->width *= 2; + } else { + atlas->height *= 2; + } + + if (!font->texture) { + return; + } + // Resize the texture storage + while (glGetError()); lovrTextureDataResize(font->texture->textureData, atlas->width, atlas->height, 0x0); lovrTextureRefresh(font->texture); + if (glGetError()) { + error("Problem expanding font texture (out of space?)"); + } // Reset the cursor atlas->x = atlas->padding; diff --git a/src/graphics/font.h b/src/graphics/font.h index 73b89ba2..61ce6713 100644 --- a/src/graphics/font.h +++ b/src/graphics/font.h @@ -44,6 +44,7 @@ typedef struct { FontAtlas atlas; map_int_t kerning; vec_float_t vertices; + int lineHeight; } Font; Font* lovrFontCreate(FontData* fontData); @@ -54,6 +55,8 @@ int lovrFontGetHeight(Font* font); int lovrFontGetAscent(Font* font); int lovrFontGetDescent(Font* font); int lovrFontGetBaseline(Font* font); +float lovrFontGetLineHeight(Font* font); +void lovrFontSetLineHeight(Font* font, float lineHeight); int lovrFontGetKerning(Font* font, unsigned int a, unsigned int b); Glyph* lovrFontGetGlyph(Font* font, uint32_t codepoint); void lovrFontAddGlyph(Font* font, Glyph* glyph); diff --git a/src/lovr/types/font.c b/src/lovr/types/font.c index 021cf762..099252a3 100644 --- a/src/lovr/types/font.c +++ b/src/lovr/types/font.c @@ -6,6 +6,8 @@ const luaL_Reg lovrFont[] = { { "getAscent", l_lovrFontGetAscent }, { "getDescent", l_lovrFontGetDescent }, { "getBaseline", l_lovrFontGetBaseline }, + { "getLineHeight", l_lovrFontGetLineHeight }, + { "setLineHeight", l_lovrFontSetLineHeight }, { NULL, NULL } }; @@ -39,3 +41,16 @@ int l_lovrFontGetBaseline(lua_State* L) { lua_pushinteger(L, lovrFontGetBaseline(font)); return 1; } + +int l_lovrFontGetLineHeight(lua_State* L) { + Font* font = luax_checktype(L, 1, Font); + lua_pushinteger(L, lovrFontGetLineHeight(font)); + return 1; +} + +int l_lovrFontSetLineHeight(lua_State* L) { + Font* font = luax_checktype(L, 1, Font); + float lineHeight = luaL_checknumber(L, 2); + lovrFontSetLineHeight(font, lineHeight); + return 0; +} diff --git a/src/lovr/types/font.h b/src/lovr/types/font.h index 1ec242d3..31690753 100644 --- a/src/lovr/types/font.h +++ b/src/lovr/types/font.h @@ -7,3 +7,5 @@ int l_lovrFontGetHeight(lua_State* L); int l_lovrFontGetAscent(lua_State* L); int l_lovrFontGetDescent(lua_State* L); int l_lovrFontGetBaseline(lua_State* L); +int l_lovrFontGetLineHeight(lua_State* L); +int l_lovrFontSetLineHeight(lua_State* L);