Skip to content

Commit

Permalink
All constructors for making a TrueType font take an optional settings…
Browse files Browse the repository at this point in the history
… 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.
}
  • Loading branch information
slime73 committed Oct 20, 2023
1 parent 8c13943 commit 5a0a6a1
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/common/Optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct Optional
hasValue = true;
}

T get(T defaultVal)
T get(T defaultVal) const
{
return hasValue ? value : defaultVal;
}
Expand Down
16 changes: 3 additions & 13 deletions src/modules/font/Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
7 changes: 2 additions & 5 deletions src/modules/font/Font.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<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);
Expand Down
7 changes: 7 additions & 0 deletions src/modules/font/TrueTypeRasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
// LOVE
#include "Rasterizer.h"
#include "common/StringMap.h"
#include "common/Optional.h"

namespace love
{
Expand All @@ -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);
Expand Down
15 changes: 5 additions & 10 deletions src/modules/font/freetype/Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions src/modules/font/freetype/Font.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions src/modules/font/freetype/TrueTypeRasterizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/modules/font/freetype/TrueTypeRasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
81 changes: 50 additions & 31 deletions src/modules/font/wrap_Font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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))
Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions src/modules/graphics/Deprecations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
9 changes: 6 additions & 3 deletions src/modules/graphics/Graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand Down Expand Up @@ -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());
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/graphics/Graphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 5a0a6a1

Please sign in to comment.