Customized fork of github.com/rxi/lite

Reformat

+8
.editorconfig
··· 1 + root = true 2 + 3 + [*.{c,h,lua}] 4 + charset = utf-8 5 + end_of_line = lf 6 + indent_style = tab 7 + insert_final_newline = true 8 + trim_trailing_whitespace = true
+2
.gitignore
··· 1 + /lite 2 + /*.o
-19
LICENSE
··· 1 - Copyright (c) 2020 rxi 2 - 3 - Permission is hereby granted, free of charge, to any person obtaining a copy of 4 - this software and associated documentation files (the "Software"), to deal in 5 - the Software without restriction, including without limitation the rights to 6 - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 - of the Software, and to permit persons to whom the Software is furnished to do 8 - so, subject to the following conditions: 9 - 10 - The above copyright notice and this permission notice shall be included in all 11 - copies or substantial portions of the Software. 12 - 13 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 - SOFTWARE.
-12
README.md doc/original-readme.md
··· 1 - # lite (emmeline's fork) 2 - 3 - A fork of the [lite](https://github.com/rxi/lite) editor by rxi. 4 - 5 - ## Changes 6 - 7 - - [ ] Reformat to my code style :p 8 - - [/] Update to SDL 3 9 - - [ ] Use LuaJIT 10 - 11 - --- 12 - 13 1 # lite 14 2 ![screenshot](https://user-images.githubusercontent.com/3920290/81471642-6c165880-91ea-11ea-8cd1-fae7ae8f0bc4.png) 15 3
+4
compile_flags.txt
··· 1 + -Wall 2 + -Isrc 3 + -fno-strict-aliasing 4 + -DLUA_USE_POSIX
+1 -1
data/user/init.lua
··· 9 9 config.indent_size = 8 10 10 11 11 -- light theme: 12 - -- require "user.colors.summer" 12 + require "user.colors.fall" 13 13 14 14 -- key binding: 15 15 -- keymap.add { ["ctrl+escape"] = "core:quit" }
+53
license
··· 1 + === emmeline/lite: MIT License === 2 + 3 + Copyright (c) 2025 emmeline 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy of 6 + this software and associated documentation files (the "Software"), to deal in 7 + the Software without restriction, including without limitation the rights to 8 + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 + of the Software, and to permit persons to whom the Software is furnished to do 10 + so, subject to the following conditions: 11 + 12 + The above copyright notice and this permission notice shall be included in all 13 + copies or substantial portions of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + SOFTWARE. 22 + 23 + === rxi/lite: MIT License === 24 + 25 + Copyright (c) 2020 rxi 26 + 27 + Permission is hereby granted, free of charge, to any person obtaining a copy of 28 + this software and associated documentation files (the "Software"), to deal in 29 + the Software without restriction, including without limitation the rights to 30 + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 31 + of the Software, and to permit persons to whom the Software is furnished to do 32 + so, subject to the following conditions: 33 + 34 + The above copyright notice and this permission notice shall be included in all 35 + copies or substantial portions of the Software. 36 + 37 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 39 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 43 + SOFTWARE. 44 + 45 + === lua 5.4.8: MIT License === 46 + 47 + Copyright © 1994–2025 Lua.org, PUC-Rio. 48 + 49 + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 50 + 51 + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 52 + 53 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+29
readme
··· 1 + lite (emmeline's fork) 2 + ====================== 3 + 4 + A fork of the [lite](https://github.com/rxi/lite) editor by rxi. 5 + 6 + A lightweight editor written in Lua. 7 + 8 + Usage: <doc/usage.md> 9 + Plugins: <https://github.com/rxi/lite-plugins> 10 + Themes: <https://github.com/rxi/lite-colors> 11 + 12 + Build 13 + ----- 14 + 15 + $ git clone https://tangled.org/emmeline.girlkisser.top/lite 16 + $ cd lite 17 + $ ./build.sh 18 + $ ln -s $(pwd)/lite ~/.local/bin/ 19 + $ lite . 20 + 21 + Changes 22 + ------- 23 + 24 + - [x] Reformat to my code style :p 25 + - [x] Update to SDL 3 26 + - [ ] Use LuaJIT 27 + 28 + License 29 + -------
+9 -7
src/api/api.c
··· 6 6 7 7 8 8 static const luaL_Reg libs[] = { 9 - { "system", luaopen_system }, 10 - { "renderer", luaopen_renderer }, 11 - { NULL, NULL } 9 + { "system", luaopen_system }, 10 + { "renderer", luaopen_renderer }, 11 + { NULL, NULL } 12 12 }; 13 13 14 - void api_load_libs(lua_State *L) { 15 - for (int i = 0; libs[i].name; i++) { 16 - luaL_requiref(L, libs[i].name, libs[i].func, 1); 17 - } 14 + void api_load_libs(lua_State *L) 15 + { 16 + for (int i = 0 ; libs[i].name ; i++) 17 + { 18 + luaL_requiref(L, libs[i].name, libs[i].func, 1); 19 + } 18 20 }
+78 -70
src/api/renderer.c
··· 3 3 #include "rencache.h" 4 4 5 5 6 - static RenColor checkcolor(lua_State *L, int idx, int def) { 7 - RenColor color; 8 - if (lua_isnoneornil(L, idx)) { 9 - return (RenColor) { def, def, def, 255 }; 10 - } 11 - lua_rawgeti(L, idx, 1); 12 - lua_rawgeti(L, idx, 2); 13 - lua_rawgeti(L, idx, 3); 14 - lua_rawgeti(L, idx, 4); 15 - color.r = luaL_checknumber(L, -4); 16 - color.g = luaL_checknumber(L, -3); 17 - color.b = luaL_checknumber(L, -2); 18 - color.a = luaL_optnumber(L, -1, 255); 19 - lua_pop(L, 4); 20 - return color; 6 + static RenColor checkcolor(lua_State *L, int idx, int def) 7 + { 8 + RenColor color; 9 + if (lua_isnoneornil(L, idx)) 10 + return (RenColor){ def, def, def, 255 }; 11 + lua_rawgeti(L, idx, 1); 12 + lua_rawgeti(L, idx, 2); 13 + lua_rawgeti(L, idx, 3); 14 + lua_rawgeti(L, idx, 4); 15 + color.r = luaL_checknumber(L, -4); 16 + color.g = luaL_checknumber(L, -3); 17 + color.b = luaL_checknumber(L, -2); 18 + color.a = luaL_optnumber(L, -1, 255); 19 + lua_pop(L, 4); 20 + return color; 21 21 } 22 22 23 23 24 - static int f_show_debug(lua_State *L) { 25 - luaL_checkany(L, 1); 26 - rencache_show_debug(lua_toboolean(L, 1)); 27 - return 0; 24 + static int f_show_debug(lua_State *L) 25 + { 26 + luaL_checkany(L, 1); 27 + rencache_show_debug(lua_toboolean(L, 1)); 28 + return 0; 28 29 } 29 30 30 31 31 - static int f_get_size(lua_State *L) { 32 - int w, h; 33 - ren_get_size(&w, &h); 34 - lua_pushnumber(L, w); 35 - lua_pushnumber(L, h); 36 - return 2; 32 + static int f_get_size(lua_State *L) 33 + { 34 + int w, h; 35 + ren_get_size(&w, &h); 36 + lua_pushnumber(L, w); 37 + lua_pushnumber(L, h); 38 + return 2; 37 39 } 38 40 39 41 40 - static int f_begin_frame(lua_State *L) { 41 - rencache_begin_frame(); 42 - return 0; 42 + static int f_begin_frame(lua_State *L) 43 + { 44 + rencache_begin_frame(); 45 + return 0; 43 46 } 44 47 45 48 46 - static int f_end_frame(lua_State *L) { 47 - rencache_end_frame(); 48 - return 0; 49 + static int f_end_frame(lua_State *L) 50 + { 51 + rencache_end_frame(); 52 + return 0; 49 53 } 50 54 51 55 52 - static int f_set_clip_rect(lua_State *L) { 53 - RenRect rect; 54 - rect.x = luaL_checknumber(L, 1); 55 - rect.y = luaL_checknumber(L, 2); 56 - rect.width = luaL_checknumber(L, 3); 57 - rect.height = luaL_checknumber(L, 4); 58 - rencache_set_clip_rect(rect); 59 - return 0; 56 + static int f_set_clip_rect(lua_State *L) 57 + { 58 + RenRect rect; 59 + rect.x = luaL_checknumber(L, 1); 60 + rect.y = luaL_checknumber(L, 2); 61 + rect.width = luaL_checknumber(L, 3); 62 + rect.height = luaL_checknumber(L, 4); 63 + rencache_set_clip_rect(rect); 64 + return 0; 60 65 } 61 66 62 67 63 - static int f_draw_rect(lua_State *L) { 64 - RenRect rect; 65 - rect.x = luaL_checknumber(L, 1); 66 - rect.y = luaL_checknumber(L, 2); 67 - rect.width = luaL_checknumber(L, 3); 68 - rect.height = luaL_checknumber(L, 4); 69 - RenColor color = checkcolor(L, 5, 255); 70 - rencache_draw_rect(rect, color); 71 - return 0; 68 + static int f_draw_rect(lua_State *L) 69 + { 70 + RenRect rect; 71 + rect.x = luaL_checknumber(L, 1); 72 + rect.y = luaL_checknumber(L, 2); 73 + rect.width = luaL_checknumber(L, 3); 74 + rect.height = luaL_checknumber(L, 4); 75 + RenColor color = checkcolor(L, 5, 255); 76 + rencache_draw_rect(rect, color); 77 + return 0; 72 78 } 73 79 74 80 75 - static int f_draw_text(lua_State *L) { 76 - RenFont **font = luaL_checkudata(L, 1, API_TYPE_FONT); 77 - const char *text = luaL_checkstring(L, 2); 78 - int x = luaL_checknumber(L, 3); 79 - int y = luaL_checknumber(L, 4); 80 - RenColor color = checkcolor(L, 5, 255); 81 - x = rencache_draw_text(*font, text, x, y, color); 82 - lua_pushnumber(L, x); 83 - return 1; 81 + static int f_draw_text(lua_State *L) 82 + { 83 + RenFont **font = luaL_checkudata(L, 1, API_TYPE_FONT); 84 + const char *text = luaL_checkstring(L, 2); 85 + int x = luaL_checknumber(L, 3); 86 + int y = luaL_checknumber(L, 4); 87 + RenColor color = checkcolor(L, 5, 255); 88 + x = rencache_draw_text(*font, text, x, y, color); 89 + lua_pushnumber(L, x); 90 + return 1; 84 91 } 85 92 86 93 87 94 static const luaL_Reg lib[] = { 88 - { "show_debug", f_show_debug }, 89 - { "get_size", f_get_size }, 90 - { "begin_frame", f_begin_frame }, 91 - { "end_frame", f_end_frame }, 92 - { "set_clip_rect", f_set_clip_rect }, 93 - { "draw_rect", f_draw_rect }, 94 - { "draw_text", f_draw_text }, 95 - { NULL, NULL } 95 + { "show_debug", f_show_debug }, 96 + { "get_size", f_get_size }, 97 + { "begin_frame", f_begin_frame }, 98 + { "end_frame", f_end_frame }, 99 + { "set_clip_rect", f_set_clip_rect }, 100 + { "draw_rect", f_draw_rect }, 101 + { "draw_text", f_draw_text }, 102 + { NULL, NULL } 96 103 }; 97 104 98 105 99 106 int luaopen_renderer_font(lua_State *L); 100 107 101 - int luaopen_renderer(lua_State *L) { 102 - luaL_newlib(L, lib); 103 - luaopen_renderer_font(L); 104 - lua_setfield(L, -2, "font"); 105 - return 1; 108 + int luaopen_renderer(lua_State *L) 109 + { 110 + luaL_newlib(L, lib); 111 + luaopen_renderer_font(L); 112 + lua_setfield(L, -2, "font"); 113 + return 1; 106 114 }
+46 -38
src/api/renderer_font.c
··· 3 3 #include "rencache.h" 4 4 5 5 6 - static int f_load(lua_State *L) { 7 - const char *filename = luaL_checkstring(L, 1); 8 - float size = luaL_checknumber(L, 2); 9 - RenFont **self = lua_newuserdata(L, sizeof(*self)); 10 - luaL_setmetatable(L, API_TYPE_FONT); 11 - *self = ren_load_font(filename, size); 12 - if (!*self) { luaL_error(L, "failed to load font"); } 13 - return 1; 6 + static int f_load(lua_State *L) 7 + { 8 + const char *filename = luaL_checkstring(L, 1); 9 + float size = luaL_checknumber(L, 2); 10 + RenFont **self = lua_newuserdata(L, sizeof(*self)); 11 + luaL_setmetatable(L, API_TYPE_FONT); 12 + *self = ren_load_font(filename, size); 13 + if (!*self) 14 + luaL_error(L, "failed to load font"); 15 + return 1; 14 16 } 15 17 16 18 17 - static int f_set_tab_width(lua_State *L) { 18 - RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 19 - int n = luaL_checknumber(L, 2); 20 - ren_set_font_tab_width(*self, n); 21 - return 0; 19 + static int f_set_tab_width(lua_State *L) 20 + { 21 + RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 22 + int n = luaL_checknumber(L, 2); 23 + ren_set_font_tab_width(*self, n); 24 + return 0; 22 25 } 23 26 24 27 25 - static int f_gc(lua_State *L) { 26 - RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 27 - if (*self) { rencache_free_font(*self); } 28 - return 0; 28 + static int f_gc(lua_State *L) 29 + { 30 + RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 31 + if (*self) 32 + rencache_free_font(*self); 33 + return 0; 29 34 } 30 35 31 36 32 - static int f_get_width(lua_State *L) { 33 - RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 34 - const char *text = luaL_checkstring(L, 2); 35 - lua_pushnumber(L, ren_get_font_width(*self, text) ); 36 - return 1; 37 + static int f_get_width(lua_State *L) 38 + { 39 + RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 40 + const char *text = luaL_checkstring(L, 2); 41 + lua_pushnumber(L, ren_get_font_width(*self, text) ); 42 + return 1; 37 43 } 38 44 39 45 40 - static int f_get_height(lua_State *L) { 41 - RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 42 - lua_pushnumber(L, ren_get_font_height(*self) ); 43 - return 1; 46 + static int f_get_height(lua_State *L) 47 + { 48 + RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT); 49 + lua_pushnumber(L, ren_get_font_height(*self) ); 50 + return 1; 44 51 } 45 52 46 53 47 54 static const luaL_Reg lib[] = { 48 - { "__gc", f_gc }, 49 - { "load", f_load }, 50 - { "set_tab_width", f_set_tab_width }, 51 - { "get_width", f_get_width }, 52 - { "get_height", f_get_height }, 53 - { NULL, NULL } 55 + { "__gc", f_gc }, 56 + { "load", f_load }, 57 + { "set_tab_width", f_set_tab_width }, 58 + { "get_width", f_get_width }, 59 + { "get_height", f_get_height }, 60 + { NULL, NULL } 54 61 }; 55 62 56 - int luaopen_renderer_font(lua_State *L) { 57 - luaL_newmetatable(L, API_TYPE_FONT); 58 - luaL_setfuncs(L, lib, 0); 59 - lua_pushvalue(L, -1); 60 - lua_setfield(L, -2, "__index"); 61 - return 1; 63 + int luaopen_renderer_font(lua_State *L) 64 + { 65 + luaL_newmetatable(L, API_TYPE_FONT); 66 + luaL_setfuncs(L, lib, 0); 67 + lua_pushvalue(L, -1); 68 + lua_setfield(L, -2, "__index"); 69 + return 1; 62 70 }
+328 -286
src/api/system.c
··· 9 9 #include "api.h" 10 10 #include "rencache.h" 11 11 #ifdef _WIN32 12 - #include <windows.h> 12 + # include <windows.h> 13 13 #endif 14 14 15 15 extern SDL_Window *window; 16 16 17 17 18 - static const char* button_name(int button) { 19 - switch (button) { 20 - case 1 : return "left"; 21 - case 2 : return "middle"; 22 - case 3 : return "right"; 23 - default : return "?"; 24 - } 18 + static const char* button_name(int button) 19 + { 20 + switch (button) 21 + { 22 + case 1 : return "left"; 23 + case 2 : return "middle"; 24 + case 3 : return "right"; 25 + default : return "?"; 26 + } 25 27 } 26 28 27 29 28 - static char* key_name(char *dst, int sym) { 29 - strcpy(dst, SDL_GetKeyName(sym)); 30 - char *p = dst; 31 - while (*p) { 32 - *p = tolower(*p); 33 - p++; 34 - } 35 - return dst; 30 + static char* key_name(char *dst, int sym) 31 + { 32 + strcpy(dst, SDL_GetKeyName(sym)); 33 + char *p = dst; 34 + while (*p) 35 + { 36 + *p = tolower(*p); 37 + p++; 38 + } 39 + return dst; 36 40 } 37 41 38 42 39 - static int f_poll_event(lua_State *L) { 40 - char buf[16]; 41 - float mx, my; 42 - int wx, wy; 43 - SDL_Event e; 43 + static int f_poll_event(lua_State *L) 44 + { 45 + char buf[16]; 46 + float mx, my; 47 + int wx, wy; 48 + SDL_Event e; 44 49 45 50 top: 46 - if ( !SDL_PollEvent(&e) ) { 47 - return 0; 48 - } 51 + if (!SDL_PollEvent(&e)) 52 + return 0; 49 53 50 - switch (e.type) { 51 - case SDL_EVENT_QUIT : 52 - lua_pushstring(L, "quit"); 53 - return 1; 54 + switch (e.type) 55 + { 56 + case SDL_EVENT_QUIT : 57 + lua_pushstring(L, "quit"); 58 + return 1; 54 59 55 - case SDL_EVENT_WINDOW_RESIZED: 56 - lua_pushstring(L, "resized"); 57 - lua_pushnumber(L, e.window.data1); 58 - lua_pushnumber(L, e.window.data2); 59 - return 3; 60 + case SDL_EVENT_WINDOW_RESIZED: 61 + lua_pushstring(L, "resized"); 62 + lua_pushnumber(L, e.window.data1); 63 + lua_pushnumber(L, e.window.data2); 64 + return 3; 60 65 61 - case SDL_EVENT_WINDOW_EXPOSED: 62 - rencache_invalidate(); 63 - lua_pushstring(L, "exposed"); 64 - return 1; 66 + case SDL_EVENT_WINDOW_EXPOSED: 67 + rencache_invalidate(); 68 + lua_pushstring(L, "exposed"); 69 + return 1; 65 70 66 - case SDL_EVENT_WINDOW_FOCUS_GAINED: 67 - /* on some systems, when alt-tabbing to the window SDL will queue up 68 - ** several KEYDOWN events for the `tab` key; we flush all keydown 69 - ** events on focus so these are discarded */ 70 - SDL_FlushEvent(SDL_EVENT_KEY_DOWN); 71 - goto top; 71 + case SDL_EVENT_WINDOW_FOCUS_GAINED: 72 + /* on some systems, when alt-tabbing to the window SDL will queue up 73 + ** several KEYDOWN events for the `tab` key; we flush all keydown 74 + ** events on focus so these are discarded */ 75 + SDL_FlushEvent(SDL_EVENT_KEY_DOWN); 76 + goto top; 72 77 73 - case SDL_EVENT_DROP_FILE : 74 - SDL_GetGlobalMouseState(&mx, &my); 75 - SDL_GetWindowPosition(window, &wx, &wy); 76 - lua_pushstring(L, "filedropped"); 77 - lua_pushstring(L, e.drop.data); 78 - lua_pushnumber(L, mx - wx); 79 - lua_pushnumber(L, my - wy); 80 - return 4; 78 + case SDL_EVENT_DROP_FILE : 79 + SDL_GetGlobalMouseState(&mx, &my); 80 + SDL_GetWindowPosition(window, &wx, &wy); 81 + lua_pushstring(L, "filedropped"); 82 + lua_pushstring(L, e.drop.data); 83 + lua_pushnumber(L, mx - wx); 84 + lua_pushnumber(L, my - wy); 85 + return 4; 81 86 82 - case SDL_EVENT_KEY_DOWN : 83 - lua_pushstring(L, "keypressed"); 84 - lua_pushstring(L, key_name(buf, e.key.key)); 85 - return 2; 87 + case SDL_EVENT_KEY_DOWN : 88 + lua_pushstring(L, "keypressed"); 89 + lua_pushstring(L, key_name(buf, e.key.key)); 90 + return 2; 86 91 87 - case SDL_EVENT_KEY_UP : 88 - lua_pushstring(L, "keyreleased"); 89 - lua_pushstring(L, key_name(buf, e.key.key)); 90 - return 2; 92 + case SDL_EVENT_KEY_UP : 93 + lua_pushstring(L, "keyreleased"); 94 + lua_pushstring(L, key_name(buf, e.key.key)); 95 + return 2; 91 96 92 - case SDL_EVENT_TEXT_INPUT : 93 - lua_pushstring(L, "textinput"); 94 - lua_pushstring(L, e.text.text); 95 - return 2; 97 + case SDL_EVENT_TEXT_INPUT : 98 + lua_pushstring(L, "textinput"); 99 + lua_pushstring(L, e.text.text); 100 + return 2; 96 101 97 - case SDL_EVENT_MOUSE_BUTTON_DOWN : 98 - if (e.button.button == 1) { SDL_CaptureMouse(1); } 99 - lua_pushstring(L, "mousepressed"); 100 - lua_pushstring(L, button_name(e.button.button)); 101 - lua_pushnumber(L, e.button.x); 102 - lua_pushnumber(L, e.button.y); 103 - lua_pushnumber(L, e.button.clicks); 104 - return 5; 102 + case SDL_EVENT_MOUSE_BUTTON_DOWN : 103 + if (e.button.button == 1) 104 + SDL_CaptureMouse(1); 105 + lua_pushstring(L, "mousepressed"); 106 + lua_pushstring(L, button_name(e.button.button)); 107 + lua_pushnumber(L, e.button.x); 108 + lua_pushnumber(L, e.button.y); 109 + lua_pushnumber(L, e.button.clicks); 110 + return 5; 105 111 106 - case SDL_EVENT_MOUSE_BUTTON_UP : 107 - if (e.button.button == 1) { SDL_CaptureMouse(0); } 108 - lua_pushstring(L, "mousereleased"); 109 - lua_pushstring(L, button_name(e.button.button)); 110 - lua_pushnumber(L, e.button.x); 111 - lua_pushnumber(L, e.button.y); 112 - return 4; 112 + case SDL_EVENT_MOUSE_BUTTON_UP : 113 + if (e.button.button == 1) 114 + SDL_CaptureMouse(0); 115 + lua_pushstring(L, "mousereleased"); 116 + lua_pushstring(L, button_name(e.button.button)); 117 + lua_pushnumber(L, e.button.x); 118 + lua_pushnumber(L, e.button.y); 119 + return 4; 113 120 114 - case SDL_EVENT_MOUSE_MOTION : 115 - lua_pushstring(L, "mousemoved"); 116 - lua_pushnumber(L, e.motion.x); 117 - lua_pushnumber(L, e.motion.y); 118 - lua_pushnumber(L, e.motion.xrel); 119 - lua_pushnumber(L, e.motion.yrel); 120 - return 5; 121 + case SDL_EVENT_MOUSE_MOTION : 122 + lua_pushstring(L, "mousemoved"); 123 + lua_pushnumber(L, e.motion.x); 124 + lua_pushnumber(L, e.motion.y); 125 + lua_pushnumber(L, e.motion.xrel); 126 + lua_pushnumber(L, e.motion.yrel); 127 + return 5; 121 128 122 - case SDL_EVENT_MOUSE_WHEEL : 123 - lua_pushstring(L, "mousewheel"); 124 - lua_pushnumber(L, e.wheel.y); 125 - return 2; 129 + case SDL_EVENT_MOUSE_WHEEL : 130 + lua_pushstring(L, "mousewheel"); 131 + lua_pushnumber(L, e.wheel.y); 132 + return 2; 126 133 127 - default: 128 - goto top; 129 - } 134 + default: 135 + goto top; 136 + } 130 137 131 - return 0; 138 + return 0; 132 139 } 133 140 134 141 135 - static int f_wait_event(lua_State *L) { 136 - double n = luaL_checknumber(L, 1); 137 - lua_pushboolean(L, SDL_WaitEventTimeout(NULL, n * 1000)); 138 - return 1; 142 + static int f_wait_event(lua_State *L) 143 + { 144 + double n = luaL_checknumber(L, 1); 145 + lua_pushboolean(L, SDL_WaitEventTimeout(NULL, n * 1000)); 146 + return 1; 139 147 } 140 148 141 149 142 150 static SDL_Cursor* cursor_cache[SDL_SYSTEM_CURSOR_POINTER + 1]; 143 151 144 152 static const char *cursor_opts[] = { 145 - "arrow", 146 - "ibeam", 147 - "sizeh", 148 - "sizev", 149 - "hand", 150 - NULL 153 + "arrow", 154 + "ibeam", 155 + "sizeh", 156 + "sizev", 157 + "hand", 158 + NULL 151 159 }; 152 160 153 161 static const int cursor_enums[] = { 154 - SDL_SYSTEM_CURSOR_DEFAULT, 155 - SDL_SYSTEM_CURSOR_TEXT, 156 - SDL_SYSTEM_CURSOR_EW_RESIZE, 157 - SDL_SYSTEM_CURSOR_NS_RESIZE, 158 - SDL_SYSTEM_CURSOR_POINTER 162 + SDL_SYSTEM_CURSOR_DEFAULT, 163 + SDL_SYSTEM_CURSOR_TEXT, 164 + SDL_SYSTEM_CURSOR_EW_RESIZE, 165 + SDL_SYSTEM_CURSOR_NS_RESIZE, 166 + SDL_SYSTEM_CURSOR_POINTER 159 167 }; 160 168 161 - static int f_set_cursor(lua_State *L) { 162 - int opt = luaL_checkoption(L, 1, "arrow", cursor_opts); 163 - int n = cursor_enums[opt]; 164 - SDL_Cursor *cursor = cursor_cache[n]; 165 - if (!cursor) { 166 - cursor = SDL_CreateSystemCursor(n); 167 - cursor_cache[n] = cursor; 168 - } 169 - SDL_SetCursor(cursor); 170 - return 0; 169 + static int f_set_cursor(lua_State *L) 170 + { 171 + int opt = luaL_checkoption(L, 1, "arrow", cursor_opts); 172 + int n = cursor_enums[opt]; 173 + SDL_Cursor *cursor = cursor_cache[n]; 174 + if (!cursor) 175 + { 176 + cursor = SDL_CreateSystemCursor(n); 177 + cursor_cache[n] = cursor; 178 + } 179 + SDL_SetCursor(cursor); 180 + return 0; 171 181 } 172 182 173 183 174 - static int f_set_window_title(lua_State *L) { 175 - const char *title = luaL_checkstring(L, 1); 176 - SDL_SetWindowTitle(window, title); 177 - return 0; 184 + static int f_set_window_title(lua_State *L) 185 + { 186 + const char *title = luaL_checkstring(L, 1); 187 + SDL_SetWindowTitle(window, title); 188 + return 0; 178 189 } 179 190 180 191 181 192 static const char *window_opts[] = { "normal", "maximized", "fullscreen", 0 }; 182 193 enum { WIN_NORMAL, WIN_MAXIMIZED, WIN_FULLSCREEN }; 183 194 184 - static int f_set_window_mode(lua_State *L) { 185 - int n = luaL_checkoption(L, 1, "normal", window_opts); 186 - SDL_SetWindowFullscreen(window, n == WIN_FULLSCREEN ? SDL_GetWindowFullscreenMode(window) : 0); 187 - if (n == WIN_NORMAL) { SDL_RestoreWindow(window); } 188 - if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window); } 189 - return 0; 195 + static int f_set_window_mode(lua_State *L) 196 + { 197 + int n = luaL_checkoption(L, 1, "normal", window_opts); 198 + SDL_SetWindowFullscreen(window, n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0); 199 + if (n == WIN_NORMAL) 200 + SDL_RestoreWindow(window); 201 + if (n == WIN_MAXIMIZED) 202 + SDL_MaximizeWindow(window); 203 + return 0; 190 204 } 191 205 192 206 193 - static int f_window_has_focus(lua_State *L) { 194 - unsigned flags = SDL_GetWindowFlags(window); 195 - lua_pushboolean(L, flags & SDL_WINDOW_INPUT_FOCUS); 196 - return 1; 207 + static int f_window_has_focus(lua_State *L) 208 + { 209 + unsigned flags = SDL_GetWindowFlags(window); 210 + lua_pushboolean(L, flags & SDL_WINDOW_INPUT_FOCUS); 211 + return 1; 197 212 } 198 213 199 214 200 - static int f_show_confirm_dialog(lua_State *L) { 201 - const char *title = luaL_checkstring(L, 1); 202 - const char *msg = luaL_checkstring(L, 2); 215 + static int f_show_confirm_dialog(lua_State *L) 216 + { 217 + const char *title = luaL_checkstring(L, 1); 218 + const char *msg = luaL_checkstring(L, 2); 203 219 204 - #if _WIN32 205 - int id = MessageBox(0, msg, title, MB_YESNO | MB_ICONWARNING); 206 - lua_pushboolean(L, id == IDYES); 220 + # if _WIN32 221 + int id = MessageBox(0, msg, title, MB_YESNO | MB_ICONWARNING); 222 + lua_pushboolean(L, id == IDYES); 207 223 208 - #else 209 - SDL_MessageBoxButtonData buttons[] = { 210 - { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" }, 211 - { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "No" }, 212 - }; 213 - SDL_MessageBoxData data = { 214 - .title = title, 215 - .message = msg, 216 - .numbuttons = 2, 217 - .buttons = buttons, 218 - }; 219 - int buttonid; 220 - SDL_ShowMessageBox(&data, &buttonid); 221 - lua_pushboolean(L, buttonid == 1); 222 - #endif 223 - return 1; 224 + # else 225 + SDL_MessageBoxButtonData buttons[] = { 226 + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" }, 227 + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "No" }, 228 + }; 229 + SDL_MessageBoxData data = { 230 + .title = title, 231 + .message = msg, 232 + .numbuttons = 2, 233 + .buttons = buttons, 234 + }; 235 + int buttonid; 236 + SDL_ShowMessageBox(&data, &buttonid); 237 + lua_pushboolean(L, buttonid == 1); 238 + # endif 239 + return 1; 224 240 } 225 241 226 242 227 - static int f_chdir(lua_State *L) { 228 - const char *path = luaL_checkstring(L, 1); 229 - int err = chdir(path); 230 - if (err) { luaL_error(L, "chdir() failed"); } 231 - return 0; 243 + static int f_chdir(lua_State *L) 244 + { 245 + const char *path = luaL_checkstring(L, 1); 246 + int err = chdir(path); 247 + if (err) 248 + luaL_error(L, "chdir() failed"); 249 + return 0; 232 250 } 233 251 234 252 235 - static int f_list_dir(lua_State *L) { 236 - const char *path = luaL_checkstring(L, 1); 253 + static int f_list_dir(lua_State *L) 254 + { 255 + const char *path = luaL_checkstring(L, 1); 237 256 238 - DIR *dir = opendir(path); 239 - if (!dir) { 240 - lua_pushnil(L); 241 - lua_pushstring(L, strerror(errno)); 242 - return 2; 243 - } 257 + DIR *dir = opendir(path); 258 + if (!dir) 259 + { 260 + lua_pushnil(L); 261 + lua_pushstring(L, strerror(errno)); 262 + return 2; 263 + } 244 264 245 - lua_newtable(L); 246 - int i = 1; 247 - struct dirent *entry; 248 - while ( (entry = readdir(dir)) ) { 249 - if (strcmp(entry->d_name, "." ) == 0) { continue; } 250 - if (strcmp(entry->d_name, "..") == 0) { continue; } 251 - lua_pushstring(L, entry->d_name); 252 - lua_rawseti(L, -2, i); 253 - i++; 254 - } 265 + lua_newtable(L); 266 + int i = 1; 267 + struct dirent *entry; 268 + while ((entry = readdir(dir))) 269 + { 270 + if (strcmp(entry->d_name, "." ) == 0 || strcmp(entry->d_name, "..") == 0) 271 + continue; 272 + lua_pushstring(L, entry->d_name); 273 + lua_rawseti(L, -2, i); 274 + i++; 275 + } 255 276 256 - closedir(dir); 257 - return 1; 277 + closedir(dir); 278 + return 1; 258 279 } 259 280 260 281 261 282 #ifdef _WIN32 262 - #include <windows.h> 263 - #define realpath(x, y) _fullpath(y, x, MAX_PATH) 283 + # include <windows.h> 284 + # define realpath(x, y) _fullpath(y, x, MAX_PATH) 264 285 #endif 265 286 266 - static int f_absolute_path(lua_State *L) { 267 - const char *path = luaL_checkstring(L, 1); 268 - char *res = realpath(path, NULL); 269 - if (!res) { return 0; } 270 - lua_pushstring(L, res); 271 - free(res); 272 - return 1; 287 + static int f_absolute_path(lua_State *L) 288 + { 289 + const char *path = luaL_checkstring(L, 1); 290 + char *res = realpath(path, NULL); 291 + if (!res) 292 + return 0; 293 + lua_pushstring(L, res); 294 + free(res); 295 + return 1; 273 296 } 274 297 275 298 276 - static int f_get_file_info(lua_State *L) { 277 - const char *path = luaL_checkstring(L, 1); 299 + static int f_get_file_info(lua_State *L) 300 + { 301 + const char *path = luaL_checkstring(L, 1); 278 302 279 - struct stat s; 280 - int err = stat(path, &s); 281 - if (err < 0) { 282 - lua_pushnil(L); 283 - lua_pushstring(L, strerror(errno)); 284 - return 2; 285 - } 303 + struct stat s; 304 + int err = stat(path, &s); 305 + if (err < 0) 306 + { 307 + lua_pushnil(L); 308 + lua_pushstring(L, strerror(errno)); 309 + return 2; 310 + } 286 311 287 - lua_newtable(L); 288 - lua_pushnumber(L, s.st_mtime); 289 - lua_setfield(L, -2, "modified"); 312 + lua_newtable(L); 313 + lua_pushnumber(L, s.st_mtime); 314 + lua_setfield(L, -2, "modified"); 290 315 291 - lua_pushnumber(L, s.st_size); 292 - lua_setfield(L, -2, "size"); 316 + lua_pushnumber(L, s.st_size); 317 + lua_setfield(L, -2, "size"); 293 318 294 - if (S_ISREG(s.st_mode)) { 295 - lua_pushstring(L, "file"); 296 - } else if (S_ISDIR(s.st_mode)) { 297 - lua_pushstring(L, "dir"); 298 - } else { 299 - lua_pushnil(L); 300 - } 301 - lua_setfield(L, -2, "type"); 319 + if (S_ISREG(s.st_mode)) 320 + lua_pushstring(L, "file"); 321 + else if (S_ISDIR(s.st_mode)) 322 + lua_pushstring(L, "dir"); 323 + else 324 + lua_pushnil(L); 325 + lua_setfield(L, -2, "type"); 302 326 303 - return 1; 327 + return 1; 304 328 } 305 329 306 330 307 - static int f_get_clipboard(lua_State *L) { 308 - char *text = SDL_GetClipboardText(); 309 - if (!text) { return 0; } 310 - lua_pushstring(L, text); 311 - SDL_free(text); 312 - return 1; 331 + static int f_get_clipboard(lua_State *L) 332 + { 333 + char *text = SDL_GetClipboardText(); 334 + if (!text) 335 + return 0; 336 + lua_pushstring(L, text); 337 + SDL_free(text); 338 + return 1; 313 339 } 314 340 315 341 316 - static int f_set_clipboard(lua_State *L) { 317 - const char *text = luaL_checkstring(L, 1); 318 - SDL_SetClipboardText(text); 319 - return 0; 342 + static int f_set_clipboard(lua_State *L) 343 + { 344 + const char *text = luaL_checkstring(L, 1); 345 + SDL_SetClipboardText(text); 346 + return 0; 320 347 } 321 348 322 349 323 - static int f_get_time(lua_State *L) { 324 - double n = SDL_GetPerformanceCounter() / (double) SDL_GetPerformanceFrequency(); 325 - lua_pushnumber(L, n); 326 - return 1; 350 + static int f_get_time(lua_State *L) 351 + { 352 + double n = SDL_GetPerformanceCounter() / (double) SDL_GetPerformanceFrequency(); 353 + lua_pushnumber(L, n); 354 + return 1; 327 355 } 328 356 329 357 330 - static int f_sleep(lua_State *L) { 331 - double n = luaL_checknumber(L, 1); 332 - SDL_Delay(n * 1000); 333 - return 0; 358 + static int f_sleep(lua_State *L) 359 + { 360 + double n = luaL_checknumber(L, 1); 361 + SDL_Delay(n * 1000); 362 + return 0; 334 363 } 335 364 336 365 337 - static int f_exec(lua_State *L) { 338 - size_t len; 339 - const char *cmd = luaL_checklstring(L, 1, &len); 340 - char *buf = malloc(len + 32); 341 - if (!buf) { luaL_error(L, "buffer allocation failed"); } 342 - #if _WIN32 343 - sprintf(buf, "cmd /c \"%s\"", cmd); 344 - WinExec(buf, SW_HIDE); 345 - #else 346 - sprintf(buf, "%s &", cmd); 347 - int res = system(buf); 348 - (void) res; 349 - #endif 350 - free(buf); 351 - return 0; 366 + static int f_exec(lua_State *L) 367 + { 368 + size_t len; 369 + const char *cmd = luaL_checklstring(L, 1, &len); 370 + char *buf = malloc(len + 32); 371 + if (!buf) 372 + luaL_error(L, "buffer allocation failed"); 373 + 374 + # if _WIN32 375 + sprintf(buf, "cmd /c \"%s\"", cmd); 376 + WinExec(buf, SW_HIDE); 377 + # else 378 + sprintf(buf, "%s &", cmd); 379 + int res = system(buf); 380 + (void)res; 381 + # endif 382 + 383 + free(buf); 384 + return 0; 352 385 } 353 386 354 387 355 - static int f_fuzzy_match(lua_State *L) { 356 - const char *str = luaL_checkstring(L, 1); 357 - const char *ptn = luaL_checkstring(L, 2); 358 - int score = 0; 359 - int run = 0; 388 + static int f_fuzzy_match(lua_State *L) 389 + { 390 + const char *str = luaL_checkstring(L, 1); 391 + const char *ptn = luaL_checkstring(L, 2); 392 + int score = 0; 393 + int run = 0; 360 394 361 - while (*str && *ptn) { 362 - while (*str == ' ') { str++; } 363 - while (*ptn == ' ') { ptn++; } 364 - if (tolower(*str) == tolower(*ptn)) { 365 - score += run * 10 - (*str != *ptn); 366 - run++; 367 - ptn++; 368 - } else { 369 - score -= 10; 370 - run = 0; 371 - } 372 - str++; 373 - } 374 - if (*ptn) { return 0; } 395 + while (*str && *ptn) 396 + { 397 + while (*str == ' ') 398 + str++; 399 + while (*ptn == ' ') 400 + ptn++; 401 + if (tolower(*str) == tolower(*ptn)) 402 + { 403 + score += run * 10 - (*str != *ptn); 404 + run++; 405 + ptn++; 406 + } 407 + else 408 + { 409 + score -= 10; 410 + run = 0; 411 + } 412 + str++; 413 + } 414 + if (*ptn) 415 + return 0; 375 416 376 - lua_pushnumber(L, score - (int) strlen(str)); 377 - return 1; 417 + lua_pushnumber(L, score - (int) strlen(str)); 418 + return 1; 378 419 } 379 420 380 421 381 422 static const luaL_Reg lib[] = { 382 - { "poll_event", f_poll_event }, 383 - { "wait_event", f_wait_event }, 384 - { "set_cursor", f_set_cursor }, 385 - { "set_window_title", f_set_window_title }, 386 - { "set_window_mode", f_set_window_mode }, 387 - { "window_has_focus", f_window_has_focus }, 388 - { "show_confirm_dialog", f_show_confirm_dialog }, 389 - { "chdir", f_chdir }, 390 - { "list_dir", f_list_dir }, 391 - { "absolute_path", f_absolute_path }, 392 - { "get_file_info", f_get_file_info }, 393 - { "get_clipboard", f_get_clipboard }, 394 - { "set_clipboard", f_set_clipboard }, 395 - { "get_time", f_get_time }, 396 - { "sleep", f_sleep }, 397 - { "exec", f_exec }, 398 - { "fuzzy_match", f_fuzzy_match }, 399 - { NULL, NULL } 423 + { "poll_event", f_poll_event }, 424 + { "wait_event", f_wait_event }, 425 + { "set_cursor", f_set_cursor }, 426 + { "set_window_title", f_set_window_title }, 427 + { "set_window_mode", f_set_window_mode }, 428 + { "window_has_focus", f_window_has_focus }, 429 + { "show_confirm_dialog", f_show_confirm_dialog }, 430 + { "chdir", f_chdir }, 431 + { "list_dir", f_list_dir }, 432 + { "absolute_path", f_absolute_path }, 433 + { "get_file_info", f_get_file_info }, 434 + { "get_clipboard", f_get_clipboard }, 435 + { "set_clipboard", f_set_clipboard }, 436 + { "get_time", f_get_time }, 437 + { "sleep", f_sleep }, 438 + { "exec", f_exec }, 439 + { "fuzzy_match", f_fuzzy_match }, 440 + { NULL, NULL } 400 441 }; 401 442 402 443 403 - int luaopen_system(lua_State *L) { 404 - luaL_newlib(L, lib); 405 - return 1; 444 + int luaopen_system(lua_State *L) 445 + { 446 + luaL_newlib(L, lib); 447 + return 1; 406 448 }
+101 -99
src/main.c
··· 5 5 #include "renderer.h" 6 6 7 7 #ifdef _WIN32 8 - #include <windows.h> 8 + # include <windows.h> 9 9 #elif __linux__ 10 - #include <unistd.h> 10 + # include <unistd.h> 11 11 #elif __APPLE__ 12 - #include <mach-o/dyld.h> 12 + # include <mach-o/dyld.h> 13 13 #endif 14 14 15 15 16 16 SDL_Window *window; 17 17 18 18 19 - static double get_scale(void) { 20 - return (double)SDL_min(SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()), 1.0); 19 + static double get_scale(void) 20 + { 21 + return (double)SDL_min(SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()), 1.0); 21 22 } 22 23 23 - 24 - static void get_exe_filename(char *buf, int sz) { 25 - #if _WIN32 26 - int len = GetModuleFileName(NULL, buf, sz - 1); 27 - buf[len] = '\0'; 28 - #elif __linux__ 29 - char path[512]; 30 - sprintf(path, "/proc/%d/exe", getpid()); 31 - int len = readlink(path, buf, sz - 1); 32 - buf[len] = '\0'; 33 - #elif __APPLE__ 34 - unsigned size = sz; 35 - _NSGetExecutablePath(buf, &size); 36 - #else 37 - strcpy(buf, "./lite"); 38 - #endif 24 + static void get_exe_filename(char *buf, int sz) 25 + { 26 + # if _WIN32 27 + int len = GetModuleFileName(NULL, buf, sz - 1); 28 + buf[len] = '\0'; 29 + # elif __linux__ 30 + char path[512]; 31 + sprintf(path, "/proc/%d/exe", getpid()); 32 + int len = readlink(path, buf, sz - 1); 33 + buf[len] = '\0'; 34 + # elif __APPLE__ 35 + unsigned size = sz; 36 + _NSGetExecutablePath(buf, &size); 37 + # else 38 + strcpy(buf, "./lite"); 39 + # endif 39 40 } 40 41 41 42 42 - static void init_window_icon(void) { 43 - #ifndef _WIN32 44 - #include "../icon.inl" 45 - (void) icon_rgba_len; /* unused */ 46 - SDL_Surface *surf = SDL_CreateSurfaceFrom(64, 64, SDL_PIXELFORMAT_ABGR8888, icon_rgba, 64 * 4); 47 - SDL_SetWindowIcon(window, surf); 48 - SDL_DestroySurface(surf); 49 - #endif 43 + static void init_window_icon(void) 44 + { 45 + # ifndef _WIN32 46 + # include "../icon.inl" 47 + (void) icon_rgba_len; /* unused */ 48 + SDL_Surface *surf = SDL_CreateSurfaceFrom(64, 64, SDL_PIXELFORMAT_ABGR8888, icon_rgba, 64 * 4); 49 + SDL_SetWindowIcon(window, surf); 50 + SDL_DestroySurface(surf); 51 + # endif 50 52 } 51 53 52 54 53 - int main(int argc, char **argv) { 54 - #ifdef _WIN32 55 - HINSTANCE lib = LoadLibrary("user32.dll"); 56 - int (*SetProcessDPIAware)() = (void*) GetProcAddress(lib, "SetProcessDPIAware"); 57 - SetProcessDPIAware(); 58 - #endif 59 - 60 - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); 61 - SDL_EnableScreenSaver(); 62 - SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, true); 63 - atexit(SDL_Quit); 64 - 65 - SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); 66 - SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); 55 + int main(int argc, char **argv) 56 + { 57 + # ifdef _WIN32 58 + HINSTANCE lib = LoadLibrary("user32.dll"); 59 + int (*SetProcessDPIAware)() = (void*) GetProcAddress(lib, "SetProcessDPIAware"); 60 + SetProcessDPIAware(); 61 + # endif 67 62 68 - const SDL_DisplayMode *dm = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); 69 - window = SDL_CreateWindow("", (int)(dm->w * 0.8), (int)(dm->h * 0.8), SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_HIDDEN); 70 - if (!window) 71 - { 72 - SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to create window: %s\n", SDL_GetError()); 73 - return EXIT_FAILURE; 74 - } 75 - init_window_icon(); 76 - ren_init(window); 63 + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); 64 + SDL_EnableScreenSaver(); 65 + SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, true); 66 + atexit(SDL_Quit); 77 67 78 - if (!SDL_StartTextInput(window)) 79 - { 80 - #ifndef _WIN32 81 - SDL_LogError(SDL_LOG_CATEGORY_ERROR, "ERROR: failed SDL_StartTextInput() - text entry may not work"); 82 - #endif 83 - } 68 + SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); 69 + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); 84 70 71 + const SDL_DisplayMode *dm = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); 72 + window = SDL_CreateWindow("", (int)(dm->w * 0.8), (int)(dm->h * 0.8), SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_HIDDEN); 73 + if (!window) 74 + { 75 + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to create window: %s\n", SDL_GetError()); 76 + return EXIT_FAILURE; 77 + } 78 + init_window_icon(); 79 + ren_init(window); 85 80 86 - lua_State *L = luaL_newstate(); 87 - luaL_openlibs(L); 88 - api_load_libs(L); 81 + if (!SDL_StartTextInput(window)) 82 + { 83 + # ifndef _WIN32 84 + SDL_LogError(SDL_LOG_CATEGORY_ERROR, "ERROR: failed SDL_StartTextInput() - text entry may not work"); 85 + # endif 86 + } 89 87 90 88 91 - lua_newtable(L); 92 - for (int i = 0; i < argc; i++) { 93 - lua_pushstring(L, argv[i]); 94 - lua_rawseti(L, -2, i + 1); 95 - } 96 - lua_setglobal(L, "ARGS"); 89 + lua_State *L = luaL_newstate(); 90 + luaL_openlibs(L); 91 + api_load_libs(L); 97 92 98 - lua_pushstring(L, "1.11"); 99 - lua_setglobal(L, "VERSION"); 93 + lua_newtable(L); 94 + for (int i = 0 ; i < argc ; i++) 95 + { 96 + lua_pushstring(L, argv[i]); 97 + lua_rawseti(L, -2, i + 1); 98 + } 99 + lua_setglobal(L, "ARGS"); 100 100 101 - lua_pushstring(L, SDL_GetPlatform()); 102 - lua_setglobal(L, "PLATFORM"); 101 + lua_pushstring(L, "1.11"); 102 + lua_setglobal(L, "VERSION"); 103 103 104 - lua_pushnumber(L, get_scale()); 105 - lua_setglobal(L, "SCALE"); 104 + lua_pushstring(L, SDL_GetPlatform()); 105 + lua_setglobal(L, "PLATFORM"); 106 106 107 - char exename[2048]; 108 - get_exe_filename(exename, sizeof(exename)); 109 - lua_pushstring(L, exename); 110 - lua_setglobal(L, "EXEFILE"); 107 + lua_pushnumber(L, get_scale()); 108 + lua_setglobal(L, "SCALE"); 111 109 110 + char exename[2048]; 111 + get_exe_filename(exename, sizeof(exename)); 112 + lua_pushstring(L, exename); 113 + lua_setglobal(L, "EXEFILE"); 112 114 113 - (void) luaL_dostring(L, 114 - "local core\n" 115 - "xpcall(function()\n" 116 - " SCALE = tonumber(os.getenv(\"LITE_SCALE\")) or SCALE\n" 117 - " PATHSEP = package.config:sub(1, 1)\n" 118 - " EXEDIR = EXEFILE:match(\"^(.+)[/\\\\].*$\")\n" 119 - " package.path = EXEDIR .. '/data/?.lua;' .. package.path\n" 120 - " package.path = EXEDIR .. '/data/?/init.lua;' .. package.path\n" 121 - " core = require('core')\n" 122 - " core.init()\n" 123 - " core.run()\n" 124 - "end, function(err)\n" 125 - " print('Error: ' .. tostring(err))\n" 126 - " print(debug.traceback(nil, 2))\n" 127 - " if core and core.on_error then\n" 128 - " pcall(core.on_error, err)\n" 129 - " end\n" 130 - " os.exit(1)\n" 131 - "end)"); 115 + (void) luaL_dostring(L, 116 + "local core\n" 117 + "xpcall(function()\n" 118 + " SCALE = tonumber(os.getenv(\"LITE_SCALE\")) or SCALE\n" 119 + " PATHSEP = package.config:sub(1, 1)\n" 120 + " EXEDIR = EXEFILE:match(\"^(.+)[/\\\\].*$\")\n" 121 + " package.path = EXEDIR .. '/data/?.lua;' .. package.path\n" 122 + " package.path = EXEDIR .. '/data/?/init.lua;' .. package.path\n" 123 + " core = require('core')\n" 124 + " core.init()\n" 125 + " core.run()\n" 126 + "end, function(err)\n" 127 + " print('Error: ' .. tostring(err))\n" 128 + " print(debug.traceback(nil, 2))\n" 129 + " if core and core.on_error then\n" 130 + " pcall(core.on_error, err)\n" 131 + " end\n" 132 + " os.exit(1)\n" 133 + "end)"); 132 134 133 135 134 - lua_close(L); 135 - SDL_DestroyWindow(window); 136 + lua_close(L); 137 + SDL_DestroyWindow(window); 136 138 137 - return EXIT_SUCCESS; 139 + return EXIT_SUCCESS; 138 140 }
+265 -197
src/rencache.c
··· 11 11 #define CELL_SIZE 96 12 12 #define COMMAND_BUF_SIZE (1024 * 512) 13 13 14 - enum { FREE_FONT, SET_CLIP, DRAW_TEXT, DRAW_RECT }; 14 + enum 15 + { 16 + FREE_FONT, 17 + SET_CLIP, 18 + DRAW_TEXT, 19 + DRAW_RECT 20 + }; 15 21 16 - typedef struct { 17 - int type, size; 18 - RenRect rect; 19 - RenColor color; 20 - RenFont *font; 21 - int tab_width; 22 - char text[0]; 22 + typedef struct 23 + { 24 + int type, size; 25 + RenRect rect; 26 + RenColor color; 27 + RenFont *font; 28 + int tab_width; 29 + char text[0]; 23 30 } Command; 24 31 25 32 ··· 40 47 /* 32bit fnv-1a hash */ 41 48 #define HASH_INITIAL 2166136261 42 49 43 - static void hash(unsigned *h, const void *data, int size) { 44 - const unsigned char *p = data; 45 - while (size--) { 46 - *h = (*h ^ *p++) * 16777619; 47 - } 50 + static void hash(unsigned *h, const void *data, int size) 51 + { 52 + const unsigned char *p = data; 53 + while (size--) 54 + { 55 + *h = (*h ^ *p++) * 16777619; 56 + } 48 57 } 49 58 50 59 51 - static inline int cell_idx(int x, int y) { 52 - return x + y * CELLS_X; 60 + static inline int cell_idx(int x, int y) 61 + { 62 + return x + y * CELLS_X; 53 63 } 54 64 55 65 56 - static inline bool rects_overlap(RenRect a, RenRect b) { 57 - return b.x + b.width >= a.x && b.x <= a.x + a.width 58 - && b.y + b.height >= a.y && b.y <= a.y + a.height; 66 + static inline bool rects_overlap(RenRect a, RenRect b) 67 + { 68 + return b.x + b.width >= a.x && 69 + b.x <= a.x + a.width && 70 + b.y + b.height >= a.y && 71 + b.y <= a.y + a.height; 59 72 } 60 73 61 74 62 - static RenRect intersect_rects(RenRect a, RenRect b) { 63 - int x1 = max(a.x, b.x); 64 - int y1 = max(a.y, b.y); 65 - int x2 = min(a.x + a.width, b.x + b.width); 66 - int y2 = min(a.y + a.height, b.y + b.height); 67 - return (RenRect) { x1, y1, max(0, x2 - x1), max(0, y2 - y1) }; 75 + static RenRect intersect_rects(RenRect a, RenRect b) 76 + { 77 + int x1 = max(a.x, b.x); 78 + int y1 = max(a.y, b.y); 79 + int x2 = min(a.x + a.width, b.x + b.width); 80 + int y2 = min(a.y + a.height, b.y + b.height); 81 + return (RenRect){ x1, y1, max(0, x2 - x1), max(0, y2 - y1) }; 68 82 } 69 83 70 84 71 - static RenRect merge_rects(RenRect a, RenRect b) { 72 - int x1 = min(a.x, b.x); 73 - int y1 = min(a.y, b.y); 74 - int x2 = max(a.x + a.width, b.x + b.width); 75 - int y2 = max(a.y + a.height, b.y + b.height); 76 - return (RenRect) { x1, y1, x2 - x1, y2 - y1 }; 85 + static RenRect merge_rects(RenRect a, RenRect b) 86 + { 87 + int x1 = min(a.x, b.x); 88 + int y1 = min(a.y, b.y); 89 + int x2 = max(a.x + a.width, b.x + b.width); 90 + int y2 = max(a.y + a.height, b.y + b.height); 91 + return (RenRect){ x1, y1, x2 - x1, y2 - y1 }; 77 92 } 78 93 79 94 80 - static Command* push_command(int type, int size) { 81 - Command *cmd = (Command*) (command_buf + command_buf_idx); 82 - int n = command_buf_idx + size; 83 - if (n > COMMAND_BUF_SIZE) { 84 - fprintf(stderr, "Warning: (" __FILE__ "): exhausted command buffer\n"); 85 - return NULL; 86 - } 87 - command_buf_idx = n; 88 - memset(cmd, 0, sizeof(Command)); 89 - cmd->type = type; 90 - cmd->size = size; 91 - return cmd; 95 + static Command* push_command(int type, int size) 96 + { 97 + Command *cmd = (Command *)(command_buf + command_buf_idx); 98 + int n = command_buf_idx + size; 99 + if (n > COMMAND_BUF_SIZE) 100 + { 101 + fprintf(stderr, "Warning: (" __FILE__ "): exhausted command buffer\n"); 102 + return NULL; 103 + } 104 + command_buf_idx = n; 105 + memset(cmd, 0, sizeof(Command)); 106 + cmd->type = type; 107 + cmd->size = size; 108 + return cmd; 92 109 } 93 110 94 111 95 - static bool next_command(Command **prev) { 96 - if (*prev == NULL) { 97 - *prev = (Command*) command_buf; 98 - } else { 99 - *prev = (Command*) (((char*) *prev) + (*prev)->size); 100 - } 101 - return *prev != ((Command*) (command_buf + command_buf_idx)); 112 + static bool next_command(Command **prev) 113 + { 114 + if (*prev == NULL) 115 + { 116 + *prev = (Command *)command_buf; 117 + } 118 + else 119 + { 120 + *prev = (Command *)(((char*) *prev) + (*prev)->size); 121 + } 122 + 123 + return *prev != ((Command *)(command_buf + command_buf_idx)); 102 124 } 103 125 104 126 105 - void rencache_show_debug(bool enable) { 106 - show_debug = enable; 127 + void rencache_show_debug(bool enable) 128 + { 129 + show_debug = enable; 107 130 } 108 131 109 132 110 - void rencache_free_font(RenFont *font) { 111 - Command *cmd = push_command(FREE_FONT, sizeof(Command)); 112 - if (cmd) { cmd->font = font; } 133 + void rencache_free_font(RenFont *font) 134 + { 135 + Command *cmd = push_command(FREE_FONT, sizeof(Command)); 136 + if (cmd) 137 + { 138 + cmd->font = font; 139 + } 113 140 } 114 141 115 142 116 - void rencache_set_clip_rect(RenRect rect) { 117 - Command *cmd = push_command(SET_CLIP, sizeof(Command)); 118 - if (cmd) { cmd->rect = intersect_rects(rect, screen_rect); } 143 + void rencache_set_clip_rect(RenRect rect) 144 + { 145 + Command *cmd = push_command(SET_CLIP, sizeof(Command)); 146 + if (cmd) 147 + { 148 + cmd->rect = intersect_rects(rect, screen_rect); 149 + } 119 150 } 120 151 121 152 122 - void rencache_draw_rect(RenRect rect, RenColor color) { 123 - if (!rects_overlap(screen_rect, rect)) { return; } 124 - Command *cmd = push_command(DRAW_RECT, sizeof(Command)); 125 - if (cmd) { 126 - cmd->rect = rect; 127 - cmd->color = color; 128 - } 153 + void rencache_draw_rect(RenRect rect, RenColor color) 154 + { 155 + if (!rects_overlap(screen_rect, rect)) 156 + { 157 + return; 158 + } 159 + Command *cmd = push_command(DRAW_RECT, sizeof(Command)); 160 + if (cmd) 161 + { 162 + cmd->rect = rect; 163 + cmd->color = color; 164 + } 129 165 } 130 166 131 167 132 - int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) { 133 - RenRect rect; 134 - rect.x = x; 135 - rect.y = y; 136 - rect.width = ren_get_font_width(font, text); 137 - rect.height = ren_get_font_height(font); 168 + int rencache_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) 169 + { 170 + RenRect rect; 171 + rect.x = x; 172 + rect.y = y; 173 + rect.width = ren_get_font_width(font, text); 174 + rect.height = ren_get_font_height(font); 138 175 139 - if (rects_overlap(screen_rect, rect)) { 140 - int sz = strlen(text) + 1; 141 - Command *cmd = push_command(DRAW_TEXT, sizeof(Command) + sz); 142 - if (cmd) { 143 - memcpy(cmd->text, text, sz); 144 - cmd->color = color; 145 - cmd->font = font; 146 - cmd->rect = rect; 147 - cmd->tab_width = ren_get_font_tab_width(font); 148 - } 149 - } 176 + if (rects_overlap(screen_rect, rect)) 177 + { 178 + int sz = strlen(text) + 1; 179 + Command *cmd = push_command(DRAW_TEXT, sizeof(Command) + sz); 180 + if (cmd) 181 + { 182 + memcpy(cmd->text, text, sz); 183 + cmd->color = color; 184 + cmd->font = font; 185 + cmd->rect = rect; 186 + cmd->tab_width = ren_get_font_tab_width(font); 187 + } 188 + } 150 189 151 - return x + rect.width; 190 + return x + rect.width; 152 191 } 153 192 154 193 155 - void rencache_invalidate(void) { 156 - memset(cells_prev, 0xff, sizeof(cells_buf1)); 194 + void rencache_invalidate(void) 195 + { 196 + memset(cells_prev, 0xff, sizeof(cells_buf1)); 157 197 } 158 198 159 199 160 - void rencache_begin_frame(void) { 161 - /* reset all cells if the screen width/height has changed */ 162 - int w, h; 163 - ren_get_size(&w, &h); 164 - if (screen_rect.width != w || h != screen_rect.height) { 165 - screen_rect.width = w; 166 - screen_rect.height = h; 167 - rencache_invalidate(); 168 - } 200 + void rencache_begin_frame(void) 201 + { 202 + /* reset all cells if the screen width/height has changed */ 203 + int w, h; 204 + ren_get_size(&w, &h); 205 + if (screen_rect.width != w || h != screen_rect.height) 206 + { 207 + screen_rect.width = w; 208 + screen_rect.height = h; 209 + rencache_invalidate(); 210 + } 169 211 } 170 212 171 213 172 - static void update_overlapping_cells(RenRect r, unsigned h) { 173 - int x1 = r.x / CELL_SIZE; 174 - int y1 = r.y / CELL_SIZE; 175 - int x2 = (r.x + r.width) / CELL_SIZE; 176 - int y2 = (r.y + r.height) / CELL_SIZE; 214 + static void update_overlapping_cells(RenRect r, unsigned h) 215 + { 216 + int x1 = r.x / CELL_SIZE; 217 + int y1 = r.y / CELL_SIZE; 218 + int x2 = (r.x + r.width) / CELL_SIZE; 219 + int y2 = (r.y + r.height) / CELL_SIZE; 177 220 178 - for (int y = y1; y <= y2; y++) { 179 - for (int x = x1; x <= x2; x++) { 180 - int idx = cell_idx(x, y); 181 - hash(&cells[idx], &h, sizeof(h)); 182 - } 183 - } 221 + for (int y = y1; y <= y2; y++) 222 + { 223 + for (int x = x1; x <= x2; x++) 224 + { 225 + int idx = cell_idx(x, y); 226 + hash(&cells[idx], &h, sizeof(h)); 227 + } 228 + } 184 229 } 185 230 186 231 187 - static void push_rect(RenRect r, int *count) { 188 - /* try to merge with existing rectangle */ 189 - for (int i = *count - 1; i >= 0; i--) { 190 - RenRect *rp = &rect_buf[i]; 191 - if (rects_overlap(*rp, r)) { 192 - *rp = merge_rects(*rp, r); 193 - return; 194 - } 195 - } 196 - /* couldn't merge with previous rectangle: push */ 197 - rect_buf[(*count)++] = r; 232 + static void push_rect(RenRect r, int *count) 233 + { 234 + /* try to merge with existing rectangle */ 235 + for (int i = *count - 1; i >= 0; i--) 236 + { 237 + RenRect *rp = &rect_buf[i]; 238 + if (rects_overlap(*rp, r)) 239 + { 240 + *rp = merge_rects(*rp, r); 241 + return; 242 + } 243 + } 244 + /* couldn't merge with previous rectangle: push */ 245 + rect_buf[(*count)++] = r; 198 246 } 199 247 200 248 201 - void rencache_end_frame(void) { 202 - /* update cells from commands */ 203 - Command *cmd = NULL; 204 - RenRect cr = screen_rect; 205 - while (next_command(&cmd)) { 206 - if (cmd->type == SET_CLIP) { cr = cmd->rect; } 207 - RenRect r = intersect_rects(cmd->rect, cr); 208 - if (r.width == 0 || r.height == 0) { continue; } 209 - unsigned h = HASH_INITIAL; 210 - hash(&h, cmd, cmd->size); 211 - update_overlapping_cells(r, h); 212 - } 249 + void rencache_end_frame(void) 250 + { 251 + /* update cells from commands */ 252 + Command *cmd = NULL; 253 + RenRect cr = screen_rect; 254 + while (next_command(&cmd)) 255 + { 256 + if (cmd->type == SET_CLIP) 257 + { 258 + cr = cmd->rect; 259 + } 260 + RenRect r = intersect_rects(cmd->rect, cr); 261 + if (r.width == 0 || r.height == 0) 262 + { 263 + continue; 264 + } 265 + unsigned h = HASH_INITIAL; 266 + hash(&h, cmd, cmd->size); 267 + update_overlapping_cells(r, h); 268 + } 213 269 214 - /* push rects for all cells changed from last frame, reset cells */ 215 - int rect_count = 0; 216 - int max_x = screen_rect.width / CELL_SIZE + 1; 217 - int max_y = screen_rect.height / CELL_SIZE + 1; 218 - for (int y = 0; y < max_y; y++) { 219 - for (int x = 0; x < max_x; x++) { 220 - /* compare previous and current cell for change */ 221 - int idx = cell_idx(x, y); 222 - if (cells[idx] != cells_prev[idx]) { 223 - push_rect((RenRect) { x, y, 1, 1 }, &rect_count); 224 - } 225 - cells_prev[idx] = HASH_INITIAL; 226 - } 227 - } 270 + /* push rects for all cells changed from last frame, reset cells */ 271 + int rect_count = 0; 272 + int max_x = screen_rect.width / CELL_SIZE + 1; 273 + int max_y = screen_rect.height / CELL_SIZE + 1; 274 + for (int y = 0; y < max_y; y++) 275 + { 276 + for (int x = 0; x < max_x; x++) 277 + { 278 + /* compare previous and current cell for change */ 279 + int idx = cell_idx(x, y); 280 + if (cells[idx] != cells_prev[idx]) 281 + { 282 + push_rect((RenRect) { x, y, 1, 1 }, &rect_count); 283 + } 284 + cells_prev[idx] = HASH_INITIAL; 285 + } 286 + } 228 287 229 - /* expand rects from cells to pixels */ 230 - for (int i = 0; i < rect_count; i++) { 231 - RenRect *r = &rect_buf[i]; 232 - r->x *= CELL_SIZE; 233 - r->y *= CELL_SIZE; 234 - r->width *= CELL_SIZE; 235 - r->height *= CELL_SIZE; 236 - *r = intersect_rects(*r, screen_rect); 237 - } 288 + /* expand rects from cells to pixels */ 289 + for (int i = 0; i < rect_count; i++) 290 + { 291 + RenRect *r = &rect_buf[i]; 292 + r->x *= CELL_SIZE; 293 + r->y *= CELL_SIZE; 294 + r->width *= CELL_SIZE; 295 + r->height *= CELL_SIZE; 296 + *r = intersect_rects(*r, screen_rect); 297 + } 238 298 239 - /* redraw updated regions */ 240 - bool has_free_commands = false; 241 - for (int i = 0; i < rect_count; i++) { 242 - /* draw */ 243 - RenRect r = rect_buf[i]; 244 - ren_set_clip_rect(r); 299 + /* redraw updated regions */ 300 + bool has_free_commands = false; 301 + for (int i = 0; i < rect_count; i++) 302 + { 303 + /* draw */ 304 + RenRect r = rect_buf[i]; 305 + ren_set_clip_rect(r); 245 306 246 - cmd = NULL; 247 - while (next_command(&cmd)) { 248 - switch (cmd->type) { 249 - case FREE_FONT: 250 - has_free_commands = true; 251 - break; 252 - case SET_CLIP: 253 - ren_set_clip_rect(intersect_rects(cmd->rect, r)); 254 - break; 255 - case DRAW_RECT: 256 - ren_draw_rect(cmd->rect, cmd->color); 257 - break; 258 - case DRAW_TEXT: 259 - ren_set_font_tab_width(cmd->font, cmd->tab_width); 260 - ren_draw_text(cmd->font, cmd->text, cmd->rect.x, cmd->rect.y, cmd->color); 261 - break; 262 - } 263 - } 307 + cmd = NULL; 308 + while (next_command(&cmd)) 309 + { 310 + switch (cmd->type) 311 + { 312 + case FREE_FONT: 313 + has_free_commands = true; 314 + break; 315 + case SET_CLIP: 316 + ren_set_clip_rect(intersect_rects(cmd->rect, r)); 317 + break; 318 + case DRAW_RECT: 319 + ren_draw_rect(cmd->rect, cmd->color); 320 + break; 321 + case DRAW_TEXT: 322 + ren_set_font_tab_width(cmd->font, cmd->tab_width); 323 + ren_draw_text(cmd->font, cmd->text, cmd->rect.x, cmd->rect.y, cmd->color); 324 + break; 325 + } 326 + } 264 327 265 - if (show_debug) { 266 - RenColor color = { rand(), rand(), rand(), 50 }; 267 - ren_draw_rect(r, color); 268 - } 269 - } 328 + if (show_debug) 329 + { 330 + RenColor color = { rand(), rand(), rand(), 50 }; 331 + ren_draw_rect(r, color); 332 + } 333 + } 270 334 271 - /* update dirty rects */ 272 - if (rect_count > 0) { 273 - ren_update_rects(rect_buf, rect_count); 274 - } 335 + /* update dirty rects */ 336 + if (rect_count > 0) 337 + { 338 + ren_update_rects(rect_buf, rect_count); 339 + } 275 340 276 - /* free fonts */ 277 - if (has_free_commands) { 278 - cmd = NULL; 279 - while (next_command(&cmd)) { 280 - if (cmd->type == FREE_FONT) { 281 - ren_free_font(cmd->font); 282 - } 283 - } 284 - } 341 + /* free fonts */ 342 + if (has_free_commands) 343 + { 344 + cmd = NULL; 345 + while (next_command(&cmd)) 346 + { 347 + if (cmd->type == FREE_FONT) 348 + { 349 + ren_free_font(cmd->font); 350 + } 351 + } 352 + } 285 353 286 - /* swap cell buffer and reset */ 287 - unsigned *tmp = cells; 288 - cells = cells_prev; 289 - cells_prev = tmp; 290 - command_buf_idx = 0; 354 + /* swap cell buffer and reset */ 355 + unsigned *tmp = cells; 356 + cells = cells_prev; 357 + cells_prev = tmp; 358 + command_buf_idx = 0; 291 359 }
+299 -249
src/renderer.c
··· 7 7 8 8 #define MAX_GLYPHSET 256 9 9 10 - struct RenImage { 11 - RenColor *pixels; 12 - int width, height; 10 + struct RenImage 11 + { 12 + RenColor *pixels; 13 + int width, height; 13 14 }; 14 15 15 - typedef struct { 16 - RenImage *image; 17 - stbtt_bakedchar glyphs[256]; 16 + typedef struct 17 + { 18 + RenImage *image; 19 + stbtt_bakedchar glyphs[256]; 18 20 } GlyphSet; 19 21 20 - struct RenFont { 21 - void *data; 22 - stbtt_fontinfo stbfont; 23 - GlyphSet *sets[MAX_GLYPHSET]; 24 - float size; 25 - int height; 22 + struct RenFont 23 + { 24 + void *data; 25 + stbtt_fontinfo stbfont; 26 + GlyphSet *sets[MAX_GLYPHSET]; 27 + float size; 28 + int height; 26 29 }; 27 30 28 31 29 32 static SDL_Window *window; 30 - static struct { int left, top, right, bottom; } clip; 33 + static struct 34 + { 35 + int left, top, right, bottom; 36 + } clip; 31 37 32 38 33 - static void* check_alloc(void *ptr) { 34 - if (!ptr) { 35 - fprintf(stderr, "Fatal error: memory allocation failed\n"); 36 - exit(EXIT_FAILURE); 37 - } 38 - return ptr; 39 + static void* check_alloc(void *ptr) 40 + { 41 + if (!ptr) 42 + { 43 + fprintf(stderr, "Fatal error: memory allocation failed\n"); 44 + exit(EXIT_FAILURE); 45 + } 46 + return ptr; 39 47 } 40 48 41 49 42 - static const char* utf8_to_codepoint(const char *p, unsigned *dst) { 43 - unsigned res, n; 44 - switch (*p & 0xf0) { 45 - case 0xf0 : res = *p & 0x07; n = 3; break; 46 - case 0xe0 : res = *p & 0x0f; n = 2; break; 47 - case 0xd0 : 48 - case 0xc0 : res = *p & 0x1f; n = 1; break; 49 - default : res = *p; n = 0; break; 50 - } 51 - while (n--) { 52 - res = (res << 6) | (*(++p) & 0x3f); 53 - } 54 - *dst = res; 55 - return p + 1; 50 + static const char* utf8_to_codepoint(const char *p, unsigned *dst) 51 + { 52 + unsigned res, n; 53 + switch (*p & 0xf0) 54 + { 55 + case 0xf0 : res = *p & 0x07; n = 3; break; 56 + case 0xe0 : res = *p & 0x0f; n = 2; break; 57 + case 0xd0 : 58 + case 0xc0 : res = *p & 0x1f; n = 1; break; 59 + default : res = *p; n = 0; break; 60 + } 61 + while (n--) 62 + res = (res << 6) | (*(++p) & 0x3f); 63 + *dst = res; 64 + return p + 1; 56 65 } 57 66 58 67 59 - void ren_init(SDL_Window *win) { 60 - assert(win); 61 - window = win; 62 - SDL_Surface *surf = SDL_GetWindowSurface(window); 63 - ren_set_clip_rect( (RenRect) { 0, 0, surf->w, surf->h } ); 68 + void ren_init(SDL_Window *win) 69 + { 70 + assert(win); 71 + window = win; 72 + SDL_Surface *surf = SDL_GetWindowSurface(window); 73 + ren_set_clip_rect((RenRect){ 0, 0, surf->w, surf->h }); 64 74 } 65 75 66 76 67 - void ren_update_rects(RenRect *rects, int count) { 68 - SDL_UpdateWindowSurfaceRects(window, (SDL_Rect*) rects, count); 69 - static bool initial_frame = true; 70 - if (initial_frame) { 71 - SDL_ShowWindow(window); 72 - initial_frame = false; 73 - } 77 + void ren_update_rects(RenRect *rects, int count) 78 + { 79 + SDL_UpdateWindowSurfaceRects(window, (SDL_Rect *)rects, count); 80 + static bool initial_frame = true; 81 + if (initial_frame) 82 + { 83 + SDL_ShowWindow(window); 84 + initial_frame = false; 85 + } 74 86 } 75 87 76 88 77 - void ren_set_clip_rect(RenRect rect) { 78 - clip.left = rect.x; 79 - clip.top = rect.y; 80 - clip.right = rect.x + rect.width; 81 - clip.bottom = rect.y + rect.height; 89 + void ren_set_clip_rect(RenRect rect) 90 + { 91 + clip.left = rect.x; 92 + clip.top = rect.y; 93 + clip.right = rect.x + rect.width; 94 + clip.bottom = rect.y + rect.height; 82 95 } 83 96 84 97 85 - void ren_get_size(int *x, int *y) { 86 - SDL_Surface *surf = SDL_GetWindowSurface(window); 87 - *x = surf->w; 88 - *y = surf->h; 98 + void ren_get_size(int *x, int *y) 99 + { 100 + SDL_Surface *surf = SDL_GetWindowSurface(window); 101 + *x = surf->w; 102 + *y = surf->h; 89 103 } 90 104 91 105 92 - RenImage* ren_new_image(int width, int height) { 93 - assert(width > 0 && height > 0); 94 - RenImage *image = malloc(sizeof(RenImage) + width * height * sizeof(RenColor)); 95 - check_alloc(image); 96 - image->pixels = (void*) (image + 1); 97 - image->width = width; 98 - image->height = height; 99 - return image; 106 + RenImage* ren_new_image(int width, int height) 107 + { 108 + assert(width > 0 && height > 0); 109 + RenImage *image = malloc(sizeof(RenImage) + width * height * sizeof(RenColor)); 110 + check_alloc(image); 111 + image->pixels = (void *)(image + 1); 112 + image->width = width; 113 + image->height = height; 114 + return image; 100 115 } 101 116 102 117 103 - void ren_free_image(RenImage *image) { 104 - free(image); 118 + void ren_free_image(RenImage *image) 119 + { 120 + free(image); 105 121 } 106 122 107 123 108 - static GlyphSet* load_glyphset(RenFont *font, int idx) { 109 - GlyphSet *set = check_alloc(calloc(1, sizeof(GlyphSet))); 124 + static GlyphSet* load_glyphset(RenFont *font, int idx) 125 + { 126 + GlyphSet *set = check_alloc(calloc(1, sizeof(GlyphSet))); 110 127 111 - /* init image */ 112 - int width = 128; 113 - int height = 128; 128 + /* init image */ 129 + int width = 128; 130 + int height = 128; 114 131 retry: 115 - set->image = ren_new_image(width, height); 132 + set->image = ren_new_image(width, height); 116 133 117 - /* load glyphs */ 118 - float s = 119 - stbtt_ScaleForMappingEmToPixels(&font->stbfont, 1) / 120 - stbtt_ScaleForPixelHeight(&font->stbfont, 1); 121 - int res = stbtt_BakeFontBitmap( 122 - font->data, 0, font->size * s, (void*) set->image->pixels, 123 - width, height, idx * 256, 256, set->glyphs); 134 + /* load glyphs */ 135 + float s = 136 + stbtt_ScaleForMappingEmToPixels(&font->stbfont, 1) / 137 + stbtt_ScaleForPixelHeight(&font->stbfont, 1); 138 + int res = stbtt_BakeFontBitmap( 139 + font->data, 0, font->size * s, (void *)set->image->pixels, 140 + width, height, idx * 256, 256, set->glyphs); 124 141 125 - /* retry with a larger image buffer if the buffer wasn't large enough */ 126 - if (res < 0) { 127 - width *= 2; 128 - height *= 2; 129 - ren_free_image(set->image); 130 - goto retry; 131 - } 142 + /* retry with a larger image buffer if the buffer wasn't large enough */ 143 + if (res < 0) 144 + { 145 + width *= 2; 146 + height *= 2; 147 + ren_free_image(set->image); 148 + goto retry; 149 + } 132 150 133 - /* adjust glyph yoffsets and xadvance */ 134 - int ascent, descent, linegap; 135 - stbtt_GetFontVMetrics(&font->stbfont, &ascent, &descent, &linegap); 136 - float scale = stbtt_ScaleForMappingEmToPixels(&font->stbfont, font->size); 137 - int scaled_ascent = ascent * scale + 0.5; 138 - for (int i = 0; i < 256; i++) { 139 - set->glyphs[i].yoff += scaled_ascent; 140 - set->glyphs[i].xadvance = floor(set->glyphs[i].xadvance); 141 - } 151 + /* adjust glyph yoffsets and xadvance */ 152 + int ascent, descent, linegap; 153 + stbtt_GetFontVMetrics(&font->stbfont, &ascent, &descent, &linegap); 154 + float scale = stbtt_ScaleForMappingEmToPixels(&font->stbfont, font->size); 155 + int scaled_ascent = ascent * scale + 0.5; 156 + for (int i = 0; i < 256; i++) 157 + { 158 + set->glyphs[i].yoff += scaled_ascent; 159 + set->glyphs[i].xadvance = floor(set->glyphs[i].xadvance); 160 + } 142 161 143 - /* convert 8bit data to 32bit */ 144 - for (int i = width * height - 1; i >= 0; i--) { 145 - uint8_t n = *((uint8_t*) set->image->pixels + i); 146 - set->image->pixels[i] = (RenColor) { .r = 255, .g = 255, .b = 255, .a = n }; 147 - } 162 + /* convert 8bit data to 32bit */ 163 + for (int i = width * height - 1; i >= 0; i--) 164 + { 165 + uint8_t n = *((uint8_t*) set->image->pixels + i); 166 + set->image->pixels[i] = (RenColor) { .r = 255, .g = 255, .b = 255, .a = n }; 167 + } 148 168 149 - return set; 169 + return set; 150 170 } 151 171 152 172 153 - static GlyphSet* get_glyphset(RenFont *font, int codepoint) { 154 - int idx = (codepoint >> 8) % MAX_GLYPHSET; 155 - if (!font->sets[idx]) { 156 - font->sets[idx] = load_glyphset(font, idx); 157 - } 158 - return font->sets[idx]; 173 + static GlyphSet* get_glyphset(RenFont *font, int codepoint) 174 + { 175 + int idx = (codepoint >> 8) % MAX_GLYPHSET; 176 + if (!font->sets[idx]) 177 + font->sets[idx] = load_glyphset(font, idx); 178 + return font->sets[idx]; 159 179 } 160 180 161 181 162 - RenFont* ren_load_font(const char *filename, float size) { 163 - RenFont *font = NULL; 164 - FILE *fp = NULL; 182 + RenFont* ren_load_font(const char *filename, float size) 183 + { 184 + RenFont *font = NULL; 185 + FILE *fp = NULL; 165 186 166 - /* init font */ 167 - font = check_alloc(calloc(1, sizeof(RenFont))); 168 - font->size = size; 187 + /* init font */ 188 + font = check_alloc(calloc(1, sizeof(RenFont))); 189 + font->size = size; 169 190 170 - /* load font into buffer */ 171 - fp = fopen(filename, "rb"); 172 - if (!fp) { return NULL; } 173 - /* get size */ 174 - fseek(fp, 0, SEEK_END); int buf_size = ftell(fp); fseek(fp, 0, SEEK_SET); 175 - /* load */ 176 - font->data = check_alloc(malloc(buf_size)); 177 - int _ = fread(font->data, 1, buf_size, fp); (void) _; 178 - fclose(fp); 179 - fp = NULL; 191 + /* load font into buffer */ 192 + fp = fopen(filename, "rb"); 193 + if (!fp) 194 + return NULL; 195 + /* get size */ 196 + fseek(fp, 0, SEEK_END); 197 + int buf_size = ftell(fp); 198 + fseek(fp, 0, SEEK_SET); 199 + /* load */ 200 + font->data = check_alloc(malloc(buf_size)); 201 + (void)fread(font->data, 1, buf_size, fp); 202 + fclose(fp); 203 + fp = NULL; 180 204 181 - /* init stbfont */ 182 - int ok = stbtt_InitFont(&font->stbfont, font->data, 0); 183 - if (!ok) { goto fail; } 205 + /* init stbfont */ 206 + int ok = stbtt_InitFont(&font->stbfont, font->data, 0); 207 + if (!ok) 208 + goto fail; 184 209 185 - /* get height and scale */ 186 - int ascent, descent, linegap; 187 - stbtt_GetFontVMetrics(&font->stbfont, &ascent, &descent, &linegap); 188 - float scale = stbtt_ScaleForMappingEmToPixels(&font->stbfont, size); 189 - font->height = (ascent - descent + linegap) * scale + 0.5; 210 + /* get height and scale */ 211 + int ascent, descent, linegap; 212 + stbtt_GetFontVMetrics(&font->stbfont, &ascent, &descent, &linegap); 213 + float scale = stbtt_ScaleForMappingEmToPixels(&font->stbfont, size); 214 + font->height = (ascent - descent + linegap) * scale + 0.5; 190 215 191 - /* make tab and newline glyphs invisible */ 192 - stbtt_bakedchar *g = get_glyphset(font, '\n')->glyphs; 193 - g['\t'].x1 = g['\t'].x0; 194 - g['\n'].x1 = g['\n'].x0; 216 + /* make tab and newline glyphs invisible */ 217 + stbtt_bakedchar *g = get_glyphset(font, '\n')->glyphs; 218 + g['\t'].x1 = g['\t'].x0; 219 + g['\n'].x1 = g['\n'].x0; 195 220 196 - return font; 221 + return font; 197 222 198 223 fail: 199 - if (fp) { fclose(fp); } 200 - if (font) { free(font->data); } 201 - free(font); 202 - return NULL; 224 + if (fp) 225 + fclose(fp); 226 + if (font) 227 + free(font->data); 228 + free(font); 229 + return NULL; 203 230 } 204 231 205 232 206 - void ren_free_font(RenFont *font) { 207 - for (int i = 0; i < MAX_GLYPHSET; i++) { 208 - GlyphSet *set = font->sets[i]; 209 - if (set) { 210 - ren_free_image(set->image); 211 - free(set); 212 - } 213 - } 214 - free(font->data); 215 - free(font); 233 + void ren_free_font(RenFont *font) 234 + { 235 + for (int i = 0; i < MAX_GLYPHSET; i++) 236 + { 237 + GlyphSet *set = font->sets[i]; 238 + if (set) 239 + { 240 + ren_free_image(set->image); 241 + free(set); 242 + } 243 + } 244 + free(font->data); 245 + free(font); 216 246 } 217 247 218 248 219 - void ren_set_font_tab_width(RenFont *font, int n) { 220 - GlyphSet *set = get_glyphset(font, '\t'); 221 - set->glyphs['\t'].xadvance = n; 249 + void ren_set_font_tab_width(RenFont *font, int n) 250 + { 251 + GlyphSet *set = get_glyphset(font, '\t'); 252 + set->glyphs['\t'].xadvance = n; 222 253 } 223 254 224 255 225 - int ren_get_font_tab_width(RenFont *font) { 226 - GlyphSet *set = get_glyphset(font, '\t'); 227 - return set->glyphs['\t'].xadvance; 256 + int ren_get_font_tab_width(RenFont *font) 257 + { 258 + GlyphSet *set = get_glyphset(font, '\t'); 259 + return set->glyphs['\t'].xadvance; 228 260 } 229 261 230 262 231 - int ren_get_font_width(RenFont *font, const char *text) { 232 - int x = 0; 233 - const char *p = text; 234 - unsigned codepoint; 235 - while (*p) { 236 - p = utf8_to_codepoint(p, &codepoint); 237 - GlyphSet *set = get_glyphset(font, codepoint); 238 - stbtt_bakedchar *g = &set->glyphs[codepoint & 0xff]; 239 - x += g->xadvance; 240 - } 241 - return x; 263 + int ren_get_font_width(RenFont *font, const char *text) 264 + { 265 + int x = 0; 266 + const char *p = text; 267 + unsigned codepoint; 268 + while (*p) 269 + { 270 + p = utf8_to_codepoint(p, &codepoint); 271 + GlyphSet *set = get_glyphset(font, codepoint); 272 + stbtt_bakedchar *g = &set->glyphs[codepoint & 0xff]; 273 + x += g->xadvance; 274 + } 275 + return x; 242 276 } 243 277 244 278 245 - int ren_get_font_height(RenFont *font) { 246 - return font->height; 279 + int ren_get_font_height(RenFont *font) 280 + { 281 + return font->height; 247 282 } 248 283 249 284 250 - static inline RenColor blend_pixel(RenColor dst, RenColor src) { 251 - int ia = 0xff - src.a; 252 - dst.r = ((src.r * src.a) + (dst.r * ia)) >> 8; 253 - dst.g = ((src.g * src.a) + (dst.g * ia)) >> 8; 254 - dst.b = ((src.b * src.a) + (dst.b * ia)) >> 8; 255 - return dst; 285 + static inline RenColor blend_pixel(RenColor dst, RenColor src) 286 + { 287 + int ia = 0xff - src.a; 288 + dst.r = ((src.r * src.a) + (dst.r * ia)) >> 8; 289 + dst.g = ((src.g * src.a) + (dst.g * ia)) >> 8; 290 + dst.b = ((src.b * src.a) + (dst.b * ia)) >> 8; 291 + return dst; 256 292 } 257 293 258 294 259 - static inline RenColor blend_pixel2(RenColor dst, RenColor src, RenColor color) { 260 - src.a = (src.a * color.a) >> 8; 261 - int ia = 0xff - src.a; 262 - dst.r = ((src.r * color.r * src.a) >> 16) + ((dst.r * ia) >> 8); 263 - dst.g = ((src.g * color.g * src.a) >> 16) + ((dst.g * ia) >> 8); 264 - dst.b = ((src.b * color.b * src.a) >> 16) + ((dst.b * ia) >> 8); 265 - return dst; 295 + static inline RenColor blend_pixel2(RenColor dst, RenColor src, RenColor color) 296 + { 297 + src.a = (src.a * color.a) >> 8; 298 + int ia = 0xff - src.a; 299 + dst.r = ((src.r * color.r * src.a) >> 16) + ((dst.r * ia) >> 8); 300 + dst.g = ((src.g * color.g * src.a) >> 16) + ((dst.g * ia) >> 8); 301 + dst.b = ((src.b * color.b * src.a) >> 16) + ((dst.b * ia) >> 8); 302 + return dst; 266 303 } 267 304 268 305 269 - #define rect_draw_loop(expr) \ 270 - for (int j = y1; j < y2; j++) { \ 271 - for (int i = x1; i < x2; i++) { \ 272 - *d = expr; \ 273 - d++; \ 274 - } \ 275 - d += dr; \ 276 - } 306 + #define rect_draw_loop(expr) do { \ 307 + for (int j = y1; j < y2; j++) \ 308 + { \ 309 + for (int i = x1; i < x2; i++) \ 310 + { \ 311 + *d = expr; \ 312 + d++; \ 313 + } \ 314 + d += dr; \ 315 + } \ 316 + } while (0) 277 317 278 - void ren_draw_rect(RenRect rect, RenColor color) { 279 - if (color.a == 0) { return; } 318 + void ren_draw_rect(RenRect rect, RenColor color) 319 + { 320 + if (color.a == 0) 321 + return; 280 322 281 - int x1 = rect.x < clip.left ? clip.left : rect.x; 282 - int y1 = rect.y < clip.top ? clip.top : rect.y; 283 - int x2 = rect.x + rect.width; 284 - int y2 = rect.y + rect.height; 285 - x2 = x2 > clip.right ? clip.right : x2; 286 - y2 = y2 > clip.bottom ? clip.bottom : y2; 323 + int x1 = rect.x < clip.left ? clip.left : rect.x; 324 + int y1 = rect.y < clip.top ? clip.top : rect.y; 325 + int x2 = rect.x + rect.width; 326 + int y2 = rect.y + rect.height; 327 + x2 = x2 > clip.right ? clip.right : x2; 328 + y2 = y2 > clip.bottom ? clip.bottom : y2; 287 329 288 - SDL_Surface *surf = SDL_GetWindowSurface(window); 289 - RenColor *d = (RenColor*) surf->pixels; 290 - d += x1 + y1 * surf->w; 291 - int dr = surf->w - (x2 - x1); 330 + SDL_Surface *surf = SDL_GetWindowSurface(window); 331 + RenColor *d = (RenColor *)surf->pixels; 332 + d += x1 + y1 * surf->w; 333 + int dr = surf->w - (x2 - x1); 292 334 293 - if (color.a == 0xff) { 294 - rect_draw_loop(color); 295 - } else { 296 - rect_draw_loop(blend_pixel(*d, color)); 297 - } 335 + if (color.a == 0xff) 336 + rect_draw_loop(color); 337 + else 338 + rect_draw_loop(blend_pixel(*d, color)); 298 339 } 299 340 300 341 301 - void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color) { 302 - if (color.a == 0) { return; } 342 + void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color) 343 + { 344 + if (color.a == 0) 345 + return; 303 346 304 - /* clip */ 305 - int n; 306 - if ((n = clip.left - x) > 0) { sub->width -= n; sub->x += n; x += n; } 307 - if ((n = clip.top - y) > 0) { sub->height -= n; sub->y += n; y += n; } 308 - if ((n = x + sub->width - clip.right ) > 0) { sub->width -= n; } 309 - if ((n = y + sub->height - clip.bottom) > 0) { sub->height -= n; } 347 + /* clip */ 348 + int n; 349 + if ((n = clip.left - x) > 0) 350 + sub->width -= n; sub->x += n; x += n; 351 + if ((n = clip.top - y) > 0) 352 + sub->height -= n; sub->y += n; y += n; 353 + if ((n = x + sub->width - clip.right ) > 0) 354 + sub->width -= n; 355 + if ((n = y + sub->height - clip.bottom) > 0) 356 + sub->height -= n; 310 357 311 - if (sub->width <= 0 || sub->height <= 0) { 312 - return; 313 - } 358 + if (sub->width <= 0 || sub->height <= 0) 359 + return; 314 360 315 - /* draw */ 316 - SDL_Surface *surf = SDL_GetWindowSurface(window); 317 - RenColor *s = image->pixels; 318 - RenColor *d = (RenColor*) surf->pixels; 319 - s += sub->x + sub->y * image->width; 320 - d += x + y * surf->w; 321 - int sr = image->width - sub->width; 322 - int dr = surf->w - sub->width; 361 + /* draw */ 362 + SDL_Surface *surf = SDL_GetWindowSurface(window); 363 + RenColor *s = image->pixels; 364 + RenColor *d = (RenColor *)surf->pixels; 365 + s += sub->x + sub->y * image->width; 366 + d += x + y * surf->w; 367 + int sr = image->width - sub->width; 368 + int dr = surf->w - sub->width; 323 369 324 - for (int j = 0; j < sub->height; j++) { 325 - for (int i = 0; i < sub->width; i++) { 326 - *d = blend_pixel2(*d, *s, color); 327 - d++; 328 - s++; 329 - } 330 - d += dr; 331 - s += sr; 332 - } 370 + for (int j = 0; j < sub->height; j++) 371 + { 372 + for (int i = 0; i < sub->width; i++) 373 + { 374 + *d = blend_pixel2(*d, *s, color); 375 + d++; 376 + s++; 377 + } 378 + d += dr; 379 + s += sr; 380 + } 333 381 } 334 382 335 383 336 - int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) { 337 - RenRect rect; 338 - const char *p = text; 339 - unsigned codepoint; 340 - while (*p) { 341 - p = utf8_to_codepoint(p, &codepoint); 342 - GlyphSet *set = get_glyphset(font, codepoint); 343 - stbtt_bakedchar *g = &set->glyphs[codepoint & 0xff]; 344 - rect.x = g->x0; 345 - rect.y = g->y0; 346 - rect.width = g->x1 - g->x0; 347 - rect.height = g->y1 - g->y0; 348 - ren_draw_image(set->image, &rect, x + g->xoff, y + g->yoff, color); 349 - x += g->xadvance; 350 - } 351 - return x; 384 + int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) 385 + { 386 + RenRect rect; 387 + const char *p = text; 388 + unsigned codepoint; 389 + while (*p) 390 + { 391 + p = utf8_to_codepoint(p, &codepoint); 392 + GlyphSet *set = get_glyphset(font, codepoint); 393 + stbtt_bakedchar *g = &set->glyphs[codepoint & 0xff]; 394 + rect.x = g->x0; 395 + rect.y = g->y0; 396 + rect.width = g->x1 - g->x0; 397 + rect.height = g->y1 - g->y0; 398 + ren_draw_image(set->image, &rect, x + g->xoff, y + g->yoff, color); 399 + x += g->xadvance; 400 + } 401 + return x; 352 402 }
+9 -2
src/renderer.h
··· 8 8 typedef struct RenImage RenImage; 9 9 typedef struct RenFont RenFont; 10 10 11 - typedef struct { uint8_t b, g, r, a; } RenColor; 12 - typedef struct { int x, y, width, height; } RenRect; 11 + typedef struct 12 + { 13 + uint8_t b, g, r, a; 14 + } RenColor; 15 + 16 + typedef struct 17 + { 18 + int x, y, width, height; 19 + } RenRect; 13 20 14 21 15 22 void ren_init(SDL_Window *win);