CLuaInstance: Add DynFonts for lua scripts

- You can create fixed-size fonts for use in Lua Scripts
 - The fonts are deleted after the script
 - The use of fonts is limited to the following functions currently:
   - RenderString()
   - getRenderWidth()
   - FontHeight()
 - Example in Lua scripts:
   Normal usage:
     local font = FONT.MENU
     RenderString(font, ....)
   Use DynFonts:
     Creates a font with height of 50px:
       local font = n:getDynFont(0, 50)
       local useDynFont = true
       RenderString(useDynFont, font, ....)
           or
     Creates a font in which the text("Example: xyz") has a width of 200px:
       local font = n:getDynFont(200, 0, "Example: xyz")
       local useDynFont = true
       RenderString(useDynFont, font, ....)

 - Set Lua api version to 1.13
This commit is contained in:
M. Liebmann
2015-11-27 12:11:50 +01:00
parent 56d76f4ebc
commit a307e806eb
2 changed files with 205 additions and 30 deletions

View File

@@ -34,6 +34,7 @@
#include <gui/filebrowser.h>
#include <gui/movieplayer.h>
#include <gui/infoclock.h>
#include <driver/neutrinofonts.h>
#include <driver/pictureviewer/pictureviewer.h>
#include <neutrino.h>
#include <zapit/types.h>
@@ -310,6 +311,18 @@ static void set_lua_variables(lua_State *L)
{ NULL, 0 }
};
table_key dynfont[] =
{
{ "STYLE_REGULAR", (lua_Integer)CNeutrinoFonts::FONT_STYLE_REGULAR },
{ "STYLE_BOLD", (lua_Integer)CNeutrinoFonts::FONT_STYLE_BOLD },
{ "STYLE_ITALIC", (lua_Integer)CNeutrinoFonts::FONT_STYLE_ITALIC },
{ "MAX", (lua_Integer)CNeutrinoFonts::DYNFONTEXT_MAX },
{ "MAXIMUM_FONTS", (lua_Integer)CLuaInstance::DYNFONT_MAXIMUM_FONTS },
{ "TO_WIDE", (lua_Integer)CLuaInstance::DYNFONT_TO_WIDE },
{ "TOO_HIGH", (lua_Integer)CLuaInstance::DYNFONT_TOO_HIGH },
{ NULL, 0 }
};
/* list of environment variable arrays to be exported */
lua_envexport e[] =
{
@@ -321,6 +334,7 @@ static void set_lua_variables(lua_State *L)
{ "APIVERSION", apiversion },
{ "PLAYSTATE", playstate },
{ "CC", ccomponents },
{ "DYNFONT", dynfont },
{ NULL, NULL }
};
@@ -564,6 +578,7 @@ const luaL_Reg CLuaInstance::methods[] =
{ "checkVersion", CLuaInstance::checkVersion },
{ "createChannelIDfromUrl", CLuaInstance::createChannelIDfromUrl },
{ "enableInfoClock", CLuaInstance::enableInfoClock },
{ "getDynFont", CLuaInstance::getDynFont },
{ NULL, NULL }
};
@@ -671,12 +686,14 @@ int CLuaInstance::PaintBox(lua_State *L)
y = luaL_checkint(L, 3);
w = luaL_checkint(L, 4);
h = luaL_checkint(L, 5);
#if HAVE_COOL_HARDWARE
c = luaL_checkunsigned(L, 6);
#else
/* luaL_checkint does not like e.g. 0xffcc0000 on powerpc (returns INT_MAX) instead */
c = (unsigned int)luaL_checknumber(L, 6);
#endif
if (count > 6)
radius = luaL_checkint(L, 7);
if (count > 7)
@@ -872,7 +889,8 @@ int CLuaInstance::GetSize(lua_State *L)
int CLuaInstance::RenderString(lua_State *L)
{
int x, y, w, boxh, f, center;
int x, y, w, boxh, f, center, id;
Font* font = NULL;
unsigned int c;
const char *text;
int numargs = lua_gettop(L);
@@ -884,53 +902,110 @@ int CLuaInstance::RenderString(lua_State *L)
CLuaData *W = CheckData(L, 1);
if (!W || !W->fbwin)
return 0;
f = luaL_checkint(L, 2); /* font number, use FONT_TYPE_XXX in the script */
text = luaL_checkstring(L, 3); /* text */
x = luaL_checkint(L, 4);
y = luaL_checkint(L, 5);
if (numargs > 5)
int step = 0;
bool isDynFont = false;
if (lua_isboolean(L, 2)) {
if (lua_toboolean(L, 2) == true)
isDynFont = true;
step = 1;
}
if (!isDynFont) {
f = luaL_checkint(L, 2+step); /* font number, use FONT_TYPE_XXX in the script */
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
f = SNeutrinoSettings::FONT_TYPE_MENU;
font = g_Font[f];
}
else {
id = luaL_checkint(L, 2+step); /* dynfont */
for (fontmap_iterator_t it = W->fontmap.begin(); it != W->fontmap.end(); ++it) {
if (it->first == id) {
font = it->second;
break;
}
}
if (font == NULL) {
printf("[CLuaInstance::%s:%d] no font found\n", __func__, __LINE__);
lua_pushinteger(L, 0); /* no font found */
return 1;
}
}
text = luaL_checkstring(L, 3+step); /* text */
x = luaL_checkint(L, 4+step);
y = luaL_checkint(L, 5+step);
if (numargs > 5+step)
#if HAVE_COOL_HARDWARE
c = luaL_checkunsigned(L, 6);
c = luaL_checkunsigned(L, 6+step);
#else
c = luaL_checkint(L, 6);
c = luaL_checkint(L, 6+step);
#endif
if (numargs > 6)
w = luaL_checkint(L, 7);
if (numargs > 6+step)
w = luaL_checkint(L, 7+step);
else
w = W->fbwin->dx - x;
if (numargs > 7)
boxh = luaL_checkint(L, 8);
if (numargs > 8)
center = luaL_checkint(L, 9);
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
f = SNeutrinoSettings::FONT_TYPE_MENU;
int rwidth = g_Font[f]->getRenderWidth(text);
if (numargs > 7+step)
boxh = luaL_checkint(L, 8+step);
if (numargs > 8+step)
center = luaL_checkint(L, 9+step);
int rwidth = font->getRenderWidth(text);
if (center) { /* center the text inside the box */
if (rwidth < w)
x += (w - rwidth) / 2;
}
checkMagicMask(c);
if (boxh > -1) /* if boxh < 0, don't paint string */
W->fbwin->RenderString(g_Font[f], x, y, w, text, c, boxh);
W->fbwin->RenderString(font, x, y, w, text, c, boxh);
lua_pushinteger(L, rwidth); /* return renderwidth */
return 1;
}
int CLuaInstance::getRenderWidth(lua_State *L)
{
int f;
int f, id;
Font* font = NULL;
const char *text;
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
CLuaData *W = CheckData(L, 1);
if (!W)
return 0;
f = luaL_checkint(L, 2); /* font number, use FONT['xxx'] for FONT_TYPE_xxx in the script */
text = luaL_checkstring(L, 3); /* text */
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
f = SNeutrinoSettings::FONT_TYPE_MENU;
lua_pushinteger(L, (int)g_Font[f]->getRenderWidth(text));
int step = 0;
bool isDynFont = false;
if (lua_isboolean(L, 2)) {
if (lua_toboolean(L, 2) == true)
isDynFont = true;
step = 1;
}
if (!isDynFont) {
f = luaL_checkint(L, 2+step); /* font number, use FONT_TYPE_XXX in the script */
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
f = SNeutrinoSettings::FONT_TYPE_MENU;
font = g_Font[f];
}
else {
id = luaL_checkint(L, 2+step); /* dynfont */
for (fontmap_iterator_t it = W->fontmap.begin(); it != W->fontmap.end(); ++it) {
if (it->first == id) {
font = it->second;
break;
}
}
if (font == NULL) {
printf("[CLuaInstance::%s:%d] no font found\n", __func__, __LINE__);
lua_pushinteger(L, 0); /* no font found */
return 1;
}
}
text = luaL_checkstring(L, 3+step); /* text */
lua_pushinteger(L, (int)font->getRenderWidth(text));
return 1;
}
@@ -961,16 +1036,44 @@ int CLuaInstance::GetInput(lua_State *L)
int CLuaInstance::FontHeight(lua_State *L)
{
int f;
int f, id;
Font* font = NULL;
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
CLuaData *W = CheckData(L, 1);
if (!W)
return 0;
f = luaL_checkint(L, 2); /* font number, use FONT['xxx'] for FONT_TYPE_xxx in the script */
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
f = SNeutrinoSettings::FONT_TYPE_MENU;
lua_pushinteger(L, (int)g_Font[f]->getHeight());
int step = 0;
bool isDynFont = false;
if (lua_isboolean(L, 2)) {
if (lua_toboolean(L, 2) == true)
isDynFont = true;
step = 1;
}
if (!isDynFont) {
f = luaL_checkint(L, 2+step); /* font number, use FONT_TYPE_XXX in the script */
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
f = SNeutrinoSettings::FONT_TYPE_MENU;
font = g_Font[f];
}
else {
id = luaL_checkint(L, 2+step); /* dynfont */
for (fontmap_iterator_t it = W->fontmap.begin(); it != W->fontmap.end(); ++it) {
if (it->first == id) {
font = it->second;
break;
}
}
if (font == NULL) {
printf("[CLuaInstance::%s:%d] no font found\n", __func__, __LINE__);
lua_pushinteger(L, 0); /* no font found */
return 1;
}
}
lua_pushinteger(L, (int)font->getHeight());
return 1;
}
@@ -978,6 +1081,12 @@ int CLuaInstance::GCWindow(lua_State *L)
{
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
CLuaData *w = (CLuaData *)lua_unboxpointer(L, 1);
if (w && w->fbwin) {
w->fontmap.clear();
}
CNeutrinoFonts::getInstance()->deleteDynFontExtAll();
delete w->fbwin;
w->rcinput = NULL;
delete w;
@@ -2808,3 +2917,56 @@ int CLuaInstance::enableInfoClock(lua_State *L)
}
// --------------------------------------------------------------------------------
int CLuaInstance::getDynFont(lua_State *L)
{
int numargs = lua_gettop(L);
CLuaData *W = CheckData(L, 1);
if (!W || !W->fbwin)
return 0;
if (numargs < 3) {
printf("CLuaInstance::%s: not enough arguments (%d, expected 2)\n", __func__, numargs);
return 0;
}
lua_Integer fontID = W->fontmap.size();
if (fontID >= CNeutrinoFonts::DYNFONTEXT_MAX) {
lua_pushnil(L);
lua_pushinteger(L, DYNFONT_MAXIMUM_FONTS);
return 2;
}
lua_Integer dx = 0, dy = 0, style = CNeutrinoFonts::FONT_STYLE_REGULAR;
std::string text="";
dx = luaL_checkint(L, 2);
if (dx > (lua_Integer)CFrameBuffer::getInstance()->getScreenWidth(true)) {
lua_pushnil(L);
lua_pushinteger(L, DYNFONT_TO_WIDE);
return 2;
}
dy = luaL_checkint(L, 3);
if (dy > 100) {
lua_pushnil(L);
lua_pushinteger(L, DYNFONT_TOO_HIGH);
return 2;
}
if (numargs > 3)
text = luaL_checkstring(L, 4);
if (numargs > 4) {
style = luaL_checkint(L, 5);
if (style > CNeutrinoFonts::FONT_STYLE_ITALIC)
style = CNeutrinoFonts::FONT_STYLE_REGULAR;
}
Font* f = CNeutrinoFonts::getInstance()->getDynFontExt(dx, dy, fontID, text, style);
lua_Integer id = fontID + 1;
W->fontmap.insert(fontmap_pair_t(id, f));
lua_pushinteger(L, id);
lua_pushinteger(L, DYNFONT_NO_ERROR);
return 2;
}
// --------------------------------------------------------------------------------

