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.
}
This commit is contained in:
Sasha Szpakowski
2023-10-20 20:19:30 -03:00
parent 8c13943f64
commit 5a0a6a1a27
12 changed files with 84 additions and 74 deletions
+3 -13
View File
@@ -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<image::ImageData *> &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)
+2 -5
View File
@@ -48,15 +48,12 @@ public:
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<image::ImageData *> &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);
+7
View File
@@ -24,6 +24,7 @@
// LOVE
#include "Rasterizer.h"
#include "common/StringMap.h"
#include "common/Optional.h"
namespace love
{
@@ -44,6 +45,12 @@ public:
HINTING_MAX_ENUM
};
struct Settings
{
Hinting hinting = HINTING_NORMAL;
OptionalFloat dpiScale;
};
virtual ~TrueTypeRasterizer() {}
static bool getConstant(const char *in, Hinting &out);
+5 -10
View File
@@ -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<window::Window>(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
+1 -2
View File
@@ -45,8 +45,7 @@ public:
// 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;
@@ -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);
@@ -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
+50 -31
View File
@@ -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);
+3 -3
View File
@@ -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();
+6 -3
View File
@@ -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<font::Font>(M_FONT);
if (!fontmodule)
throw love::Exception("Font module has not been loaded.");
StrongRef<font::Rasterizer> r(fontmodule->newTrueTypeRasterizer(size, hinting), Acquire::NORETAIN);
StrongRef<font::Rasterizer> 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());
}
+1 -1
View File
@@ -459,7 +459,7 @@ public:
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);