From d48d1fd441123bc22dc44ad3611545784290d89f Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Sun, 16 Jun 2013 07:36:18 -0300 Subject: [PATCH] Exposed the internal Rasterizer and GlyphData object methods to Lua. Also added Font:hasGlyph. --- src/modules/font/Font.h | 1 + src/modules/font/GlyphData.cpp | 47 +++++++- src/modules/font/GlyphData.h | 30 ++++-- src/modules/font/ImageRasterizer.cpp | 5 + src/modules/font/ImageRasterizer.h | 1 + src/modules/font/Rasterizer.cpp | 38 +++++++ src/modules/font/Rasterizer.h | 26 ++++- src/modules/font/freetype/Font.cpp | 22 +++- src/modules/font/freetype/Font.h | 1 + .../font/freetype/TrueTypeRasterizer.cpp | 9 +- .../font/freetype/TrueTypeRasterizer.h | 1 + src/modules/font/freetype/wrap_Font.cpp | 26 ++++- src/modules/font/wrap_GlyphData.cpp | 101 ++++++++++++++++++ src/modules/font/wrap_GlyphData.h | 9 ++ src/modules/font/wrap_Rasterizer.cpp | 100 +++++++++++++++++ src/modules/font/wrap_Rasterizer.h | 8 ++ src/modules/graphics/opengl/Font.cpp | 14 ++- src/modules/graphics/opengl/Font.h | 3 + src/modules/graphics/opengl/wrap_Font.cpp | 22 ++++ src/modules/graphics/opengl/wrap_Font.h | 1 + src/modules/graphics/opengl/wrap_Graphics.cpp | 8 +- 21 files changed, 449 insertions(+), 24 deletions(-) diff --git a/src/modules/font/Font.h b/src/modules/font/Font.h index 827a81746..b7029fa84 100644 --- a/src/modules/font/Font.h +++ b/src/modules/font/Font.h @@ -42,6 +42,7 @@ public: virtual Rasterizer *newRasterizer(Data *data, int size) = 0; virtual Rasterizer *newRasterizer(love::image::ImageData *data, const std::string &glyphs) = 0; virtual Rasterizer *newRasterizer(love::image::ImageData *data, unsigned int *glyphs, int length) = 0; + virtual GlyphData *newGlyphData(Rasterizer *r, const std::string &glyph) = 0; virtual GlyphData *newGlyphData(Rasterizer *r, unsigned int glyph) = 0; // Implement Module diff --git a/src/modules/font/GlyphData.cpp b/src/modules/font/GlyphData.cpp index 8054d7c6e..15f903fc4 100644 --- a/src/modules/font/GlyphData.cpp +++ b/src/modules/font/GlyphData.cpp @@ -18,8 +18,13 @@ * 3. This notice may not be removed or altered from any source distribution. **/ +// LOVE #include "GlyphData.h" +// UTF-8 +#include "libraries/utf8/utf8.h" + +// stdlib #include namespace love @@ -33,7 +38,7 @@ GlyphData::GlyphData(unsigned int glyph, GlyphMetrics glyphMetrics, GlyphData::F , data(0) , format(f) { - if (metrics.width && metrics.height) + if (metrics.width > 0 && metrics.height > 0) { switch (f) { @@ -88,6 +93,28 @@ unsigned int GlyphData::getGlyph() const return glyph; } +std::string GlyphData::getGlyphString() const +{ + char u[5] = {0, 0, 0, 0, 0}; + ptrdiff_t length = 0; + + try + { + char *end = utf8::append(glyph, u); + length = end - u; + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + // Just in case... + if (length < 0) + return ""; + + return std::string(u, length); +} + int GlyphData::getAdvance() const { return metrics.advance; @@ -128,5 +155,23 @@ GlyphData::Format GlyphData::getFormat() const return format; } +bool GlyphData::getConstant(const char *in, GlyphData::Format &out) +{ + return formats.find(in, out); +} + +bool GlyphData::getConstant(GlyphData::Format in, const char *&out) +{ + return formats.find(in, out); +} + +StringMap::Entry GlyphData::formatEntries[] = +{ + {"luminance alpha", GlyphData::FORMAT_LUMINANCE_ALPHA}, + {"rgba", GlyphData::FORMAT_RGBA}, +}; + +StringMap GlyphData::formats(GlyphData::formatEntries, sizeof(GlyphData::formatEntries)); + } // font } // love diff --git a/src/modules/font/GlyphData.h b/src/modules/font/GlyphData.h index acfd6a5b8..079c6717b 100644 --- a/src/modules/font/GlyphData.h +++ b/src/modules/font/GlyphData.h @@ -24,6 +24,11 @@ // LOVE #include "common/config.h" #include "common/Data.h" +#include "common/Exception.h" +#include "common/StringMap.h" + +// stdlib +#include namespace love { @@ -48,12 +53,13 @@ struct GlyphMetrics **/ class GlyphData : public Data { - public: + enum Format { FORMAT_LUMINANCE_ALPHA, - FORMAT_RGBA + FORMAT_RGBA, + FORMAT_MAX_ENUM }; GlyphData(unsigned int glyph, GlyphMetrics glyphMetrics, Format f); @@ -78,6 +84,11 @@ public: **/ unsigned int getGlyph() const; + /** + * Gets the glyph as a UTF-8 string (instead of a UTF-8 code point.) + **/ + std::string getGlyphString() const; + /** * Gets the advance (the space the glyph takes up) of the glyph. **/ @@ -118,19 +129,26 @@ public: **/ Format getFormat() const; + static bool getConstant(const char *in, Format &out); + static bool getConstant(Format in, const char *&out); + private: - // The glyph itself + + // The glyph codepoint itself. unsigned int glyph; - // Glyph metrics + // Glyph metrics. GlyphMetrics metrics; - // Glyph texture data + // Glyph texture data. unsigned char *data; - // The format the data's in + // The format the data's in. Format format; + static StringMap::Entry formatEntries[]; + static StringMap formats; + }; // GlyphData } // font diff --git a/src/modules/font/ImageRasterizer.cpp b/src/modules/font/ImageRasterizer.cpp index 5773b271a..3d3cf210c 100644 --- a/src/modules/font/ImageRasterizer.cpp +++ b/src/modules/font/ImageRasterizer.cpp @@ -151,5 +151,10 @@ int ImageRasterizer::getGlyphCount() const return numglyphs; } +bool ImageRasterizer::hasGlyph(unsigned int glyph) const +{ + return imageGlyphs.find(glyph) != imageGlyphs.end(); +} + } // font } // love diff --git a/src/modules/font/ImageRasterizer.h b/src/modules/font/ImageRasterizer.h index 863e54ff6..8bf40e135 100644 --- a/src/modules/font/ImageRasterizer.h +++ b/src/modules/font/ImageRasterizer.h @@ -46,6 +46,7 @@ public: virtual int getLineHeight() const; virtual GlyphData *getGlyphData(unsigned int glyph) const; virtual int getGlyphCount() const; + virtual bool hasGlyph(unsigned int glyph) const; private: // Load all the glyph positions into memory diff --git a/src/modules/font/Rasterizer.cpp b/src/modules/font/Rasterizer.cpp index 03f05a441..0e4c8abd7 100644 --- a/src/modules/font/Rasterizer.cpp +++ b/src/modules/font/Rasterizer.cpp @@ -21,6 +21,9 @@ // LOVE #include "Rasterizer.h" +// UTF-8 +#include "libraries/utf8/utf8.h" + namespace love { namespace font @@ -50,5 +53,40 @@ int Rasterizer::getDescent() const return metrics.descent; } +GlyphData *Rasterizer::getGlyphData(const std::string &text) const +{ + unsigned int codepoint = 0; + + try + { + codepoint = utf8::peek_next(text.begin(), text.end()); + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + return getGlyphData(codepoint); +} + +bool Rasterizer::hasGlyph(const std::string &text) const +{ + if (text.size() == 0) + return false; + + unsigned int codepoint = 0; + + try + { + codepoint = utf8::peek_next(text.begin(), text.end()); + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + return hasGlyph(codepoint); +} + } // font } // love \ No newline at end of file diff --git a/src/modules/font/Rasterizer.h b/src/modules/font/Rasterizer.h index a51435a2c..b98a23bdf 100644 --- a/src/modules/font/Rasterizer.h +++ b/src/modules/font/Rasterizer.h @@ -46,9 +46,6 @@ struct FontMetrics **/ class Rasterizer : public Object { -protected: - FontMetrics metrics; - public: virtual ~Rasterizer(); @@ -80,15 +77,36 @@ public: /** * Gets a specific glyph. - * @param glyph The (UNICODE) glyph to get data for + * @param glyph The (UNICODE) glyph codepoint to get data for. **/ virtual GlyphData *getGlyphData(unsigned int glyph) const = 0; + /** + * Gets a specific glyph. + * @param text The (UNICODE) glyph character to get the data for. + **/ + virtual GlyphData *getGlyphData(const std::string &text) const; + /** * Gets the number of glyphs the rasterizer has data for. **/ virtual int getGlyphCount() const = 0; + /** + * Gets whether this Rasterizer has a specific glyph. + * @param glyph The (UNICODE) glyph codepoint. + **/ + virtual bool hasGlyph(unsigned int glyph) const = 0; + + /** + * Gets whether this Rasterizer has a specific glyph. + * @param text The (UNICODE) glyph character. + **/ + virtual bool hasGlyph(const std::string &text) const; + +protected: + + FontMetrics metrics; }; // Rasterizer diff --git a/src/modules/font/freetype/Font.cpp b/src/modules/font/freetype/Font.cpp index 0379a847f..c9496e35b 100644 --- a/src/modules/font/freetype/Font.cpp +++ b/src/modules/font/freetype/Font.cpp @@ -66,12 +66,12 @@ Rasterizer *Font::newRasterizer(love::image::ImageData *data, const std::string catch (utf8::exception &e) { delete [] glyphs; - throw love::Exception("%s", e.what()); + throw love::Exception("Decoding error: %s", e.what()); } - + Rasterizer *r = newRasterizer(data, glyphs, numglyphs); delete [] glyphs; - + return r; } @@ -80,6 +80,22 @@ Rasterizer *Font::newRasterizer(love::image::ImageData *data, unsigned int *glyp return new ImageRasterizer(data, glyphs, numglyphs); } +GlyphData *Font::newGlyphData(Rasterizer *r, const std::string &text) +{ + unsigned int codepoint = 0; + + try + { + codepoint = utf8::peek_next(text.begin(), text.end()); + } + catch (utf8::exception &e) + { + throw love::Exception("Decoding error: %s", e.what()); + } + + return r->getGlyphData(codepoint); +} + GlyphData *Font::newGlyphData(Rasterizer *r, unsigned int glyph) { return r->getGlyphData(glyph); diff --git a/src/modules/font/freetype/Font.h b/src/modules/font/freetype/Font.h index b58d66589..d9c390c7d 100644 --- a/src/modules/font/freetype/Font.h +++ b/src/modules/font/freetype/Font.h @@ -57,6 +57,7 @@ public: Rasterizer *newRasterizer(Data *data, int size); Rasterizer *newRasterizer(love::image::ImageData *data, const std::string &text); Rasterizer *newRasterizer(love::image::ImageData *data, unsigned int *glyphs, int numglyphs); + GlyphData *newGlyphData(Rasterizer *r, const std::string &glyph); GlyphData *newGlyphData(Rasterizer *r, unsigned int glyph); // Implement Module diff --git a/src/modules/font/freetype/TrueTypeRasterizer.cpp b/src/modules/font/freetype/TrueTypeRasterizer.cpp index c457bfaa1..a63265107 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.cpp +++ b/src/modules/font/freetype/TrueTypeRasterizer.cpp @@ -91,8 +91,8 @@ GlyphData *TrueTypeRasterizer::getGlyphData(unsigned int glyph) const int size = bitmap.rows * bitmap.width; unsigned char *dst = (unsigned char *) glyphData->getData(); - // Note that bitmap.buffer contains only luminosity. We copy that single value to - // our luminosity-alpha format. + // Note that bitmap.buffer contains only luminosity. We copy that single + // value to our luminosity-alpha format. for (int i = 0; i < size; i++) { dst[2*i] = 255; @@ -111,6 +111,11 @@ int TrueTypeRasterizer::getGlyphCount() const return face->num_glyphs; } +bool TrueTypeRasterizer::hasGlyph(unsigned int glyph) const +{ + return FT_Get_Char_Index(face, glyph) != 0; +} + } // freetype } // font } // love \ No newline at end of file diff --git a/src/modules/font/freetype/TrueTypeRasterizer.h b/src/modules/font/freetype/TrueTypeRasterizer.h index 3efd2ad65..8e0be69d5 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.h +++ b/src/modules/font/freetype/TrueTypeRasterizer.h @@ -52,6 +52,7 @@ public: virtual int getLineHeight() const; virtual GlyphData *getGlyphData(unsigned int glyph) const; virtual int getGlyphCount() const; + virtual bool hasGlyph(unsigned int glyph) const; private: diff --git a/src/modules/font/freetype/wrap_Font.cpp b/src/modules/font/freetype/wrap_Font.cpp index 27830fe33..fa791d00c 100644 --- a/src/modules/font/freetype/wrap_Font.cpp +++ b/src/modules/font/freetype/wrap_Font.cpp @@ -38,6 +38,10 @@ static Font *instance = 0; int w_newRasterizer(lua_State *L) { + // Convert to FileData, if necessary. + if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T)) + luax_convobj(L, 1, "filesystem", "newFileData"); + Rasterizer *t = NULL; try { @@ -67,9 +71,27 @@ int w_newRasterizer(lua_State *L) int w_newGlyphData(lua_State *L) { Rasterizer *r = luax_checkrasterizer(L, 1); - unsigned int g = (unsigned int)luaL_checknumber(L, 2); + GlyphData *t = 0; + + // newGlyphData accepts a unicode character or a codepoint number. + if (lua_type(L, 2) == LUA_TSTRING) + { + std::string glyph = luax_checkstring(L, 2); + try + { + t = instance->newGlyphData(r, glyph); + } + catch (love::Exception &e) + { + return luaL_error(L, "%s", e.what()); + } + } + else + { + unsigned int g = (unsigned int) luaL_checknumber(L, 2); + t = instance->newGlyphData(r, g); + } - GlyphData *t = instance->newGlyphData(r, g); luax_newtype(L, "GlyphData", FONT_GLYPH_DATA_T, t); return 1; } diff --git a/src/modules/font/wrap_GlyphData.cpp b/src/modules/font/wrap_GlyphData.cpp index 6b236ba0c..6b6066b65 100644 --- a/src/modules/font/wrap_GlyphData.cpp +++ b/src/modules/font/wrap_GlyphData.cpp @@ -30,11 +30,112 @@ GlyphData *luax_checkglyphdata(lua_State *L, int idx) return luax_checktype(L, idx, "GlyphData", FONT_GLYPH_DATA_T); } +int w_GlyphData_getWidth(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getWidth()); + return 1; +} + +int w_GlyphData_getHeight(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getHeight()); + return 1; +} + +int w_GlyphData_getDimensions(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getWidth()); + lua_pushinteger(L, t->getHeight()); + return 2; +} + +int w_GlyphData_getGlyph(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + unsigned int glyph = t->getGlyph(); + lua_pushnumber(L, (lua_Number) glyph); + return 1; +} + +int w_GlyphData_getGlyphString(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + try + { + luax_pushstring(L, t->getGlyphString()); + } + catch (love::Exception &e) + { + return luaL_error(L, "%s", e.what()); + } + return 1; +} + +int w_GlyphData_getAdvance(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getAdvance()); + return 1; +} + +int w_GlyphData_getBearing(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + lua_pushinteger(L, t->getBearingX()); + lua_pushinteger(L, t->getBearingY()); + return 2; +} + +int w_GlyphData_getBoundingBox(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + + int minX = t->getMinX(); + int minY = t->getMinY(); + int maxX = t->getMaxX(); + int maxY = t->getMaxY(); + + int width = maxX - minX; + int height = maxY - minY; + + lua_pushinteger(L, minX); + lua_pushinteger(L, minY); + lua_pushinteger(L, width); + lua_pushinteger(L, height); + + return 4; +} + +int w_GlyphData_getFormat(lua_State *L) +{ + GlyphData *t = luax_checkglyphdata(L, 1); + + const char *str; + if (!GlyphData::getConstant(t->getFormat(), str)) + return luaL_error(L, "unknown GlyphData format."); + + lua_pushstring(L, str); + return 1; +} + static const luaL_Reg functions[] = { // Data { "getString", w_Data_getString }, { "getSize", w_Data_getSize }, + + { "getWidth", w_GlyphData_getWidth }, + { "getHeight", w_GlyphData_getHeight }, + { "getDimensions", w_GlyphData_getDimensions }, + { "getGlyph", w_GlyphData_getGlyph }, + { "getGlyphString", w_GlyphData_getGlyphString }, + { "getAdvance", w_GlyphData_getAdvance }, + { "getBearing", w_GlyphData_getBearing }, + { "getBoundingBox", w_GlyphData_getBoundingBox }, + { "getFormat", w_GlyphData_getFormat }, { 0, 0 } }; diff --git a/src/modules/font/wrap_GlyphData.h b/src/modules/font/wrap_GlyphData.h index 40b963b73..d76881d17 100644 --- a/src/modules/font/wrap_GlyphData.h +++ b/src/modules/font/wrap_GlyphData.h @@ -33,6 +33,15 @@ namespace font { GlyphData *luax_checkglyphdata(lua_State *L, int idx); +int w_GlyphData_getWidth(lua_State *L); +int w_GlyphData_getHeight(lua_State *L); +int w_GlyphData_getDimensions(lua_State *L); +int w_GlyphData_getGlyph(lua_State *L); +int w_GlyphData_getGlyphString(lua_State *L); +int w_GlyphData_getAdvance(lua_State *L); +int w_GlyphData_getBearing(lua_State *L); +int w_GlyphData_getBoundingBox(lua_State *L); +int w_GlyphData_getFormat(lua_State *L); extern "C" int luaopen_glyphdata(lua_State *L); } // font diff --git a/src/modules/font/wrap_Rasterizer.cpp b/src/modules/font/wrap_Rasterizer.cpp index 169daad7e..df9f539da 100644 --- a/src/modules/font/wrap_Rasterizer.cpp +++ b/src/modules/font/wrap_Rasterizer.cpp @@ -32,8 +32,108 @@ Rasterizer *luax_checkrasterizer(lua_State *L, int idx) return luax_checktype(L, idx, "Rasterizer", FONT_RASTERIZER_T); } +int w_Rasterizer_getHeight(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getHeight()); + return 1; +} + +int w_Rasterizer_getAdvance(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getAdvance()); + return 1; +} + +int w_Rasterizer_getAscent(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getAscent()); + return 1; +} + +int w_Rasterizer_getDescent(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getDescent()); + return 1; +} + +int w_Rasterizer_getLineHeight(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getLineHeight()); + return 1; +} + +int w_Rasterizer_getGlyphData(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + GlyphData *g = 0; + + try + { + // getGlyphData accepts a unicode character or a codepoint number. + if (lua_type(L, 2) == LUA_TSTRING) + { + std::string glyph = luax_checkstring(L, 2); + g = t->getGlyphData(glyph); + } + else + { + unsigned int glyph = (unsigned int) luaL_checknumber(L, 2); + g = t->getGlyphData(glyph); + } + } + catch (love::Exception &e) + { + return luaL_error(L, "%s", e.what()); + } + + luax_newtype(L, "GlyphData", FONT_GLYPH_DATA_T, (void *) g); + return 1; +} + +int w_Rasterizer_getGlyphCount(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + lua_pushinteger(L, t->getGlyphCount()); + return 1; +} + +int w_Rasterizer_hasGlyph(lua_State *L) +{ + Rasterizer *t = luax_checkrasterizer(L, 1); + + bool hasglyph = false; + + try + { + if (lua_type(L, 2) == LUA_TSTRING) + hasglyph = t->hasGlyph(luax_checkstring(L, 2)); + else + hasglyph = t->hasGlyph((unsigned int) luaL_checknumber(L, 2)); + } + catch (love::Exception &e) + { + return luaL_error(L, "%s", e.what()); + } + + luax_pushboolean(L, hasglyph); + return 1; +} + static const luaL_Reg functions[] = { + { "getHeight", w_Rasterizer_getHeight }, + { "getAdvance", w_Rasterizer_getAdvance }, + { "getAscent", w_Rasterizer_getAscent }, + { "getDescent", w_Rasterizer_getDescent }, + { "getLineHeight", w_Rasterizer_getLineHeight }, + { "getGlyphData", w_Rasterizer_getGlyphData }, + { "getGlyphCount", w_Rasterizer_getGlyphCount }, + { "hasGlyph", w_Rasterizer_hasGlyph }, { 0, 0 } }; diff --git a/src/modules/font/wrap_Rasterizer.h b/src/modules/font/wrap_Rasterizer.h index eabb6cdb3..f092e66b1 100644 --- a/src/modules/font/wrap_Rasterizer.h +++ b/src/modules/font/wrap_Rasterizer.h @@ -31,6 +31,14 @@ namespace font { Rasterizer *luax_checkrasterizer(lua_State *L, int idx); +int w_Rasterizer_getHeight(lua_State *L); +int w_Rasterizer_getAdvance(lua_State *L); +int w_Rasterizer_getAscent(lua_State *L); +int w_Rasterizer_getDescent(lua_State *L); +int w_Rasterizer_getLineHeight(lua_State *L); +int w_Rasterizer_getGlyphData(lua_State *L); +int w_Rasterizer_getGlyphCount(lua_State *L); +int w_Rasterizer_hasGlyph(lua_State *L); extern "C" int luaopen_rasterizer(lua_State *L); } // font diff --git a/src/modules/graphics/opengl/Font.cpp b/src/modules/graphics/opengl/Font.cpp index a76c15270..16c04a194 100644 --- a/src/modules/graphics/opengl/Font.cpp +++ b/src/modules/graphics/opengl/Font.cpp @@ -339,7 +339,7 @@ void Font::print(const std::string &text, float x, float y, float letter_spacing catch (utf8::exception &e) { glPopMatrix(); - throw love::Exception("%s", e.what()); + throw love::Exception("Decoding error: %s", e.what()); } if (quadindex > 0 && glyphinfolist.size() > 0) @@ -399,7 +399,7 @@ int Font::getWidth(const std::string &str) } catch(utf8::exception &e) { - throw love::Exception("%s", e.what()); + throw love::Exception("Decoding error: %s", e.what()); } if (width > max_width) @@ -559,6 +559,16 @@ float Font::getBaseline() const return (type == FONT_TRUETYPE) ? floor(getHeight() / 1.25f + 0.5f) : 0.0f; } +bool Font::hasGlyph(unsigned int glyph) const +{ + return rasterizer->hasGlyph(glyph); +} + +bool Font::hasGlyph(const std::string &text) const +{ + return rasterizer->hasGlyph(text); +} + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Font.h b/src/modules/graphics/opengl/Font.h index f070e4b8e..8a96d32f8 100644 --- a/src/modules/graphics/opengl/Font.h +++ b/src/modules/graphics/opengl/Font.h @@ -138,6 +138,9 @@ public: int getDescent() const; float getBaseline() const; + bool hasGlyph(unsigned int glyph) const; + bool hasGlyph(const std::string &text) const; + private: enum FontType diff --git a/src/modules/graphics/opengl/wrap_Font.cpp b/src/modules/graphics/opengl/wrap_Font.cpp index 82b5c152a..cc6dce784 100644 --- a/src/modules/graphics/opengl/wrap_Font.cpp +++ b/src/modules/graphics/opengl/wrap_Font.cpp @@ -152,6 +152,27 @@ int w_Font_getBaseline(lua_State *L) return 1; } +int w_Font_hasGlyph(lua_State *L) +{ + Font *t = luax_checkfont(L, 1); + bool hasglyph = false; + + try + { + if (lua_type(L, 2) == LUA_TSTRING) + hasglyph = t->hasGlyph(luax_checkstring(L, 2)); + else + hasglyph = t->hasGlyph((unsigned int) luaL_checknumber(L, 2)); + } + catch (love::Exception &e) + { + return luaL_error(L, "%s", e.what()); + } + + luax_pushboolean(L, hasglyph); + return 1; +} + static const luaL_Reg functions[] = { { "getHeight", w_Font_getHeight }, @@ -164,6 +185,7 @@ static const luaL_Reg functions[] = { "getAscent", w_Font_getAscent }, { "getDescent", w_Font_getDescent }, { "getBaseline", w_Font_getBaseline }, + { "hasGlyph", w_Font_hasGlyph }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Font.h b/src/modules/graphics/opengl/wrap_Font.h index 3482baf7f..8cd05fe65 100644 --- a/src/modules/graphics/opengl/wrap_Font.h +++ b/src/modules/graphics/opengl/wrap_Font.h @@ -43,6 +43,7 @@ int w_Font_getFilter(lua_State *L); int w_Font_getAscent(lua_State *L); int w_Font_getDescent(lua_State *L); int w_Font_getBaseline(lua_State *L); +int w_Font_hasGlyph(lua_State *L); extern "C" int luaopen_font(lua_State *L); } // opengl diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index e9b149b7a..85484ccf1 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -1150,9 +1150,9 @@ int w_print(lua_State *L) { instance->print(str, x, y, angle, sx, sy, ox, oy, kx,ky); } - catch(love::Exception e) + catch(love::Exception &e) { - return luaL_error(L, "Decoding error: %s", e.what()); + return luaL_error(L, "%s", e.what()); } return 0; } @@ -1193,9 +1193,9 @@ int w_printf(lua_State *L) { instance->printf(str, x, y, wrap, align, angle, sx, sy, ox, oy, kx, ky); } - catch(love::Exception e) + catch(love::Exception &e) { - return luaL_error(L, "Decoding error: %s", e.what()); + return luaL_error(L, "%s", e.what()); } return 0; }