View File

@@ -34,13 +34,18 @@ extern "C" {
#include <vector>
#define LUA_API_VERSION_MAJOR 1
#define LUA_API_VERSION_MINOR 12
#define LUA_API_VERSION_MINOR 13
typedef std::pair<lua_Integer, Font*> fontmap_pair_t;
typedef std::map<lua_Integer, Font*> fontmap_t;
typedef fontmap_t::iterator fontmap_iterator_t;
/* this is stored as userdata in the lua_State */
struct CLuaData
{
CFBWindow *fbwin;
CRCInput *rcinput;
fontmap_t fontmap;
};
struct CLuaMenuItem
@@ -200,6 +205,13 @@ public:
void runScript(const char *fileName, std::vector<std::string> *argv = NULL, std::string *result_code = NULL, std::string *result_string = NULL, std::string *error_string = NULL);
void abortScript();
enum {
DYNFONT_NO_ERROR = 0,
DYNFONT_MAXIMUM_FONTS = 1,
DYNFONT_TO_WIDE = 2,
DYNFONT_TOO_HIGH = 3
};
// Example: runScript(fileName, "Arg1", "Arg2", "Arg3", ..., NULL);
// Type of all parameters: const char*
// The last parameter to NULL is imperative.
@@ -324,6 +336,7 @@ private:
static int checkVersion(lua_State *L);
static int createChannelIDfromUrl(lua_State *L);
static int enableInfoClock(lua_State *L);
static int getDynFont(lua_State *L);
};
#endif /* _LUAINSTANCE_H */