[win32 build/link]
- Build milepost as a dynamic library - Add import/export directives to public API symbols - Change example build scripts accordingly
This commit is contained in:
parent
dc2961f513
commit
665c63c3d0
|
@ -6,5 +6,6 @@ set glsl_shaders=src\glsl_shaders\common.glsl src\glsl_shaders\blit_vertex.glsl
|
|||
call python3 scripts\embed_text.py %glsl_shaders% --prefix=glsl_ --output src\glsl_shaders.h
|
||||
|
||||
set INCLUDES=/I src /I src/util /I src/platform /I ext /I ext/angle_headers
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% /c /Fo:bin/milepost.obj src/milepost.c
|
||||
lib bin/milepost.obj /OUT:bin/milepost.lib
|
||||
set LIBS=user32.lib opengl32.lib gdi32.lib shcore.lib /LIBPATH:./bin libEGL.dll.lib libGLESv2.dll.lib
|
||||
|
||||
cl /we4013 /Zi /Zc:preprocessor /DMP_BUILD_DLL /std:c11 %INCLUDES% src/milepost.c /Fo:bin/milepost.o /LD /link %LIBS% /OUT:bin/milepost.dll /IMPLIB:bin/milepost.dll.lib
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
|
||||
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_canvas.exe
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_canvas.exe
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext
|
||||
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/perf_text.exe
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/perf_text.exe
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext
|
||||
|
||||
cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib /out:../../bin/example_gl_triangle.exe
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_gl_triangle.exe
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers
|
||||
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_gles_triangle.exe
|
||||
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.dll.lib /out:../../bin/example_gles_triangle.exe
|
||||
|
|
|
@ -96,12 +96,13 @@ for func in glall:
|
|||
f.write('\t' + 'PFN' + func.upper() + 'PROC ' + remove_prefix(func, 'gl') + ';\n')
|
||||
|
||||
f.write('} mg_gl_api;\n\n')
|
||||
f.write('extern mp_thread_local mg_gl_api* __mgGLAPI;\n\n');
|
||||
|
||||
# generate interface macros
|
||||
# TODO guard for different api/versions and only #define functions present in desired version
|
||||
f.write("MP_API mg_gl_api* mg_gl_get_api(void);\n\n")
|
||||
|
||||
for func in glall:
|
||||
f.write('#define ' + func + ' __mgGLAPI->' + remove_prefix(func, 'gl') + '\n')
|
||||
f.write('#define ' + func + ' mg_gl_get_api()->' + remove_prefix(func, 'gl') + '\n')
|
||||
|
||||
emit_end_guard(f, apiName)
|
||||
f.close()
|
||||
|
@ -124,8 +125,8 @@ f.write("void mg_gl_load_gl43(mg_gl_api* api, mg_gl_load_proc loadProc);\n")
|
|||
f.write("void mg_gl_load_gles31(mg_gl_api* api, mg_gl_load_proc loadProc);\n")
|
||||
f.write("void mg_gl_load_gles32(mg_gl_api* api, mg_gl_load_proc loadProc);\n\n")
|
||||
|
||||
f.write("void mg_gl_select_api(mg_gl_api* api);\n")
|
||||
f.write("mg_gl_api* mg_gl_get_api(void);\n\n")
|
||||
f.write("void mg_gl_select_api(mg_gl_api* api);\n\n")
|
||||
|
||||
|
||||
emit_end_guard(f, loaderName)
|
||||
f.close()
|
||||
|
|
2142
src/gl_api.h
2142
src/gl_api.h
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* @file: gl_loader.c
|
||||
* @note: auto-generated by glapi.py from gl.xml
|
||||
* @date: 20/022023
|
||||
* @date: 21/022023
|
||||
*
|
||||
*********************************************************/
|
||||
#include"gl_loader.h"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* @file: gl_loader.h
|
||||
* @note: auto-generated by glapi.py from gl.xml
|
||||
* @date: 20/022023
|
||||
* @date: 21/022023
|
||||
*
|
||||
*********************************************************/
|
||||
#ifndef __GL_LOADER_H__
|
||||
|
@ -18,6 +18,5 @@ void mg_gl_load_gles31(mg_gl_api* api, mg_gl_load_proc loadProc);
|
|||
void mg_gl_load_gles32(mg_gl_api* api, mg_gl_load_proc loadProc);
|
||||
|
||||
void mg_gl_select_api(mg_gl_api* api);
|
||||
mg_gl_api* mg_gl_get_api(void);
|
||||
|
||||
#endif // __GL_LOADER_H__
|
||||
|
|
174
src/graphics.h
174
src/graphics.h
|
@ -79,27 +79,27 @@ typedef enum {
|
|||
|
||||
//TODO: add MG_INCLUDE_OPENGL/GLES/etc, once we know how we make different gl versions co-exist
|
||||
|
||||
bool mg_is_surface_backend_available(mg_backend_id id);
|
||||
bool mg_is_canvas_backend_available(mg_backend_id id);
|
||||
MP_API bool mg_is_surface_backend_available(mg_backend_id id);
|
||||
MP_API bool mg_is_canvas_backend_available(mg_backend_id id);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): graphics surface
|
||||
//------------------------------------------------------------------------------------------
|
||||
typedef struct mg_surface { u64 h; } mg_surface;
|
||||
|
||||
mg_surface mg_surface_nil();
|
||||
bool mg_surface_is_nil(mg_surface surface);
|
||||
MP_API mg_surface mg_surface_nil();
|
||||
MP_API bool mg_surface_is_nil(mg_surface surface);
|
||||
|
||||
mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend);
|
||||
void mg_surface_destroy(mg_surface surface);
|
||||
void mg_surface_prepare(mg_surface surface);
|
||||
void mg_surface_present(mg_surface surface);
|
||||
void mg_surface_swap_interval(mg_surface surface, int swap);
|
||||
vec2 mg_surface_contents_scaling(mg_surface surface);
|
||||
mp_rect mg_surface_get_frame(mg_surface surface);
|
||||
void mg_surface_set_frame(mg_surface surface, mp_rect frame);
|
||||
bool mg_surface_get_hidden(mg_surface surface);
|
||||
void mg_surface_set_hidden(mg_surface surface, bool hidden);
|
||||
MP_API mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend);
|
||||
MP_API void mg_surface_destroy(mg_surface surface);
|
||||
MP_API void mg_surface_prepare(mg_surface surface);
|
||||
MP_API void mg_surface_present(mg_surface surface);
|
||||
MP_API void mg_surface_swap_interval(mg_surface surface, int swap);
|
||||
MP_API vec2 mg_surface_contents_scaling(mg_surface surface);
|
||||
MP_API mp_rect mg_surface_get_frame(mg_surface surface);
|
||||
MP_API void mg_surface_set_frame(mg_surface surface, mp_rect frame);
|
||||
MP_API bool mg_surface_get_hidden(mg_surface surface);
|
||||
MP_API void mg_surface_set_hidden(mg_surface surface, bool hidden);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
@ -161,128 +161,128 @@ typedef struct mg_text_extents
|
|||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): graphics canvas
|
||||
//------------------------------------------------------------------------------------------
|
||||
mg_canvas mg_canvas_nil();
|
||||
bool mg_canvas_is_nil(mg_canvas canvas);
|
||||
MP_API mg_canvas mg_canvas_nil();
|
||||
MP_API bool mg_canvas_is_nil(mg_canvas canvas);
|
||||
|
||||
mg_canvas mg_canvas_create(mg_surface surface);
|
||||
void mg_canvas_destroy(mg_canvas canvas);
|
||||
mg_canvas mg_canvas_set_current(mg_canvas canvas);
|
||||
MP_API mg_canvas mg_canvas_create(mg_surface surface);
|
||||
MP_API void mg_canvas_destroy(mg_canvas canvas);
|
||||
MP_API mg_canvas mg_canvas_set_current(mg_canvas canvas);
|
||||
|
||||
void mg_flush();
|
||||
MP_API void mg_flush();
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): transform, viewport and clipping
|
||||
//------------------------------------------------------------------------------------------
|
||||
void mg_viewport(mp_rect viewPort);
|
||||
MP_API void mg_viewport(mp_rect viewPort);
|
||||
|
||||
void mg_matrix_push(mg_mat2x3 matrix);
|
||||
void mg_matrix_pop();
|
||||
MP_API void mg_matrix_push(mg_mat2x3 matrix);
|
||||
MP_API void mg_matrix_pop();
|
||||
|
||||
void mg_clip_push(f32 x, f32 y, f32 w, f32 h);
|
||||
void mg_clip_pop();
|
||||
MP_API void mg_clip_push(f32 x, f32 y, f32 w, f32 h);
|
||||
MP_API void mg_clip_pop();
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): graphics attributes setting/getting
|
||||
//------------------------------------------------------------------------------------------
|
||||
void mg_set_color(mg_color color);
|
||||
void mg_set_color_rgba(f32 r, f32 g, f32 b, f32 a);
|
||||
void mg_set_width(f32 width);
|
||||
void mg_set_tolerance(f32 tolerance);
|
||||
void mg_set_joint(mg_joint_type joint);
|
||||
void mg_set_max_joint_excursion(f32 maxJointExcursion);
|
||||
void mg_set_cap(mg_cap_type cap);
|
||||
void mg_set_font(mg_font font);
|
||||
void mg_set_font_size(f32 size);
|
||||
void mg_set_text_flip(bool flip);
|
||||
MP_API void mg_set_color(mg_color color);
|
||||
MP_API void mg_set_color_rgba(f32 r, f32 g, f32 b, f32 a);
|
||||
MP_API void mg_set_width(f32 width);
|
||||
MP_API void mg_set_tolerance(f32 tolerance);
|
||||
MP_API void mg_set_joint(mg_joint_type joint);
|
||||
MP_API void mg_set_max_joint_excursion(f32 maxJointExcursion);
|
||||
MP_API void mg_set_cap(mg_cap_type cap);
|
||||
MP_API void mg_set_font(mg_font font);
|
||||
MP_API void mg_set_font_size(f32 size);
|
||||
MP_API void mg_set_text_flip(bool flip);
|
||||
|
||||
mg_color mg_get_color();
|
||||
f32 mg_get_width();
|
||||
f32 mg_get_tolerance();
|
||||
mg_joint_type mg_get_joint();
|
||||
f32 mg_get_max_joint_excursion();
|
||||
mg_cap_type mg_get_cap();
|
||||
mg_font mg_get_font();
|
||||
f32 mg_get_font_size();
|
||||
bool mg_get_text_flip();
|
||||
MP_API mg_color mg_get_color();
|
||||
MP_API f32 mg_get_width();
|
||||
MP_API f32 mg_get_tolerance();
|
||||
MP_API mg_joint_type mg_get_joint();
|
||||
MP_API f32 mg_get_max_joint_excursion();
|
||||
MP_API mg_cap_type mg_get_cap();
|
||||
MP_API mg_font mg_get_font();
|
||||
MP_API f32 mg_get_font_size();
|
||||
MP_API bool mg_get_text_flip();
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): path construction
|
||||
//------------------------------------------------------------------------------------------
|
||||
vec2 mg_get_position();
|
||||
void mg_move_to(f32 x, f32 y);
|
||||
void mg_line_to(f32 x, f32 y);
|
||||
void mg_quadratic_to(f32 x1, f32 y1, f32 x2, f32 y2);
|
||||
void mg_cubic_to(f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3);
|
||||
void mg_close_path();
|
||||
MP_API vec2 mg_get_position();
|
||||
MP_API void mg_move_to(f32 x, f32 y);
|
||||
MP_API void mg_line_to(f32 x, f32 y);
|
||||
MP_API void mg_quadratic_to(f32 x1, f32 y1, f32 x2, f32 y2);
|
||||
MP_API void mg_cubic_to(f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3);
|
||||
MP_API void mg_close_path();
|
||||
|
||||
mp_rect mg_glyph_outlines(str32 glyphIndices);
|
||||
void mg_codepoints_outlines(str32 string);
|
||||
void mg_text_outlines(str8 string);
|
||||
MP_API mp_rect mg_glyph_outlines(str32 glyphIndices);
|
||||
MP_API void mg_codepoints_outlines(str32 string);
|
||||
MP_API void mg_text_outlines(str8 string);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): clear/fill/stroke
|
||||
//------------------------------------------------------------------------------------------
|
||||
void mg_clear();
|
||||
void mg_fill();
|
||||
void mg_stroke();
|
||||
MP_API void mg_clear();
|
||||
MP_API void mg_fill();
|
||||
MP_API void mg_stroke();
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): 'fast' shapes primitives
|
||||
//------------------------------------------------------------------------------------------
|
||||
void mg_rectangle_fill(f32 x, f32 y, f32 w, f32 h);
|
||||
void mg_rectangle_stroke(f32 x, f32 y, f32 w, f32 h);
|
||||
void mg_rounded_rectangle_fill(f32 x, f32 y, f32 w, f32 h, f32 r);
|
||||
void mg_rounded_rectangle_stroke(f32 x, f32 y, f32 w, f32 h, f32 r);
|
||||
void mg_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry);
|
||||
void mg_ellipse_stroke(f32 x, f32 y, f32 rx, f32 ry);
|
||||
void mg_circle_fill(f32 x, f32 y, f32 r);
|
||||
void mg_circle_stroke(f32 x, f32 y, f32 r);
|
||||
void mg_arc(f32 x, f32 y, f32 r, f32 arcAngle, f32 startAngle);
|
||||
MP_API void mg_rectangle_fill(f32 x, f32 y, f32 w, f32 h);
|
||||
MP_API void mg_rectangle_stroke(f32 x, f32 y, f32 w, f32 h);
|
||||
MP_API void mg_rounded_rectangle_fill(f32 x, f32 y, f32 w, f32 h, f32 r);
|
||||
MP_API void mg_rounded_rectangle_stroke(f32 x, f32 y, f32 w, f32 h, f32 r);
|
||||
MP_API void mg_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry);
|
||||
MP_API void mg_ellipse_stroke(f32 x, f32 y, f32 rx, f32 ry);
|
||||
MP_API void mg_circle_fill(f32 x, f32 y, f32 r);
|
||||
MP_API void mg_circle_stroke(f32 x, f32 y, f32 r);
|
||||
MP_API void mg_arc(f32 x, f32 y, f32 r, f32 arcAngle, f32 startAngle);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): fonts
|
||||
//------------------------------------------------------------------------------------------
|
||||
mg_font mg_font_nil();
|
||||
mg_font mg_font_create_from_memory(u32 size, byte* buffer, u32 rangeCount, unicode_range* ranges);
|
||||
void mg_font_destroy(mg_font font);
|
||||
MP_API mg_font mg_font_nil();
|
||||
MP_API mg_font mg_font_create_from_memory(u32 size, byte* buffer, u32 rangeCount, unicode_range* ranges);
|
||||
MP_API void mg_font_destroy(mg_font font);
|
||||
|
||||
//NOTE(martin): the following int valued functions return -1 if font is invalid or codepoint is not present in font//
|
||||
//TODO(martin): add enum error codes
|
||||
|
||||
mg_font_extents mg_font_get_extents(mg_font font);
|
||||
mg_font_extents mg_font_get_scaled_extents(mg_font font, f32 emSize);
|
||||
f32 mg_font_get_scale_for_em_pixels(mg_font font, f32 emSize);
|
||||
MP_API mg_font_extents mg_font_get_extents(mg_font font);
|
||||
MP_API mg_font_extents mg_font_get_scaled_extents(mg_font font, f32 emSize);
|
||||
MP_API f32 mg_font_get_scale_for_em_pixels(mg_font font, f32 emSize);
|
||||
|
||||
//NOTE(martin): if you need to process more than one codepoint, first convert your codepoints to glyph indices, then use the
|
||||
// glyph index versions of the functions, which can take an array of glyph indices.
|
||||
|
||||
str32 mg_font_get_glyph_indices(mg_font font, str32 codePoints, str32 backing);
|
||||
str32 mg_font_push_glyph_indices(mg_font font, mem_arena* arena, str32 codePoints);
|
||||
u32 mg_font_get_glyph_index(mg_font font, utf32 codePoint);
|
||||
MP_API str32 mg_font_get_glyph_indices(mg_font font, str32 codePoints, str32 backing);
|
||||
MP_API str32 mg_font_push_glyph_indices(mg_font font, mem_arena* arena, str32 codePoints);
|
||||
MP_API u32 mg_font_get_glyph_index(mg_font font, utf32 codePoint);
|
||||
|
||||
int mg_font_get_codepoint_extents(mg_font font, utf32 codePoint, mg_text_extents* outExtents);
|
||||
MP_API int mg_font_get_codepoint_extents(mg_font font, utf32 codePoint, mg_text_extents* outExtents);
|
||||
|
||||
int mg_font_get_glyph_extents(mg_font font, str32 glyphIndices, mg_text_extents* outExtents);
|
||||
MP_API int mg_font_get_glyph_extents(mg_font font, str32 glyphIndices, mg_text_extents* outExtents);
|
||||
|
||||
mp_rect mg_text_bounding_box_utf32(mg_font font, f32 fontSize, str32 text);
|
||||
mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text);
|
||||
MP_API mp_rect mg_text_bounding_box_utf32(mg_font font, f32 fontSize, str32 text);
|
||||
MP_API mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//NOTE(martin): images
|
||||
//------------------------------------------------------------------------------------------
|
||||
typedef struct mg_image { u64 h; } mg_image;
|
||||
|
||||
mg_image mg_image_nil();
|
||||
bool mg_image_equal(mg_image a, mg_image b);
|
||||
MP_API mg_image mg_image_nil();
|
||||
MP_API bool mg_image_equal(mg_image a, mg_image b);
|
||||
|
||||
mg_image mg_image_create_from_rgba8(u32 width, u32 height, u8* pixels);
|
||||
mg_image mg_image_create_from_data(str8 data, bool flip);
|
||||
mg_image mg_image_create_from_file(str8 path, bool flip);
|
||||
MP_API mg_image mg_image_create_from_rgba8(u32 width, u32 height, u8* pixels);
|
||||
MP_API mg_image mg_image_create_from_data(str8 data, bool flip);
|
||||
MP_API mg_image mg_image_create_from_file(str8 path, bool flip);
|
||||
|
||||
void mg_image_drestroy(mg_image image);
|
||||
MP_API void mg_image_drestroy(mg_image image);
|
||||
|
||||
vec2 mg_image_size(mg_image image);
|
||||
void mg_image_draw(mg_image image, mp_rect rect);
|
||||
void mg_rounded_image_draw(mg_image image, mp_rect rect, f32 roundness);
|
||||
MP_API vec2 mg_image_size(mg_image image);
|
||||
MP_API void mg_image_draw(mg_image image, mp_rect rect);
|
||||
MP_API void mg_rounded_image_draw(mg_image image, mp_rect rect, f32 roundness);
|
||||
|
||||
#endif //__GRAPHICS_H_
|
||||
|
|
796
src/mp_app.h
796
src/mp_app.h
|
@ -1,398 +1,398 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: platform_app.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 16/05/2020
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __PLATFORM_APP_H_
|
||||
#define __PLATFORM_APP_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"utf8.h"
|
||||
#include"lists.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Typedefs, enums and constants
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
typedef struct mp_window { u64 h; } mp_window;
|
||||
|
||||
typedef enum { MP_MOUSE_CURSOR_ARROW,
|
||||
MP_MOUSE_CURSOR_RESIZE_0,
|
||||
MP_MOUSE_CURSOR_RESIZE_90,
|
||||
MP_MOUSE_CURSOR_RESIZE_45,
|
||||
MP_MOUSE_CURSOR_RESIZE_135,
|
||||
MP_MOUSE_CURSOR_TEXT } mp_mouse_cursor;
|
||||
|
||||
typedef i32 mp_window_style;
|
||||
static const mp_window_style MP_WINDOW_STYLE_NO_TITLE = 0x01<<0,
|
||||
MP_WINDOW_STYLE_FIXED_SIZE = 0x01<<1,
|
||||
MP_WINDOW_STYLE_NO_CLOSE = 0x01<<2,
|
||||
MP_WINDOW_STYLE_NO_MINIFY = 0x01<<3,
|
||||
MP_WINDOW_STYLE_NO_FOCUS = 0x01<<4,
|
||||
MP_WINDOW_STYLE_FLOAT = 0x01<<5,
|
||||
MP_WINDOW_STYLE_POPUPMENU = 0x01<<6,
|
||||
MP_WINDOW_STYLE_NO_BUTTONS = 0x01<<7;
|
||||
|
||||
typedef enum { MP_EVENT_NONE,
|
||||
MP_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
|
||||
MP_EVENT_KEYBOARD_KEY,
|
||||
MP_EVENT_KEYBOARD_CHAR,
|
||||
MP_EVENT_MOUSE_BUTTON,
|
||||
MP_EVENT_MOUSE_MOVE,
|
||||
MP_EVENT_MOUSE_WHEEL,
|
||||
MP_EVENT_MOUSE_ENTER,
|
||||
MP_EVENT_MOUSE_LEAVE,
|
||||
MP_EVENT_WINDOW_RESIZE,
|
||||
MP_EVENT_WINDOW_MOVE,
|
||||
MP_EVENT_WINDOW_FOCUS,
|
||||
MP_EVENT_WINDOW_UNFOCUS,
|
||||
MP_EVENT_WINDOW_HIDE, // rename to minimize?
|
||||
MP_EVENT_WINDOW_SHOW, // rename to restore?
|
||||
MP_EVENT_WINDOW_CLOSE,
|
||||
MP_EVENT_PATHDROP,
|
||||
MP_EVENT_FRAME,
|
||||
MP_EVENT_QUIT } mp_event_type;
|
||||
|
||||
typedef enum { MP_KEY_NO_ACTION,
|
||||
MP_KEY_PRESS,
|
||||
MP_KEY_RELEASE,
|
||||
MP_KEY_REPEAT } mp_key_action;
|
||||
|
||||
typedef enum { MP_KEY_UNKNOWN = 0,
|
||||
MP_KEY_SPACE = 32,
|
||||
MP_KEY_APOSTROPHE = 39, /* ' */
|
||||
MP_KEY_COMMA = 44, /* , */
|
||||
MP_KEY_MINUS = 45, // -
|
||||
MP_KEY_PERIOD = 46, // .
|
||||
MP_KEY_SLASH = 47, // /
|
||||
MP_KEY_0 = 48,
|
||||
MP_KEY_1 = 49,
|
||||
MP_KEY_2 = 50,
|
||||
MP_KEY_3 = 51,
|
||||
MP_KEY_4 = 52,
|
||||
MP_KEY_5 = 53,
|
||||
MP_KEY_6 = 54,
|
||||
MP_KEY_7 = 55,
|
||||
MP_KEY_8 = 56,
|
||||
MP_KEY_9 = 57,
|
||||
MP_KEY_SEMICOLON = 59, // ;
|
||||
MP_KEY_EQUAL = 61, // =
|
||||
MP_KEY_A = 65,
|
||||
MP_KEY_B = 66,
|
||||
MP_KEY_C = 67,
|
||||
MP_KEY_D = 68,
|
||||
MP_KEY_E = 69,
|
||||
MP_KEY_F = 70,
|
||||
MP_KEY_G = 71,
|
||||
MP_KEY_H = 72,
|
||||
MP_KEY_I = 73,
|
||||
MP_KEY_J = 74,
|
||||
MP_KEY_K = 75,
|
||||
MP_KEY_L = 76,
|
||||
MP_KEY_M = 77,
|
||||
MP_KEY_N = 78,
|
||||
MP_KEY_O = 79,
|
||||
MP_KEY_P = 80,
|
||||
MP_KEY_Q = 81,
|
||||
MP_KEY_R = 82,
|
||||
MP_KEY_S = 83,
|
||||
MP_KEY_T = 84,
|
||||
MP_KEY_U = 85,
|
||||
MP_KEY_V = 86,
|
||||
MP_KEY_W = 87,
|
||||
MP_KEY_X = 88,
|
||||
MP_KEY_Y = 89,
|
||||
MP_KEY_Z = 90,
|
||||
MP_KEY_LEFT_BRACKET = 91, // [
|
||||
MP_KEY_BACKSLASH = 92, // \ */
|
||||
MP_KEY_RIGHT_BRACKET = 93, // ]
|
||||
MP_KEY_GRAVE_ACCENT = 96, // `
|
||||
MP_KEY_WORLD_1 = 161, // non-US #1
|
||||
MP_KEY_WORLD_2 = 162, // non-US #2
|
||||
MP_KEY_ESCAPE = 256,
|
||||
MP_KEY_ENTER = 257,
|
||||
MP_KEY_TAB = 258,
|
||||
MP_KEY_BACKSPACE = 259,
|
||||
MP_KEY_INSERT = 260,
|
||||
MP_KEY_DELETE = 261,
|
||||
MP_KEY_RIGHT = 262,
|
||||
MP_KEY_LEFT = 263,
|
||||
MP_KEY_DOWN = 264,
|
||||
MP_KEY_UP = 265,
|
||||
MP_KEY_PAGE_UP = 266,
|
||||
MP_KEY_PAGE_DOWN = 267,
|
||||
MP_KEY_HOME = 268,
|
||||
MP_KEY_END = 269,
|
||||
MP_KEY_CAPS_LOCK = 280,
|
||||
MP_KEY_SCROLL_LOCK = 281,
|
||||
MP_KEY_NUM_LOCK = 282,
|
||||
MP_KEY_PRINT_SCREEN = 283,
|
||||
MP_KEY_PAUSE = 284,
|
||||
MP_KEY_F1 = 290,
|
||||
MP_KEY_F2 = 291,
|
||||
MP_KEY_F3 = 292,
|
||||
MP_KEY_F4 = 293,
|
||||
MP_KEY_F5 = 294,
|
||||
MP_KEY_F6 = 295,
|
||||
MP_KEY_F7 = 296,
|
||||
MP_KEY_F8 = 297,
|
||||
MP_KEY_F9 = 298,
|
||||
MP_KEY_F10 = 299,
|
||||
MP_KEY_F11 = 300,
|
||||
MP_KEY_F12 = 301,
|
||||
MP_KEY_F13 = 302,
|
||||
MP_KEY_F14 = 303,
|
||||
MP_KEY_F15 = 304,
|
||||
MP_KEY_F16 = 305,
|
||||
MP_KEY_F17 = 306,
|
||||
MP_KEY_F18 = 307,
|
||||
MP_KEY_F19 = 308,
|
||||
MP_KEY_F20 = 309,
|
||||
MP_KEY_F21 = 310,
|
||||
MP_KEY_F22 = 311,
|
||||
MP_KEY_F23 = 312,
|
||||
MP_KEY_F24 = 313,
|
||||
MP_KEY_F25 = 314,
|
||||
MP_KEY_KP_0 = 320,
|
||||
MP_KEY_KP_1 = 321,
|
||||
MP_KEY_KP_2 = 322,
|
||||
MP_KEY_KP_3 = 323,
|
||||
MP_KEY_KP_4 = 324,
|
||||
MP_KEY_KP_5 = 325,
|
||||
MP_KEY_KP_6 = 326,
|
||||
MP_KEY_KP_7 = 327,
|
||||
MP_KEY_KP_8 = 328,
|
||||
MP_KEY_KP_9 = 329,
|
||||
MP_KEY_KP_DECIMAL = 330,
|
||||
MP_KEY_KP_DIVIDE = 331,
|
||||
MP_KEY_KP_MULTIPLY = 332,
|
||||
MP_KEY_KP_SUBTRACT = 333,
|
||||
MP_KEY_KP_ADD = 334,
|
||||
MP_KEY_KP_ENTER = 335,
|
||||
MP_KEY_KP_EQUAL = 336,
|
||||
MP_KEY_LEFT_SHIFT = 340,
|
||||
MP_KEY_LEFT_CONTROL = 341,
|
||||
MP_KEY_LEFT_ALT = 342,
|
||||
MP_KEY_LEFT_SUPER = 343,
|
||||
MP_KEY_RIGHT_SHIFT = 344,
|
||||
MP_KEY_RIGHT_CONTROL = 345,
|
||||
MP_KEY_RIGHT_ALT = 346,
|
||||
MP_KEY_RIGHT_SUPER = 347,
|
||||
MP_KEY_MENU = 348,
|
||||
MP_KEY_COUNT } mp_key_code;
|
||||
|
||||
typedef enum {
|
||||
MP_KEYMOD_NONE = 0x00,
|
||||
MP_KEYMOD_ALT = 0x01,
|
||||
MP_KEYMOD_SHIFT = 0x02,
|
||||
MP_KEYMOD_CTRL = 0x04,
|
||||
MP_KEYMOD_CMD = 0x08 } mp_key_mods;
|
||||
|
||||
typedef enum {
|
||||
MP_MOUSE_LEFT = 0x00,
|
||||
MP_MOUSE_RIGHT = 0x01,
|
||||
MP_MOUSE_MIDDLE = 0x02,
|
||||
MP_MOUSE_EXT1 = 0x03,
|
||||
MP_MOUSE_EXT2 = 0x04,
|
||||
MP_MOUSE_BUTTON_COUNT } mp_mouse_button;
|
||||
|
||||
typedef struct mp_key_event // keyboard and mouse buttons input
|
||||
{
|
||||
mp_key_action action;
|
||||
i32 code;
|
||||
mp_key_mods mods;
|
||||
char label[8];
|
||||
u8 labelLen;
|
||||
int clickCount;
|
||||
} mp_key_event;
|
||||
|
||||
typedef struct mp_char_event // character input
|
||||
{
|
||||
utf32 codepoint;
|
||||
char sequence[8];
|
||||
u8 seqLen;
|
||||
} mp_char_event;
|
||||
|
||||
typedef struct mp_move_event // mouse move/scroll
|
||||
{
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 deltaX;
|
||||
f32 deltaY;
|
||||
mp_key_mods mods;
|
||||
} mp_move_event;
|
||||
|
||||
typedef struct mp_frame_event // window resize / move
|
||||
{
|
||||
mp_rect rect;
|
||||
} mp_frame_event;
|
||||
|
||||
typedef struct mp_event
|
||||
{
|
||||
//TODO clipboard and path drop
|
||||
|
||||
mp_window window;
|
||||
mp_event_type type;
|
||||
|
||||
union
|
||||
{
|
||||
mp_key_event key;
|
||||
mp_char_event character;
|
||||
mp_move_event move;
|
||||
mp_frame_event frame;
|
||||
str8 path;
|
||||
};
|
||||
|
||||
//TODO(martin): chain externally ?
|
||||
list_elt list;
|
||||
} mp_event;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// app management
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void mp_init();
|
||||
void mp_terminate();
|
||||
|
||||
bool mp_should_quit();
|
||||
void mp_cancel_quit();
|
||||
void mp_request_quit();
|
||||
|
||||
void mp_set_cursor(mp_mouse_cursor cursor);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Main loop and events handling
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
void mp_pump_events(f64 timeout);
|
||||
bool mp_next_event(mp_event* event);
|
||||
|
||||
typedef void(*mp_live_resize_callback)(mp_event event, void* data);
|
||||
void mp_set_live_resize_callback(mp_live_resize_callback callback, void* data);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// window management
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
bool mp_window_handle_is_null(mp_window window);
|
||||
mp_window mp_window_null_handle();
|
||||
|
||||
mp_window mp_window_create(mp_rect contentRect, const char* title, mp_window_style style);
|
||||
void mp_window_destroy(mp_window window);
|
||||
void* mp_window_native_pointer(mp_window window);
|
||||
|
||||
bool mp_window_should_close(mp_window window);
|
||||
void mp_window_request_close(mp_window window);
|
||||
void mp_window_cancel_close(mp_window window);
|
||||
|
||||
bool mp_window_is_hidden(mp_window window);
|
||||
void mp_window_hide(mp_window window);
|
||||
void mp_window_show(mp_window window);
|
||||
|
||||
bool mp_window_is_minimized(mp_window window);
|
||||
bool mp_window_is_maximized(mp_window window);
|
||||
void mp_window_minimize(mp_window window);
|
||||
void mp_window_maximize(mp_window window);
|
||||
void mp_window_restore(mp_window window);
|
||||
|
||||
bool mp_window_has_focus(mp_window window);
|
||||
void mp_window_focus(mp_window window);
|
||||
void mp_window_unfocus(mp_window window);
|
||||
|
||||
void mp_window_send_to_back(mp_window window);
|
||||
void mp_window_bring_to_front(mp_window window);
|
||||
|
||||
mp_rect mp_window_get_content_rect(mp_window window);
|
||||
mp_rect mp_window_get_frame_rect(mp_window window);
|
||||
void mp_window_set_content_rect(mp_window window, mp_rect contentRect);
|
||||
void mp_window_set_frame_rect(mp_window window, mp_rect frameRect);
|
||||
|
||||
void mp_window_center(mp_window window);
|
||||
|
||||
mp_rect mp_window_content_rect_for_frame_rect(mp_rect frameRect, mp_window_style style);
|
||||
mp_rect mp_window_frame_rect_for_content_rect(mp_rect contentRect, mp_window_style style);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Input state polling
|
||||
//--------------------------------------------------------------------
|
||||
bool mp_input_key_down(mp_key_code key);
|
||||
bool mp_input_key_pressed(mp_key_code key);
|
||||
bool mp_input_key_released(mp_key_code key);
|
||||
mp_key_mods mp_input_key_mods();
|
||||
|
||||
str8 mp_key_to_label(mp_key_code key);
|
||||
mp_key_code mp_label_to_key(str8 label);
|
||||
|
||||
bool mp_input_mouse_down(mp_mouse_button button);
|
||||
bool mp_input_mouse_pressed(mp_mouse_button button);
|
||||
bool mp_input_mouse_released(mp_mouse_button button);
|
||||
bool mp_input_mouse_clicked(mp_mouse_button button);
|
||||
bool mp_input_mouse_double_clicked(mp_mouse_button button);
|
||||
|
||||
vec2 mp_input_mouse_position();
|
||||
vec2 mp_input_mouse_delta();
|
||||
vec2 mp_input_mouse_wheel();
|
||||
|
||||
str32 mp_input_text_utf32(mem_arena* arena);
|
||||
str8 mp_input_text_utf8(mem_arena* arena);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Clipboard
|
||||
//--------------------------------------------------------------------
|
||||
void mp_clipboard_clear();
|
||||
|
||||
void mp_clipboard_set_string(str8 string);
|
||||
str8 mp_clipboard_get_string(mem_arena* arena);
|
||||
str8 mp_clipboard_copy_string(str8 backing);
|
||||
|
||||
bool mp_clipboard_has_tag(const char* tag);
|
||||
void mp_clipboard_set_data_for_tag(const char* tag, str8 data);
|
||||
str8 mp_clipboard_get_data_for_tag(mem_arena* arena, const char* tag);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// native open/save/alert windows
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
str8 mp_open_dialog(mem_arena* arena,
|
||||
const char* title,
|
||||
const char* defaultPath,
|
||||
int filterCount,
|
||||
const char** filters,
|
||||
bool directory);
|
||||
|
||||
str8 mp_save_dialog(mem_arena* arena,
|
||||
const char* title,
|
||||
const char* defaultPath,
|
||||
int filterCount,
|
||||
const char** filters);
|
||||
|
||||
int mp_alert_popup(const char* title,
|
||||
const char* message,
|
||||
u32 count,
|
||||
const char** options);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// file system stuff... //TODO: move elsewhere
|
||||
//--------------------------------------------------------------------
|
||||
int mp_file_move(str8 from, str8 to);
|
||||
int mp_file_remove(str8 path);
|
||||
|
||||
int mp_directory_create(str8 path);
|
||||
|
||||
str8 mp_app_get_resource_path(mem_arena* arena, const char* name);
|
||||
str8 mp_app_get_executable_path(mem_arena* arena);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__PLATFORM_APP_H_
|
||||
/************************************************************//**
|
||||
*
|
||||
* @file: platform_app.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 16/05/2020
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __PLATFORM_APP_H_
|
||||
#define __PLATFORM_APP_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"utf8.h"
|
||||
#include"lists.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Typedefs, enums and constants
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
typedef struct mp_window { u64 h; } mp_window;
|
||||
|
||||
typedef enum { MP_MOUSE_CURSOR_ARROW,
|
||||
MP_MOUSE_CURSOR_RESIZE_0,
|
||||
MP_MOUSE_CURSOR_RESIZE_90,
|
||||
MP_MOUSE_CURSOR_RESIZE_45,
|
||||
MP_MOUSE_CURSOR_RESIZE_135,
|
||||
MP_MOUSE_CURSOR_TEXT } mp_mouse_cursor;
|
||||
|
||||
typedef i32 mp_window_style;
|
||||
static const mp_window_style MP_WINDOW_STYLE_NO_TITLE = 0x01<<0,
|
||||
MP_WINDOW_STYLE_FIXED_SIZE = 0x01<<1,
|
||||
MP_WINDOW_STYLE_NO_CLOSE = 0x01<<2,
|
||||
MP_WINDOW_STYLE_NO_MINIFY = 0x01<<3,
|
||||
MP_WINDOW_STYLE_NO_FOCUS = 0x01<<4,
|
||||
MP_WINDOW_STYLE_FLOAT = 0x01<<5,
|
||||
MP_WINDOW_STYLE_POPUPMENU = 0x01<<6,
|
||||
MP_WINDOW_STYLE_NO_BUTTONS = 0x01<<7;
|
||||
|
||||
typedef enum { MP_EVENT_NONE,
|
||||
MP_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key?
|
||||
MP_EVENT_KEYBOARD_KEY,
|
||||
MP_EVENT_KEYBOARD_CHAR,
|
||||
MP_EVENT_MOUSE_BUTTON,
|
||||
MP_EVENT_MOUSE_MOVE,
|
||||
MP_EVENT_MOUSE_WHEEL,
|
||||
MP_EVENT_MOUSE_ENTER,
|
||||
MP_EVENT_MOUSE_LEAVE,
|
||||
MP_EVENT_WINDOW_RESIZE,
|
||||
MP_EVENT_WINDOW_MOVE,
|
||||
MP_EVENT_WINDOW_FOCUS,
|
||||
MP_EVENT_WINDOW_UNFOCUS,
|
||||
MP_EVENT_WINDOW_HIDE, // rename to minimize?
|
||||
MP_EVENT_WINDOW_SHOW, // rename to restore?
|
||||
MP_EVENT_WINDOW_CLOSE,
|
||||
MP_EVENT_PATHDROP,
|
||||
MP_EVENT_FRAME,
|
||||
MP_EVENT_QUIT } mp_event_type;
|
||||
|
||||
typedef enum { MP_KEY_NO_ACTION,
|
||||
MP_KEY_PRESS,
|
||||
MP_KEY_RELEASE,
|
||||
MP_KEY_REPEAT } mp_key_action;
|
||||
|
||||
typedef enum { MP_KEY_UNKNOWN = 0,
|
||||
MP_KEY_SPACE = 32,
|
||||
MP_KEY_APOSTROPHE = 39, /* ' */
|
||||
MP_KEY_COMMA = 44, /* , */
|
||||
MP_KEY_MINUS = 45, // -
|
||||
MP_KEY_PERIOD = 46, // .
|
||||
MP_KEY_SLASH = 47, // /
|
||||
MP_KEY_0 = 48,
|
||||
MP_KEY_1 = 49,
|
||||
MP_KEY_2 = 50,
|
||||
MP_KEY_3 = 51,
|
||||
MP_KEY_4 = 52,
|
||||
MP_KEY_5 = 53,
|
||||
MP_KEY_6 = 54,
|
||||
MP_KEY_7 = 55,
|
||||
MP_KEY_8 = 56,
|
||||
MP_KEY_9 = 57,
|
||||
MP_KEY_SEMICOLON = 59, // ;
|
||||
MP_KEY_EQUAL = 61, // =
|
||||
MP_KEY_A = 65,
|
||||
MP_KEY_B = 66,
|
||||
MP_KEY_C = 67,
|
||||
MP_KEY_D = 68,
|
||||
MP_KEY_E = 69,
|
||||
MP_KEY_F = 70,
|
||||
MP_KEY_G = 71,
|
||||
MP_KEY_H = 72,
|
||||
MP_KEY_I = 73,
|
||||
MP_KEY_J = 74,
|
||||
MP_KEY_K = 75,
|
||||
MP_KEY_L = 76,
|
||||
MP_KEY_M = 77,
|
||||
MP_KEY_N = 78,
|
||||
MP_KEY_O = 79,
|
||||
MP_KEY_P = 80,
|
||||
MP_KEY_Q = 81,
|
||||
MP_KEY_R = 82,
|
||||
MP_KEY_S = 83,
|
||||
MP_KEY_T = 84,
|
||||
MP_KEY_U = 85,
|
||||
MP_KEY_V = 86,
|
||||
MP_KEY_W = 87,
|
||||
MP_KEY_X = 88,
|
||||
MP_KEY_Y = 89,
|
||||
MP_KEY_Z = 90,
|
||||
MP_KEY_LEFT_BRACKET = 91, // [
|
||||
MP_KEY_BACKSLASH = 92, // \ */
|
||||
MP_KEY_RIGHT_BRACKET = 93, // ]
|
||||
MP_KEY_GRAVE_ACCENT = 96, // `
|
||||
MP_KEY_WORLD_1 = 161, // non-US #1
|
||||
MP_KEY_WORLD_2 = 162, // non-US #2
|
||||
MP_KEY_ESCAPE = 256,
|
||||
MP_KEY_ENTER = 257,
|
||||
MP_KEY_TAB = 258,
|
||||
MP_KEY_BACKSPACE = 259,
|
||||
MP_KEY_INSERT = 260,
|
||||
MP_KEY_DELETE = 261,
|
||||
MP_KEY_RIGHT = 262,
|
||||
MP_KEY_LEFT = 263,
|
||||
MP_KEY_DOWN = 264,
|
||||
MP_KEY_UP = 265,
|
||||
MP_KEY_PAGE_UP = 266,
|
||||
MP_KEY_PAGE_DOWN = 267,
|
||||
MP_KEY_HOME = 268,
|
||||
MP_KEY_END = 269,
|
||||
MP_KEY_CAPS_LOCK = 280,
|
||||
MP_KEY_SCROLL_LOCK = 281,
|
||||
MP_KEY_NUM_LOCK = 282,
|
||||
MP_KEY_PRINT_SCREEN = 283,
|
||||
MP_KEY_PAUSE = 284,
|
||||
MP_KEY_F1 = 290,
|
||||
MP_KEY_F2 = 291,
|
||||
MP_KEY_F3 = 292,
|
||||
MP_KEY_F4 = 293,
|
||||
MP_KEY_F5 = 294,
|
||||
MP_KEY_F6 = 295,
|
||||
MP_KEY_F7 = 296,
|
||||
MP_KEY_F8 = 297,
|
||||
MP_KEY_F9 = 298,
|
||||
MP_KEY_F10 = 299,
|
||||
MP_KEY_F11 = 300,
|
||||
MP_KEY_F12 = 301,
|
||||
MP_KEY_F13 = 302,
|
||||
MP_KEY_F14 = 303,
|
||||
MP_KEY_F15 = 304,
|
||||
MP_KEY_F16 = 305,
|
||||
MP_KEY_F17 = 306,
|
||||
MP_KEY_F18 = 307,
|
||||
MP_KEY_F19 = 308,
|
||||
MP_KEY_F20 = 309,
|
||||
MP_KEY_F21 = 310,
|
||||
MP_KEY_F22 = 311,
|
||||
MP_KEY_F23 = 312,
|
||||
MP_KEY_F24 = 313,
|
||||
MP_KEY_F25 = 314,
|
||||
MP_KEY_KP_0 = 320,
|
||||
MP_KEY_KP_1 = 321,
|
||||
MP_KEY_KP_2 = 322,
|
||||
MP_KEY_KP_3 = 323,
|
||||
MP_KEY_KP_4 = 324,
|
||||
MP_KEY_KP_5 = 325,
|
||||
MP_KEY_KP_6 = 326,
|
||||
MP_KEY_KP_7 = 327,
|
||||
MP_KEY_KP_8 = 328,
|
||||
MP_KEY_KP_9 = 329,
|
||||
MP_KEY_KP_DECIMAL = 330,
|
||||
MP_KEY_KP_DIVIDE = 331,
|
||||
MP_KEY_KP_MULTIPLY = 332,
|
||||
MP_KEY_KP_SUBTRACT = 333,
|
||||
MP_KEY_KP_ADD = 334,
|
||||
MP_KEY_KP_ENTER = 335,
|
||||
MP_KEY_KP_EQUAL = 336,
|
||||
MP_KEY_LEFT_SHIFT = 340,
|
||||
MP_KEY_LEFT_CONTROL = 341,
|
||||
MP_KEY_LEFT_ALT = 342,
|
||||
MP_KEY_LEFT_SUPER = 343,
|
||||
MP_KEY_RIGHT_SHIFT = 344,
|
||||
MP_KEY_RIGHT_CONTROL = 345,
|
||||
MP_KEY_RIGHT_ALT = 346,
|
||||
MP_KEY_RIGHT_SUPER = 347,
|
||||
MP_KEY_MENU = 348,
|
||||
MP_KEY_COUNT } mp_key_code;
|
||||
|
||||
typedef enum {
|
||||
MP_KEYMOD_NONE = 0x00,
|
||||
MP_KEYMOD_ALT = 0x01,
|
||||
MP_KEYMOD_SHIFT = 0x02,
|
||||
MP_KEYMOD_CTRL = 0x04,
|
||||
MP_KEYMOD_CMD = 0x08 } mp_key_mods;
|
||||
|
||||
typedef enum {
|
||||
MP_MOUSE_LEFT = 0x00,
|
||||
MP_MOUSE_RIGHT = 0x01,
|
||||
MP_MOUSE_MIDDLE = 0x02,
|
||||
MP_MOUSE_EXT1 = 0x03,
|
||||
MP_MOUSE_EXT2 = 0x04,
|
||||
MP_MOUSE_BUTTON_COUNT } mp_mouse_button;
|
||||
|
||||
typedef struct mp_key_event // keyboard and mouse buttons input
|
||||
{
|
||||
mp_key_action action;
|
||||
i32 code;
|
||||
mp_key_mods mods;
|
||||
char label[8];
|
||||
u8 labelLen;
|
||||
int clickCount;
|
||||
} mp_key_event;
|
||||
|
||||
typedef struct mp_char_event // character input
|
||||
{
|
||||
utf32 codepoint;
|
||||
char sequence[8];
|
||||
u8 seqLen;
|
||||
} mp_char_event;
|
||||
|
||||
typedef struct mp_move_event // mouse move/scroll
|
||||
{
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 deltaX;
|
||||
f32 deltaY;
|
||||
mp_key_mods mods;
|
||||
} mp_move_event;
|
||||
|
||||
typedef struct mp_frame_event // window resize / move
|
||||
{
|
||||
mp_rect rect;
|
||||
} mp_frame_event;
|
||||
|
||||
typedef struct mp_event
|
||||
{
|
||||
//TODO clipboard and path drop
|
||||
|
||||
mp_window window;
|
||||
mp_event_type type;
|
||||
|
||||
union
|
||||
{
|
||||
mp_key_event key;
|
||||
mp_char_event character;
|
||||
mp_move_event move;
|
||||
mp_frame_event frame;
|
||||
str8 path;
|
||||
};
|
||||
|
||||
//TODO(martin): chain externally ?
|
||||
list_elt list;
|
||||
} mp_event;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// app management
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
MP_API void mp_init(void);
|
||||
MP_API void mp_terminate(void);
|
||||
|
||||
MP_API bool mp_should_quit(void);
|
||||
MP_API void mp_cancel_quit(void);
|
||||
MP_API void mp_request_quit(void);
|
||||
|
||||
MP_API void mp_set_cursor(mp_mouse_cursor cursor);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Main loop and events handling
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
MP_API void mp_pump_events(f64 timeout);
|
||||
MP_API bool mp_next_event(mp_event* event);
|
||||
|
||||
typedef void(*mp_live_resize_callback)(mp_event event, void* data);
|
||||
MP_API void mp_set_live_resize_callback(mp_live_resize_callback callback, void* data);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// window management
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
MP_API bool mp_window_handle_is_null(mp_window window);
|
||||
MP_API mp_window mp_window_null_handle(void);
|
||||
|
||||
MP_API mp_window mp_window_create(mp_rect contentRect, const char* title, mp_window_style style);
|
||||
MP_API void mp_window_destroy(mp_window window);
|
||||
MP_API void* mp_window_native_pointer(mp_window window);
|
||||
|
||||
MP_API bool mp_window_should_close(mp_window window);
|
||||
MP_API void mp_window_request_close(mp_window window);
|
||||
MP_API void mp_window_cancel_close(mp_window window);
|
||||
|
||||
MP_API bool mp_window_is_hidden(mp_window window);
|
||||
MP_API void mp_window_hide(mp_window window);
|
||||
MP_API void mp_window_show(mp_window window);
|
||||
|
||||
MP_API bool mp_window_is_minimized(mp_window window);
|
||||
MP_API bool mp_window_is_maximized(mp_window window);
|
||||
MP_API void mp_window_minimize(mp_window window);
|
||||
MP_API void mp_window_maximize(mp_window window);
|
||||
MP_API void mp_window_restore(mp_window window);
|
||||
|
||||
MP_API bool mp_window_has_focus(mp_window window);
|
||||
MP_API void mp_window_focus(mp_window window);
|
||||
MP_API void mp_window_unfocus(mp_window window);
|
||||
|
||||
MP_API void mp_window_send_to_back(mp_window window);
|
||||
MP_API void mp_window_bring_to_front(mp_window window);
|
||||
|
||||
MP_API mp_rect mp_window_get_content_rect(mp_window window);
|
||||
MP_API mp_rect mp_window_get_frame_rect(mp_window window);
|
||||
MP_API void mp_window_set_content_rect(mp_window window, mp_rect contentRect);
|
||||
MP_API void mp_window_set_frame_rect(mp_window window, mp_rect frameRect);
|
||||
|
||||
MP_API void mp_window_center(mp_window window);
|
||||
|
||||
MP_API mp_rect mp_window_content_rect_for_frame_rect(mp_rect frameRect, mp_window_style style);
|
||||
MP_API mp_rect mp_window_frame_rect_for_content_rect(mp_rect contentRect, mp_window_style style);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Input state polling
|
||||
//--------------------------------------------------------------------
|
||||
MP_API bool mp_input_key_down(mp_key_code key);
|
||||
MP_API bool mp_input_key_pressed(mp_key_code key);
|
||||
MP_API bool mp_input_key_released(mp_key_code key);
|
||||
MP_API mp_key_mods mp_input_key_mods(void);
|
||||
|
||||
MP_API str8 mp_key_to_label(mp_key_code key);
|
||||
MP_API mp_key_code mp_label_to_key(str8 label);
|
||||
|
||||
MP_API bool mp_input_mouse_down(mp_mouse_button button);
|
||||
MP_API bool mp_input_mouse_pressed(mp_mouse_button button);
|
||||
MP_API bool mp_input_mouse_released(mp_mouse_button button);
|
||||
MP_API bool mp_input_mouse_clicked(mp_mouse_button button);
|
||||
MP_API bool mp_input_mouse_double_clicked(mp_mouse_button button);
|
||||
|
||||
MP_API vec2 mp_input_mouse_position(void);
|
||||
MP_API vec2 mp_input_mouse_delta(void);
|
||||
MP_API vec2 mp_input_mouse_wheel(void);
|
||||
|
||||
MP_API str32 mp_input_text_utf32(mem_arena* arena);
|
||||
MP_API str8 mp_input_text_utf8(mem_arena* arena);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Clipboard
|
||||
//--------------------------------------------------------------------
|
||||
MP_API void mp_clipboard_clear(void);
|
||||
|
||||
MP_API void mp_clipboard_set_string(str8 string);
|
||||
MP_API str8 mp_clipboard_get_string(mem_arena* arena);
|
||||
MP_API str8 mp_clipboard_copy_string(str8 backing);
|
||||
|
||||
MP_API bool mp_clipboard_has_tag(const char* tag);
|
||||
MP_API void mp_clipboard_set_data_for_tag(const char* tag, str8 data);
|
||||
MP_API str8 mp_clipboard_get_data_for_tag(mem_arena* arena, const char* tag);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// native open/save/alert windows
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
MP_API str8 mp_open_dialog(mem_arena* arena,
|
||||
const char* title,
|
||||
const char* defaultPath,
|
||||
int filterCount,
|
||||
const char** filters,
|
||||
bool directory);
|
||||
|
||||
MP_API str8 mp_save_dialog(mem_arena* arena,
|
||||
const char* title,
|
||||
const char* defaultPath,
|
||||
int filterCount,
|
||||
const char** filters);
|
||||
|
||||
MP_API int mp_alert_popup(const char* title,
|
||||
const char* message,
|
||||
u32 count,
|
||||
const char** options);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// file system stuff... //TODO: move elsewhere
|
||||
//--------------------------------------------------------------------
|
||||
MP_API int mp_file_move(str8 from, str8 to);
|
||||
MP_API int mp_file_remove(str8 path);
|
||||
|
||||
MP_API int mp_directory_create(str8 path);
|
||||
|
||||
MP_API str8 mp_app_get_resource_path(mem_arena* arena, const char* name);
|
||||
MP_API str8 mp_app_get_executable_path(mem_arena* arena);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__PLATFORM_APP_H_
|
||||
|
|
|
@ -1,85 +1,93 @@
|
|||
//*****************************************************************
|
||||
//
|
||||
// $file: platform.h $
|
||||
// $author: Martin Fouilleul $
|
||||
// $date: 22/12/2022 $
|
||||
// $revision: $
|
||||
// $note: (C) 2022 by Martin Fouilleul - all rights reserved $
|
||||
//
|
||||
//*****************************************************************
|
||||
#ifndef __PLATFORM_H_
|
||||
#define __PLATFORM_H_
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Compiler identification
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(__clang__)
|
||||
#define COMPILER_CLANG 1
|
||||
#if defined(__apple_build_version__)
|
||||
#define COMPILER_CLANG_APPLE 1
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_CLANG_CL 1
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_CL 1
|
||||
#elif defined(__GNUC__)
|
||||
#define COMPILER_GCC 1
|
||||
#else
|
||||
#error "Can't identify compiler"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// OS identification
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(_WIN64)
|
||||
#define OS_WIN64 1
|
||||
#elif defined(_WIN32)
|
||||
#error "Unsupported OS (32bit only version of Windows)"
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#define OS_MACOS 1
|
||||
#elif defined(__gnu_linux__)
|
||||
#define OS_LINUX 1
|
||||
#else
|
||||
#error "Can't identify OS"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Architecture identification
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(COMPILER_CL)
|
||||
#if defined(_M_AMD64)
|
||||
#define ARCH_X64 1
|
||||
#elif defined(_M_I86)
|
||||
#define ARCH_X86 1
|
||||
#elif defined(_M_ARM64)
|
||||
#define ARCH_ARM64 1
|
||||
#elif defined(_M_ARM)
|
||||
#define ARCH_ARM32 1
|
||||
#else
|
||||
#error "Can't identify architecture"
|
||||
#endif
|
||||
#else
|
||||
#if defined(__x86_64__)
|
||||
#define ARCH_X64 1
|
||||
#elif defined(__i386__)
|
||||
#define ARCH_X86 1
|
||||
#elif defined(__arm__)
|
||||
#define ARCH_ARM32 1
|
||||
#elif defined(__aarch64__)
|
||||
#define ARCH_ARM64 1
|
||||
#else
|
||||
#error "Can't identify architecture"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// platform helper macros
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(COMPILER_CL)
|
||||
#define mp_thread_local __declspec(thread)
|
||||
#elif defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
||||
#define mp_thread_local __thread
|
||||
#endif
|
||||
|
||||
#endif // __PLATFORM_H_
|
||||
//*****************************************************************
|
||||
//
|
||||
// $file: platform.h $
|
||||
// $author: Martin Fouilleul $
|
||||
// $date: 22/12/2022 $
|
||||
// $revision: $
|
||||
// $note: (C) 2022 by Martin Fouilleul - all rights reserved $
|
||||
//
|
||||
//*****************************************************************
|
||||
#ifndef __PLATFORM_H_
|
||||
#define __PLATFORM_H_
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Compiler identification
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(__clang__)
|
||||
#define COMPILER_CLANG 1
|
||||
#if defined(__apple_build_version__)
|
||||
#define COMPILER_CLANG_APPLE 1
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_CLANG_CL 1
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_CL 1
|
||||
#elif defined(__GNUC__)
|
||||
#define COMPILER_GCC 1
|
||||
#else
|
||||
#error "Can't identify compiler"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// OS identification
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(_WIN64)
|
||||
#define OS_WIN64 1
|
||||
#elif defined(_WIN32)
|
||||
#error "Unsupported OS (32bit only version of Windows)"
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#define OS_MACOS 1
|
||||
#elif defined(__gnu_linux__)
|
||||
#define OS_LINUX 1
|
||||
#else
|
||||
#error "Can't identify OS"
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Architecture identification
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(COMPILER_CL)
|
||||
#if defined(_M_AMD64)
|
||||
#define ARCH_X64 1
|
||||
#elif defined(_M_I86)
|
||||
#define ARCH_X86 1
|
||||
#elif defined(_M_ARM64)
|
||||
#define ARCH_ARM64 1
|
||||
#elif defined(_M_ARM)
|
||||
#define ARCH_ARM32 1
|
||||
#else
|
||||
#error "Can't identify architecture"
|
||||
#endif
|
||||
#else
|
||||
#if defined(__x86_64__)
|
||||
#define ARCH_X64 1
|
||||
#elif defined(__i386__)
|
||||
#define ARCH_X86 1
|
||||
#elif defined(__arm__)
|
||||
#define ARCH_ARM32 1
|
||||
#elif defined(__aarch64__)
|
||||
#define ARCH_ARM64 1
|
||||
#else
|
||||
#error "Can't identify architecture"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// platform helper macros
|
||||
//-----------------------------------------------------------------
|
||||
#if defined(COMPILER_CL)
|
||||
#if defined(MP_BUILD_DLL)
|
||||
#define MP_API __declspec(dllexport)
|
||||
#else
|
||||
#define MP_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#define mp_thread_local __declspec(thread)
|
||||
|
||||
#elif defined(COMPILER_GCC) || defined(COMPILER_CLANG)
|
||||
#define MP_API
|
||||
#define mp_thread_local __thread
|
||||
#endif
|
||||
|
||||
#endif // __PLATFORM_H_
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: platform_clock.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 07/03/2019
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __PLATFORM_CLOCK_H_
|
||||
#define __PLATFORM_CLOCK_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef enum {
|
||||
MP_CLOCK_MONOTONIC, // clock that increment monotonically
|
||||
MP_CLOCK_UPTIME, // clock that increment monotonically during uptime
|
||||
MP_CLOCK_DATE // clock that is driven by the platform time
|
||||
} mp_clock_kind;
|
||||
|
||||
void mp_clock_init(); // initialize the clock subsystem
|
||||
u64 mp_get_timestamp(mp_clock_kind clock);
|
||||
f64 mp_get_time(mp_clock_kind clock);
|
||||
void mp_sleep_nanoseconds(u64 nanoseconds); // sleep for a given number of nanoseconds
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#endif //__PLATFORM_CLOCK_H_
|
||||
/************************************************************//**
|
||||
*
|
||||
* @file: platform_clock.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 07/03/2019
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __PLATFORM_CLOCK_H_
|
||||
#define __PLATFORM_CLOCK_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef enum {
|
||||
MP_CLOCK_MONOTONIC, // clock that increment monotonically
|
||||
MP_CLOCK_UPTIME, // clock that increment monotonically during uptime
|
||||
MP_CLOCK_DATE // clock that is driven by the platform time
|
||||
} mp_clock_kind;
|
||||
|
||||
MP_API void mp_clock_init(); // initialize the clock subsystem
|
||||
MP_API u64 mp_get_timestamp(mp_clock_kind clock);
|
||||
MP_API f64 mp_get_time(mp_clock_kind clock);
|
||||
MP_API void mp_sleep_nanoseconds(u64 nanoseconds); // sleep for a given number of nanoseconds
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#endif //__PLATFORM_CLOCK_H_
|
||||
|
|
|
@ -1,97 +1,98 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: debug_log.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 05/04/2019
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __DEBUG_LOG_H_
|
||||
#define __DEBUG_LOG_H_
|
||||
|
||||
#include<stdio.h>
|
||||
#include"typedefs.h"
|
||||
#include"macro_helpers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
//NOTE(martin): the default logging level can be adjusted by defining LOG_DEFAULT_LEVEL. As the name suggest, it is the default, but it
|
||||
// can be adjusted at runtime with LogLevel()
|
||||
#ifndef LOG_DEFAULT_LEVEL
|
||||
#define LOG_DEFAULT_LEVEL LOG_LEVEL_WARNING
|
||||
#endif
|
||||
|
||||
//NOTE(martin): the default output can be adjusted by defining LOG_DEFAULT_OUTPUT. It can be adjusted at runtime with LogOutput()
|
||||
#ifndef LOG_DEFAULT_OUTPUT
|
||||
#define LOG_DEFAULT_OUTPUT stdout
|
||||
#endif
|
||||
|
||||
//NOTE(martin): LOG_SUBSYSTEM can be defined in each compilation unit to associate it with a subsystem, like this:
|
||||
// #define LOG_SUBSYSTEM "name"
|
||||
|
||||
typedef enum { LOG_LEVEL_ERROR,
|
||||
LOG_LEVEL_WARNING,
|
||||
LOG_LEVEL_MESSAGE,
|
||||
LOG_LEVEL_DEBUG,
|
||||
LOG_LEVEL_COUNT } log_level;
|
||||
|
||||
void LogGeneric(log_level level,
|
||||
const char* subsystem,
|
||||
const char* functionName,
|
||||
const char* fileName,
|
||||
u32 line,
|
||||
const char* msg,
|
||||
...);
|
||||
|
||||
void LogOutput(FILE* output);
|
||||
void LogLevel(log_level level);
|
||||
void LogFilter(const char* subsystem, log_level level);
|
||||
|
||||
#define LOG_GENERIC(level, func, file, line, msg, ...) LogGeneric(level, LOG_SUBSYSTEM, func, file, line, msg, ##__VA_ARGS__ )
|
||||
|
||||
#define LOG_ERROR(msg, ...) LOG_GENERIC(LOG_LEVEL_ERROR, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
|
||||
//NOTE(martin): warnings, messages, and debug info can be enabled in debug mode by defining LOG_COMPILE_XXX, XXX being the max desired log level
|
||||
// error logging is always compiled
|
||||
#if defined(LOG_COMPILE_WARNING) || defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG)
|
||||
#define LOG_WARNING(msg, ...) LOG_GENERIC(LOG_LEVEL_WARNING, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
|
||||
#if defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG)
|
||||
#define LOG_MESSAGE(msg, ...) LOG_GENERIC(LOG_LEVEL_MESSAGE, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
|
||||
#if defined(LOG_COMPILE_DEBUG)
|
||||
#define LOG_DEBUG(msg, ...) LOG_GENERIC(LOG_LEVEL_DEBUG, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
#else
|
||||
#define LOG_DEBUG(msg, ...)
|
||||
#endif
|
||||
#else
|
||||
#define LOG_MESSAGE(msg, ...)
|
||||
#define LOG_DEBUG(msg, ...)
|
||||
#endif
|
||||
#else
|
||||
#define LOG_WARNING(msg, ...)
|
||||
#define LOG_MESSAGE(msg, ...)
|
||||
#define LOG_DEBUG(msg, ...)
|
||||
#endif
|
||||
|
||||
#ifndef NO_ASSERT
|
||||
#include<assert.h>
|
||||
#define _ASSERT_(x, msg) assert(x && msg)
|
||||
#define ASSERT(x, ...) _ASSERT_(x, #__VA_ARGS__)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_ASSERT(x, ...) ASSERT(x, ##__VA_ARGS__ )
|
||||
#else
|
||||
#define DEBUG_ASSERT(x, ...)
|
||||
#endif
|
||||
#else
|
||||
#define ASSERT(x, ...)
|
||||
#define DEBUG_ASSERT(x, ...)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__DEBUG_LOG_H_
|
||||
/************************************************************//**
|
||||
*
|
||||
* @file: debug_log.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 05/04/2019
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __DEBUG_LOG_H_
|
||||
#define __DEBUG_LOG_H_
|
||||
|
||||
#include<stdio.h>
|
||||
#include"platform.h"
|
||||
#include"typedefs.h"
|
||||
#include"macro_helpers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
//NOTE(martin): the default logging level can be adjusted by defining LOG_DEFAULT_LEVEL. As the name suggest, it is the default, but it
|
||||
// can be adjusted at runtime with LogLevel()
|
||||
#ifndef LOG_DEFAULT_LEVEL
|
||||
#define LOG_DEFAULT_LEVEL LOG_LEVEL_WARNING
|
||||
#endif
|
||||
|
||||
//NOTE(martin): the default output can be adjusted by defining LOG_DEFAULT_OUTPUT. It can be adjusted at runtime with LogOutput()
|
||||
#ifndef LOG_DEFAULT_OUTPUT
|
||||
#define LOG_DEFAULT_OUTPUT stdout
|
||||
#endif
|
||||
|
||||
//NOTE(martin): LOG_SUBSYSTEM can be defined in each compilation unit to associate it with a subsystem, like this:
|
||||
// #define LOG_SUBSYSTEM "name"
|
||||
|
||||
typedef enum { LOG_LEVEL_ERROR,
|
||||
LOG_LEVEL_WARNING,
|
||||
LOG_LEVEL_MESSAGE,
|
||||
LOG_LEVEL_DEBUG,
|
||||
LOG_LEVEL_COUNT } log_level;
|
||||
|
||||
MP_API void LogGeneric(log_level level,
|
||||
const char* subsystem,
|
||||
const char* functionName,
|
||||
const char* fileName,
|
||||
u32 line,
|
||||
const char* msg,
|
||||
...);
|
||||
|
||||
MP_API void LogOutput(FILE* output);
|
||||
MP_API void LogLevel(log_level level);
|
||||
MP_API void LogFilter(const char* subsystem, log_level level);
|
||||
|
||||
#define LOG_GENERIC(level, func, file, line, msg, ...) LogGeneric(level, LOG_SUBSYSTEM, func, file, line, msg, ##__VA_ARGS__ )
|
||||
|
||||
#define LOG_ERROR(msg, ...) LOG_GENERIC(LOG_LEVEL_ERROR, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
|
||||
//NOTE(martin): warnings, messages, and debug info can be enabled in debug mode by defining LOG_COMPILE_XXX, XXX being the max desired log level
|
||||
// error logging is always compiled
|
||||
#if defined(LOG_COMPILE_WARNING) || defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG)
|
||||
#define LOG_WARNING(msg, ...) LOG_GENERIC(LOG_LEVEL_WARNING, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
|
||||
#if defined(LOG_COMPILE_MESSAGE) || defined(LOG_COMPILE_DEBUG)
|
||||
#define LOG_MESSAGE(msg, ...) LOG_GENERIC(LOG_LEVEL_MESSAGE, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
|
||||
#if defined(LOG_COMPILE_DEBUG)
|
||||
#define LOG_DEBUG(msg, ...) LOG_GENERIC(LOG_LEVEL_DEBUG, __FUNCTION__, __FILE__, __LINE__, msg, ##__VA_ARGS__ )
|
||||
#else
|
||||
#define LOG_DEBUG(msg, ...)
|
||||
#endif
|
||||
#else
|
||||
#define LOG_MESSAGE(msg, ...)
|
||||
#define LOG_DEBUG(msg, ...)
|
||||
#endif
|
||||
#else
|
||||
#define LOG_WARNING(msg, ...)
|
||||
#define LOG_MESSAGE(msg, ...)
|
||||
#define LOG_DEBUG(msg, ...)
|
||||
#endif
|
||||
|
||||
#ifndef NO_ASSERT
|
||||
#include<assert.h>
|
||||
#define _ASSERT_(x, msg) assert(x && msg)
|
||||
#define ASSERT(x, ...) _ASSERT_(x, #__VA_ARGS__)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_ASSERT(x, ...) ASSERT(x, ##__VA_ARGS__ )
|
||||
#else
|
||||
#define DEBUG_ASSERT(x, ...)
|
||||
#endif
|
||||
#else
|
||||
#define ASSERT(x, ...)
|
||||
#define DEBUG_ASSERT(x, ...)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__DEBUG_LOG_H_
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: hash.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 08/08/2022
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __HASH_H_
|
||||
#define __HASH_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"strings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
u64 mp_hash_aes_u64(u64 x);
|
||||
u64 mp_hash_aes_u64_x2(u64 x, u64 y);
|
||||
u64 mp_hash_aes_string(str8 string);
|
||||
u64 mp_hash_aes_string_seed(str8 string, u64 seed);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
#endif //__HASH_H_
|
||||
/************************************************************//**
|
||||
*
|
||||
* @file: hash.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 08/08/2022
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __HASH_H_
|
||||
#define __HASH_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"strings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MP_API u64 mp_hash_aes_u64(u64 x);
|
||||
MP_API u64 mp_hash_aes_u64_x2(u64 x, u64 y);
|
||||
MP_API u64 mp_hash_aes_string(str8 string);
|
||||
MP_API u64 mp_hash_aes_string_seed(str8 string, u64 seed);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
#endif //__HASH_H_
|
||||
|
|
|
@ -1,106 +1,106 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: memory.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 24/10/2019
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __MEMORY_H_
|
||||
#define __MEMORY_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"lists.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): base allocator
|
||||
//--------------------------------------------------------------------------------
|
||||
typedef void*(*mem_reserve_function)(void* context, u64 size);
|
||||
typedef void(*mem_modify_function)(void* context, void* ptr, u64 size);
|
||||
|
||||
typedef struct mem_base_allocator
|
||||
{
|
||||
mem_reserve_function reserve;
|
||||
mem_modify_function commit;
|
||||
mem_modify_function decommit;
|
||||
mem_modify_function release;
|
||||
void* context;
|
||||
|
||||
} mem_base_allocator;
|
||||
|
||||
mem_base_allocator* mem_base_allocator_default();
|
||||
|
||||
#define mem_base_reserve(base, size) base->reserve(base->context, size)
|
||||
#define mem_base_commit(base, ptr, size) base->commit(base->context, ptr, size)
|
||||
#define mem_base_decommit(base, ptr, size) base->decommit(base->context, ptr, size)
|
||||
#define mem_base_release(base, ptr, size) base->release(base->context, ptr, size)
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): memory arena
|
||||
//--------------------------------------------------------------------------------
|
||||
typedef struct mem_arena
|
||||
{
|
||||
mem_base_allocator* base;
|
||||
char* ptr;
|
||||
u64 offset;
|
||||
u64 committed;
|
||||
u64 cap;
|
||||
} mem_arena;
|
||||
|
||||
typedef struct mem_arena_options
|
||||
{
|
||||
mem_base_allocator* base;
|
||||
u64 reserve;
|
||||
} mem_arena_options;
|
||||
|
||||
void mem_arena_init(mem_arena* arena);
|
||||
void mem_arena_init_with_options(mem_arena* arena, mem_arena_options* options);
|
||||
void mem_arena_release(mem_arena* arena);
|
||||
|
||||
void* mem_arena_alloc(mem_arena* arena, u64 size);
|
||||
void mem_arena_clear(mem_arena* arena);
|
||||
|
||||
#define mem_arena_alloc_type(arena, type) ((type*)mem_arena_alloc(arena, sizeof(type)))
|
||||
#define mem_arena_alloc_array(arena, type, count) ((type*)mem_arena_alloc(arena, sizeof(type)*(count)))
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): memory pool
|
||||
//--------------------------------------------------------------------------------
|
||||
typedef struct mem_pool
|
||||
{
|
||||
mem_arena arena;
|
||||
list_info freeList;
|
||||
u64 blockSize;
|
||||
} mem_pool;
|
||||
|
||||
typedef struct mem_pool_options
|
||||
{
|
||||
mem_base_allocator* base;
|
||||
u64 reserve;
|
||||
} mem_pool_options;
|
||||
|
||||
void mem_pool_init(mem_pool* pool, u64 blockSize);
|
||||
void mem_pool_init_with_options(mem_pool* pool, u64 blockSize, mem_pool_options* options);
|
||||
void mem_pool_release(mem_pool* pool);
|
||||
|
||||
void* mem_pool_alloc(mem_pool* pool);
|
||||
void mem_pool_recycle(mem_pool* pool, void* ptr);
|
||||
void mem_pool_clear(mem_pool* pool);
|
||||
|
||||
#define mem_pool_alloc_type(arena, type) ((type*)mem_pool_alloc(arena))
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): per-thread implicit scratch arena
|
||||
//--------------------------------------------------------------------------------
|
||||
void mem_scratch_clear();
|
||||
mem_arena* mem_scratch();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__MEMORY_H_
|
||||
/************************************************************//**
|
||||
*
|
||||
* @file: memory.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 24/10/2019
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __MEMORY_H_
|
||||
#define __MEMORY_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"lists.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): base allocator
|
||||
//--------------------------------------------------------------------------------
|
||||
typedef void*(*mem_reserve_function)(void* context, u64 size);
|
||||
typedef void(*mem_modify_function)(void* context, void* ptr, u64 size);
|
||||
|
||||
typedef struct mem_base_allocator
|
||||
{
|
||||
mem_reserve_function reserve;
|
||||
mem_modify_function commit;
|
||||
mem_modify_function decommit;
|
||||
mem_modify_function release;
|
||||
void* context;
|
||||
|
||||
} mem_base_allocator;
|
||||
|
||||
MP_API mem_base_allocator* mem_base_allocator_default();
|
||||
|
||||
#define mem_base_reserve(base, size) base->reserve(base->context, size)
|
||||
#define mem_base_commit(base, ptr, size) base->commit(base->context, ptr, size)
|
||||
#define mem_base_decommit(base, ptr, size) base->decommit(base->context, ptr, size)
|
||||
#define mem_base_release(base, ptr, size) base->release(base->context, ptr, size)
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): memory arena
|
||||
//--------------------------------------------------------------------------------
|
||||
typedef struct mem_arena
|
||||
{
|
||||
mem_base_allocator* base;
|
||||
char* ptr;
|
||||
u64 offset;
|
||||
u64 committed;
|
||||
u64 cap;
|
||||
} mem_arena;
|
||||
|
||||
typedef struct mem_arena_options
|
||||
{
|
||||
mem_base_allocator* base;
|
||||
u64 reserve;
|
||||
} mem_arena_options;
|
||||
|
||||
MP_API void mem_arena_init(mem_arena* arena);
|
||||
MP_API void mem_arena_init_with_options(mem_arena* arena, mem_arena_options* options);
|
||||
MP_API void mem_arena_release(mem_arena* arena);
|
||||
|
||||
MP_API void* mem_arena_alloc(mem_arena* arena, u64 size);
|
||||
MP_API void mem_arena_clear(mem_arena* arena);
|
||||
|
||||
#define mem_arena_alloc_type(arena, type) ((type*)mem_arena_alloc(arena, sizeof(type)))
|
||||
#define mem_arena_alloc_array(arena, type, count) ((type*)mem_arena_alloc(arena, sizeof(type)*(count)))
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): memory pool
|
||||
//--------------------------------------------------------------------------------
|
||||
typedef struct mem_pool
|
||||
{
|
||||
mem_arena arena;
|
||||
list_info freeList;
|
||||
u64 blockSize;
|
||||
} mem_pool;
|
||||
|
||||
typedef struct mem_pool_options
|
||||
{
|
||||
mem_base_allocator* base;
|
||||
u64 reserve;
|
||||
} mem_pool_options;
|
||||
|
||||
MP_API void mem_pool_init(mem_pool* pool, u64 blockSize);
|
||||
MP_API void mem_pool_init_with_options(mem_pool* pool, u64 blockSize, mem_pool_options* options);
|
||||
MP_API void mem_pool_release(mem_pool* pool);
|
||||
|
||||
MP_API void* mem_pool_alloc(mem_pool* pool);
|
||||
MP_API void mem_pool_recycle(mem_pool* pool, void* ptr);
|
||||
MP_API void mem_pool_clear(mem_pool* pool);
|
||||
|
||||
#define mem_pool_alloc_type(arena, type) ((type*)mem_pool_alloc(arena))
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//NOTE(martin): per-thread implicit scratch arena
|
||||
//--------------------------------------------------------------------------------
|
||||
MP_API void mem_scratch_clear();
|
||||
MP_API mem_arena* mem_scratch();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__MEMORY_H_
|
||||
|
|
|
@ -1,113 +1,113 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: strings.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 29/05/2021
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __STRINGS_H_
|
||||
#define __STRINGS_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"lists.h"
|
||||
#include"memory.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// string slices as values
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct str8
|
||||
{
|
||||
u64 len;
|
||||
char* ptr;
|
||||
} str8;
|
||||
|
||||
#define str8_lit(s) ((str8){.len = sizeof(s)-1, .ptr = (char*)(s)})
|
||||
#define str8_unbox(s) (int)((s).len), ((s).ptr)
|
||||
|
||||
str8 str8_from_buffer(u64 len, char* buffer);
|
||||
str8 str8_from_cstring(char* str);
|
||||
str8 str8_slice(str8 s, u64 start, u64 end);
|
||||
|
||||
str8 str8_push_buffer(mem_arena* arena, u64 len, char* buffer);
|
||||
str8 str8_push_cstring(mem_arena* arena, const char* str);
|
||||
str8 str8_push_copy(mem_arena* arena, str8 s);
|
||||
str8 str8_push_slice(mem_arena* arena, str8 s, u64 start, u64 end);
|
||||
|
||||
str8 str8_pushfv(mem_arena* arena, const char* format, va_list args);
|
||||
str8 str8_pushf(mem_arena* arena, const char* format, ...);
|
||||
|
||||
int str8_cmp(str8 s1, str8 s2);
|
||||
|
||||
char* str8_to_cstring(mem_arena* arena, str8 string);
|
||||
//----------------------------------------------------------------------------------
|
||||
// string lists
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct str8_elt
|
||||
{
|
||||
list_elt listElt;
|
||||
str8 string;
|
||||
} str8_elt;
|
||||
|
||||
typedef struct str8_list
|
||||
{
|
||||
list_info list;
|
||||
u64 eltCount;
|
||||
u64 len;
|
||||
} str8_list;
|
||||
|
||||
void str8_list_push(mem_arena* arena, str8_list* list, str8 str);
|
||||
void str8_list_pushf(mem_arena* arena, str8_list* list, const char* format, ...);
|
||||
|
||||
str8 str8_list_join(mem_arena* arena, str8_list list);
|
||||
str8_list str8_split(mem_arena* arena, str8 str, str8_list separators);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// u32 strings
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct str32
|
||||
{
|
||||
u64 len;
|
||||
u32* ptr;
|
||||
} str32;
|
||||
|
||||
str32 str32_from_buffer(u64 len, u32* buffer);
|
||||
str32 str32_slice(str32 s, u64 start, u64 end);
|
||||
|
||||
str32 str32_push_buffer(mem_arena* arena, u64 len, u32* buffer);
|
||||
str32 str32_push_copy(mem_arena* arena, str32 s);
|
||||
str32 str32_push_slice(mem_arena* arena, str32 s, u64 start, u64 end);
|
||||
|
||||
typedef struct str32_elt
|
||||
{
|
||||
list_elt listElt;
|
||||
str32 string;
|
||||
} str32_elt;
|
||||
|
||||
typedef struct str32_list
|
||||
{
|
||||
list_info list;
|
||||
u64 eltCount;
|
||||
u64 len;
|
||||
} str32_list;
|
||||
|
||||
void str32_list_push(mem_arena* arena, str32_list* list, str32 str);
|
||||
str32 str32_list_join(mem_arena* arena, str32_list list);
|
||||
str32_list str32_split(mem_arena* arena, str32 str, str32_list separators);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Paths helpers
|
||||
//----------------------------------------------------------------------------------
|
||||
str8 mp_path_directory(str8 fullPath);
|
||||
str8 mp_path_base_name(str8 fullPath);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
#endif //__STRINGS_H_
|
||||
/************************************************************//**
|
||||
*
|
||||
* @file: strings.h
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 29/05/2021
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
#ifndef __STRINGS_H_
|
||||
#define __STRINGS_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"lists.h"
|
||||
#include"memory.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// string slices as values
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct str8
|
||||
{
|
||||
u64 len;
|
||||
char* ptr;
|
||||
} str8;
|
||||
|
||||
#define str8_lit(s) ((str8){.len = sizeof(s)-1, .ptr = (char*)(s)})
|
||||
#define str8_unbox(s) (int)((s).len), ((s).ptr)
|
||||
|
||||
MP_API str8 str8_from_buffer(u64 len, char* buffer);
|
||||
MP_API str8 str8_from_cstring(char* str);
|
||||
MP_API str8 str8_slice(str8 s, u64 start, u64 end);
|
||||
|
||||
MP_API str8 str8_push_buffer(mem_arena* arena, u64 len, char* buffer);
|
||||
MP_API str8 str8_push_cstring(mem_arena* arena, const char* str);
|
||||
MP_API str8 str8_push_copy(mem_arena* arena, str8 s);
|
||||
MP_API str8 str8_push_slice(mem_arena* arena, str8 s, u64 start, u64 end);
|
||||
|
||||
MP_API str8 str8_pushfv(mem_arena* arena, const char* format, va_list args);
|
||||
MP_API str8 str8_pushf(mem_arena* arena, const char* format, ...);
|
||||
|
||||
MP_API int str8_cmp(str8 s1, str8 s2);
|
||||
|
||||
MP_API char* str8_to_cstring(mem_arena* arena, str8 string);
|
||||
//----------------------------------------------------------------------------------
|
||||
// string lists
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct str8_elt
|
||||
{
|
||||
list_elt listElt;
|
||||
str8 string;
|
||||
} str8_elt;
|
||||
|
||||
typedef struct str8_list
|
||||
{
|
||||
list_info list;
|
||||
u64 eltCount;
|
||||
u64 len;
|
||||
} str8_list;
|
||||
|
||||
MP_API void str8_list_push(mem_arena* arena, str8_list* list, str8 str);
|
||||
MP_API void str8_list_pushf(mem_arena* arena, str8_list* list, const char* format, ...);
|
||||
|
||||
MP_API str8 str8_list_join(mem_arena* arena, str8_list list);
|
||||
MP_API str8_list str8_split(mem_arena* arena, str8 str, str8_list separators);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// u32 strings
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef struct str32
|
||||
{
|
||||
u64 len;
|
||||
u32* ptr;
|
||||
} str32;
|
||||
|
||||
MP_API str32 str32_from_buffer(u64 len, u32* buffer);
|
||||
MP_API str32 str32_slice(str32 s, u64 start, u64 end);
|
||||
|
||||
MP_API str32 str32_push_buffer(mem_arena* arena, u64 len, u32* buffer);
|
||||
MP_API str32 str32_push_copy(mem_arena* arena, str32 s);
|
||||
MP_API str32 str32_push_slice(mem_arena* arena, str32 s, u64 start, u64 end);
|
||||
|
||||
typedef struct str32_elt
|
||||
{
|
||||
list_elt listElt;
|
||||
str32 string;
|
||||
} str32_elt;
|
||||
|
||||
typedef struct str32_list
|
||||
{
|
||||
list_info list;
|
||||
u64 eltCount;
|
||||
u64 len;
|
||||
} str32_list;
|
||||
|
||||
MP_API void str32_list_push(mem_arena* arena, str32_list* list, str32 str);
|
||||
MP_API str32 str32_list_join(mem_arena* arena, str32_list list);
|
||||
MP_API str32_list str32_split(mem_arena* arena, str32 str, str32_list separators);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Paths helpers
|
||||
//----------------------------------------------------------------------------------
|
||||
MP_API str8 mp_path_directory(str8 fullPath);
|
||||
MP_API str8 mp_path_base_name(str8 fullPath);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
#endif //__STRINGS_H_
|
||||
|
|
567
src/util/utf8.c
567
src/util/utf8.c
|
@ -1,283 +1,284 @@
|
|||
//*****************************************************************
|
||||
//
|
||||
// $file: utf8.c $
|
||||
// $author: Martin Fouilleul $
|
||||
// $date: 05/11/2016 $
|
||||
// $revision: $
|
||||
// $note: (C) 2016 by Martin Fouilleul - all rights reserved $
|
||||
//
|
||||
//*****************************************************************
|
||||
#include"utf8.h"
|
||||
#include<string.h>
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// utf-8 gore
|
||||
//-----------------------------------------------------------------
|
||||
const u32 offsetsFromUTF8[6] = {
|
||||
0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
||||
|
||||
const char trailingBytesForUTF8[256] = {
|
||||
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,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,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,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,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,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
|
||||
};
|
||||
|
||||
#define utf8_is_start_byte(c) (((c)&0xc0)!=0x80)
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: getting sizes / offsets / indices
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
u32 utf8_size_from_leading_char(char leadingChar)
|
||||
{
|
||||
return(trailingBytesForUTF8[(unsigned int)(unsigned char)leadingChar] + 1);
|
||||
}
|
||||
|
||||
u32 utf8_codepoint_size(utf32 codePoint)
|
||||
{
|
||||
if(codePoint < 0x80)
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
if(codePoint < 0x800)
|
||||
{
|
||||
return(2);
|
||||
}
|
||||
if(codePoint < 0x10000)
|
||||
{
|
||||
return(3);
|
||||
}
|
||||
if(codePoint < 0x110000)
|
||||
{
|
||||
return(4);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
u64 utf8_codepoint_count_for_string(str8 string)
|
||||
{
|
||||
u64 byteOffset = 0;
|
||||
u64 codePointIndex = 0;
|
||||
for(;
|
||||
(byteOffset < string.len) && (string.ptr[byteOffset] != 0);
|
||||
codePointIndex++)
|
||||
{
|
||||
utf8_dec decode = utf8_decode_at(string, byteOffset);
|
||||
byteOffset += decode.size;
|
||||
}
|
||||
return(codePointIndex);
|
||||
}
|
||||
|
||||
u64 utf8_byte_count_for_codepoints(str32 codePoints)
|
||||
{
|
||||
//NOTE(martin): return the exact number of bytes taken by the encoded
|
||||
// version of codePoints. (ie do not attempt to provision
|
||||
// for a zero terminator).
|
||||
u64 byteCount = 0;
|
||||
for(u64 i=0; i<codePoints.len; i++)
|
||||
{
|
||||
byteCount += utf8_codepoint_size(codePoints.ptr[i]);
|
||||
}
|
||||
return(byteCount);
|
||||
}
|
||||
|
||||
u64 utf8_next_offset(str8 string, u64 byteOffset)
|
||||
{
|
||||
u64 res = 0;
|
||||
if(byteOffset >= string.len)
|
||||
{
|
||||
res = string.len;
|
||||
}
|
||||
else
|
||||
{
|
||||
u64 nextOffset = byteOffset + utf8_size_from_leading_char(string.ptr[byteOffset]);
|
||||
res = minimum(nextOffset, string.len);
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
u64 utf8_prev_offset(str8 string, u64 byteOffset)
|
||||
{
|
||||
u64 res = 0;
|
||||
if(byteOffset > string.len)
|
||||
{
|
||||
res = string.len;
|
||||
}
|
||||
else if(byteOffset)
|
||||
{
|
||||
byteOffset--;
|
||||
while(byteOffset > 0 && !utf8_is_start_byte(string.ptr[byteOffset]))
|
||||
{
|
||||
byteOffset--;
|
||||
}
|
||||
res = byteOffset;
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: encoding / decoding
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
utf8_dec utf8_decode_at(str8 string, u64 offset)
|
||||
{
|
||||
//NOTE(martin): get the first codepoint in str, and advance index to the
|
||||
// next utf8 character
|
||||
//TODO(martin): check for utf-16 surrogate pairs
|
||||
utf32 cp = 0;
|
||||
u64 sz = 0;
|
||||
|
||||
if(offset >= string.len || !string.ptr[offset])
|
||||
{
|
||||
cp = 0;
|
||||
sz = 1;
|
||||
}
|
||||
else if( !utf8_is_start_byte(string.ptr[offset]))
|
||||
{
|
||||
//NOTE(martin): unexpected continuation or invalid character.
|
||||
cp = 0xfffd;
|
||||
sz = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int expectedSize = utf8_size_from_leading_char(string.ptr[offset]);
|
||||
do
|
||||
{
|
||||
/*NOTE(martin):
|
||||
we shift 6 bits and add the next byte at each round.
|
||||
at the end we have our utf8 codepoint, added to the shifted versions
|
||||
of the utf8 leading bits for each encoded byte. These values are
|
||||
precomputed in offsetsFromUTF8.
|
||||
*/
|
||||
unsigned char b = string.ptr[offset];
|
||||
cp <<= 6;
|
||||
cp += b;
|
||||
offset += 1;
|
||||
sz++;
|
||||
|
||||
if(b == 0xc0 || b == 0xc1 || b >= 0xc5)
|
||||
{
|
||||
//NOTE(martin): invalid byte encountered
|
||||
break;
|
||||
}
|
||||
|
||||
} while( offset < string.len
|
||||
&& string.ptr[offset]
|
||||
&& !utf8_is_start_byte(string.ptr[offset])
|
||||
&& sz < expectedSize);
|
||||
|
||||
if(sz != expectedSize)
|
||||
{
|
||||
//NOTE(martin): if we encountered an error, we return the replacement codepoint U+FFFD
|
||||
cp = 0xfffd;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp -= offsetsFromUTF8[sz-1];
|
||||
|
||||
//NOTE(martin): check for invalid codepoints
|
||||
if(cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff))
|
||||
{
|
||||
cp = 0xfffd;
|
||||
}
|
||||
}
|
||||
}
|
||||
utf8_dec res = {.codepoint = cp, .size = sz};
|
||||
return(res);
|
||||
}
|
||||
|
||||
utf8_dec utf8_decode(str8 string)
|
||||
{
|
||||
return(utf8_decode_at(string, 0));
|
||||
}
|
||||
|
||||
str8 utf8_encode(char* dest, utf32 codePoint)
|
||||
{
|
||||
u64 sz = 0;
|
||||
if (codePoint < 0x80)
|
||||
{
|
||||
dest[0] = (char)codePoint;
|
||||
sz = 1;
|
||||
}
|
||||
else if (codePoint < 0x800)
|
||||
{
|
||||
dest[0] = (codePoint>>6) | 0xC0;
|
||||
dest[1] = (codePoint & 0x3F) | 0x80;
|
||||
sz = 2;
|
||||
}
|
||||
else if (codePoint < 0x10000)
|
||||
{
|
||||
dest[0] = (codePoint>>12) | 0xE0;
|
||||
dest[1] = ((codePoint>>6) & 0x3F) | 0x80;
|
||||
dest[2] = (codePoint & 0x3F) | 0x80;
|
||||
sz = 3;
|
||||
}
|
||||
else if (codePoint < 0x110000)
|
||||
{
|
||||
dest[0] = (codePoint>>18) | 0xF0;
|
||||
dest[1] = ((codePoint>>12) & 0x3F) | 0x80;
|
||||
dest[2] = ((codePoint>>6) & 0x3F) | 0x80;
|
||||
dest[3] = (codePoint & 0x3F) | 0x80;
|
||||
sz = 4;
|
||||
}
|
||||
str8 res = {.len = sz, .ptr = dest};
|
||||
return(res);
|
||||
}
|
||||
|
||||
str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string)
|
||||
{
|
||||
u64 codePointIndex = 0;
|
||||
u64 byteOffset = 0;
|
||||
for(; codePointIndex < maxCount && byteOffset < string.len; codePointIndex++)
|
||||
{
|
||||
utf8_dec decode = utf8_decode_at(string, byteOffset);
|
||||
backing[codePointIndex] = decode.codepoint;
|
||||
byteOffset += decode.size;
|
||||
}
|
||||
str32 res = {.len = codePointIndex, .ptr = backing};
|
||||
return(res);
|
||||
}
|
||||
|
||||
str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints)
|
||||
{
|
||||
u64 byteOffset = 0;
|
||||
for(u64 codePointIndex = 0; (codePointIndex < codePoints.len); codePointIndex++)
|
||||
{
|
||||
utf32 codePoint = codePoints.ptr[codePointIndex];
|
||||
u32 byteCount = utf8_codepoint_size(codePoint);
|
||||
if(byteOffset + byteCount > maxBytes)
|
||||
{
|
||||
break;
|
||||
}
|
||||
utf8_encode(backing+byteOffset, codePoint);
|
||||
byteOffset += byteCount;
|
||||
}
|
||||
str8 res = {.len = byteOffset, .ptr = backing};
|
||||
return(res);
|
||||
}
|
||||
|
||||
str32 utf8_push_to_codepoints(mem_arena* arena, str8 string)
|
||||
{
|
||||
u64 count = utf8_codepoint_count_for_string(string);
|
||||
utf32* backing = mem_arena_alloc_array(arena, utf32, count);
|
||||
str32 res = utf8_to_codepoints(count, backing, string);
|
||||
return(res);
|
||||
}
|
||||
|
||||
str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints)
|
||||
{
|
||||
u64 count = utf8_byte_count_for_codepoints(codePoints);
|
||||
char* backing = mem_arena_alloc_array(arena, char, count);
|
||||
str8 res = utf8_from_codepoints(count, backing, codePoints);
|
||||
return(res);
|
||||
}
|
||||
|
||||
#define UNICODE_RANGE(start, cnt, name) const unicode_range _cat2_(UNICODE_RANGE_, name) = { .firstCodePoint = start, .count = cnt };
|
||||
UNICODE_RANGES
|
||||
#undef UNICODE_RANGE
|
||||
//*****************************************************************
|
||||
//
|
||||
// $file: utf8.c $
|
||||
// $author: Martin Fouilleul $
|
||||
// $date: 05/11/2016 $
|
||||
// $revision: $
|
||||
// $note: (C) 2016 by Martin Fouilleul - all rights reserved $
|
||||
//
|
||||
//*****************************************************************
|
||||
#include"utf8.h"
|
||||
#include"platform.h"
|
||||
#include<string.h>
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// utf-8 gore
|
||||
//-----------------------------------------------------------------
|
||||
const u32 offsetsFromUTF8[6] = {
|
||||
0x00000000UL, 0x00003080UL, 0x000E2080UL,
|
||||
0x03C82080UL, 0xFA082080UL, 0x82082080UL };
|
||||
|
||||
const char trailingBytesForUTF8[256] = {
|
||||
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,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,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,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,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,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
|
||||
};
|
||||
|
||||
#define utf8_is_start_byte(c) (((c)&0xc0)!=0x80)
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: getting sizes / offsets / indices
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
u32 utf8_size_from_leading_char(char leadingChar)
|
||||
{
|
||||
return(trailingBytesForUTF8[(unsigned int)(unsigned char)leadingChar] + 1);
|
||||
}
|
||||
|
||||
u32 utf8_codepoint_size(utf32 codePoint)
|
||||
{
|
||||
if(codePoint < 0x80)
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
if(codePoint < 0x800)
|
||||
{
|
||||
return(2);
|
||||
}
|
||||
if(codePoint < 0x10000)
|
||||
{
|
||||
return(3);
|
||||
}
|
||||
if(codePoint < 0x110000)
|
||||
{
|
||||
return(4);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
u64 utf8_codepoint_count_for_string(str8 string)
|
||||
{
|
||||
u64 byteOffset = 0;
|
||||
u64 codePointIndex = 0;
|
||||
for(;
|
||||
(byteOffset < string.len) && (string.ptr[byteOffset] != 0);
|
||||
codePointIndex++)
|
||||
{
|
||||
utf8_dec decode = utf8_decode_at(string, byteOffset);
|
||||
byteOffset += decode.size;
|
||||
}
|
||||
return(codePointIndex);
|
||||
}
|
||||
|
||||
u64 utf8_byte_count_for_codepoints(str32 codePoints)
|
||||
{
|
||||
//NOTE(martin): return the exact number of bytes taken by the encoded
|
||||
// version of codePoints. (ie do not attempt to provision
|
||||
// for a zero terminator).
|
||||
u64 byteCount = 0;
|
||||
for(u64 i=0; i<codePoints.len; i++)
|
||||
{
|
||||
byteCount += utf8_codepoint_size(codePoints.ptr[i]);
|
||||
}
|
||||
return(byteCount);
|
||||
}
|
||||
|
||||
u64 utf8_next_offset(str8 string, u64 byteOffset)
|
||||
{
|
||||
u64 res = 0;
|
||||
if(byteOffset >= string.len)
|
||||
{
|
||||
res = string.len;
|
||||
}
|
||||
else
|
||||
{
|
||||
u64 nextOffset = byteOffset + utf8_size_from_leading_char(string.ptr[byteOffset]);
|
||||
res = minimum(nextOffset, string.len);
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
u64 utf8_prev_offset(str8 string, u64 byteOffset)
|
||||
{
|
||||
u64 res = 0;
|
||||
if(byteOffset > string.len)
|
||||
{
|
||||
res = string.len;
|
||||
}
|
||||
else if(byteOffset)
|
||||
{
|
||||
byteOffset--;
|
||||
while(byteOffset > 0 && !utf8_is_start_byte(string.ptr[byteOffset]))
|
||||
{
|
||||
byteOffset--;
|
||||
}
|
||||
res = byteOffset;
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: encoding / decoding
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
utf8_dec utf8_decode_at(str8 string, u64 offset)
|
||||
{
|
||||
//NOTE(martin): get the first codepoint in str, and advance index to the
|
||||
// next utf8 character
|
||||
//TODO(martin): check for utf-16 surrogate pairs
|
||||
utf32 cp = 0;
|
||||
u64 sz = 0;
|
||||
|
||||
if(offset >= string.len || !string.ptr[offset])
|
||||
{
|
||||
cp = 0;
|
||||
sz = 1;
|
||||
}
|
||||
else if( !utf8_is_start_byte(string.ptr[offset]))
|
||||
{
|
||||
//NOTE(martin): unexpected continuation or invalid character.
|
||||
cp = 0xfffd;
|
||||
sz = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int expectedSize = utf8_size_from_leading_char(string.ptr[offset]);
|
||||
do
|
||||
{
|
||||
/*NOTE(martin):
|
||||
we shift 6 bits and add the next byte at each round.
|
||||
at the end we have our utf8 codepoint, added to the shifted versions
|
||||
of the utf8 leading bits for each encoded byte. These values are
|
||||
precomputed in offsetsFromUTF8.
|
||||
*/
|
||||
unsigned char b = string.ptr[offset];
|
||||
cp <<= 6;
|
||||
cp += b;
|
||||
offset += 1;
|
||||
sz++;
|
||||
|
||||
if(b == 0xc0 || b == 0xc1 || b >= 0xc5)
|
||||
{
|
||||
//NOTE(martin): invalid byte encountered
|
||||
break;
|
||||
}
|
||||
|
||||
} while( offset < string.len
|
||||
&& string.ptr[offset]
|
||||
&& !utf8_is_start_byte(string.ptr[offset])
|
||||
&& sz < expectedSize);
|
||||
|
||||
if(sz != expectedSize)
|
||||
{
|
||||
//NOTE(martin): if we encountered an error, we return the replacement codepoint U+FFFD
|
||||
cp = 0xfffd;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp -= offsetsFromUTF8[sz-1];
|
||||
|
||||
//NOTE(martin): check for invalid codepoints
|
||||
if(cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff))
|
||||
{
|
||||
cp = 0xfffd;
|
||||
}
|
||||
}
|
||||
}
|
||||
utf8_dec res = {.codepoint = cp, .size = sz};
|
||||
return(res);
|
||||
}
|
||||
|
||||
utf8_dec utf8_decode(str8 string)
|
||||
{
|
||||
return(utf8_decode_at(string, 0));
|
||||
}
|
||||
|
||||
str8 utf8_encode(char* dest, utf32 codePoint)
|
||||
{
|
||||
u64 sz = 0;
|
||||
if (codePoint < 0x80)
|
||||
{
|
||||
dest[0] = (char)codePoint;
|
||||
sz = 1;
|
||||
}
|
||||
else if (codePoint < 0x800)
|
||||
{
|
||||
dest[0] = (codePoint>>6) | 0xC0;
|
||||
dest[1] = (codePoint & 0x3F) | 0x80;
|
||||
sz = 2;
|
||||
}
|
||||
else if (codePoint < 0x10000)
|
||||
{
|
||||
dest[0] = (codePoint>>12) | 0xE0;
|
||||
dest[1] = ((codePoint>>6) & 0x3F) | 0x80;
|
||||
dest[2] = (codePoint & 0x3F) | 0x80;
|
||||
sz = 3;
|
||||
}
|
||||
else if (codePoint < 0x110000)
|
||||
{
|
||||
dest[0] = (codePoint>>18) | 0xF0;
|
||||
dest[1] = ((codePoint>>12) & 0x3F) | 0x80;
|
||||
dest[2] = ((codePoint>>6) & 0x3F) | 0x80;
|
||||
dest[3] = (codePoint & 0x3F) | 0x80;
|
||||
sz = 4;
|
||||
}
|
||||
str8 res = {.len = sz, .ptr = dest};
|
||||
return(res);
|
||||
}
|
||||
|
||||
str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string)
|
||||
{
|
||||
u64 codePointIndex = 0;
|
||||
u64 byteOffset = 0;
|
||||
for(; codePointIndex < maxCount && byteOffset < string.len; codePointIndex++)
|
||||
{
|
||||
utf8_dec decode = utf8_decode_at(string, byteOffset);
|
||||
backing[codePointIndex] = decode.codepoint;
|
||||
byteOffset += decode.size;
|
||||
}
|
||||
str32 res = {.len = codePointIndex, .ptr = backing};
|
||||
return(res);
|
||||
}
|
||||
|
||||
str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints)
|
||||
{
|
||||
u64 byteOffset = 0;
|
||||
for(u64 codePointIndex = 0; (codePointIndex < codePoints.len); codePointIndex++)
|
||||
{
|
||||
utf32 codePoint = codePoints.ptr[codePointIndex];
|
||||
u32 byteCount = utf8_codepoint_size(codePoint);
|
||||
if(byteOffset + byteCount > maxBytes)
|
||||
{
|
||||
break;
|
||||
}
|
||||
utf8_encode(backing+byteOffset, codePoint);
|
||||
byteOffset += byteCount;
|
||||
}
|
||||
str8 res = {.len = byteOffset, .ptr = backing};
|
||||
return(res);
|
||||
}
|
||||
|
||||
str32 utf8_push_to_codepoints(mem_arena* arena, str8 string)
|
||||
{
|
||||
u64 count = utf8_codepoint_count_for_string(string);
|
||||
utf32* backing = mem_arena_alloc_array(arena, utf32, count);
|
||||
str32 res = utf8_to_codepoints(count, backing, string);
|
||||
return(res);
|
||||
}
|
||||
|
||||
str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints)
|
||||
{
|
||||
u64 count = utf8_byte_count_for_codepoints(codePoints);
|
||||
char* backing = mem_arena_alloc_array(arena, char, count);
|
||||
str8 res = utf8_from_codepoints(count, backing, codePoints);
|
||||
return(res);
|
||||
}
|
||||
|
||||
#define UNICODE_RANGE(start, cnt, name) MP_API extern const unicode_range _cat2_(UNICODE_RANGE_, name) = { .firstCodePoint = start, .count = cnt };
|
||||
UNICODE_RANGES
|
||||
#undef UNICODE_RANGE
|
||||
|
|
403
src/util/utf8.h
403
src/util/utf8.h
|
@ -1,202 +1,201 @@
|
|||
//*****************************************************************
|
||||
//
|
||||
// $file: utf8.h $
|
||||
// $author: Martin Fouilleul $
|
||||
// $date: 05/11/2016 $
|
||||
// $revision: $
|
||||
// $note: (C) 2016 by Martin Fouilleul - all rights reserved $
|
||||
//
|
||||
//*****************************************************************
|
||||
#ifndef __UTF8_H_
|
||||
#define __UTF8_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"macro_helpers.h"
|
||||
#include"strings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef u32 utf32;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: getting sizes / offsets / indices
|
||||
//-----------------------------------------------------------------
|
||||
u32 utf8_size_from_leading_char(char leadingChar);
|
||||
u32 utf8_codepoint_size(utf32 codePoint);
|
||||
|
||||
u64 utf8_codepoint_count_for_string(str8 string);
|
||||
u64 utf8_byte_count_for_codepoints(str32 codePoints);
|
||||
|
||||
u64 utf8_next_offset(str8 string, u64 byteOffset);
|
||||
u64 utf8_prev_offset(str8 string, u64 byteOffset);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: encoding / decoding
|
||||
//-----------------------------------------------------------------
|
||||
typedef struct utf8_dec
|
||||
{
|
||||
utf32 codepoint; //NOTE: decoded codepoint
|
||||
u32 size; //NOTE: size of corresponding utf8 sequence
|
||||
} utf8_dec;
|
||||
|
||||
utf8_dec utf8_decode(str8 string); //NOTE: decode a single utf8 sequence at start of string
|
||||
utf8_dec utf8_decode_at(str8 string, u64 offset); //NOTE: decode a single utf8 sequence starting at byte offset
|
||||
str8 utf8_encode(char* dst, utf32 codePoint); //NOTE: encode codepoint into backing buffer dst
|
||||
|
||||
str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string);
|
||||
str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints);
|
||||
|
||||
str32 utf8_push_to_codepoints(mem_arena* arena, str8 string);
|
||||
str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// utf8 range struct and X-macros for defining utf8 ranges
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
typedef struct unicode_range
|
||||
{
|
||||
utf32 firstCodePoint;
|
||||
u32 count;
|
||||
} unicode_range;
|
||||
|
||||
//NOTE(martin): range declared here are defined in utf8.cpp
|
||||
// they can be used by prefixing them with UTF8_RANGE_, as in 'UTF8_RANGE_BASIC_LATIN'
|
||||
#define UNICODE_RANGES \
|
||||
UNICODE_RANGE(0x0000, 127, BASIC_LATIN) \
|
||||
UNICODE_RANGE(0x0080, 127, C1_CONTROLS_AND_LATIN_1_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0x0100, 127, LATIN_EXTENDED_A) \
|
||||
UNICODE_RANGE(0x0180, 207, LATIN_EXTENDED_B) \
|
||||
UNICODE_RANGE(0x0250, 95, IPA_EXTENSIONS) \
|
||||
UNICODE_RANGE(0x02b0, 79, SPACING_MODIFIER_LETTERS) \
|
||||
UNICODE_RANGE(0x0300, 111, COMBINING_DIACRITICAL_MARKS) \
|
||||
UNICODE_RANGE(0x0370, 143, GREEK_COPTIC) \
|
||||
UNICODE_RANGE(0x0400, 255, CYRILLIC) \
|
||||
UNICODE_RANGE(0x0500, 47, CYRILLIC_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0x0530, 95, ARMENIAN) \
|
||||
UNICODE_RANGE(0x0590, 111, HEBREW) \
|
||||
UNICODE_RANGE(0x0600, 255, ARABIC) \
|
||||
UNICODE_RANGE(0x0700, 79, SYRIAC) \
|
||||
UNICODE_RANGE(0x0780, 63, THAANA) \
|
||||
UNICODE_RANGE(0x0900, 127, DEVANAGARI) \
|
||||
UNICODE_RANGE(0x0980, 127, BENGALI_ASSAMESE) \
|
||||
UNICODE_RANGE(0x0a00, 127, GURMUKHI) \
|
||||
UNICODE_RANGE(0x0a80, 127, GUJARATI) \
|
||||
UNICODE_RANGE(0x0b00, 127, ORIYA) \
|
||||
UNICODE_RANGE(0x0b80, 127, TAMIL) \
|
||||
UNICODE_RANGE(0x0c00, 127, TELUGU) \
|
||||
UNICODE_RANGE(0x0c80, 127, KANNADA) \
|
||||
UNICODE_RANGE(0x0d00, 255, MALAYALAM) \
|
||||
UNICODE_RANGE(0x0d80, 127, SINHALA) \
|
||||
UNICODE_RANGE(0x0e00, 127, THAI) \
|
||||
UNICODE_RANGE(0x0e80, 127, LAO) \
|
||||
UNICODE_RANGE(0x0f00, 255, TIBETAN) \
|
||||
UNICODE_RANGE(0x1000, 159, MYANMAR) \
|
||||
UNICODE_RANGE(0x10a0, 95, GEORGIAN) \
|
||||
UNICODE_RANGE(0x1100, 255, HANGUL_JAMO) \
|
||||
UNICODE_RANGE(0x1200, 383, ETHIOPIC) \
|
||||
UNICODE_RANGE(0x13a0, 95, CHEROKEE) \
|
||||
UNICODE_RANGE(0x1400, 639, UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS) \
|
||||
UNICODE_RANGE(0x1680, 31, OGHAM) \
|
||||
UNICODE_RANGE(0x16a0, 95, RUNIC) \
|
||||
UNICODE_RANGE(0x1700, 31, TAGALOG) \
|
||||
UNICODE_RANGE(0x1720, 31, HANUNOO) \
|
||||
UNICODE_RANGE(0x1740, 31, BUHID) \
|
||||
UNICODE_RANGE(0x1760, 31, TAGBANWA) \
|
||||
UNICODE_RANGE(0x1780, 127, KHMER) \
|
||||
UNICODE_RANGE(0x1800, 175, MONGOLIAN) \
|
||||
UNICODE_RANGE(0x1900, 79, LIMBU) \
|
||||
UNICODE_RANGE(0x1950, 47, TAI_LE) \
|
||||
UNICODE_RANGE(0x19e0, 31, KHMER_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d00, 127, PHONETIC_EXTENSIONS) \
|
||||
UNICODE_RANGE(0x1e00, 255, LATIN_EXTENDED_ADDITIONAL) \
|
||||
UNICODE_RANGE(0x1f00, 255, GREEK_EXTENDED) \
|
||||
UNICODE_RANGE(0x2000, 111, GENERAL_PUNCTUATION) \
|
||||
UNICODE_RANGE(0x2070, 47, SUPERSCRIPTS_AND_SUBSCRIPTS) \
|
||||
UNICODE_RANGE(0x20a0, 47, CURRENCY_SYMBOLS) \
|
||||
UNICODE_RANGE(0x20d0, 47, COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS) \
|
||||
UNICODE_RANGE(0x2100, 79, LETTERLIKE_SYMBOLS) \
|
||||
UNICODE_RANGE(0x2150, 63, NUMBER_FORMS) \
|
||||
UNICODE_RANGE(0x2190, 111, ARROWS) \
|
||||
UNICODE_RANGE(0x2200, 255, MATHEMATICAL_OPERATORS) \
|
||||
UNICODE_RANGE(0x2300, 255, MISCELLANEOUS_TECHNICAL) \
|
||||
UNICODE_RANGE(0x2400, 63, CONTROL_PICTURES) \
|
||||
UNICODE_RANGE(0x2440, 31, OPTICAL_CHARACTER_RECOGNITION) \
|
||||
UNICODE_RANGE(0x2460, 159, ENCLOSED_ALPHANUMERICS) \
|
||||
UNICODE_RANGE(0x2500, 127, BOX_DRAWING) \
|
||||
UNICODE_RANGE(0x2580, 31, BLOCK_ELEMENTS) \
|
||||
UNICODE_RANGE(0x25a0, 95, GEOMETRIC_SHAPES) \
|
||||
UNICODE_RANGE(0x2600, 255, MISCELLANEOUS_SYMBOLS) \
|
||||
UNICODE_RANGE(0x2700, 191, DINGBATS) \
|
||||
UNICODE_RANGE(0x27c0, 47, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A) \
|
||||
UNICODE_RANGE(0x27f0, 15, SUPPLEMENTAL_ARROWS_A) \
|
||||
UNICODE_RANGE(0x2800, 255, BRAILLE_PATTERNS) \
|
||||
UNICODE_RANGE(0x2900, 127, SUPPLEMENTAL_ARROWS_B) \
|
||||
UNICODE_RANGE(0x2980, 127, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B) \
|
||||
UNICODE_RANGE(0x2a00, 255, SUPPLEMENTAL_MATHEMATICAL_OPERATORS) \
|
||||
UNICODE_RANGE(0x2b00, 255, MISCELLANEOUS_SYMBOLS_AND_ARROWS) \
|
||||
UNICODE_RANGE(0x2e80, 127, CJK_RADICALS_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0x2f00, 223, KANGXI_RADICALS) \
|
||||
UNICODE_RANGE(0x2ff0, 15, IDEOGRAPHIC_DESCRIPTION_CHARACTERS) \
|
||||
UNICODE_RANGE(0x3000, 63, CJK_SYMBOLS_AND_PUNCTUATION) \
|
||||
UNICODE_RANGE(0x3040, 95, HIRAGANA) \
|
||||
UNICODE_RANGE(0x30a0, 95, KATAKANA) \
|
||||
UNICODE_RANGE(0x3100, 47, BOPOMOFO) \
|
||||
UNICODE_RANGE(0x3130, 95, HANGUL_COMPATIBILITY_JAMO) \
|
||||
UNICODE_RANGE(0x3190, 15, KANBUN_KUNTEN) \
|
||||
UNICODE_RANGE(0x31a0, 31, BOPOMOFO_EXTENDED) \
|
||||
UNICODE_RANGE(0x31f0, 15, KATAKANA_PHONETIC_EXTENSIONS) \
|
||||
UNICODE_RANGE(0x3200, 255, ENCLOSED_CJK_LETTERS_AND_MONTHS) \
|
||||
UNICODE_RANGE(0x3300, 255, CJK_COMPATIBILITY) \
|
||||
UNICODE_RANGE(0x3400, 6591, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) \
|
||||
UNICODE_RANGE(0x4dc0, 63, YIJING_HEXAGRAM_SYMBOLS) \
|
||||
UNICODE_RANGE(0x4e00, 20911, CJK_UNIFIED_IDEOGRAPHS) \
|
||||
UNICODE_RANGE(0xa000, 1167, YI_SYLLABLES) \
|
||||
UNICODE_RANGE(0xa490, 63, YI_RADICALS) \
|
||||
UNICODE_RANGE(0xac00, 11183, HANGUL_SYLLABLES) \
|
||||
UNICODE_RANGE(0xd800, 1023, HIGH_SURROGATE_AREA) \
|
||||
UNICODE_RANGE(0xdc00, 1023, LOW_SURROGATE_AREA) \
|
||||
UNICODE_RANGE(0xe000, 6399, PRIVATE_USE_AREA) \
|
||||
UNICODE_RANGE(0xf900, 511, CJK_COMPATIBILITY_IDEOGRAPHS) \
|
||||
UNICODE_RANGE(0xfb00, 79, ALPHABETIC_PRESENTATION_FORMS) \
|
||||
UNICODE_RANGE(0xfb50, 687, ARABIC_PRESENTATION_FORMS_A) \
|
||||
UNICODE_RANGE(0xfe00, 15, VARIATION_SELECTORS) \
|
||||
UNICODE_RANGE(0xfe20, 15, COMBINING_HALF_MARKS) \
|
||||
UNICODE_RANGE(0xfe30, 31, CJK_COMPATIBILITY_FORMS) \
|
||||
UNICODE_RANGE(0xfe50, 31, SMALL_FORM_VARIANTS) \
|
||||
UNICODE_RANGE(0xfe70, 143, ARABIC_PRESENTATION_FORMS_B) \
|
||||
UNICODE_RANGE(0xff00, 239, HALFWIDTH_AND_FULLWIDTH_FORMS) \
|
||||
UNICODE_RANGE(0xfff0, 15, SPECIALS) \
|
||||
UNICODE_RANGE(0x10000, 127, LINEAR_B_SYLLABARY) \
|
||||
UNICODE_RANGE(0x10080, 127, LINEAR_B_IDEOGRAMS) \
|
||||
UNICODE_RANGE(0x10100, 63, AEGEAN_NUMBERS) \
|
||||
UNICODE_RANGE(0x10300, 47, OLD_ITALIC) \
|
||||
UNICODE_RANGE(0x10330, 31, GOTHIC) \
|
||||
UNICODE_RANGE(0x10380, 31, UGARITIC) \
|
||||
UNICODE_RANGE(0x10400, 79, DESERET) \
|
||||
UNICODE_RANGE(0x10450, 47, SHAVIAN) \
|
||||
UNICODE_RANGE(0x10480, 47, OSMANYA) \
|
||||
UNICODE_RANGE(0x10800, 63, CYPRIOT_SYLLABARY) \
|
||||
UNICODE_RANGE(0x1d000, 255, BYZANTINE_MUSICAL_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d100, 255, MUSICAL_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d300, 95, TAI_XUAN_JING_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d400, 1023, MATHEMATICAL_ALPHANUMERIC_SYMBOLS) \
|
||||
UNICODE_RANGE(0x20000, 42719, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B) \
|
||||
UNICODE_RANGE(0x2f800, 543, CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0xe0000, 127, TAGS) \
|
||||
UNICODE_RANGE(0xe0100, 239, VARIATION_SELECTORS_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0xf0000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_A) \
|
||||
UNICODE_RANGE(0x100000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_B)
|
||||
|
||||
|
||||
#define UNICODE_RANGE(start, count, name) \
|
||||
extern const unicode_range _cat2_(UNICODE_RANGE_, name);
|
||||
UNICODE_RANGES
|
||||
#undef UNICODE_RANGE
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__UTF8_H_
|
||||
//*****************************************************************
|
||||
//
|
||||
// $file: utf8.h $
|
||||
// $author: Martin Fouilleul $
|
||||
// $date: 05/11/2016 $
|
||||
// $revision: $
|
||||
// $note: (C) 2016 by Martin Fouilleul - all rights reserved $
|
||||
//
|
||||
//*****************************************************************
|
||||
#ifndef __UTF8_H_
|
||||
#define __UTF8_H_
|
||||
|
||||
#include"typedefs.h"
|
||||
#include"macro_helpers.h"
|
||||
#include"strings.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef u32 utf32;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: getting sizes / offsets / indices
|
||||
//-----------------------------------------------------------------
|
||||
MP_API u32 utf8_size_from_leading_char(char leadingChar);
|
||||
MP_API u32 utf8_codepoint_size(utf32 codePoint);
|
||||
|
||||
MP_API u64 utf8_codepoint_count_for_string(str8 string);
|
||||
MP_API u64 utf8_byte_count_for_codepoints(str32 codePoints);
|
||||
|
||||
MP_API u64 utf8_next_offset(str8 string, u64 byteOffset);
|
||||
MP_API u64 utf8_prev_offset(str8 string, u64 byteOffset);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//NOTE: encoding / decoding
|
||||
//-----------------------------------------------------------------
|
||||
typedef struct utf8_dec
|
||||
{
|
||||
utf32 codepoint; //NOTE: decoded codepoint
|
||||
u32 size; //NOTE: size of corresponding utf8 sequence
|
||||
} utf8_dec;
|
||||
|
||||
MP_API utf8_dec utf8_decode(str8 string); //NOTE: decode a single utf8 sequence at start of string
|
||||
MP_API utf8_dec utf8_decode_at(str8 string, u64 offset); //NOTE: decode a single utf8 sequence starting at byte offset
|
||||
MP_API str8 utf8_encode(char* dst, utf32 codePoint); //NOTE: encode codepoint into backing buffer dst
|
||||
|
||||
MP_API str32 utf8_to_codepoints(u64 maxCount, utf32* backing, str8 string);
|
||||
MP_API str8 utf8_from_codepoints(u64 maxBytes, char* backing, str32 codePoints);
|
||||
|
||||
MP_API str32 utf8_push_to_codepoints(mem_arena* arena, str8 string);
|
||||
MP_API str8 utf8_push_from_codepoints(mem_arena* arena, str32 codePoints);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// utf8 range struct and X-macros for defining utf8 ranges
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
typedef struct unicode_range
|
||||
{
|
||||
utf32 firstCodePoint;
|
||||
u32 count;
|
||||
} unicode_range;
|
||||
|
||||
//NOTE(martin): range declared here are defined in utf8.cpp
|
||||
// they can be used by prefixing them with UTF8_RANGE_, as in 'UTF8_RANGE_BASIC_LATIN'
|
||||
#define UNICODE_RANGES \
|
||||
UNICODE_RANGE(0x0000, 127, BASIC_LATIN) \
|
||||
UNICODE_RANGE(0x0080, 127, C1_CONTROLS_AND_LATIN_1_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0x0100, 127, LATIN_EXTENDED_A) \
|
||||
UNICODE_RANGE(0x0180, 207, LATIN_EXTENDED_B) \
|
||||
UNICODE_RANGE(0x0250, 95, IPA_EXTENSIONS) \
|
||||
UNICODE_RANGE(0x02b0, 79, SPACING_MODIFIER_LETTERS) \
|
||||
UNICODE_RANGE(0x0300, 111, COMBINING_DIACRITICAL_MARKS) \
|
||||
UNICODE_RANGE(0x0370, 143, GREEK_COPTIC) \
|
||||
UNICODE_RANGE(0x0400, 255, CYRILLIC) \
|
||||
UNICODE_RANGE(0x0500, 47, CYRILLIC_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0x0530, 95, ARMENIAN) \
|
||||
UNICODE_RANGE(0x0590, 111, HEBREW) \
|
||||
UNICODE_RANGE(0x0600, 255, ARABIC) \
|
||||
UNICODE_RANGE(0x0700, 79, SYRIAC) \
|
||||
UNICODE_RANGE(0x0780, 63, THAANA) \
|
||||
UNICODE_RANGE(0x0900, 127, DEVANAGARI) \
|
||||
UNICODE_RANGE(0x0980, 127, BENGALI_ASSAMESE) \
|
||||
UNICODE_RANGE(0x0a00, 127, GURMUKHI) \
|
||||
UNICODE_RANGE(0x0a80, 127, GUJARATI) \
|
||||
UNICODE_RANGE(0x0b00, 127, ORIYA) \
|
||||
UNICODE_RANGE(0x0b80, 127, TAMIL) \
|
||||
UNICODE_RANGE(0x0c00, 127, TELUGU) \
|
||||
UNICODE_RANGE(0x0c80, 127, KANNADA) \
|
||||
UNICODE_RANGE(0x0d00, 255, MALAYALAM) \
|
||||
UNICODE_RANGE(0x0d80, 127, SINHALA) \
|
||||
UNICODE_RANGE(0x0e00, 127, THAI) \
|
||||
UNICODE_RANGE(0x0e80, 127, LAO) \
|
||||
UNICODE_RANGE(0x0f00, 255, TIBETAN) \
|
||||
UNICODE_RANGE(0x1000, 159, MYANMAR) \
|
||||
UNICODE_RANGE(0x10a0, 95, GEORGIAN) \
|
||||
UNICODE_RANGE(0x1100, 255, HANGUL_JAMO) \
|
||||
UNICODE_RANGE(0x1200, 383, ETHIOPIC) \
|
||||
UNICODE_RANGE(0x13a0, 95, CHEROKEE) \
|
||||
UNICODE_RANGE(0x1400, 639, UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS) \
|
||||
UNICODE_RANGE(0x1680, 31, OGHAM) \
|
||||
UNICODE_RANGE(0x16a0, 95, RUNIC) \
|
||||
UNICODE_RANGE(0x1700, 31, TAGALOG) \
|
||||
UNICODE_RANGE(0x1720, 31, HANUNOO) \
|
||||
UNICODE_RANGE(0x1740, 31, BUHID) \
|
||||
UNICODE_RANGE(0x1760, 31, TAGBANWA) \
|
||||
UNICODE_RANGE(0x1780, 127, KHMER) \
|
||||
UNICODE_RANGE(0x1800, 175, MONGOLIAN) \
|
||||
UNICODE_RANGE(0x1900, 79, LIMBU) \
|
||||
UNICODE_RANGE(0x1950, 47, TAI_LE) \
|
||||
UNICODE_RANGE(0x19e0, 31, KHMER_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d00, 127, PHONETIC_EXTENSIONS) \
|
||||
UNICODE_RANGE(0x1e00, 255, LATIN_EXTENDED_ADDITIONAL) \
|
||||
UNICODE_RANGE(0x1f00, 255, GREEK_EXTENDED) \
|
||||
UNICODE_RANGE(0x2000, 111, GENERAL_PUNCTUATION) \
|
||||
UNICODE_RANGE(0x2070, 47, SUPERSCRIPTS_AND_SUBSCRIPTS) \
|
||||
UNICODE_RANGE(0x20a0, 47, CURRENCY_SYMBOLS) \
|
||||
UNICODE_RANGE(0x20d0, 47, COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS) \
|
||||
UNICODE_RANGE(0x2100, 79, LETTERLIKE_SYMBOLS) \
|
||||
UNICODE_RANGE(0x2150, 63, NUMBER_FORMS) \
|
||||
UNICODE_RANGE(0x2190, 111, ARROWS) \
|
||||
UNICODE_RANGE(0x2200, 255, MATHEMATICAL_OPERATORS) \
|
||||
UNICODE_RANGE(0x2300, 255, MISCELLANEOUS_TECHNICAL) \
|
||||
UNICODE_RANGE(0x2400, 63, CONTROL_PICTURES) \
|
||||
UNICODE_RANGE(0x2440, 31, OPTICAL_CHARACTER_RECOGNITION) \
|
||||
UNICODE_RANGE(0x2460, 159, ENCLOSED_ALPHANUMERICS) \
|
||||
UNICODE_RANGE(0x2500, 127, BOX_DRAWING) \
|
||||
UNICODE_RANGE(0x2580, 31, BLOCK_ELEMENTS) \
|
||||
UNICODE_RANGE(0x25a0, 95, GEOMETRIC_SHAPES) \
|
||||
UNICODE_RANGE(0x2600, 255, MISCELLANEOUS_SYMBOLS) \
|
||||
UNICODE_RANGE(0x2700, 191, DINGBATS) \
|
||||
UNICODE_RANGE(0x27c0, 47, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A) \
|
||||
UNICODE_RANGE(0x27f0, 15, SUPPLEMENTAL_ARROWS_A) \
|
||||
UNICODE_RANGE(0x2800, 255, BRAILLE_PATTERNS) \
|
||||
UNICODE_RANGE(0x2900, 127, SUPPLEMENTAL_ARROWS_B) \
|
||||
UNICODE_RANGE(0x2980, 127, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B) \
|
||||
UNICODE_RANGE(0x2a00, 255, SUPPLEMENTAL_MATHEMATICAL_OPERATORS) \
|
||||
UNICODE_RANGE(0x2b00, 255, MISCELLANEOUS_SYMBOLS_AND_ARROWS) \
|
||||
UNICODE_RANGE(0x2e80, 127, CJK_RADICALS_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0x2f00, 223, KANGXI_RADICALS) \
|
||||
UNICODE_RANGE(0x2ff0, 15, IDEOGRAPHIC_DESCRIPTION_CHARACTERS) \
|
||||
UNICODE_RANGE(0x3000, 63, CJK_SYMBOLS_AND_PUNCTUATION) \
|
||||
UNICODE_RANGE(0x3040, 95, HIRAGANA) \
|
||||
UNICODE_RANGE(0x30a0, 95, KATAKANA) \
|
||||
UNICODE_RANGE(0x3100, 47, BOPOMOFO) \
|
||||
UNICODE_RANGE(0x3130, 95, HANGUL_COMPATIBILITY_JAMO) \
|
||||
UNICODE_RANGE(0x3190, 15, KANBUN_KUNTEN) \
|
||||
UNICODE_RANGE(0x31a0, 31, BOPOMOFO_EXTENDED) \
|
||||
UNICODE_RANGE(0x31f0, 15, KATAKANA_PHONETIC_EXTENSIONS) \
|
||||
UNICODE_RANGE(0x3200, 255, ENCLOSED_CJK_LETTERS_AND_MONTHS) \
|
||||
UNICODE_RANGE(0x3300, 255, CJK_COMPATIBILITY) \
|
||||
UNICODE_RANGE(0x3400, 6591, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) \
|
||||
UNICODE_RANGE(0x4dc0, 63, YIJING_HEXAGRAM_SYMBOLS) \
|
||||
UNICODE_RANGE(0x4e00, 20911, CJK_UNIFIED_IDEOGRAPHS) \
|
||||
UNICODE_RANGE(0xa000, 1167, YI_SYLLABLES) \
|
||||
UNICODE_RANGE(0xa490, 63, YI_RADICALS) \
|
||||
UNICODE_RANGE(0xac00, 11183, HANGUL_SYLLABLES) \
|
||||
UNICODE_RANGE(0xd800, 1023, HIGH_SURROGATE_AREA) \
|
||||
UNICODE_RANGE(0xdc00, 1023, LOW_SURROGATE_AREA) \
|
||||
UNICODE_RANGE(0xe000, 6399, PRIVATE_USE_AREA) \
|
||||
UNICODE_RANGE(0xf900, 511, CJK_COMPATIBILITY_IDEOGRAPHS) \
|
||||
UNICODE_RANGE(0xfb00, 79, ALPHABETIC_PRESENTATION_FORMS) \
|
||||
UNICODE_RANGE(0xfb50, 687, ARABIC_PRESENTATION_FORMS_A) \
|
||||
UNICODE_RANGE(0xfe00, 15, VARIATION_SELECTORS) \
|
||||
UNICODE_RANGE(0xfe20, 15, COMBINING_HALF_MARKS) \
|
||||
UNICODE_RANGE(0xfe30, 31, CJK_COMPATIBILITY_FORMS) \
|
||||
UNICODE_RANGE(0xfe50, 31, SMALL_FORM_VARIANTS) \
|
||||
UNICODE_RANGE(0xfe70, 143, ARABIC_PRESENTATION_FORMS_B) \
|
||||
UNICODE_RANGE(0xff00, 239, HALFWIDTH_AND_FULLWIDTH_FORMS) \
|
||||
UNICODE_RANGE(0xfff0, 15, SPECIALS) \
|
||||
UNICODE_RANGE(0x10000, 127, LINEAR_B_SYLLABARY) \
|
||||
UNICODE_RANGE(0x10080, 127, LINEAR_B_IDEOGRAMS) \
|
||||
UNICODE_RANGE(0x10100, 63, AEGEAN_NUMBERS) \
|
||||
UNICODE_RANGE(0x10300, 47, OLD_ITALIC) \
|
||||
UNICODE_RANGE(0x10330, 31, GOTHIC) \
|
||||
UNICODE_RANGE(0x10380, 31, UGARITIC) \
|
||||
UNICODE_RANGE(0x10400, 79, DESERET) \
|
||||
UNICODE_RANGE(0x10450, 47, SHAVIAN) \
|
||||
UNICODE_RANGE(0x10480, 47, OSMANYA) \
|
||||
UNICODE_RANGE(0x10800, 63, CYPRIOT_SYLLABARY) \
|
||||
UNICODE_RANGE(0x1d000, 255, BYZANTINE_MUSICAL_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d100, 255, MUSICAL_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d300, 95, TAI_XUAN_JING_SYMBOLS) \
|
||||
UNICODE_RANGE(0x1d400, 1023, MATHEMATICAL_ALPHANUMERIC_SYMBOLS) \
|
||||
UNICODE_RANGE(0x20000, 42719, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B) \
|
||||
UNICODE_RANGE(0x2f800, 543, CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0xe0000, 127, TAGS) \
|
||||
UNICODE_RANGE(0xe0100, 239, VARIATION_SELECTORS_SUPPLEMENT) \
|
||||
UNICODE_RANGE(0xf0000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_A) \
|
||||
UNICODE_RANGE(0x100000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_B)
|
||||
|
||||
#define UNICODE_RANGE(start, count, name) \
|
||||
MP_API extern const unicode_range _cat2_(UNICODE_RANGE_, name);
|
||||
UNICODE_RANGES
|
||||
#undef UNICODE_RANGE
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //__UTF8_H_
|
||||
|
|
2
todo.txt
2
todo.txt
|
@ -16,7 +16,7 @@ Overview
|
|||
[.] Make linking with libEGL optional, even if EGL backend is compiled in milepost?
|
||||
[x] using weak linking on macos
|
||||
[ ] use /DELAYLOAD:lib on windows?
|
||||
[.] Remove the need for client apps to link with all dependent libs explicitly
|
||||
[x] Remove the need for client apps to link with all dependent libs explicitly
|
||||
|
||||
[!] Allow controlling surface overlaying
|
||||
[!] Sort out contents scaling for high dpi on osx
|
||||
|
|
Loading…
Reference in New Issue