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
View File
@@ -235,6 +235,8 @@ set(LOVE_SRC_MODULE_FONT_ROOT
src/modules/font/ImageRasterizer.h
src/modules/font/Rasterizer.cpp
src/modules/font/Rasterizer.h
src/modules/font/TrueTypeRasterizer.cpp
src/modules/font/TrueTypeRasterizer.h
src/modules/font/wrap_Font.cpp
src/modules/font/wrap_Font.h
src/modules/font/wrap_GlyphData.cpp
@@ -854,6 +854,9 @@
FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; };
FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA627CD18E7E1560080752D /* CoreServices.framework */; };
FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; };
FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; };
FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; };
FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -1488,6 +1491,8 @@
FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
FAA627CD18E7E1560080752D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrueTypeRasterizer.cpp; sourceTree = "<group>"; };
FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrueTypeRasterizer.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -2137,6 +2142,8 @@
FA0B7B7D1A95902C000E1D17 /* ImageRasterizer.h */,
FA0B7B7E1A95902C000E1D17 /* Rasterizer.cpp */,
FA0B7B7F1A95902C000E1D17 /* Rasterizer.h */,
FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */,
FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */,
FA0B7B801A95902C000E1D17 /* Vera.ttf.h */,
FA0B7B811A95902C000E1D17 /* wrap_Font.cpp */,
FA0B7B821A95902C000E1D17 /* wrap_Font.h */,
@@ -2810,6 +2817,7 @@
FA0B7DB01A95902C000E1D17 /* wrap_CompressedData.h in Headers */,
FA0B7AC11A958EA3000E1D17 /* callbacks.h in Headers */,
FA0B7D8F1A95902C000E1D17 /* ddsHandler.h in Headers */,
FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */,
FA0B7AA31A958EA3000E1D17 /* b2PulleyJoint.h in Headers */,
FA0B7B2F1A958EA3000E1D17 /* utf8.h in Headers */,
FA0B79231A958E3B000E1D17 /* EnumMap.h in Headers */,
@@ -3365,6 +3373,7 @@
FA0B7AF21A958EA3000E1D17 /* io.c in Sources */,
FA0B7DBF1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
FA0B7D4F1A95902C000E1D17 /* SpriteBatch.cpp in Sources */,
FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */,
FA0B7A9F1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */,
FA0B79331A958E3B000E1D17 /* Object.cpp in Sources */,
FA0B7E5B1A95902C000E1D17 /* wrap_MotorJoint.cpp in Sources */,
@@ -3644,6 +3653,7 @@
FA0B7A671A958EA3000E1D17 /* b2Island.cpp in Sources */,
FA0B7DBE1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
FA0B7D4E1A95902C000E1D17 /* SpriteBatch.cpp in Sources */,
FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */,
FA0B7ACD1A958EA3000E1D17 /* packet.c in Sources */,
FA0B7A921A958EA3000E1D17 /* b2GearJoint.cpp in Sources */,
FA0B7E5A1A95902C000E1D17 /* wrap_MotorJoint.cpp in Sources */,
+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.