From 5a0a6a1a27dec0fbd429c98a8c4b11989fb0b719 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Fri, 20 Oct 2023 20:19:30 -0300 Subject: [PATCH] All constructors for making a TrueType font take an optional settings table. This supersedes the existing optional hinting and dpi scale parameters. The table's fields are: { hinting = "normal", dpiscale = 1, -- nil will default to the current window DPI scale. } --- src/common/Optional.h | 2 +- src/modules/font/Font.cpp | 16 +--- src/modules/font/Font.h | 7 +- src/modules/font/TrueTypeRasterizer.h | 7 ++ src/modules/font/freetype/Font.cpp | 15 ++-- src/modules/font/freetype/Font.h | 3 +- .../font/freetype/TrueTypeRasterizer.cpp | 8 +- .../font/freetype/TrueTypeRasterizer.h | 2 +- src/modules/font/wrap_Font.cpp | 81 ++++++++++++------- src/modules/graphics/Deprecations.cpp | 6 +- src/modules/graphics/Graphics.cpp | 9 ++- src/modules/graphics/Graphics.h | 2 +- 12 files changed, 84 insertions(+), 74 deletions(-) diff --git a/src/common/Optional.h b/src/common/Optional.h index fe3b4b2ef..d0fc11ea9 100644 --- a/src/common/Optional.h +++ b/src/common/Optional.h @@ -46,7 +46,7 @@ struct Optional hasValue = true; } - T get(T defaultVal) + T get(T defaultVal) const { return hasValue ? value : defaultVal; } diff --git a/src/modules/font/Font.cpp b/src/modules/font/Font.cpp index 818e3facf..f3f85bfa5 100644 --- a/src/modules/font/Font.cpp +++ b/src/modules/font/Font.cpp @@ -45,14 +45,9 @@ Font::Font() defaultFontData.set(new data::ByteData(fontdata, rawsize, true), Acquire::NORETAIN); } -Rasterizer *Font::newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting) +Rasterizer *Font::newTrueTypeRasterizer(int size, const TrueTypeRasterizer::Settings &settings) { - return newTrueTypeRasterizer(defaultFontData.get(), size, hinting); -} - -Rasterizer *Font::newTrueTypeRasterizer(int size, float dpiscale, TrueTypeRasterizer::Hinting hinting) -{ - return newTrueTypeRasterizer(defaultFontData.get(), size, dpiscale, hinting); + return newTrueTypeRasterizer(defaultFontData.get(), size, settings); } Rasterizer *Font::newBMFontRasterizer(love::filesystem::FileData *fontdef, const std::vector &images, float dpiscale) @@ -78,12 +73,7 @@ Rasterizer *Font::newImageRasterizer(love::image::ImageData *data, const std::st throw love::Exception("UTF-8 decoding error: %s", e.what()); } - return newImageRasterizer(data, &glyphs[0], (int) glyphs.size(), extraspacing, dpiscale); -} - -Rasterizer *Font::newImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs, int extraspacing, float dpiscale) -{ - return new ImageRasterizer(data, glyphs, numglyphs, extraspacing, dpiscale); + return new ImageRasterizer(data, glyphs.data(), (int) glyphs.size(), extraspacing, dpiscale); } GlyphData *Font::newGlyphData(Rasterizer *r, const std::string &text) diff --git a/src/modules/font/Font.h b/src/modules/font/Font.h index ed01557df..3b217a33a 100644 --- a/src/modules/font/Font.h +++ b/src/modules/font/Font.h @@ -48,15 +48,12 @@ class Font : public Module virtual Rasterizer *newRasterizer(love::filesystem::FileData *data) = 0; - virtual Rasterizer *newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting); - virtual Rasterizer *newTrueTypeRasterizer(int size, float dpiscale, TrueTypeRasterizer::Hinting hinting); - virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting) = 0; - virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, float dpiscale, TrueTypeRasterizer::Hinting hinting) = 0; + Rasterizer *newTrueTypeRasterizer(int size, const TrueTypeRasterizer::Settings &settings); + virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, const TrueTypeRasterizer::Settings &settings) = 0; virtual Rasterizer *newBMFontRasterizer(love::filesystem::FileData *fontdef, const std::vector &images, float dpiscale); virtual Rasterizer *newImageRasterizer(love::image::ImageData *data, const std::string &glyphs, int extraspacing, float dpiscale); - virtual Rasterizer *newImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int length, int extraspacing, float dpiscale); virtual GlyphData *newGlyphData(Rasterizer *r, const std::string &glyph); virtual GlyphData *newGlyphData(Rasterizer *r, uint32 glyph); diff --git a/src/modules/font/TrueTypeRasterizer.h b/src/modules/font/TrueTypeRasterizer.h index 62b225927..62d7253ab 100644 --- a/src/modules/font/TrueTypeRasterizer.h +++ b/src/modules/font/TrueTypeRasterizer.h @@ -24,6 +24,7 @@ // LOVE #include "Rasterizer.h" #include "common/StringMap.h" +#include "common/Optional.h" namespace love { @@ -44,6 +45,12 @@ class TrueTypeRasterizer : public Rasterizer HINTING_MAX_ENUM }; + struct Settings + { + Hinting hinting = HINTING_NORMAL; + OptionalFloat dpiScale; + }; + virtual ~TrueTypeRasterizer() {} static bool getConstant(const char *in, Hinting &out); diff --git a/src/modules/font/freetype/Font.cpp b/src/modules/font/freetype/Font.cpp index ec7fe9c27..9a52f7b08 100644 --- a/src/modules/font/freetype/Font.cpp +++ b/src/modules/font/freetype/Font.cpp @@ -49,26 +49,21 @@ Font::~Font() Rasterizer *Font::newRasterizer(love::filesystem::FileData *data) { if (TrueTypeRasterizer::accepts(library, data)) - return newTrueTypeRasterizer(data, 12, TrueTypeRasterizer::HINTING_NORMAL); + return newTrueTypeRasterizer(data, 12, font::TrueTypeRasterizer::Settings()); else if (BMFontRasterizer::accepts(data)) return newBMFontRasterizer(data, {}, 1.0f); throw love::Exception("Invalid font file: %s", data->getFilename().c_str()); } -Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting) +Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size, const font::TrueTypeRasterizer::Settings &settings) { - float dpiscale = 1.0f; + float defaultdpiscale = 1.0f; auto window = Module::getInstance(Module::M_WINDOW); if (window != nullptr) - dpiscale = window->getDPIScale(); + defaultdpiscale = window->getDPIScale(); - return newTrueTypeRasterizer(data, size, dpiscale, hinting); -} - -Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size, float dpiscale, TrueTypeRasterizer::Hinting hinting) -{ - return new TrueTypeRasterizer(library, data, size, dpiscale, hinting); + return new TrueTypeRasterizer(library, data, size, settings, defaultdpiscale); } const char *Font::getName() const diff --git a/src/modules/font/freetype/Font.h b/src/modules/font/freetype/Font.h index 8d023cf48..0a4c70e86 100644 --- a/src/modules/font/freetype/Font.h +++ b/src/modules/font/freetype/Font.h @@ -45,8 +45,7 @@ class Font : public love::font::Font // Implements Font Rasterizer *newRasterizer(love::filesystem::FileData *data) override; - Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting) override; - Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, float dpiscale, TrueTypeRasterizer::Hinting hinting) override; + Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, const font::TrueTypeRasterizer::Settings &settings) override; // Implement Module const char *getName() const override; diff --git a/src/modules/font/freetype/TrueTypeRasterizer.cpp b/src/modules/font/freetype/TrueTypeRasterizer.cpp index b48f63cb2..1baed329a 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.cpp +++ b/src/modules/font/freetype/TrueTypeRasterizer.cpp @@ -33,12 +33,12 @@ namespace font namespace freetype { -TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, love::Data *data, int size, float dpiscale, Hinting hinting) +TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, love::Data *data, int size, const Settings &settings, float defaultdpiscale) : data(data) - , hinting(hinting) + , hinting(settings.hinting) { - this->dpiScale = dpiscale; - size = floorf(size * dpiscale + 0.5f); + dpiScale = settings.dpiScale.get(defaultdpiscale); + size = floorf(size * dpiScale + 0.5f); if (size <= 0) throw love::Exception("Invalid TrueType font size: %d", size); diff --git a/src/modules/font/freetype/TrueTypeRasterizer.h b/src/modules/font/freetype/TrueTypeRasterizer.h index e97e91967..e26b79646 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.h +++ b/src/modules/font/freetype/TrueTypeRasterizer.h @@ -44,7 +44,7 @@ class TrueTypeRasterizer : public love::font::TrueTypeRasterizer { public: - TrueTypeRasterizer(FT_Library library, love::Data *data, int size, float dpiscale, Hinting hinting); + TrueTypeRasterizer(FT_Library library, love::Data *data, int size, const Settings &settings, float defaultdpiscale); virtual ~TrueTypeRasterizer(); // Implement Rasterizer diff --git a/src/modules/font/wrap_Font.cpp b/src/modules/font/wrap_Font.cpp index 499583b03..e2ec84f08 100644 --- a/src/modules/font/wrap_Font.cpp +++ b/src/modules/font/wrap_Font.cpp @@ -64,6 +64,42 @@ int w_newRasterizer(lua_State *L) } } +static TrueTypeRasterizer::Settings luax_checktruetypesettings(lua_State* L, int startidx) +{ + TrueTypeRasterizer::Settings s; + + if (lua_type(L, startidx) == LUA_TSTRING) + { + // Legacy parameters. + const char *hintstr = lua_isnoneornil(L, startidx) ? nullptr : luaL_checkstring(L, startidx); + if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, s.hinting)) + luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(s.hinting), hintstr); + + if (!lua_isnoneornil(L, startidx + 1)) + s.dpiScale.set((float)luaL_checknumber(L, startidx + 1)); + } + else + { + luaL_checktype(L, startidx, LUA_TTABLE); + + lua_getfield(L, startidx, "hinting"); + if (!lua_isnoneornil(L, -1)) + { + const char *hintstr = luaL_checkstring(L, -1); + if (!TrueTypeRasterizer::getConstant(hintstr, s.hinting)) + luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(s.hinting), hintstr); + } + lua_pop(L, 1); + + lua_getfield(L, startidx, "dpiscale"); + if (!lua_isnoneornil(L, -1)) + s.dpiScale.set((float)luaL_checknumber(L, -1)); + lua_pop(L, 1); + } + + return s; +} + int w_newTrueTypeRasterizer(lua_State *L) { Rasterizer *t = nullptr; @@ -74,20 +110,20 @@ int w_newTrueTypeRasterizer(lua_State *L) // First argument is a number: use the default TrueType font. int size = (int) luaL_optinteger(L, 1, 13); - const char *hintstr = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2); - if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting)) - return luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(hinting), hintstr); + TrueTypeRasterizer::Settings settings; + if (!lua_isnoneornil(L, 2)) + settings = luax_checktruetypesettings(L, 2); - if (lua_isnoneornil(L, 3)) - luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size, hinting); }); - else - { - float dpiscale = (float) luaL_checknumber(L, 3); - luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size, dpiscale, hinting); }); - } + luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size, settings); }); } else { + int size = (int) luaL_optinteger(L, 2, 12); + + TrueTypeRasterizer::Settings settings; + if (!lua_isnoneornil(L, 3)) + settings = luax_checktruetypesettings(L, 3); + love::Data *d = nullptr; if (luax_istype(L, 1, love::Data::type)) @@ -98,27 +134,10 @@ int w_newTrueTypeRasterizer(lua_State *L) else d = filesystem::luax_getfiledata(L, 1); - int size = (int) luaL_optinteger(L, 2, 12); - - const char *hintstr = lua_isnoneornil(L, 3) ? nullptr : luaL_checkstring(L, 3); - if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting)) - return luax_enumerror(L, "TrueType font hinting mode", TrueTypeRasterizer::getConstants(hinting), hintstr); - - if (lua_isnoneornil(L, 4)) - { - luax_catchexcept(L, - [&]() { t = instance()->newTrueTypeRasterizer(d, size, hinting); }, - [&](bool) { d->release(); } - ); - } - else - { - float dpiscale = (float) luaL_checknumber(L, 4); - luax_catchexcept(L, - [&]() { t = instance()->newTrueTypeRasterizer(d, size, dpiscale, hinting); }, - [&](bool) { d->release(); } - ); - } + luax_catchexcept(L, + [&]() { t = instance()->newTrueTypeRasterizer(d, size, settings); }, + [&](bool) { d->release(); } + ); } luax_pushtype(L, t); diff --git a/src/modules/graphics/Deprecations.cpp b/src/modules/graphics/Deprecations.cpp index 92a5d51c5..6e43a9350 100644 --- a/src/modules/graphics/Deprecations.cpp +++ b/src/modules/graphics/Deprecations.cpp @@ -74,12 +74,12 @@ void Deprecations::draw(Graphics *gfx) if (font.get() == nullptr) { - auto hinting = font::TrueTypeRasterizer::HINTING_NORMAL; + font::TrueTypeRasterizer::Settings settings; if (!isGammaCorrect() && gfx->getScreenDPIScale() <= 1.0) - hinting = font::TrueTypeRasterizer::HINTING_LIGHT; + settings.hinting = font::TrueTypeRasterizer::HINTING_LIGHT; - font.set(gfx->newDefaultFont(9, hinting), Acquire::NORETAIN); + font.set(gfx->newDefaultFont(9, settings), Acquire::NORETAIN); } gfx->flushBatchedDraws(); diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 3d32b727b..4704daabc 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -294,13 +294,13 @@ Font *Graphics::newFont(love::font::Rasterizer *data) return new Font(data, states.back().defaultSamplerState); } -Font *Graphics::newDefaultFont(int size, font::TrueTypeRasterizer::Hinting hinting) +Font *Graphics::newDefaultFont(int size, const font::TrueTypeRasterizer::Settings &settings) { auto fontmodule = Module::getInstance(M_FONT); if (!fontmodule) throw love::Exception("Font module has not been loaded."); - StrongRef r(fontmodule->newTrueTypeRasterizer(size, hinting), Acquire::NORETAIN); + StrongRef r(fontmodule->newTrueTypeRasterizer(size, settings), Acquire::NORETAIN); return newFont(r.get()); } @@ -731,7 +731,10 @@ void Graphics::checkSetDefaultFont() // Create a new default font if we don't have one yet. if (!defaultFont.get()) - defaultFont.set(newDefaultFont(13, font::TrueTypeRasterizer::HINTING_NORMAL), Acquire::NORETAIN); + { + font::TrueTypeRasterizer::Settings settings; + defaultFont.set(newDefaultFont(13, settings), Acquire::NORETAIN); + } states.back().font.set(defaultFont.get()); } diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index d2989213d..32ac208b0 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -459,7 +459,7 @@ class Graphics : public Module Quad *newQuad(Quad::Viewport v, double sw, double sh); Font *newFont(love::font::Rasterizer *data); - Font *newDefaultFont(int size, font::TrueTypeRasterizer::Hinting hinting); + Font *newDefaultFont(int size, const font::TrueTypeRasterizer::Settings &settings); Video *newVideo(love::video::VideoStream *stream, float dpiscale); SpriteBatch *newSpriteBatch(Texture *texture, int size, BufferDataUsage usage);