From 40810b125143b767ca4abcfca3f7e2a90c85fc38 Mon Sep 17 00:00:00 2001 From: RodrigoDornelles Date: Fri, 22 Nov 2024 18:03:01 -0300 Subject: [PATCH] feat: start new text api --- ee/engine/core/ginga/draw.lua | 2 +- examples/asteroids/game.lua | 70 ++++++++++----------- examples/gridsystem/game.lua | 7 ++- examples/helloworld/game.lua | 2 +- examples/launcher/game.lua | 10 +-- examples/pong/game.lua | 4 +- examples/two_games/game.lua | 1 + src/engine/core/lite/main.lua | 2 +- src/engine/core/love/draw.lua | 49 --------------- src/engine/core/love/main.lua | 2 + src/engine/core/love/text.lua | 62 +++++++++++++++++++ src/engine/core/native/main.lua | 105 +++++++++++++++++++++++++++----- src/lib/util/http.lua | 2 +- tools/doxygen_filter.lua | 6 ++ 14 files changed, 207 insertions(+), 117 deletions(-) create mode 100644 src/engine/core/love/text.lua diff --git a/ee/engine/core/ginga/draw.lua b/ee/engine/core/ginga/draw.lua index 8866c33..b6bd3e7 100644 --- a/ee/engine/core/ginga/draw.lua +++ b/ee/engine/core/ginga/draw.lua @@ -92,7 +92,7 @@ local function install(std, engine) std.draw.text = util_decorator.prefix3(std, engine, engine.canvas, text) std.draw.font = util_decorator.prefix3(std, engine, engine.canvas, font) std.draw.line = util_decorator.prefix3(std, engine, engine.canvas, line) - std.draw.tui_text = util_decorator.prefix3(std, engine, engine.canvas, tui_text) + std.text.put = util_decorator.prefix3(std, engine, engine.canvas, tui_text) return { draw=std.draw diff --git a/examples/asteroids/game.lua b/examples/asteroids/game.lua index dd1c29f..86fc5f5 100644 --- a/examples/asteroids/game.lua +++ b/examples/asteroids/game.lua @@ -47,13 +47,13 @@ end local function draw_logo(std, game, height, anim) anim = anim or 0 - std.draw.font('sans', 32) + std.text.font_size(32) std.draw.color(std.color.white) - local s1 = std.draw.text('AsteroidsTv') - local s2 = std.draw.text('Tv') - std.draw.text(game.width/2 - s1/2, height + anim, 'Asteroids') + local s1 = std.text.mensure('AsteroidsTv') + local s2 = std.text.mensure('Tv') + std.text.print(game.width/2 - s1/2, height + anim, 'Asteroids') std.draw.color(std.color.red) - std.draw.text(game.width/2 + s1/2 - s2, height - anim, 'Tv') + std.text.print(game.width/2 + s1/2 - s2, height - anim, 'Tv') return s1 end @@ -395,40 +395,34 @@ local function draw(std, game) local language = std.i18n.get_language() local graphics = game.graphics_fastest == 1 and 'fast' or 'pretty' local s = draw_logo(std, game, h*2) - std.draw.font('sans', 16) + std.text.font_size(16) std.draw.color(std.color.white) if game.player_pos_x ~= (game.width/2) then - std.draw.text(game.width/2 - s, h*5, 'Continue') + std.text.print(game.width/2 - s, h*5, 'Continue') end - std.draw.text(game.width/2 - s, h*6, 'New Game') - std.draw.text(game.width/2 - s, h*7, 'Dificulty') - std.draw.text(game.width/2 - s, h*8, 'Invincibility') - std.draw.text(game.width/2 - s, h*9, 'Object Limit') - std.draw.text(game.width/2 - s, h*10, 'Graphics') - std.draw.text(game.width/2 - s, h*11, 'Language') - std.draw.text(game.width/2 - s, h*12, 'Credits') - std.draw.text(game.width/2 - s, h*13, 'Exit') + std.text.print(game.width/2 - s, h*6, 'New Game') + std.text.print(game.width/2 - s, h*7, 'Dificulty') + std.text.print(game.width/2 - s, h*8, 'Invincibility') + std.text.print(game.width/2 - s, h*9, 'Object Limit') + std.text.print(game.width/2 - s, h*10, 'Graphics') + std.text.print(game.width/2 - s, h*11, 'Language') + std.text.print(game.width/2 - s, h*12, 'Credits') + std.text.print(game.width/2 - s, h*13, 'Exit') std.draw.line(game.width/2 - s, hmenu, game.width/2 + s, hmenu) std.draw.color(std.color.red) - s2=std.draw.text(game.level) - std.draw.text(game.width/2 + s - s2, h*7, game.level) - s2=std.draw.text(game.imortal) - std.draw.text(game.width/2 + s - s2, h*8, game.imortal) - s2=std.draw.text(game.asteroids_max) - std.draw.text(game.width/2 + s - s2, h*9, game.asteroids_max) - s2=std.draw.text(graphics) - std.draw.text(game.width/2 + s - s2, h*10, graphics) - s3=std.draw.text(language) - std.draw.text(game.width/2 + s - s3, h*11, language) + std.text.print_ex(game.width/2 + s, h*7, game.level, -1) + std.text.print_ex(game.width/2 + s, h*8, game.imortal, -1) + std.text.print_ex(game.width/2 + s, h*9, game.asteroids_max, -1) + std.text.print_ex(game.width/2 + s, h*10, graphics, -1) + std.text.print_ex(game.width/2 + s, h*11, language, -1) return elseif game.state == 2 then local height = game.height/4 - local w = std.draw.text('Rodrigo Dornelles') local anim = std.math.cos(std.math.cycle(std.milis, 200) * std.math.pi*2) draw_logo(std, game, height, anim) - std.draw.font('sans', 16) + std.text.font_size(16) std.draw.color(std.color.white) - std.draw.text(game.width/2 - w/2 + (anim*0.5), height*2, 'Rodrigo Dornelles') + std.text.print_ex(game.width/2 + anim, height*2, 'Rodrigo Dornelles', 0) return end -- draw asteroids @@ -481,16 +475,16 @@ local function draw(std, game) std.draw.color(std.color.black) std.draw.rect(0, 0, 0, game.width, 32) std.draw.color(std.color.white) - s=std.draw.text(8, 8, 'lifes:') - std.draw.text(8+s, 8, game.lifes) - s=std.draw.text(w*2, 8, 'level:') - std.draw.text(w*2+s, 8, game.level) - s=std.draw.text(w*4, 8, 'asteroids:') - std.draw.text(w*4+s, 8, game.asteroids_count) - s=std.draw.text(w*9, 8, 'score:') - std.draw.text(w*9+s, 8, game.score) - s=std.draw.text(w*12, 8, 'highscore:') - std.draw.text(w*12+s, 8, game.highscore) + s=std.text.print_ex(8, 8, 'lifes:') + std.text.print(8+s, 8, game.lifes) + s=std.text.print_ex(w*2, 8, 'level:') + std.text.print(w*2+s, 8, game.level) + s=std.text.print_ex(w*4, 8, 'asteroids:') + std.text.print(w*4+s, 8, game.asteroids_count) + s=std.text.print_ex(w*9, 8, 'score:') + std.text.print(w*9+s, 8, game.score) + s=std.text.print_ex(w*12, 8, 'highscore:') + std.text.print(w*12+s, 8, game.highscore) end local function exit(std, game) diff --git a/examples/gridsystem/game.lua b/examples/gridsystem/game.lua index a7c61f3..1e1b1ed 100644 --- a/examples/gridsystem/game.lua +++ b/examples/gridsystem/game.lua @@ -10,7 +10,7 @@ local ClimaTV = { std.draw.color(std.color.red) std.draw.rect(1, 1, 1, data.width - 2, data.height - 2) local w, h = tostring(std.math.ceil(data.width)), tostring(std.math.ceil(data.height)) - std.draw.text(8, 8, 'Clima TV\n'..w..'x'..h) + std.text.print(8, 8, 'Clima TV\n'..w..'x'..h) end } @@ -19,7 +19,7 @@ local HoraTv = { std.draw.color(std.color.green) std.draw.rect(1, 1, 1, data.width - 2, data.height - 2) local w, h = tostring(std.math.ceil(data.width)), tostring(std.math.ceil(data.height)) - std.draw.text(8, 8, 'Clima TV\n'..w..'x'..h) + std.text.print(8, 8, 'Clima TV\n'..w..'x'..h) end } @@ -28,7 +28,7 @@ local TestTv = { std.draw.color(std.color.yellow) std.draw.rect(1, 1, 1, data.width - 2, data.height - 2) local w, h = tostring(std.math.ceil(data.width)), tostring(std.math.ceil(data.height)) - std.draw.text(8, 8, 'Clima TV\n'..w..'x'..h) + std.text.print(8, 8, 'Clima TV\n'..w..'x'..h) end } @@ -47,6 +47,7 @@ function App.load(std, data) ) :add(TestTv, 3) :add(ClimaTV) + :apply() end return App diff --git a/examples/helloworld/game.lua b/examples/helloworld/game.lua index b0643fa..f0c4834 100644 --- a/examples/helloworld/game.lua +++ b/examples/helloworld/game.lua @@ -7,7 +7,7 @@ end local function draw(std, game) std.draw.clear(std.color.black) std.draw.color(std.color.white) - std.draw.text(8 , 8, 'Hello world!') + std.text.print(8 , 8, 'Hello world!') end local function exit(std, game) diff --git a/examples/launcher/game.lua b/examples/launcher/game.lua index b7041da..7f5944b 100644 --- a/examples/launcher/game.lua +++ b/examples/launcher/game.lua @@ -31,15 +31,15 @@ local function draw(std, data) std.draw.clear(0x333333FF) std.draw.color(std.color.white) if not data._list then - std.draw.tui_text(10, 10, 10, 'loading...') + std.text.put(10, 10, 10, 'loading...') return end local index = 1 - std.draw.font(12) + std.text.font_size(12) while index <= #data._list do - std.draw.text(16, 8 + (index * 14), data._list[index].title) - std.draw.text(200, 8 + (index * 14), data._list[index].version) - std.draw.text(300, 8 + (index * 14), data._list[index].author) + std.text.print(16, 8 + (index * 14), data._list[index].title) + std.text.print(200, 8 + (index * 14), data._list[index].version) + std.text.print(300, 8 + (index * 14), data._list[index].author) index = index + 1 end std.draw.color(std.color.red) diff --git a/examples/pong/game.lua b/examples/pong/game.lua index 8dfc37e..f4c27d0 100644 --- a/examples/pong/game.lua +++ b/examples/pong/game.lua @@ -42,8 +42,8 @@ local function draw(std, game) std.draw.color(std.color.white) std.draw.rect(0, game.ball_size, game.player_pos, game.ball_size, game.player_size) std.draw.rect(0, game.ball_pos_x, game.ball_pos_y, game.ball_size, game.ball_size) - std.draw.tui_text(20, 1, 2, game.score) - std.draw.tui_text(60, 1, 2, game.highscore) + std.text.put(2, 20, 1, game.score) + std.text.put(2, 60, 1, game.highscore) end local function exit(std, game) diff --git a/examples/two_games/game.lua b/examples/two_games/game.lua index f3c628b..d01da66 100644 --- a/examples/two_games/game.lua +++ b/examples/two_games/game.lua @@ -9,6 +9,7 @@ local function load(std, game) game.ui_split = std.ui.grid('2x1') :add(game1) :add(game2) + :apply() std.node.pause(game.ui_split:get_item(2), 'loop') end diff --git a/src/engine/core/lite/main.lua b/src/engine/core/lite/main.lua index 4b8238d..2f29fb9 100644 --- a/src/engine/core/lite/main.lua +++ b/src/engine/core/lite/main.lua @@ -72,7 +72,7 @@ function native_callback_init(width, height, game_lua) std.draw.clear=function(tint) native_draw_clear(tint, 0, 0, application.data.width, application.data.height) end - std.draw.tui_text=function(x, y, s, text) + std.text.put=function(x, y, s, text) native_draw_text_tui(x, y, 0, 0, application.data.width, application.data.height, s, text) end diff --git a/src/engine/core/love/draw.lua b/src/engine/core/love/draw.lua index 8cfc9b5..1b015d2 100644 --- a/src/engine/core/love/draw.lua +++ b/src/engine/core/love/draw.lua @@ -28,37 +28,6 @@ local function rect(std, engine, mode, pos_x, pos_y, width, height) love.graphics.rectangle(modes[mode], x, y, width, height) end -local function tui_text(std, engine, pos_x, pos_y, size, text) - local hem = engine.current.data.width / 80 - local vem = engine.current.data.height / 24 - local x = engine.offset_x + (pos_x * hem) - local y = engine.offset_y + (pos_y * vem) - local font_size = hem * size - - local old_font = love.graphics.getFont() - local new_font = std.mem.cache('font_tui'..tostring(font_size), function() - return love.graphics.newFont(font_size) - end) - - love.graphics.setFont(new_font) - love.graphics.print(text, x, y) - love.graphics.setFont(old_font) -end - -local function text(std, engine, pos_x, pos_y, text) - local font = love.graphics.getFont() - local t = text and tostring(text) or tostring(pos_x) - local n = select(2, t:gsub('\n', '')) + 1 - local w = font:getWidth(t) - local h = (font:getHeight('A') * n) + (font:getLineHeight() * n) - if pos_x and pos_y then - local x = engine.offset_x + pos_x - local y = engine.offset_y + pos_y - love.graphics.print(t, x, y) - end - return w, h -end - local function line(std, engine, x1, y1, x2, y2) local ox = engine.offset_x local oy = engine.offset_y @@ -77,17 +46,6 @@ local function triangle(mode, x1, y1, x2, y2, x3, y3) end end -local function font(std, engine, name, size) - if not size and type(name) == 'number' then - size = name - name = 'Tiresias' - end - local f = std.mem.cache('font_'..name..tostring(size), function() - return love.graphics.newFont(size) - end) - love.graphics.setFont(f) -end - local function image(std, engine, src, pos_x, pos_y) local r, g, b, a = love.graphics.getColor() local image = std.mem.cache('image'..src, function() @@ -114,14 +72,7 @@ local function install(std, engine) std.draw.clear = util_decorator.prefix2(std, engine, clear) std.draw.color = util_decorator.prefix2(std, engine, color) std.draw.rect = util_decorator.prefix2(std, engine, rect) - std.draw.text = util_decorator.prefix2(std, engine, text) - std.draw.font = util_decorator.prefix2(std, engine, font) std.draw.line = util_decorator.prefix2(std, engine, line) - std.draw.tui_text = util_decorator.prefix2(std, engine, tui_text) - - return { - draw=std.draw - } end local P = { diff --git a/src/engine/core/love/main.lua b/src/engine/core/love/main.lua index 23419a1..5492480 100644 --- a/src/engine/core/love/main.lua +++ b/src/engine/core/love/main.lua @@ -2,6 +2,7 @@ local os = require('os') -- local zeebo_module = require('src/lib/common/module') -- +local core_text = require('src/engine/core/love/text') local core_draw = require('src/engine/core/love/draw') local core_loop = require('src/engine/core/love/loop') local lib_api_encoder = require('src/lib/engine/api/encoder') @@ -83,6 +84,7 @@ function love.load(args) :package('@game', lib_api_game, cfg_game_api) :package('@math', lib_api_math) :package('@key', lib_api_key, cfg_keys) + :package('@draw.text', core_text) :package('@draw.poly', lib_draw_poly, cfg_poly) :package('@draw.fps', lib_draw_fps) :package('@draw.ui', lib_draw_ui) diff --git a/src/engine/core/love/text.lua b/src/engine/core/love/text.lua new file mode 100644 index 0000000..b29feaa --- /dev/null +++ b/src/engine/core/love/text.lua @@ -0,0 +1,62 @@ +local util_decorator = require('src/lib/util/decorator') + +local function text_put(std, engine, size, pos_x, pos_y, text) + local hem = engine.current.data.width / 80 + local vem = engine.current.data.height / 24 + local x = engine.offset_x + (pos_x * hem) + local y = engine.offset_y + (pos_y * vem) + local font_size = hem * size + + local old_font = love.graphics.getFont() + local new_font = std.mem.cache('font_tui'..tostring(font_size), function() + return love.graphics.newFont(font_size) + end) + + love.graphics.setFont(new_font) + love.graphics.print(text, x, y) + love.graphics.setFont(old_font) +end + +local function text_print(std, engine, pos_x, pos_y, text) + local x = engine.offset_x + pos_x + local y = engine.offset_y + pos_y + love.graphics.print(text, x, y) +end + +local function font_size(std, engine, size) + local f = std.mem.cache('font_'..tostring(size), function() + return love.graphics.newFont(size) + end) + love.graphics.setFont(f) +end + +local function text_mensure(std, engine, text) + local font = love.graphics.getFont() + local t = tostring(text) + local n = select(2, t:gsub('\n', '')) + 1 + local w = font:getWidth(t) + local h = (font:getHeight('A') * n) + (font:getLineHeight() * n) + return w, h +end + +local function install(std, engine) + std.text = std.text or {} + std.text.put = util_decorator.prefix2(std, engine, text_put) + std.text.print = util_decorator.prefix2(std, engine, text_print) + std.text.font_size = util_decorator.prefix2(std, engine, font_size) + std.text.font_name = util_decorator.prefix2(std, engine, function() end) + std.text.font_default = util_decorator.prefix2(std, engine, function() end) + std.text.mensure = util_decorator.prefix2(std, engine, text_mensure) + std.text.print_ex = function(x, y, text, align) + local w, h = text_mensure(std, engine, text) + local aligns = {w, w/2, 0} + text_print(std, engine, x - aligns[(align or 1) + 2], y, text) + return w, h + end +end + +local P = { + install = install +} + +return P diff --git a/src/engine/core/native/main.lua b/src/engine/core/native/main.lua index ac82492..72ab8ad 100644 --- a/src/engine/core/native/main.lua +++ b/src/engine/core/native/main.lua @@ -54,15 +54,44 @@ local function rect(mode, pos_x, pos_y, width, height) native_draw_rect(mode, pos_x + ox, pos_y + oy, width, height) end ---! @short std.draw.tui_text -local function tui_text(pos_x, pos_y, size, text) +--! @short std.draw.line +local function line(x1, y1, x2, y2) local ox, oy = engine.offset_x, engine.offset_y - local width, height = engine.current.data.width, engine.current.data.height - native_draw_text_tui(pos_x, pos_y, ox, oy, width, height, size, text) + native_draw_line(x1 + ox, y1 + oy, x2 + ox, y2 + oy) end ---! @short std.draw.text -local function text(pos_x, pos_y, text) +--! @short std.draw.image +local function image(src, pos_x, pos_y) + local x = engine.offset_x + (pos_x or 0) + local y = engine.offset_y + (pos_y or 0) + native_draw_image(src, x, y) +end + +--! @} +--! @defgroup text +--! @{ +--! @par Align text +--! @code{.java} +--! std.text.print_ex(240, 80, 'center', 0) +--! std.text.print_ex(240, 80, 'right', -1) +--! std.text.print_ex(240, 80, 'left', 1) +--! @endcode +--! @par Print and Mensure +--! @code{.java} +--! local w = std.text.print_ex(240, 80, 'foo') +--! std.text.print(240, 80 + w, 'bar') +--! @endcode +--! + +--! @renamefunc print +--! @short std.text.print +--! @par Alternatives +--! @li @b std.text.print_ex returning @ref mensure and can align @b -1, @b 0 or @b 1 +--! @par Example +--! @code{.java} +--! std.text.put((std.app.width/4) * 3, 8, '1/4 text') +--! @endcode +local function text_print(pos_x, pos_y, text) local ox, oy = engine.offset_x, engine.offset_y if pos_x and pos_y then return native_draw_text(pos_x + ox, pos_y + oy, text) @@ -70,18 +99,62 @@ local function text(pos_x, pos_y, text) return native_draw_text(pos_x) end ---! @short std.draw.line -local function line(x1, y1, x2, y2) +--! @renamefunc put +--! @short std.text.put +--! @brief @b TUI grid based text print +--! @par Grid +--! @startuml +--! rectangle "\t\t\t\t\n\n\n\n" as terminal +--! label "80" as columns +--! label "24" as lines +--! terminal <.u. columns +--! terminal <.r. lines +--! @enduml +--! @par Equation +--! @startmath +--! \text{hem} = \frac{\text{width}}{80} \\ +--! \text{vem} = \frac{\text{height}}{24} \\ +--! f(\text{x}) = \text{x} \times \text{hem} \\ +--! f(\text{y}) = \text{y} \times \text{vem} \\ +--! f(\text{size}) = \text{size} \times \text{hem} +--! @endmath +--! @par Example +--! @code{.java} +--! std.text.put(1, 20, 1, '1/4 text') +--! @endcode +local function text_put(size, pos_x, pos_y, text) local ox, oy = engine.offset_x, engine.offset_y - native_draw_line(x1 + ox, y1 + oy, x2 + ox, y2 + oy) + local width, height = engine.current.data.width, engine.current.data.height + native_draw_text_tui(pos_x, pos_y, ox, oy, width, height, size, text) end ---! @short std.draw.image -local function image(src, pos_x, pos_y) - local x = engine.offset_x + (pos_x or 0) - local y = engine.offset_y + (pos_y or 0) - native_draw_image(src, x, y) -end +--! @short std.text.font_size +--! @par Example +--! @code{.java} +--! std.text.font_size(8) +--! @endcode +--! @fakefunc font_size(size) + +--! @short std.text.font_name +--! @par Example +--! @code{.java} +--! std.text.font_name('Comic Sans') +--! @endcode +--! @fakefunc font_name(name) + +--! @short std.text.font_default +--! @par List +--! @li @b 1 [Noto Sans](https://fonts.google.com/noto/specimen/Noto+Sans) +--! @li @b 2 [IBM Plex Sans](https://fonts.google.com/specimen/IBM+Plex+Sans) +--! +--! @par Example +--! @code{.java} +--! std.text.font_default(1) +--! @endcode +--! @fakefunc font_default(id) + +--! @short std.text.mensure +--! @fakefunc mensure(text) --! @} --! @} @@ -124,7 +197,7 @@ function native_callback_init(width, height, game_lua) std.draw.font=native_draw_font std.draw.clear=clear std.draw.text=text - std.draw.tui_text=tui_text + std.text.put=tui_text std.draw.rect=rect std.draw.line=line std.draw.image=image diff --git a/src/lib/util/http.lua b/src/lib/util/http.lua index 1334712..a49a779 100644 --- a/src/lib/util/http.lua +++ b/src/lib/util/http.lua @@ -112,7 +112,7 @@ local function create_request(method, uri) local index = 1 local request = 'curl -L -'..'-silent -'..'-insecure ' - if print_http_status then + if self.print_http_status then request = request..'-w "\n%{http_code}" ' end diff --git a/tools/doxygen_filter.lua b/tools/doxygen_filter.lua index 11dffd2..501a744 100644 --- a/tools/doxygen_filter.lua +++ b/tools/doxygen_filter.lua @@ -131,6 +131,7 @@ function main() local is_lua = arg[1]:sub(#arg[1] - 3) == '.lua' local is_game = arg[1]:sub(#arg[1] - 7) == 'game.lua' and arg[1]:find('examples') local renamefunc_pattern = '@renamefunc ([%w_]+)' + local fake_func_pattern = '@fakefunc ([%w_]+%b())' local hideparam_pattern = '@hideparam ([%w_]+)' local include_pattern = '^local [%w_%-]+ = require%(\'(.-)\'%)' local function_pattern = '^local function ([%w_]+%b())' @@ -172,6 +173,7 @@ function main() local include = line:match(include_pattern) local clojure = line:match(function_pattern) local hideparam = line:match(hideparam_pattern) + local fake_func = line:match(fake_func_pattern) local rename_func = line:match(renamefunc_pattern) local variable, literal = line:match(literal_pattern) @@ -179,6 +181,10 @@ function main() line = line:gsub(doxygen_pattern, '//!') end + if fake_func then + clojure = fake_func + end + if rename_function and clojure then clojure = clojure:gsub('^([%w_]+)', rename_function) rename_function = false