mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2026-02-15 04:03:49 +01:00
graphics
This commit is contained in:
parent
a2ddcfa030
commit
51224a46a2
@ -40,5 +40,6 @@ shell.setWorkingDirectory(os.getenv("HOME"))
|
||||
|
||||
local home_shrc = shell.resolve(".shrc")
|
||||
if fs.exists(home_shrc) then
|
||||
assert(loadfile(shell.resolve("source", "lua")))(home_shrc)
|
||||
local resolved = shell.resolve("source", "lua")
|
||||
assert(loadfile(resolved))(home_shrc)
|
||||
end
|
||||
|
||||
@ -14,12 +14,10 @@ do
|
||||
end
|
||||
|
||||
while true do
|
||||
debug.print("try shell")
|
||||
local result, reason = xpcall(require("shell").getShell(), function(msg)
|
||||
return tostring(msg).."\n"..debug.traceback()
|
||||
end)
|
||||
if not result then
|
||||
debug.print(reason)
|
||||
io.stderr:write((reason ~= nil and tostring(reason) or "unknown error") .. "\n")
|
||||
io.write("Press any key to continue.\n")
|
||||
os.sleep(0.5)
|
||||
|
||||
@ -446,6 +446,12 @@ static int luaArch_unicode_sub(lua_State *L) {
|
||||
|
||||
size_t len = nn_unicode_lenPermissive(s, slen);
|
||||
|
||||
// OpenOS does this...
|
||||
if(len == 0) {
|
||||
lua_pushstring(L, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int start = lua_tointeger(L, 2);
|
||||
int end = lua_tointeger(L, 3);
|
||||
|
||||
@ -464,6 +470,11 @@ static int luaArch_unicode_sub(lua_State *L) {
|
||||
if(end < 0) end = 0;
|
||||
if(end >= len) end = len-1;
|
||||
|
||||
if(start > end) {
|
||||
lua_pushstring(L, "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nn_codepoint *cp = malloc(sizeof(*cp) * len);
|
||||
nn_unicode_codepointsPermissive(s, slen, cp);
|
||||
|
||||
@ -484,6 +495,11 @@ static int luaArch_unicode_wlen(lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaArch_unicode_wtrunc(lua_State *L) {
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void luaArch_loadEnv(lua_State *L) {
|
||||
lua_createtable(L, 0, 10);
|
||||
int computer = lua_gettop(L);
|
||||
@ -547,8 +563,10 @@ static void luaArch_loadEnv(lua_State *L) {
|
||||
lua_setfield(L, component, "len");
|
||||
lua_pushcfunction(L, luaArch_unicode_sub);
|
||||
lua_setfield(L, component, "sub");
|
||||
lua_pushcfunction(L, luaArch_unicode_wlen);
|
||||
lua_pushcfunction(L, luaArch_unicode_len);
|
||||
lua_setfield(L, component, "wlen");
|
||||
lua_pushcfunction(L, luaArch_unicode_wtrunc);
|
||||
lua_setfield(L, component, "wtrunc");
|
||||
lua_setglobal(L, "unicode");
|
||||
}
|
||||
|
||||
|
||||
@ -21,8 +21,9 @@ function coroutine.resume(co, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local clist, cinvoke, computer, component, print = component.list, component.invoke, computer, component, print
|
||||
local clist, cinvoke, computer, component, print, unicode = component.list, component.invoke, computer, component, print, unicode
|
||||
debug.print = print
|
||||
debug.sysyield = sysyield
|
||||
|
||||
function component.list(ctype, exact)
|
||||
local list = clist()
|
||||
@ -155,6 +156,44 @@ function computer.pullSignal(timeout)
|
||||
end
|
||||
end
|
||||
|
||||
unicode.upper, unicode.lower = string.upper, string.lower
|
||||
|
||||
unicode.isWide = function(s)
|
||||
local c = unicode.sub(s, 1, 1)
|
||||
return unicode.wlen(c) > unicode.len(c)
|
||||
end
|
||||
|
||||
unicode.wtrunc = function(str,space)
|
||||
space = space - 1
|
||||
return unicode.sub(str, 1, space)
|
||||
end
|
||||
|
||||
unicode.sub = function(str, a, b)
|
||||
if not b then b = utf8.len(str) end
|
||||
if not a then a = 1 end
|
||||
-- a = math.max(a,1)
|
||||
|
||||
if a < 0 then
|
||||
-- negative
|
||||
|
||||
a = utf8.len(str) + a + 1
|
||||
end
|
||||
|
||||
if b < 0 then
|
||||
b = utf8.len(str) + b + 1
|
||||
end
|
||||
|
||||
if a > b then return "" end
|
||||
|
||||
if b >= utf8.len(str) then b = #str else b = utf8.offset(str,b+1)-1 end
|
||||
|
||||
if a > utf8.len(str) then return "" end
|
||||
a = utf8.offset(str,a)
|
||||
|
||||
return str:sub(a,b)
|
||||
-- return str:sub(a, b)
|
||||
end
|
||||
|
||||
function checkArg(arg, val, ...)
|
||||
local t = {...}
|
||||
for i=1,#t do
|
||||
@ -165,7 +204,7 @@ end
|
||||
|
||||
if os.getenv("NN_REPL") == "1" then
|
||||
while true do
|
||||
io.write("lua> ")
|
||||
io.write("\x1b[34mlua>\x1b[0m ")
|
||||
io.flush()
|
||||
local l = io.read("l")
|
||||
if not l then break end
|
||||
@ -176,6 +215,7 @@ if os.getenv("NN_REPL") == "1" then
|
||||
f, err = load(l, "=repl")
|
||||
if f then f() else print(err) end
|
||||
end
|
||||
coroutine.yield()
|
||||
end
|
||||
io.write("\n")
|
||||
print("exiting repl")
|
||||
|
||||
112
rewrite/main.c
112
rewrite/main.c
@ -153,12 +153,16 @@ nn_Exit ne_fsState_handler(nn_FilesystemRequest *req) {
|
||||
switch(mode[0]) {
|
||||
case 'r':
|
||||
mode = "rb";
|
||||
break;
|
||||
case 'w':
|
||||
mode = "wb";
|
||||
break;
|
||||
case 'a':
|
||||
mode = "ab";
|
||||
break;
|
||||
default:
|
||||
mode = "rb";
|
||||
break;
|
||||
}
|
||||
ne_fsState_truepath(state, truepath, path);
|
||||
|
||||
@ -568,15 +572,21 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) {
|
||||
|
||||
x = req->x;
|
||||
y = req->y;
|
||||
for(int i = 0; i < req->width; i++) {
|
||||
const char *s = req->text;
|
||||
for(int i = 0; i < req->width;) {
|
||||
if(!ne_inScreenBuf(activeBuf, x, y)) break;
|
||||
size_t w = nn_unicode_validateFirstChar(s + i, req->width - i);
|
||||
ne_Pixel p = {
|
||||
.fg = state->currentFg,
|
||||
.bg = state->currentBg,
|
||||
.isFgPalette = state->isFgPalette,
|
||||
.isBgPalette = state->isBgPalette,
|
||||
.codepoint = req->text[i],
|
||||
.codepoint = (unsigned char)s[i],
|
||||
};
|
||||
if(w > 0) {
|
||||
p.codepoint = nn_unicode_firstCodepoint(s + i);
|
||||
i += w;
|
||||
} else i++;
|
||||
ne_setPixel(activeBuf, x, y, p);
|
||||
x += dx;
|
||||
y += dy;
|
||||
@ -592,8 +602,7 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) {
|
||||
y = req->y;
|
||||
w = req->width;
|
||||
h = req->height;
|
||||
if(x < 1) x = 1;
|
||||
if(y < 1) y = 1;
|
||||
// prevent CPU DoS
|
||||
if(w >= activeBuf->width) w = activeBuf->width - 1;
|
||||
if(h >= activeBuf->height) h = activeBuf->height - 1;
|
||||
|
||||
@ -609,6 +618,93 @@ nn_Exit ne_gpu_handler(nn_GPURequest *req) {
|
||||
ne_setPixel(activeBuf, x + ox, y + oy, p);
|
||||
}
|
||||
}
|
||||
ne_remapScreen(activeBuf);
|
||||
return NN_OK;
|
||||
case NN_GPU_COPY:
|
||||
if(activeBuf == NULL) {
|
||||
nn_setError(C, "no screen");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
x = req->x;
|
||||
y = req->y;
|
||||
w = req->width;
|
||||
h = req->height;
|
||||
// prevent CPU DoS
|
||||
if(w >= activeBuf->width) w = activeBuf->width - 1;
|
||||
if(h >= activeBuf->height) h = activeBuf->height - 1;
|
||||
|
||||
ne_Pixel *buf = malloc(sizeof(*buf) * w * h);
|
||||
if(buf == NULL) return NN_ENOMEM;
|
||||
|
||||
for(int oy = 0; oy < h; oy++) {
|
||||
for(int ox = 0; ox < w; ox++) {
|
||||
buf[oy * w + ox] = ne_getPixel(activeBuf, x + ox, y + oy);
|
||||
}
|
||||
}
|
||||
|
||||
for(int oy = 0; oy < h; oy++) {
|
||||
for(int ox = 0; ox < w; ox++) {
|
||||
p = buf[oy * w + ox];
|
||||
ne_setPixel(activeBuf, x + ox + req->tx, y + oy + req->ty, p);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
ne_remapScreen(activeBuf);
|
||||
return NN_OK;
|
||||
case NN_GPU_GETDEPTH:
|
||||
if(activeBuf != NULL) {
|
||||
req->x = activeBuf->depth;
|
||||
} else {
|
||||
req->x = req->gpuConf->maxDepth;
|
||||
}
|
||||
return NN_OK;
|
||||
case NN_GPU_GETVIEWPORT:
|
||||
if(activeBuf == NULL) {
|
||||
nn_setError(C, "no screen");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
req->width = activeBuf->width;
|
||||
req->height = activeBuf->height;
|
||||
return NN_OK;
|
||||
case NN_GPU_GETFOREGROUND:
|
||||
req->x = state->currentFg;
|
||||
req->y = state->isFgPalette ? 1 : 0;
|
||||
return NN_OK;
|
||||
case NN_GPU_GETBACKGROUND:
|
||||
req->x = state->currentBg;
|
||||
req->y = state->isBgPalette ? 1 : 0;
|
||||
return NN_OK;
|
||||
case NN_GPU_SETFOREGROUND:
|
||||
x = req->x;
|
||||
y = req->y;
|
||||
if(y != 0) {
|
||||
// validate the palette index
|
||||
if(activeBuf == NULL || x < 0 || x >= activeBuf->maxPalette) {
|
||||
nn_setError(C, "invalid palette index");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
}
|
||||
req->x = state->currentFg;
|
||||
req->y = state->isFgPalette ? 1 : 0;
|
||||
state->currentFg = x;
|
||||
state->isFgPalette = y != 0;
|
||||
ne_remapScreen(activeBuf);
|
||||
return NN_OK;
|
||||
case NN_GPU_SETBACKGROUND:
|
||||
x = req->x;
|
||||
y = req->y;
|
||||
if(y != 0) {
|
||||
// validate the palette index
|
||||
if(activeBuf == NULL || x < 0 || x >= activeBuf->maxPalette) {
|
||||
nn_setError(C, "invalid palette index");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
}
|
||||
req->x = state->currentBg;
|
||||
req->y = state->isBgPalette ? 1 : 0;
|
||||
state->currentBg = x;
|
||||
state->isBgPalette = y != 0;
|
||||
ne_remapScreen(activeBuf);
|
||||
return NN_OK;
|
||||
}
|
||||
return NN_OK;
|
||||
@ -620,11 +716,19 @@ Color ne_processColor(unsigned int color) {
|
||||
return GetColor(color);
|
||||
}
|
||||
|
||||
double ne_timeProc(void *_) {
|
||||
(void)_;
|
||||
double t = GetTime();
|
||||
return (int)(t*100) / 100.0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
nn_Context ctx;
|
||||
nn_initContext(&ctx);
|
||||
nn_initPalettes();
|
||||
|
||||
ctx.time = ne_timeProc;
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||
InitWindow(800, 600, "NeoNucleus Test Emulator");
|
||||
|
||||
|
||||
@ -2752,11 +2752,15 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
|
||||
greq.text = (char *)nn_tolstring(C, 0, &len);
|
||||
greq.width = len;
|
||||
greq.x = nn_toboolean(C, 1) ? 1 : 0;
|
||||
return state->handler(&greq);
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
return nn_pushbool(C, true);
|
||||
}
|
||||
if(nn_strcmp(method, "unbind") == 0) {
|
||||
greq.action = NN_GPU_UNBIND;
|
||||
return state->handler(&greq);
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
return nn_pushbool(C, true);
|
||||
}
|
||||
if(nn_strcmp(method, "getScreen") == 0) {
|
||||
char buf[NN_MAX_ADDRESS];
|
||||
@ -2798,6 +2802,148 @@ nn_Exit nn_gpu_handler(nn_ComponentRequest *req) {
|
||||
req->returnCount = 1;
|
||||
return nn_pushbool(C, true);
|
||||
}
|
||||
if(nn_strcmp(method, "get") == 0) {
|
||||
nn_costComponent(C, req->compAddress, conf.setPerTick);
|
||||
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 1, "bad argument #2 (integer expected)")) return NN_EBADCALL;
|
||||
greq.action = NN_GPU_GET;
|
||||
greq.x = nn_tointeger(C, 0);
|
||||
greq.y = nn_tointeger(C, 1);
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 5;
|
||||
char buf[NN_MAX_UNICODE_BUFFER];
|
||||
size_t len = nn_unicode_codepointToChar(buf, greq.codepoint);
|
||||
err = nn_pushlstring(C, buf, len);
|
||||
if(err) return err;
|
||||
err = nn_pushinteger(C, greq.width);
|
||||
if(err) return err;
|
||||
err = nn_pushinteger(C, greq.height);
|
||||
if(err) return err;
|
||||
if(greq.dest == -1) err = nn_pushnull(C);
|
||||
else err = nn_pushinteger(C, greq.dest);
|
||||
if(err) return err;
|
||||
if(greq.src == -1) err = nn_pushnull(C);
|
||||
else err = nn_pushinteger(C, greq.src);
|
||||
if(err) return err;
|
||||
return NN_OK;
|
||||
}
|
||||
if(nn_strcmp(method, "fill") == 0) {
|
||||
nn_costComponent(C, req->compAddress, conf.fillPerTick);
|
||||
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 1, "bad argument #2 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 2, "bad argument #3 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 3, "bad argument #4 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkstring(C, 4, "bad argument #5 (string expected)")) return NN_EBADCALL;
|
||||
greq.action = NN_GPU_FILL;
|
||||
size_t len;
|
||||
const char *text = nn_tolstring(C, 4, &len);
|
||||
if(nn_unicode_validateFirstChar(text, len) == 0) {
|
||||
nn_setError(C, "invalid UTF-8 character");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
greq.codepoint = nn_unicode_firstCodepoint(text);
|
||||
greq.x = nn_tointeger(C, 0);
|
||||
greq.y = nn_tointeger(C, 1);
|
||||
greq.width = nn_tointeger(C, 2);
|
||||
greq.height = nn_tointeger(C, 3);
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 1;
|
||||
return nn_pushbool(C, true);
|
||||
}
|
||||
if(nn_strcmp(method, "copy") == 0) {
|
||||
nn_costComponent(C, req->compAddress, conf.copyPerTick);
|
||||
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 1, "bad argument #2 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 2, "bad argument #3 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 3, "bad argument #4 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 4, "bad argument #5 (integer expected)")) return NN_EBADCALL;
|
||||
if(nn_checkinteger(C, 5, "bad argument #6 (integer expected)")) return NN_EBADCALL;
|
||||
greq.action = NN_GPU_COPY;
|
||||
greq.x = nn_tointeger(C, 0);
|
||||
greq.y = nn_tointeger(C, 1);
|
||||
greq.width = nn_tointeger(C, 2);
|
||||
greq.height = nn_tointeger(C, 3);
|
||||
greq.tx = nn_tointeger(C, 4);
|
||||
greq.ty = nn_tointeger(C, 5);
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 1;
|
||||
return nn_pushbool(C, true);
|
||||
}
|
||||
if(nn_strcmp(method, "getDepth") == 0) {
|
||||
greq.action = NN_GPU_GETDEPTH;
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 1;
|
||||
return nn_pushinteger(C, greq.x);
|
||||
}
|
||||
if(nn_strcmp(method, "getViewport") == 0) {
|
||||
greq.action = NN_GPU_GETVIEWPORT;
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 2;
|
||||
err = nn_pushinteger(C, greq.width);
|
||||
if(err) return err;
|
||||
return nn_pushinteger(C, greq.height);
|
||||
}
|
||||
if(nn_strcmp(method, "setForeground") == 0) {
|
||||
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||
err = nn_defaultboolean(C, 1, false);
|
||||
if(err) return err;
|
||||
if(nn_checkinteger(C, 1, "bad argument #2 (boolean expected)")) return NN_EBADCALL;
|
||||
greq.action = NN_GPU_SETFOREGROUND;
|
||||
greq.x = nn_tointeger(C, 0);
|
||||
greq.y = nn_toboolean(C, 1) ? 1 : 0;
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 2;
|
||||
err = nn_pushinteger(C, greq.x);
|
||||
if(err) return err;
|
||||
err = nn_pushbool(C, greq.y != 0);
|
||||
if(err) return err;
|
||||
return NN_OK;
|
||||
}
|
||||
if(nn_strcmp(method, "getForeground") == 0) {
|
||||
greq.action = NN_GPU_GETFOREGROUND;
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 2;
|
||||
err = nn_pushinteger(C, greq.x);
|
||||
if(err) return err;
|
||||
err = nn_pushbool(C, greq.y != 0);
|
||||
if(err) return err;
|
||||
return NN_OK;
|
||||
}
|
||||
if(nn_strcmp(method, "setBackground") == 0) {
|
||||
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||
err = nn_defaultboolean(C, 1, false);
|
||||
if(err) return err;
|
||||
if(nn_checkinteger(C, 1, "bad argument #2 (boolean expected)")) return NN_EBADCALL;
|
||||
greq.action = NN_GPU_SETBACKGROUND;
|
||||
greq.x = nn_tointeger(C, 0);
|
||||
greq.y = nn_toboolean(C, 1) ? 1 : 0;
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 2;
|
||||
err = nn_pushinteger(C, greq.x);
|
||||
if(err) return err;
|
||||
err = nn_pushbool(C, greq.y != 0);
|
||||
if(err) return err;
|
||||
return NN_OK;
|
||||
}
|
||||
if(nn_strcmp(method, "getBackground") == 0) {
|
||||
greq.action = NN_GPU_GETBACKGROUND;
|
||||
err = state->handler(&greq);
|
||||
if(err) return err;
|
||||
req->returnCount = 2;
|
||||
err = nn_pushinteger(C, greq.x);
|
||||
if(err) return err;
|
||||
err = nn_pushbool(C, greq.y != 0);
|
||||
if(err) return err;
|
||||
return NN_OK;
|
||||
}
|
||||
nn_setError(C, "method not yet implemented");
|
||||
return NN_EBADCALL;
|
||||
}
|
||||
@ -3254,7 +3400,7 @@ size_t nn_unicode_codepointSize(nn_codepoint codepoint) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t nn_unicode_codepointToChar(char buffer[NN_MAXIMUM_UNICODE_BUFFER], nn_codepoint codepoint) {
|
||||
size_t nn_unicode_codepointToChar(char buffer[NN_MAX_UNICODE_BUFFER], nn_codepoint codepoint) {
|
||||
size_t codepointSize = nn_unicode_codepointSize(codepoint);
|
||||
|
||||
if (codepointSize == 1) {
|
||||
@ -3304,7 +3450,9 @@ size_t nn_unicode_wlen(const char *s, size_t len) {
|
||||
for(size_t i = 0; i < len;) {
|
||||
nn_codepoint codepoint = nn_unicode_firstCodepoint(s + i);
|
||||
size_t size = nn_unicode_codepointSize(codepoint);
|
||||
wlen += nn_unicode_charWidth(codepoint);
|
||||
size_t width = nn_unicode_charWidth(codepoint);
|
||||
if(width == 0) width = 1;
|
||||
wlen += width;
|
||||
i += size;
|
||||
}
|
||||
return wlen;
|
||||
@ -3315,12 +3463,14 @@ size_t nn_unicode_wlenPermissive(const char *s, size_t len) {
|
||||
for(size_t i = 0; i < len;) {
|
||||
if(nn_unicode_validateFirstChar(s + i, len - i) == 0) {
|
||||
size_t width = nn_unicode_charWidth((unsigned char)s[i]);
|
||||
if(width == 0) width = 1;
|
||||
wlen += width;
|
||||
i++;
|
||||
} else {
|
||||
nn_codepoint codepoint = nn_unicode_firstCodepoint(s + i);
|
||||
size_t size = nn_unicode_codepointSize(codepoint);
|
||||
size_t width = nn_unicode_charWidth(codepoint);
|
||||
if(width == 0) width = 1;
|
||||
wlen += width;
|
||||
i += size;
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ extern "C" {
|
||||
#define NN_MAX_USERNAME 128
|
||||
|
||||
// the maximum size of a UTF-8 character
|
||||
#define NN_MAXIMUM_UNICODE_BUFFER 4
|
||||
#define NN_MAX_UNICODE_BUFFER 4
|
||||
|
||||
// the maximum size of a component error message. If the error is bigger than this,
|
||||
// it is truncated.
|
||||
@ -126,7 +126,7 @@ nn_codepoint nn_unicode_firstCodepoint(const char *s);
|
||||
size_t nn_unicode_codepointSize(nn_codepoint codepoint);
|
||||
// Writes the UTF-8 bytes for a given codepoint into buffer.
|
||||
// It does NOT write a NULL terminator, but it does return the length.
|
||||
size_t nn_unicode_codepointToChar(char buffer[NN_MAXIMUM_UNICODE_BUFFER], nn_codepoint codepoint);
|
||||
size_t nn_unicode_codepointToChar(char buffer[NN_MAX_UNICODE_BUFFER], nn_codepoint codepoint);
|
||||
// the width, on a screen, for a codepoint.
|
||||
// This matters for emojies.
|
||||
size_t nn_unicode_charWidth(nn_codepoint codepoint);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user