From 7b6978f05288069648853d0294e2fb7583fa19b0 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 5 Apr 2021 11:22:54 -0300 Subject: [PATCH] Add Font:getKerning. Also add a variant of Font:getWidth which accepts a codepoint number. Fixes #1403 --- changes.txt | 2 ++ src/modules/graphics/Font.cpp | 22 +++++++++++++++-- src/modules/graphics/Font.h | 10 ++++---- src/modules/graphics/wrap_Font.cpp | 38 +++++++++++++++++++++++++++--- 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/changes.txt b/changes.txt index 79f20c003..6540115af 100644 --- a/changes.txt +++ b/changes.txt @@ -4,6 +4,8 @@ LOVE 11.4 [Mysterious Mysteries] Released: N/A * Added Body:getLocalPoints. +* Added Font:getKerning. +* Added a variant of Font:getWidth which takes a codepoint number argument. * Added support for r16, rg16, and rgba16 pixel formats in Canvases. * Added Shader:send(name, matrixlayout, data, ...) variant, whose argument order is more consistent than Shader:send(name, data, matrixlayout, ...). diff --git a/src/modules/graphics/Font.cpp b/src/modules/graphics/Font.cpp index f991ce38f..eb9f29742 100644 --- a/src/modules/graphics/Font.cpp +++ b/src/modules/graphics/Font.cpp @@ -348,6 +348,24 @@ float Font::getKerning(uint32 leftglyph, uint32 rightglyph) return k; } +float Font::getKerning(const std::string &leftchar, const std::string &rightchar) +{ + uint32 left = 0; + uint32 right = 0; + + try + { + left = utf8::peek_next(leftchar.begin(), leftchar.end()); + right = utf8::peek_next(rightchar.begin(), rightchar.end()); + } + catch (utf8::exception &e) + { + throw love::Exception("UTF-8 decoding error: %s", e.what()); + } + + return getKerning(left, right); +} + void Font::getCodepointsFromString(const std::string &text, Codepoints &codepoints) { codepoints.reserve(text.size()); @@ -724,9 +742,9 @@ int Font::getWidth(const std::string &str) return max_width; } -int Font::getWidth(char character) +int Font::getWidth(uint32 glyph) { - const Glyph &g = findGlyph(character); + const Glyph &g = findGlyph(glyph); return g.spacing; } diff --git a/src/modules/graphics/Font.h b/src/modules/graphics/Font.h index 8a1728d31..bc2bd0ca7 100644 --- a/src/modules/graphics/Font.h +++ b/src/modules/graphics/Font.h @@ -128,11 +128,9 @@ public: int getWidth(const std::string &str); /** - * Returns the width of the passed character. - * - * @param character A character. + * Returns the width of the passed glyph. **/ - int getWidth(char character); + int getWidth(uint32 glyph); /** * Returns the maximal width of a wrapped string @@ -169,6 +167,9 @@ public: bool hasGlyph(uint32 glyph) const; bool hasGlyphs(const std::string &text) const; + float getKerning(uint32 leftglyph, uint32 rightglyph); + float getKerning(const std::string &leftchar, const std::string &rightchar); + void setFallbacks(const std::vector &fallbacks); float getDPIScale() const; @@ -206,7 +207,6 @@ private: love::font::GlyphData *getRasterizerGlyphData(uint32 glyph, float &dpiscale); const Glyph &addGlyph(uint32 glyph); const Glyph &findGlyph(uint32 glyph); - float getKerning(uint32 leftglyph, uint32 rightglyph); void printv(Graphics *gfx, const Matrix4 &t, const std::vector &drawcommands, const std::vector &vertices); std::vector> rasterizers; diff --git a/src/modules/graphics/wrap_Font.cpp b/src/modules/graphics/wrap_Font.cpp index 115a84348..e3565027a 100644 --- a/src/modules/graphics/wrap_Font.cpp +++ b/src/modules/graphics/wrap_Font.cpp @@ -86,9 +86,16 @@ int w_Font_getHeight(lua_State *L) int w_Font_getWidth(lua_State *L) { Font *t = luax_checkfont(L, 1); - const char *str = luaL_checkstring(L, 2); - - luax_catchexcept(L, [&](){ lua_pushinteger(L, t->getWidth(str)); }); + if (lua_type(L, 2) == LUA_TSTRING) + { + const char *str = luaL_checkstring(L, 2); + luax_catchexcept(L, [&](){ lua_pushinteger(L, t->getWidth(str)); }); + } + else + { + uint32 glyph = (uint32) luaL_checknumber(L, 2); + luax_catchexcept(L, [&](){ lua_pushinteger(L, t->getWidth(glyph)); }); + } return 1; } @@ -214,6 +221,30 @@ int w_Font_hasGlyphs(lua_State *L) return 1; } +int w_Font_getKerning(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + float kerning = 0.0f; + + luax_catchexcept(L, [&]() { + if (lua_type(L, 2) == LUA_TSTRING) + { + std::string left = luax_checkstring(L, 2); + std::string right = luax_checkstring(L, 3); + kerning = t->getKerning(left, right); + } + else + { + uint32 left = (uint32) luaL_checknumber(L, 2); + uint32 right = (uint32) luaL_checknumber(L, 3); + kerning = t->getKerning(left, right); + } + }); + + lua_pushnumber(L, kerning); + return 1; +} + int w_Font_setFallbacks(lua_State *L) { Font *t = luax_checkfont(L, 1); @@ -246,6 +277,7 @@ static const luaL_Reg w_Font_functions[] = { "getDescent", w_Font_getDescent }, { "getBaseline", w_Font_getBaseline }, { "hasGlyphs", w_Font_hasGlyphs }, + { "getKerning", w_Font_getKerning }, { "setFallbacks", w_Font_setFallbacks }, { "getDPIScale", w_Font_getDPIScale }, { 0, 0 }