diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2025-04-26 05:51:35 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2025-04-26 05:51:35 +0200 |
commit | ba9fa367c824b515a66e28368ccf24757f02db93 (patch) | |
tree | 2621419c9d2546c8eaa149f9d6e49374d8564ded | |
parent | 7322f1c5e94d6b4ceef742636fe8233b53b08347 (diff) | |
download | reduced_system_layer-ba9fa367c824b515a66e28368ccf24757f02db93.zip |
UTF-16; Refactor dynamic libraries loading
-rw-r--r-- | graphics.c | 35 | ||||
-rw-r--r-- | runtime.c | 317 |
2 files changed, 204 insertions, 148 deletions
@@ -589,8 +589,8 @@ b8 hit_line(vec2 vertices[2], f64 width, vec2 point) { tx /= tl; ty /= tl; } - tx *= width * .5; - ty *= width * .5; + tx *= width * 0.5; + ty *= width * 0.5; return hit_quad((vec2[4]) { { x0 - tx, y0 - ty }, @@ -890,7 +890,7 @@ static b8 quad_from_line_(vec2 *dst, vec2 vertices[2], f64 width) { if (tl < EPSILON) return 0; - f64 k = .5 / tl; + f64 k = 0.5 / tl; tx *= width * k; ty *= width * k; @@ -1365,7 +1365,7 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box (Box) { .x = area.x + kx * cursor_x, .y = area.y + ky * cursor_y - ky * LCD_Height, - .width = kx * .5, + .width = kx * 0.5, .height = ky * (LCD_Height - 1), } ); @@ -1694,10 +1694,10 @@ static Box graphics_request_area_(Graphics_Request req) { static Graphics_Request_Norm_ normalize_graphics_request_(Graphics_Request req) { Box area = graphics_request_area_(req); - i64 x = (i64) floor(area.x - .5); - i64 y = (i64) floor(area.y - .5); - i64 w = (i64) ceil (area.x + area.width + .5) - x; - i64 h = (i64) ceil (area.y + area.height + .5) - y; + i64 x = (i64) floor(area.x - 0.5); + i64 y = (i64) floor(area.y - 0.5); + i64 w = (i64) ceil (area.x + area.width + 0.5) - x; + i64 h = (i64) ceil (area.y + area.height + 0.5) - y; return (Graphics_Request_Norm_) { .req = graphics_request_moved_(req, (vec2) { -x, -y }), @@ -2454,6 +2454,21 @@ TEST("rectangle aliasing") { (Box) { .x = 7.4, .y = 4.4, .width = 1.2, .height = 1.2, } ); + fill_rectangle_to_buffer( + (Pixel_Buffer) { .width = w, .height = h, .stride = w, .pixels = pixels }, + (vec4_f32) { 1.0f, 1.0f, 1.0f, 1.0f, }, + (Box) { .x = 7.44, .y = 6.51, .width = 1.07, .height = 1.991, } + ); + + // printf("\n"); + // for (i64 j = 0; j < h; ++j) { + // for (i64 i = 0; i < w; ++i) { + // printf(" %c", pixels[j * w + i].x > 0.5 ? 'x' : '.'); + // } + // printf("\n"); + // } + // printf("\n"); + b8 expect_bits[100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, @@ -2462,8 +2477,8 @@ TEST("rectangle aliasing") { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; @@ -44,15 +44,6 @@ // To-Do list // // - Work in progress -// - Graphics perf - request cache -// Requires: -// + [x] Graphics tests -// + [x] Graphics requests -// + [x] Memory buffer allocator -// + [x] Blake2 hash -// + [x] Requests cache -// + [x] Global anti-aliasing -// + [x] Fill triangles // - Examples // - Conway's Game of Life // - Julia Set @@ -133,7 +124,7 @@ // - Graph // - Sine Wave // - Utility -// - UTF-8 +// - UTF-8, UTF-16 // - Testing // - Stackless coroutines // - Allocator @@ -286,6 +277,7 @@ typedef unsigned short u16; typedef unsigned u32; typedef unsigned long long u64; typedef char c8; +typedef short c16; typedef int c32; typedef unsigned char b8; typedef float f32; @@ -604,6 +596,11 @@ typedef struct { } UTF8_Char; typedef struct { + c32 code; + i8 len; +} UTF16_Char; + +typedef struct { u16 protocol; u16 port; union { @@ -672,10 +669,15 @@ typedef struct { } Platform; // UTF-8 -i8 utf8_size (c32 c); +i8 utf8_len (c32 c); UTF8_Char utf8_read (i64 len, c8 *s); i8 utf8_write(c32 c, c8 *buffer); +// UTF-16 +i8 utf16_len (c32 c); +UTF16_Char utf16_read (i64 len, c16 *s); +i8 utf16_write(c32 c, c16 *buffer); + // Time and sleep i64 current_utc_time_in_milliseconds(void); void current_utc_time_in_sec_and_nsec(i64 *seconds, i64 *nanoseconds); @@ -1269,11 +1271,11 @@ i32 blake2b(u8 *out, void *in, void *key, u8 outlen, u64 inlen, u8 keylen) { // ================================================================ // -// UTF-8 +// Unicode // // ================================================================ -i8 utf8_size(c32 c) { +i8 utf8_len(c32 c) { if ((c & 0x00007f) == c) return 1; if ((c & 0x0007ff) == c) return 2; if ((c & 0x00ffff) == c) return 3; @@ -1282,13 +1284,13 @@ i8 utf8_size(c32 c) { } UTF8_Char utf8_read(i64 len, c8 *s) { - if (len >= 1 && + if ( len >= 1 && (s[0] & 0x80) == 0) return (UTF8_Char) { .code = s[0], .len = 1, }; - if (len >= 2 && + if ( len >= 2 && (s[0] & 0xe0) == 0xc0 && (s[1] & 0xc0) == 0x80) return (UTF8_Char) { @@ -1296,7 +1298,7 @@ UTF8_Char utf8_read(i64 len, c8 *s) { | ((s[0] & 0x1f) << 6), .len = 2, }; - if (len >= 3 && + if ( len >= 3 && (s[0] & 0xf0) == 0xe0 && (s[1] & 0xc0) == 0x80 && (s[2] & 0xc0) == 0x80) @@ -1306,7 +1308,7 @@ UTF8_Char utf8_read(i64 len, c8 *s) { | ((s[0] & 0x0f) << 12), .len = 3, }; - if (len >= 4 && + if ( len >= 4 && (s[0] & 0xf8) == 0xf0 && (s[1] & 0xc0) == 0x80 && (s[2] & 0xc0) == 0x80 && @@ -1351,6 +1353,55 @@ i8 utf8_write(c32 c, c8 *buffer) { return 0; } +i8 utf16_len(c32 c) { + // TODO: Testing. + + if (c >= 0x000000 && c <= 0x00d7ff) return 1; + if (c >= 0x00e000 && c <= 0x00ffff) return 1; + if (c >= 0x010000 && c <= 0x10ffff) return 2; + return 0; +} + +UTF16_Char utf16_read(i64 len, c16 *s) { + // TODO: Testing. + + if ( len >= 1 && + (s[0] & 0x8000) == 0) + return (UTF16_Char) { + .code = s[0], + .len = 1, + }; + if ( len >= 2 && + (s[0] & 0xfc00) == 0xd800 && + (s[1] & 0xfc00) == 0xdc00) + return (UTF16_Char) { + .code = 0x10000 + + ( (s[1] & 0x3ff) + | ((s[0] & 0x3ff) << 10)), + .len = 2, + }; + return (UTF16_Char) {0}; +} + +i8 utf16_write(c32 c, c16 *buffer) { + // TODO: Testing. + + if ((c >= 0x0000 && c <= 0xd7ff) + || (c >= 0xe000 && c <= 0xffff)) { + buffer[0] = (c16) c; + return 1; + } + + if (c >= 0x010000 && c <= 0x10ffff) { + c32 cc = c - 0x10000; + buffer[0] = 0xd800 | ((cc >> 10) & 0x3ff); + buffer[1] = 0xdc00 | ( cc & 0x3ff); + return 2; + } + + return 0; +} + // ================================================================ // // Colors @@ -2159,95 +2210,79 @@ static void store_clipboard_text_(i64 size, c8 *data) { // ================================================================ // -// PLATFORM-SPECIFIC CODE -// -// ================================================================ -// -// Dynamic libraries +// UTF-16 buffer // // ================================================================ -typedef struct { - void *handle; -} Dynamic_Library_Slot_; +static i64 _utf16_buffer_len = 0; +static c16 *_utf16_buffer = NULL; -typedef struct { - i64 num_slots; - Dynamic_Library_Slot_ *slots; -} Dynamic_Libraries_; +static void buffer_utf16_set_len_(i16 len) { + if (_utf16_buffer_len >= len) + return; -static Dynamic_Libraries_ _dynamic_libraries = {0}; + resize_dynamic_array_exact(&_utf16_buffer_len, (void **) &_utf16_buffer, sizeof *_utf16_buffer, _utf16_buffer_len); +} -#if defined(__unix__) -#include <dlfcn.h> +static c16 *buffer_utf16_empty_(void) { + buffer_utf16_set_len_(1); + if (_utf16_buffer != NULL && _utf16_buffer_len > 0) + _utf16_buffer[0] = '\0'; + return _utf16_buffer; +} -void dynamic_library_open(u16 slot, c8 *name) { - if (name == NULL) { +static c16 *buffer_utf16_from_utf8_(c8 *s) { + if (s == NULL) { LOG_error("Sanity"); - return; - } - - if ((i64) (u64) slot >= _dynamic_libraries.num_slots) - resize_dynamic_array_exact(&_dynamic_libraries.num_slots, (void **) &_dynamic_libraries.slots, sizeof *_dynamic_libraries.slots, (i64) slot + 1); - - if ((i64) (u64) slot >= _dynamic_libraries.num_slots) { - LOG_error("Invalid slot: %d", (i32) slot); - return; + return buffer_utf16_empty_(); } - if (_dynamic_libraries.slots[slot].handle != NULL) { - dlclose(_dynamic_libraries.slots[slot].handle); - _dynamic_libraries.slots[slot].handle = NULL; - } + c8 *s_end = s; + while (*s_end != '\0') ++s_end; - void *h = dlopen(name, RTLD_LAZY); + i64 len = 0; - if (h == NULL) { - LOG_error("Failed to open: %s", name); - LOG_error("%s", dlerror()); - return; - } + for (c8 *a = s; a < s_end;) { + UTF8_Char c = utf8_read(s_end - a, a); - _dynamic_libraries.slots[slot].handle = h; -} + if (c.len == 0) { + LOG_error("Invalid UTF-8 string."); + return buffer_utf16_empty_(); + } -void *dynamic_library_get_proc_address(u16 slot, c8 *proc) { - if ((i64) (u64) slot >= _dynamic_libraries.num_slots) { - LOG_error("Invalid slot: %d", (i32) slot); - return NULL; - } + buffer_utf16_set_len_(len + 2); + i8 n = utf16_write(c.code, _utf16_buffer + len); - if (proc == NULL) { - LOG_error("Sanity"); - return NULL; - } + if (n == 0) { + LOG_error("Unexpected UTF-16 character."); + return buffer_utf16_empty_(); + } - if (_dynamic_libraries.slots[slot].handle == NULL) { - LOG_error("Slot is closed: %d", (i32) slot); - return NULL; + len += n; + a += c.len; } - void *proc_address = dlsym(_dynamic_libraries.slots[slot].handle, proc); + buffer_utf16_set_len_(len + 1); + _utf16_buffer[len] = '\0'; - if (proc_address == NULL) { - LOG_error("Failed to get proc: %s", proc); - LOG_error("%s", dlerror()); - } - - return proc_address; + return _utf16_buffer; } -static void close_all_dynamic_libraries_(void) { - for (i64 i = 0; i < _dynamic_libraries.num_slots; ++i) - if (_dynamic_libraries.slots[i].handle != NULL) - dlclose(_dynamic_libraries.slots[i].handle); - resize_dynamic_array_exact(&_dynamic_libraries.num_slots, (void **) &_dynamic_libraries.slots, sizeof *_dynamic_libraries.slots, 0); -} +// ================================================================ +// +// PLATFORM-SPECIFIC CODE +// +// ================================================================ +// +// Dynamic libraries +// +// ================================================================ -#elif defined(_WIN32) +#if defined(__unix__) +#include <dlfcn.h> +#endif -// Windows definitions -#if !defined(_INC_WINDOWS) +#if defined(_WIN32) && !defined(_INC_WINDOWS) #ifndef WINAPI #if defined(_ARM_) #define WINAPI @@ -2256,18 +2291,30 @@ static void close_all_dynamic_libraries_(void) { #endif #endif - typedef c8 const *LPCSTR; - typedef void ** HMODULE; - typedef int WINBOOL; + typedef c8 const *LPCSTR; + typedef c16 const *LPCWSTR; + typedef void ** HMODULE; + typedef int WINBOOL; typedef iptr (WINAPI *FARPROC)(); // Kernel32.dll - HMODULE WINAPI LoadLibraryA (LPCSTR lpLibFileName); + HMODULE WINAPI LoadLibraryW (LPCWSTR lpLibFileName); WINBOOL WINAPI FreeLibrary (HMODULE hLibModule); FARPROC WINAPI GetProcAddress (HMODULE hModule, LPCSTR lpProcName); DWORD WINAPI GetLastError (void); #endif +typedef struct { + void *handle; +} Dynamic_Library_Slot_; + +typedef struct { + i64 num_slots; + Dynamic_Library_Slot_ *slots; +} Dynamic_Libraries_; + +static Dynamic_Libraries_ _dynamic_libraries = {0}; + void dynamic_library_open(u16 slot, c8 *name) { if (name == NULL) { LOG_error("Sanity"); @@ -2283,16 +2330,30 @@ void dynamic_library_open(u16 slot, c8 *name) { } if (_dynamic_libraries.slots[slot].handle != NULL) { + #if defined(__unix__) + dlclose(_dynamic_libraries.slots[slot].handle); + #elif defined(_WIN32) FreeLibrary((HMODULE) _dynamic_libraries.slots[slot].handle); + #endif _dynamic_libraries.slots[slot].handle = NULL; } - void *h = (void *) LoadLibraryA(name); + void *h = NULL; + + #if defined(__unix__) + h = dlopen(name, RTLD_LAZY); + #elif defined(_WIN32) + h = (void *) LoadLibraryW(buffer_utf16_from_utf8(name)); + #endif if (h == NULL) { LOG_error("Failed to open: %s", name); + + #if defined(__unix__) LOG_error("%s", dlerror()); - return; + #elif defined(_WIN32) + LOG_error("Error code: %d", GetLastError()); + #endif } _dynamic_libraries.slots[slot].handle = h; @@ -2314,59 +2375,39 @@ void *dynamic_library_get_proc_address(u16 slot, c8 *proc) { return NULL; } - void *proc_address = GetProcAddress((HMODULE) _dynamic_libraries.slots[slot].handle, proc); + void *proc_address = NULL; - if (proc_address == NULL) - LOG_error("Failed to get proc: %s (error code %d)", proc, GetLastError()); - - return proc_address; -} - -static void close_all_dynamic_libraries_(void) { - for (i64 i = 0; i < _dynamic_libraries.num_slots; ++i) - if (_dynamic_libraries.slots[i].handle != NULL) - FreeLibrary((HMODULE) _dynamic_libraries.slots[i].handle); - resize_dynamic_array_exact(&_dynamic_libraries.num_slots, (void **) &_dynamic_libraries.slots, sizeof *_dynamic_libraries.slots, 0); -} - -#elif defined(__wasm__) - -void dynamic_library_open(u16 slot, c8 *name) { - if (name == NULL) { - LOG_error("Sanity"); - return; - } - - (void) slot; - (void) name; - - LOG_error("Dynamic library not found: %s", name); -} + #if defined(__unix__) + proc_address = dlsym(_dynamic_libraries.slots[slot].handle, proc); + #elif defined(_WIN32) + proc_address = (void *) GetProcAddress((HMODULE) _dynamic_libraries.slots[slot].handle, proc); + #endif -void *dynamic_library_get_proc_address(u16 slot, c8 *proc) { - if ((i64) (u64) slot >= _dynamic_libraries.num_slots) { - LOG_error("Invalid slot: %d", (i32) slot); - return NULL; - } + if (proc_address == NULL) { + LOG_error("Failed to get proc: %s", proc); - if (proc == NULL) { - LOG_error("Sanity"); - return NULL; + #if defined(__unix__) + LOG_error("%s", dlerror()); + #elif defined(_WIN32) + LOG_error("Error code: %d", GetLastError()); + #endif } - (void) slot; - (void) proc; - - LOG_error("Proc address not found: %s", proc); - return NULL; + return proc_address; } static void close_all_dynamic_libraries_(void) { + for (i64 i = 0; i < _dynamic_libraries.num_slots; ++i) + if (_dynamic_libraries.slots[i].handle != NULL) { + #if defined(__unix__) + dlclose(_dynamic_libraries.slots[i].handle); + #elif defined(_WIN32) + FreeLibrary((HMODULE) _dynamic_libraries.slots[i].handle); + #endif + } resize_dynamic_array_exact(&_dynamic_libraries.num_slots, (void **) &_dynamic_libraries.slots, sizeof *_dynamic_libraries.slots, 0); } -#endif - // ================================================================ // // Time @@ -5135,13 +5176,13 @@ TEST("math sanity") { } TEST("utf8") { - REQUIRE_EQ(utf8_size(1), 1); - REQUIRE_EQ(utf8_size(127), 1); - REQUIRE_EQ(utf8_size(128), 2); - REQUIRE_EQ(utf8_size((1 << 11) - 1), 2); - REQUIRE_EQ(utf8_size((1 << 11)), 3); - REQUIRE_EQ(utf8_size((1 << 16) - 1), 3); - REQUIRE_EQ(utf8_size((1 << 16)), 4); + REQUIRE_EQ(utf8_len(1), 1); + REQUIRE_EQ(utf8_len(127), 1); + REQUIRE_EQ(utf8_len(128), 2); + REQUIRE_EQ(utf8_len((1 << 11) - 1), 2); + REQUIRE_EQ(utf8_len((1 << 11)), 3); + REQUIRE_EQ(utf8_len((1 << 16) - 1), 3); + REQUIRE_EQ(utf8_len((1 << 16)), 4); } TEST("time sanity") { |