Browse Source

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.
}
Sasha Szpakowski 1 year ago
parent
commit
5a0a6a1a27

+ 1 - 1
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;
 	}

+ 3 - 13
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<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
src/modules/font/Font.h

@@ -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 - 0
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 @@ public:
 		HINTING_MAX_ENUM
 	};
 
+	struct Settings
+	{
+		Hinting hinting = HINTING_NORMAL;
+		OptionalFloat dpiScale;
+	};
+
 	virtual ~TrueTypeRasterizer() {}
 
 	static bool getConstant(const char *in, Hinting &out);

+ 5 - 10
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<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
src/modules/font/freetype/Font.h

@@ -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;

+ 4 - 4
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);

+ 1 - 1
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

+ 50 - 31
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);

+ 3 - 3
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();

+ 6 - 3
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<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
src/modules/graphics/Graphics.h

@@ -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);