mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-29 00:11:14 +02:00
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:
@@ -34,6 +34,7 @@
|
|||||||
#include <gui/filebrowser.h>
|
#include <gui/filebrowser.h>
|
||||||
#include <gui/movieplayer.h>
|
#include <gui/movieplayer.h>
|
||||||
#include <gui/infoclock.h>
|
#include <gui/infoclock.h>
|
||||||
|
#include <driver/neutrinofonts.h>
|
||||||
#include <driver/pictureviewer/pictureviewer.h>
|
#include <driver/pictureviewer/pictureviewer.h>
|
||||||
#include <neutrino.h>
|
#include <neutrino.h>
|
||||||
#include <zapit/types.h>
|
#include <zapit/types.h>
|
||||||
@@ -310,6 +311,18 @@ static void set_lua_variables(lua_State *L)
|
|||||||
{ NULL, 0 }
|
{ 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 */
|
/* list of environment variable arrays to be exported */
|
||||||
lua_envexport e[] =
|
lua_envexport e[] =
|
||||||
{
|
{
|
||||||
@@ -321,6 +334,7 @@ static void set_lua_variables(lua_State *L)
|
|||||||
{ "APIVERSION", apiversion },
|
{ "APIVERSION", apiversion },
|
||||||
{ "PLAYSTATE", playstate },
|
{ "PLAYSTATE", playstate },
|
||||||
{ "CC", ccomponents },
|
{ "CC", ccomponents },
|
||||||
|
{ "DYNFONT", dynfont },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -564,6 +578,7 @@ const luaL_Reg CLuaInstance::methods[] =
|
|||||||
{ "checkVersion", CLuaInstance::checkVersion },
|
{ "checkVersion", CLuaInstance::checkVersion },
|
||||||
{ "createChannelIDfromUrl", CLuaInstance::createChannelIDfromUrl },
|
{ "createChannelIDfromUrl", CLuaInstance::createChannelIDfromUrl },
|
||||||
{ "enableInfoClock", CLuaInstance::enableInfoClock },
|
{ "enableInfoClock", CLuaInstance::enableInfoClock },
|
||||||
|
{ "getDynFont", CLuaInstance::getDynFont },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -671,12 +686,14 @@ int CLuaInstance::PaintBox(lua_State *L)
|
|||||||
y = luaL_checkint(L, 3);
|
y = luaL_checkint(L, 3);
|
||||||
w = luaL_checkint(L, 4);
|
w = luaL_checkint(L, 4);
|
||||||
h = luaL_checkint(L, 5);
|
h = luaL_checkint(L, 5);
|
||||||
|
|
||||||
#if HAVE_COOL_HARDWARE
|
#if HAVE_COOL_HARDWARE
|
||||||
c = luaL_checkunsigned(L, 6);
|
c = luaL_checkunsigned(L, 6);
|
||||||
#else
|
#else
|
||||||
/* luaL_checkint does not like e.g. 0xffcc0000 on powerpc (returns INT_MAX) instead */
|
/* luaL_checkint does not like e.g. 0xffcc0000 on powerpc (returns INT_MAX) instead */
|
||||||
c = (unsigned int)luaL_checknumber(L, 6);
|
c = (unsigned int)luaL_checknumber(L, 6);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (count > 6)
|
if (count > 6)
|
||||||
radius = luaL_checkint(L, 7);
|
radius = luaL_checkint(L, 7);
|
||||||
if (count > 7)
|
if (count > 7)
|
||||||
@@ -872,7 +889,8 @@ int CLuaInstance::GetSize(lua_State *L)
|
|||||||
|
|
||||||
int CLuaInstance::RenderString(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;
|
unsigned int c;
|
||||||
const char *text;
|
const char *text;
|
||||||
int numargs = lua_gettop(L);
|
int numargs = lua_gettop(L);
|
||||||
@@ -884,53 +902,110 @@ int CLuaInstance::RenderString(lua_State *L)
|
|||||||
CLuaData *W = CheckData(L, 1);
|
CLuaData *W = CheckData(L, 1);
|
||||||
if (!W || !W->fbwin)
|
if (!W || !W->fbwin)
|
||||||
return 0;
|
return 0;
|
||||||
f = luaL_checkint(L, 2); /* font number, use FONT_TYPE_XXX in the script */
|
|
||||||
text = luaL_checkstring(L, 3); /* text */
|
int step = 0;
|
||||||
x = luaL_checkint(L, 4);
|
bool isDynFont = false;
|
||||||
y = luaL_checkint(L, 5);
|
if (lua_isboolean(L, 2)) {
|
||||||
if (numargs > 5)
|
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
|
#if HAVE_COOL_HARDWARE
|
||||||
c = luaL_checkunsigned(L, 6);
|
c = luaL_checkunsigned(L, 6+step);
|
||||||
#else
|
#else
|
||||||
c = luaL_checkint(L, 6);
|
c = luaL_checkint(L, 6+step);
|
||||||
#endif
|
#endif
|
||||||
if (numargs > 6)
|
if (numargs > 6+step)
|
||||||
w = luaL_checkint(L, 7);
|
w = luaL_checkint(L, 7+step);
|
||||||
else
|
else
|
||||||
w = W->fbwin->dx - x;
|
w = W->fbwin->dx - x;
|
||||||
if (numargs > 7)
|
if (numargs > 7+step)
|
||||||
boxh = luaL_checkint(L, 8);
|
boxh = luaL_checkint(L, 8+step);
|
||||||
if (numargs > 8)
|
if (numargs > 8+step)
|
||||||
center = luaL_checkint(L, 9);
|
center = luaL_checkint(L, 9+step);
|
||||||
if (f >= SNeutrinoSettings::FONT_TYPE_COUNT || f < 0)
|
|
||||||
f = SNeutrinoSettings::FONT_TYPE_MENU;
|
int rwidth = font->getRenderWidth(text);
|
||||||
int rwidth = g_Font[f]->getRenderWidth(text);
|
|
||||||
if (center) { /* center the text inside the box */
|
if (center) { /* center the text inside the box */
|
||||||
if (rwidth < w)
|
if (rwidth < w)
|
||||||
x += (w - rwidth) / 2;
|
x += (w - rwidth) / 2;
|
||||||
}
|
}
|
||||||
checkMagicMask(c);
|
checkMagicMask(c);
|
||||||
if (boxh > -1) /* if boxh < 0, don't paint string */
|
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 */
|
lua_pushinteger(L, rwidth); /* return renderwidth */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CLuaInstance::getRenderWidth(lua_State *L)
|
int CLuaInstance::getRenderWidth(lua_State *L)
|
||||||
{
|
{
|
||||||
int f;
|
int f, id;
|
||||||
|
Font* font = NULL;
|
||||||
const char *text;
|
const char *text;
|
||||||
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
||||||
|
|
||||||
CLuaData *W = CheckData(L, 1);
|
CLuaData *W = CheckData(L, 1);
|
||||||
if (!W)
|
if (!W)
|
||||||
return 0;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -961,16 +1036,44 @@ int CLuaInstance::GetInput(lua_State *L)
|
|||||||
|
|
||||||
int CLuaInstance::FontHeight(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));
|
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
||||||
|
|
||||||
CLuaData *W = CheckData(L, 1);
|
CLuaData *W = CheckData(L, 1);
|
||||||
if (!W)
|
if (!W)
|
||||||
return 0;
|
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)
|
int step = 0;
|
||||||
f = SNeutrinoSettings::FONT_TYPE_MENU;
|
bool isDynFont = false;
|
||||||
lua_pushinteger(L, (int)g_Font[f]->getHeight());
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -978,6 +1081,12 @@ int CLuaInstance::GCWindow(lua_State *L)
|
|||||||
{
|
{
|
||||||
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
DBG1("CLuaInstance::%s %d\n", __func__, lua_gettop(L));
|
||||||
CLuaData *w = (CLuaData *)lua_unboxpointer(L, 1);
|
CLuaData *w = (CLuaData *)lua_unboxpointer(L, 1);
|
||||||
|
|
||||||
|
if (w && w->fbwin) {
|
||||||
|
w->fontmap.clear();
|
||||||
|
}
|
||||||
|
CNeutrinoFonts::getInstance()->deleteDynFontExtAll();
|
||||||
|
|
||||||
delete w->fbwin;
|
delete w->fbwin;
|
||||||
w->rcinput = NULL;
|
w->rcinput = NULL;
|
||||||
delete w;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
@@ -34,13 +34,18 @@ extern "C" {
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define LUA_API_VERSION_MAJOR 1
|
#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 */
|
/* this is stored as userdata in the lua_State */
|
||||||
struct CLuaData
|
struct CLuaData
|
||||||
{
|
{
|
||||||
CFBWindow *fbwin;
|
CFBWindow *fbwin;
|
||||||
CRCInput *rcinput;
|
CRCInput *rcinput;
|
||||||
|
fontmap_t fontmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CLuaMenuItem
|
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 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();
|
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);
|
// Example: runScript(fileName, "Arg1", "Arg2", "Arg3", ..., NULL);
|
||||||
// Type of all parameters: const char*
|
// Type of all parameters: const char*
|
||||||
// The last parameter to NULL is imperative.
|
// The last parameter to NULL is imperative.
|
||||||
@@ -324,6 +336,7 @@ private:
|
|||||||
static int checkVersion(lua_State *L);
|
static int checkVersion(lua_State *L);
|
||||||
static int createChannelIDfromUrl(lua_State *L);
|
static int createChannelIDfromUrl(lua_State *L);
|
||||||
static int enableInfoClock(lua_State *L);
|
static int enableInfoClock(lua_State *L);
|
||||||
|
static int getDynFont(lua_State *L);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _LUAINSTANCE_H */
|
#endif /* _LUAINSTANCE_H */
|
||||||
|
Reference in New Issue
Block a user