Work on unicode
This commit is contained in:
@@ -33,7 +33,7 @@ arena_init :: (a: *Arena)
|
|||||||
a.memory = Os.reserve(a.DEFAULT_RESERVE_SIZE)
|
a.memory = Os.reserve(a.DEFAULT_RESERVE_SIZE)
|
||||||
a.alignment = a.DEFAULT_ALIGNMENT
|
a.alignment = a.DEFAULT_ALIGNMENT
|
||||||
a.di = arena_di++
|
a.di = arena_di++
|
||||||
a.allocator.proc = arena_allocator_proc
|
// a.allocator.proc = arena_allocator_proc
|
||||||
|
|
||||||
arena_push_size :: (a: *Arena, size: SizeU): *void
|
arena_push_size :: (a: *Arena, size: SizeU): *void
|
||||||
generous_size := size + a.alignment
|
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
|
allocate :: (a: *Allocator, size: SizeU): *void
|
||||||
return a.proc(a, ALLOCATOR_ACTION.ALLOCATE, size, 0)
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -4,96 +4,15 @@
|
|||||||
#import "os.kl"
|
#import "os.kl"
|
||||||
#import "Windows.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
|
process_heap: HANDLE
|
||||||
allocate :: (size: U64): *void
|
allocate :: (size: U64): *void
|
||||||
if process_heap == 0
|
if process_heap == 0
|
||||||
process_heap = GetProcessHeap()
|
process_heap = GetProcessHeap()
|
||||||
return HeapAlloc(process_heap, 0, size)
|
return HeapAlloc(process_heap, 0, size)
|
||||||
|
|
||||||
string_to_string16 :: (in: String): String16
|
test_unicode :: (arena: *Arena)
|
||||||
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 :: ()
|
|
||||||
string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..."
|
string := " 豈 更 車 賈 滑 串 句 龜 龜 契 金 喇 奈 懶 癩 羅 蘿 螺 裸 邏 樂 洛 烙 珞 落 酪 駱 亂 卵 欄 爛 蘭 鸞 嵐 濫 藍 襤 拉 臘 蠟 廊 朗 浪 狼 郎 來 冷 勞 擄 櫓 爐 盧 老 蘆 虜 路 露 魯 鷺 碌 祿 綠 菉 錄 鹿 論 壟 弄 籠 聾 牢 磊 賂 雷 壘 屢 樓 淚 漏 累 縷 陋 勒 肋 凜 凌 稜 綾 菱 陵 讀 拏 樂 諾 丹 寧 怒 率 異 北 磻 便 復 不 泌 數 索 參 塞 省 葉 說 殺 辰 沈 拾 若 掠 略 亮 兩 凉 梁 糧 良 諒 量 勵 ..."
|
||||||
string_result := string_to_string16(string)
|
string_result := string_to_string16(arena, string)
|
||||||
print(string_result)
|
print(string_result)
|
||||||
|
|
||||||
s32, s32_len := utf8_to_utf32(&"A"[0], 1)
|
s32, s32_len := utf8_to_utf32(&"A"[0], 1)
|
||||||
@@ -113,6 +32,10 @@ Windows_Bitmap :: struct
|
|||||||
hdc: HDC
|
hdc: HDC
|
||||||
dib: HBITMAP
|
dib: HBITMAP
|
||||||
|
|
||||||
|
Bitmap :: struct
|
||||||
|
size: Vec2I
|
||||||
|
data: *U32
|
||||||
|
|
||||||
create_bitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap
|
create_bitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap
|
||||||
result: Windows_Bitmap = {size = size}
|
result: Windows_Bitmap = {size = size}
|
||||||
if bottom_up == false
|
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)
|
else;; return DefWindowProcW(hwnd, msg, wparam, lparam)
|
||||||
|
|
||||||
WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int
|
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{
|
w := WNDCLASSW{
|
||||||
lpfnWndProc = window_procedure,
|
lpfnWndProc = window_procedure,
|
||||||
hInstance = hInstance,
|
hInstance = hInstance,
|
||||||
@@ -153,9 +77,10 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
|
|||||||
}
|
}
|
||||||
assert(RegisterClassW(&w) != 0)
|
assert(RegisterClassW(&w) != 0)
|
||||||
|
|
||||||
|
screen_size: Vec2I = {1280, 720}
|
||||||
window := CreateWindowExW(
|
window := CreateWindowExW(
|
||||||
dwExStyle = 0, hWndParent = 0, hMenu = 0, lpParam = 0,
|
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,
|
lpClassName = window_name.str,
|
||||||
lpWindowName = window_name.str,
|
lpWindowName = window_name.str,
|
||||||
dwStyle = WS_OVERLAPPEDWINDOW,
|
dwStyle = WS_OVERLAPPEDWINDOW,
|
||||||
@@ -165,7 +90,7 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
|
|||||||
ShowWindow(window, nShowCmd)
|
ShowWindow(window, nShowCmd)
|
||||||
|
|
||||||
window_dc := GetDC(window)
|
window_dc := GetDC(window)
|
||||||
bitmap := create_bitmap({1280, 720})
|
bitmap := create_bitmap(screen_size)
|
||||||
for app_is_running
|
for app_is_running
|
||||||
msg: MSG
|
msg: MSG
|
||||||
for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0
|
for PeekMessageW(&msg, window, 0, 0, PM_REMOVE) > 0
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ release :: (m: *Memory)
|
|||||||
m.commit = 0
|
m.commit = 0
|
||||||
m.reserve = 0
|
m.reserve = 0
|
||||||
|
|
||||||
String16 :: struct;; str: *U16; len: S64
|
|
||||||
print :: (string: String16)
|
print :: (string: String16)
|
||||||
handle := GetStdHandle(STD_OUTPUT_HANDLE)
|
handle := GetStdHandle(STD_OUTPUT_HANDLE)
|
||||||
WriteConsoleW(handle, (string.str)->*void, string.len->DWORD, 0, 0)
|
WriteConsoleW(handle, (string.str)->*void, string.len->DWORD, 0, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user