diff --git a/programs/base.kl b/programs/base.kl index 0fcfb94..4618fcd 100644 --- a/programs/base.kl +++ b/programs/base.kl @@ -33,7 +33,7 @@ arena_init :: (a: *Arena) a.memory = Os.reserve(a.DEFAULT_RESERVE_SIZE) a.alignment = a.DEFAULT_ALIGNMENT a.di = arena_di++ - a.allocator.proc = arena_allocator_proc + // a.allocator.proc = arena_allocator_proc arena_push_size :: (a: *Arena, size: SizeU): *void generous_size := size + a.alignment @@ -73,6 +73,80 @@ arena_allocator_proc :: (a: *Allocator, action: ALLOCATOR_ACTION, size: SizeU, o allocate :: (a: *Allocator, size: SizeU): *void return a.proc(a, ALLOCATOR_ACTION.ALLOCATE, size, 0) +*/ +// +// Unicode +// +question_mark16 :: 0x003f +String32 :: struct;; str: *U32; len: S64 +String16 :: struct;; str: *U16; len: S64 -*/ \ No newline at end of file +utf8_to_utf32 :: (c: *U8, max_advance: S64): U32, S64 + out_str: U32 + advance: S64 + if (c[0] & 0b10000000) == 0 + if max_advance >= 1 + c0 := c[0]->U32 + out_str = c0 + advance = 1 + + elif (c[0] & 0b11100000) == 0b11000000 + if (c[1] & 0b11000000) == 0b10000000 // Continuation byte required + if max_advance >= 2 + c0 := c[0]->U32; c1 := c[1]->U32 + out_str = (c0 & 0b00011111) << 6 | (c1 & 0b00111111) + advance = 2 + + elif (c[0] & 0b11110000) == 0b11100000 + if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 // Two continuation bytes required + if max_advance >= 3 + c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32 + out_str = (c0 & 0b00001111) << 12 | (c1 & 0b00111111) << 6 | (c2 & 0b00111111) + advance = 3 + + elif (c[0] & 0b11111000) == 0b11110000 + if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 && (c[3] & 0b11000000) == 0b10000000 // Three continuation bytes required + if max_advance >= 4 + c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32; c3 := c[3]->U32 + out_str = (c0 & 0b00001111) << 18 | (c1 & 0b00111111) << 12 | (c2 & 0b00111111) << 6 | (c3 & 0b00111111) + advance = 4 + + return out_str, advance + +utf32_to_utf16 :: (codepoint: U32): [2]U16, S64 + str: [2]U16 + len := 0 + if codepoint < 0x10000 + str[0] = codepoint->U16 + len = 1 + elif codepoint <= 0x10FFFF + code: U32 = (codepoint - 0x10000) + str[0] = (0xD800 | (code >> 10))->U16 + str[1] = (0xDC00 | (code & 0x3FF))->U16 + len = 2 + + return str, len + +string_to_string16 :: (arena: *Arena, in: String): String16 + in_str := &in[0] + // @Note(Krzosa): Should be more then enough space + alloc_size := (length_of(in)*2)+1 + result := String16{str = arena_push_size(arena, alloc_size->U64)} + for i := 0, i < length_of(in) + s32, s32_len := utf8_to_utf32(in_str + i, length_of(in) - i) + if s32_len != 0 + i += s32_len + s16, s16_len := utf32_to_utf16(s32) + if s16_len != 0 + for j := 0, j < s16_len, j++ + result.str[result.len++] = s16[j] + else + result.str[result.len++] = question_mark16 + break + else + result.str[result.len++] = question_mark16 + break + + result.str[result.len] = 0 + return result diff --git a/programs/main.kl b/programs/main.kl index 299f1ff..58adf2b 100644 --- a/programs/main.kl +++ b/programs/main.kl @@ -4,96 +4,15 @@ #import "os.kl" #import "Windows.kl" -question_mark16 :: 0x003f -String32 :: struct;; str: *U32; len: S64 -UTF32_Result :: struct - out_str: U32 - advance: S64 - error : S64 -UTF16_Result :: struct - out_str: [2]U16 - len : S64 - error : S64 - - -utf8_to_utf32 :: (c: *U8, max_advance: S64): U32, S64 - out_str: U32 - advance: S64 - if (c[0] & 0b10000000) == 0 - if max_advance >= 1 - c0 := c[0]->U32 - out_str = c0 - advance = 1 - - elif (c[0] & 0b11100000) == 0b11000000 - if (c[1] & 0b11000000) == 0b10000000 // Continuation byte required - if max_advance >= 2 - c0 := c[0]->U32; c1 := c[1]->U32 - out_str = (c0 & 0b00011111) << 6 | (c1 & 0b00111111) - advance = 2 - - elif (c[0] & 0b11110000) == 0b11100000 - if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 // Two continuation bytes required - if max_advance >= 3 - c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32 - out_str = (c0 & 0b00001111) << 12 | (c1 & 0b00111111) << 6 | (c2 & 0b00111111) - advance = 3 - - elif (c[0] & 0b11111000) == 0b11110000 - if (c[1] & 0b11000000) == 0b10000000 && (c[2] & 0b11000000) == 0b10000000 && (c[3] & 0b11000000) == 0b10000000 // Three continuation bytes required - if max_advance >= 4 - c0 := c[0]->U32; c1 := c[1]->U32; c2 := c[2]->U32; c3 := c[3]->U32 - out_str = (c0 & 0b00001111) << 18 | (c1 & 0b00111111) << 12 | (c2 & 0b00111111) << 6 | (c3 & 0b00111111) - advance = 4 - - return out_str, advance - -utf32_to_utf16 :: (codepoint: U32): [2]U16, S64 - str: [2]U16 - len := 0 - if codepoint < 0x10000 - str[0] = codepoint->U16 - len = 1 - elif codepoint <= 0x10FFFF - code: U32 = (codepoint - 0x10000) - str[0] = (0xD800 | (code >> 10))->U16 - str[1] = (0xDC00 | (code & 0x3FF))->U16 - len = 2 - - return str, len - process_heap: HANDLE allocate :: (size: U64): *void if process_heap == 0 process_heap = GetProcessHeap() return HeapAlloc(process_heap, 0, size) -string_to_string16 :: (in: String): String16 - in_str := &in[0] - // @Note(Krzosa): Should be more then enough space - alloc_size := (length_of(in)*2)+1 - result := String16{str = allocate(alloc_size->U64)->*U16} - for i := 0, i < length_of(in) - s32, s32_len := utf8_to_utf32(in_str + i, length_of(in) - i) - if s32_len != 0 - i += s32_len - s16, s16_len := utf32_to_utf16(s32) - if s16_len != 0 - for j := 0, j < s16_len, j++ - result.str[result.len++] = s16[j] - else - result.str[result.len++] = question_mark16 - break - else - result.str[result.len++] = question_mark16 - break - - result.str[result.len] = 0 - return result - -test_unicode :: () +test_unicode :: (arena: *Arena) string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..." - string_result := string_to_string16(string) + string_result := string_to_string16(arena, string) print(string_result) s32, s32_len := utf8_to_utf32(&"A"[0], 1) @@ -113,6 +32,10 @@ Windows_Bitmap :: struct hdc: HDC dib: HBITMAP +Bitmap :: struct + size: Vec2I + data: *U32 + create_bitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap result: Windows_Bitmap = {size = size} if bottom_up == false @@ -145,7 +68,8 @@ window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRE else;; return DefWindowProcW(hwnd, msg, wparam, lparam) WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int - window_name := string_to_string16("Have a wonderful day! 豈 更 車 賈 滑 串 句 龜 ") + arena: Arena + window_name := string_to_string16(&arena, "Have a wonderful day! 豈 更 車 賈 滑 串 句 龜 ") w := WNDCLASSW{ lpfnWndProc = window_procedure, hInstance = hInstance, @@ -153,9 +77,10 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS } assert(RegisterClassW(&w) != 0) + screen_size: Vec2I = {1280, 720} window := CreateWindowExW( dwExStyle = 0, hWndParent = 0, hMenu = 0, lpParam = 0, - X = CW_USEDEFAULT, Y = CW_USEDEFAULT, nWidth = 1280, nHeight = 720, + X = CW_USEDEFAULT, Y = CW_USEDEFAULT, nWidth = screen_size.x->int, nHeight = screen_size.y->int, lpClassName = window_name.str, lpWindowName = window_name.str, dwStyle = WS_OVERLAPPEDWINDOW, @@ -165,7 +90,7 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS ShowWindow(window, nShowCmd) window_dc := GetDC(window) - bitmap := create_bitmap({1280, 720}) + bitmap := create_bitmap(screen_size) for app_is_running msg: MSG for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0 diff --git a/programs/os.kl b/programs/os.kl index 0e25b8b..43c6e37 100644 --- a/programs/os.kl +++ b/programs/os.kl @@ -39,7 +39,6 @@ release :: (m: *Memory) m.commit = 0 m.reserve = 0 -String16 :: struct;; str: *U16; len: S64 print :: (string: String16) handle := GetStdHandle(STD_OUTPUT_HANDLE) WriteConsoleW(handle, (string.str)->*void, string.len->DWORD, 0, 0)