Added an optional font hinting argument to love.graphics.newFont / love.font.newRasterizer when loading TrueType fonts. Resolves issue #963.

Accepted values are "normal", "light", "mono", and "none".
This commit is contained in:
Alex Szpakowski
2015-03-07 22:05:37 -04:00
parent afcad4defc
commit 4ef0d257e9
15 changed files with 187 additions and 32 deletions
+2 -3
View File
@@ -39,15 +39,14 @@ public:
virtual void *getData() const { return Vera_ttf; }
virtual size_t getSize() const { return sizeof(Vera_ttf); }
};
Rasterizer *Font::newTrueTypeRasterizer(int size)
Rasterizer *Font::newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting)
{
StrongRef<DefaultFontData> data(new DefaultFontData);
data->release();
return newTrueTypeRasterizer(data.get(), size);
return newTrueTypeRasterizer(data.get(), size, hinting);
}
Rasterizer *Font::newBMFontRasterizer(love::filesystem::FileData *fontdef, const std::vector<image::ImageData *> &images)
+3 -2
View File
@@ -23,6 +23,7 @@
// LOVE
#include "Rasterizer.h"
#include "TrueTypeRasterizer.h"
#include "image/ImageData.h"
#include "filesystem/FileData.h"
#include "common/Module.h"
@@ -46,8 +47,8 @@ public:
virtual Rasterizer *newRasterizer(love::filesystem::FileData *data) = 0;
virtual Rasterizer *newTrueTypeRasterizer(int size);
virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size) = 0;
virtual Rasterizer *newTrueTypeRasterizer(int size, TrueTypeRasterizer::Hinting hinting);
virtual Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting) = 0;
virtual Rasterizer *newBMFontRasterizer(love::filesystem::FileData *fontdef, const std::vector<image::ImageData *> &images);
+49
View File
@@ -0,0 +1,49 @@
/**
* Copyright (c) 2006-2015 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "TrueTypeRasterizer.h"
namespace love
{
namespace font
{
bool TrueTypeRasterizer::getConstant(const char *in, Hinting &out)
{
return hintings.find(in, out);
}
bool TrueTypeRasterizer::getConstant(Hinting in, const char *&out)
{
return hintings.find(in, out);
}
StringMap<TrueTypeRasterizer::Hinting, TrueTypeRasterizer::HINTING_MAX_ENUM>::Entry TrueTypeRasterizer::hintingEntries[] =
{
{"normal", HINTING_NORMAL},
{"light", HINTING_LIGHT},
{"mono", HINTING_MONO},
{"none", HINTING_NONE},
};
StringMap<TrueTypeRasterizer::Hinting, TrueTypeRasterizer::HINTING_MAX_ENUM> TrueTypeRasterizer::hintings(TrueTypeRasterizer::hintingEntries, sizeof(TrueTypeRasterizer::hintingEntries));
} // font
} // love
+62
View File
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2006-2015 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_FONT_TRUE_TYPE_RASTERIZER_H
#define LOVE_FONT_TRUE_TYPE_RASTERIZER_H
// LOVE
#include "Rasterizer.h"
#include "common/StringMap.h"
namespace love
{
namespace font
{
class TrueTypeRasterizer : public Rasterizer
{
public:
// Types of hinting for TrueType font glyphs.
enum Hinting
{
HINTING_NORMAL,
HINTING_LIGHT,
HINTING_MONO,
HINTING_NONE,
HINTING_MAX_ENUM
};
virtual ~TrueTypeRasterizer() {}
static bool getConstant(const char *in, Hinting &out);
static bool getConstant(Hinting in, const char *&out);
private:
static StringMap<Hinting, HINTING_MAX_ENUM>::Entry hintingEntries[];
static StringMap<Hinting, HINTING_MAX_ENUM> hintings;
}; // TrueTypeRasterizer
} // font
} // love
#endif // LOVE_FONT_TRUE_TYPE_RASTERIZER_H
+3 -3
View File
@@ -46,16 +46,16 @@ Font::~Font()
Rasterizer *Font::newRasterizer(love::filesystem::FileData *data)
{
if (TrueTypeRasterizer::accepts(library, data))
return newTrueTypeRasterizer(data, 12);
return newTrueTypeRasterizer(data, 12, TrueTypeRasterizer::HINTING_NORMAL);
else if (BMFontRasterizer::accepts(data))
return newBMFontRasterizer(data, {});
throw love::Exception("Invalid font file: %s", data->getFilename().c_str());
}
Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size)
Rasterizer *Font::newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting)
{
return new TrueTypeRasterizer(library, data, size);
return new TrueTypeRasterizer(library, data, size, hinting);
}
const char *Font::getName() const
+1 -1
View File
@@ -45,7 +45,7 @@ public:
// Implements Font
Rasterizer *newRasterizer(love::filesystem::FileData *data);
Rasterizer *newTrueTypeRasterizer(love::Data *data, int size);
Rasterizer *newTrueTypeRasterizer(love::Data *data, int size, TrueTypeRasterizer::Hinting hinting);
// Implement Module
const char *getName() const;
@@ -30,8 +30,9 @@ namespace font
namespace freetype
{
TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, love::Data *data, int size)
TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, love::Data *data, int size, Hinting hinting)
: data(data)
, hinting(hinting)
{
if (size <= 0)
throw love::Exception("Invalid TrueType font size: %d", size);
@@ -75,9 +76,10 @@ GlyphData *TrueTypeRasterizer::getGlyphData(uint32 glyph) const
FT_Glyph ftglyph;
FT_Error err = FT_Err_Ok;
FT_ULong loadoption = hintingToLoadOption(hinting);
// Initialize
err = FT_Load_Glyph(face, FT_Get_Char_Index(face, glyph), FT_LOAD_DEFAULT);
err = FT_Load_Glyph(face, FT_Get_Char_Index(face, glyph), FT_LOAD_DEFAULT | loadoption);
if (err != FT_Err_Ok)
throw love::Exception("TrueType Font glyph error: FT_Load_Glyph failed (0x%x)", err);
@@ -87,7 +89,11 @@ GlyphData *TrueTypeRasterizer::getGlyphData(uint32 glyph) const
if (err != FT_Err_Ok)
throw love::Exception("TrueType Font glyph error: FT_Get_Glyph failed (0x%x)", err);
err = FT_Glyph_To_Bitmap(&ftglyph, FT_RENDER_MODE_NORMAL, 0, 1);
FT_Render_Mode rendermode = FT_RENDER_MODE_NORMAL;
if (hinting == HINTING_MONO)
rendermode = FT_RENDER_MODE_MONO;
err = FT_Glyph_To_Bitmap(&ftglyph, rendermode, 0, 1);
if (err != FT_Err_Ok)
throw love::Exception("TrueType Font glyph error: FT_Glyph_To_Bitmap failed (0x%x)", err);
@@ -168,6 +174,22 @@ bool TrueTypeRasterizer::accepts(FT_Library library, love::Data *data)
return FT_New_Memory_Face(library, fbase, fsize, -1, nullptr) == 0;
}
FT_ULong TrueTypeRasterizer::hintingToLoadOption(Hinting hint)
{
switch (hint)
{
case HINTING_NORMAL:
default:
return FT_LOAD_TARGET_NORMAL;
case HINTING_LIGHT:
return FT_LOAD_TARGET_LIGHT;
case HINTING_MONO:
return FT_LOAD_TARGET_MONO;
case HINTING_NONE:
return FT_LOAD_NO_HINTING;
}
}
} // freetype
} // font
} // love
@@ -23,7 +23,7 @@
// LOVE
#include "filesystem/FileData.h"
#include "font/Rasterizer.h"
#include "font/TrueTypeRasterizer.h"
// FreeType2
#include <ft2build.h>
@@ -40,11 +40,11 @@ namespace freetype
/**
* Holds data for a font object.
**/
class TrueTypeRasterizer : public Rasterizer
class TrueTypeRasterizer : public love::font::TrueTypeRasterizer
{
public:
TrueTypeRasterizer(FT_Library library, love::Data *data, int size);
TrueTypeRasterizer(FT_Library library, love::Data *data, int size, Hinting hinting);
virtual ~TrueTypeRasterizer();
// Implement Rasterizer
@@ -57,12 +57,16 @@ public:
private:
static FT_ULong hintingToLoadOption(Hinting hinting);
// TrueType face
FT_Face face;
// Font data
StrongRef<love::Data> data;
Hinting hinting;
}; // TrueTypeRasterizer
} // freetype
+19 -13
View File
@@ -37,12 +37,13 @@ namespace font
int w_newRasterizer(lua_State *L)
{
if (lua_isnoneornil(L, 2))
if (lua_type(L, 1) == LUA_TNUMBER || lua_type(L, 2) == LUA_TNUMBER)
{
// First or second argument is a number: call newTrueTypeRasterizer.
return w_newTrueTypeRasterizer(L);
}
else if (lua_isnoneornil(L, 2))
{
// Single number argument: use the default TrueType font.
if (lua_type(L, 1) == LUA_TNUMBER)
return w_newTrueTypeRasterizer(L);
// Single argument of another type: call Font::newRasterizer.
Rasterizer *t = nullptr;
filesystem::FileData *d = filesystem::luax_getfiledata(L, 1);
@@ -56,11 +57,6 @@ int w_newRasterizer(lua_State *L)
t->release();
return 1;
}
else if (lua_type(L, 2) == LUA_TNUMBER)
{
// Second argument is a number: call newTrueTypeRasterizer.
return w_newTrueTypeRasterizer(L);
}
else
{
// Otherwise call newBMFontRasterizer.
@@ -71,12 +67,18 @@ int w_newRasterizer(lua_State *L)
int w_newTrueTypeRasterizer(lua_State *L)
{
Rasterizer *t = nullptr;
TrueTypeRasterizer::Hinting hinting = TrueTypeRasterizer::HINTING_NORMAL;
if (lua_type(L, 1) == LUA_TNUMBER)
{
// First argument is a number: use the default TrueType font.
int size = luaL_checkint(L, 1);
luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size); });
const char *hintstr = lua_isnoneornil(L, 2) ? nullptr : luaL_checkstring(L, 2);
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
return luaL_error(L, "Invalid TrueType font hinting mode: %s", hintstr);
luax_catchexcept(L, [&](){ t = instance()->newTrueTypeRasterizer(size, hinting); });
}
else
{
@@ -89,8 +91,12 @@ int w_newTrueTypeRasterizer(lua_State *L)
int size = luaL_optint(L, 2, 12);
const char *hintstr = lua_isnoneornil(L, 3) ? nullptr : luaL_checkstring(L, 3);
if (hintstr && !TrueTypeRasterizer::getConstant(hintstr, hinting))
return luaL_error(L, "Invalid TrueType font hinting mode: %s", hintstr);
luax_catchexcept(L,
[&]() { t = instance()->newTrueTypeRasterizer(d, size); },
[&]() { t = instance()->newTrueTypeRasterizer(d, size, hinting); },
[&]() { d->release(); }
);
}
@@ -102,7 +108,7 @@ int w_newTrueTypeRasterizer(lua_State *L)
static void convimagedata(lua_State *L, int idx)
{
if (lua_isstring(L, idx) || luax_istype(L, idx, FILESYSTEM_FILE_ID) || luax_istype(L, idx, FILESYSTEM_FILE_DATA_ID))
if (lua_type(L, 1) == LUA_TSTRING || luax_istype(L, idx, FILESYSTEM_FILE_ID) || luax_istype(L, idx, FILESYSTEM_FILE_DATA_ID))
luax_convobj(L, idx, "image", "newImageData");
}
+1 -1
View File
@@ -195,7 +195,7 @@ void Graphics::checkSetDefaultFont()
if (!fontmodule)
throw love::Exception("Font module has not been loaded.");
StrongRef<font::Rasterizer> r(fontmodule->newTrueTypeRasterizer(12));
StrongRef<font::Rasterizer> r(fontmodule->newTrueTypeRasterizer(12, font::TrueTypeRasterizer::HINTING_NORMAL));
r->release();
defaultFont.set(newFont(r.get()));
+1 -1
View File
@@ -137,7 +137,7 @@ void Image::generateMipmaps()
{
// Driver bug: http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation
#if defined(LOVE_WINDOWS) || defined(LOVE_LINUX)
if (gl.getVendor() == OpenGL::VENDOR_ATI_AMD)
if (gl.getVendor() == OpenGL::VENDOR_AMD)
glEnable(GL_TEXTURE_2D);
#endif
+1 -1
View File
@@ -160,7 +160,7 @@ void OpenGL::initVendor()
// http://feedback.wildfiregames.com/report/opengl/feature/GL_VENDOR
// http://stackoverflow.com/questions/2093594/opengl-extensions-available-on-different-android-devices
if (strstr(vstr, "ATI Technologies"))
vendor = VENDOR_ATI_AMD;
vendor = VENDOR_AMD;
else if (strstr(vstr, "NVIDIA"))
vendor = VENDOR_NVIDIA;
else if (strstr(vstr, "Intel"))
+1 -1
View File
@@ -72,7 +72,7 @@ public:
// OpenGL GPU vendors.
enum Vendor
{
VENDOR_ATI_AMD,
VENDOR_AMD,
VENDOR_NVIDIA,
VENDOR_INTEL,
VENDOR_MESA_SOFT, // Software renderer.